Skip to content

Commit e29388a

Browse files
committed
feat(Reflection): Impl variable reflection, Change the reflection class to namespace
1 parent ee95149 commit e29388a

10 files changed

Lines changed: 222 additions & 112 deletions

File tree

include/Core/Reflaction.hpp

Lines changed: 148 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,181 @@
11
#pragma once
22

33
#include "Export.h"
4+
#include "SObject.h"
45

56
#include <cstddef>
67
#include <typeinfo>
78
#include <type_traits>
89
#include <utility>
10+
#include <vector>
11+
#include <map>
12+
#include <string>
913

1014
#define SCLASS(class_name)\
1115
public:\
12-
using Super = sh::core::Reflection::MakeSuper<class_name>::type;\
16+
using Super = sh::core::reflection::MakeSuper<class_name>::type;\
1317
using This = class_name;\
1418
public:\
15-
static auto GetStaticTypeInfo() -> const sh::core::Reflection::TypeInfo&\
19+
static auto GetStaticType() -> sh::core::reflection::TypeInfo&\
1620
{\
17-
static sh::core::Reflection::TypeInfo info{ sh::core::Reflection::TypeInfoData<class_name>(#class_name) };\
21+
static sh::core::reflection::TypeInfo info{ sh::core::reflection::TypeInfoData<class_name>(#class_name) };\
1822
return info;\
1923
}\
20-
virtual auto GetTypeInfo() const -> const sh::core::Reflection::TypeInfo&\
24+
virtual auto GetType() const -> sh::core::reflection::TypeInfo&\
2125
{\
2226
return typeInfo;\
2327
}\
24-
private:\
25-
inline static const sh::core::Reflection::TypeInfo& typeInfo = GetStaticTypeInfo();
28+
private:\
29+
inline static sh::core::reflection::TypeInfo& typeInfo = GetStaticType();
2630

27-
namespace sh::core
31+
#define PROPERTY(variable_name)\
32+
struct _PropertyFactory_##variable_name\
33+
{\
34+
_PropertyFactory_##variable_name()\
35+
{\
36+
static sh::core::reflection::PropertyInfo\
37+
<This, \
38+
decltype(variable_name), \
39+
decltype(&This::##variable_name), \
40+
&This::##variable_name> property_##variable_name{ #variable_name };\
41+
}\
42+
} _propertyFactory_##variable_name;\
43+
44+
namespace sh::core::reflection
2845
{
29-
class SH_CORE_API Reflection
46+
class TypeInfo;
47+
class Property;
48+
49+
template<typename T>
50+
struct TypeInfoData
3051
{
31-
public:
32-
class TypeInfo;
52+
const char* name;
53+
const TypeInfo* super;
3354

34-
template<typename T>
35-
struct TypeInfoData
55+
TypeInfoData(const char* name) :
56+
name(name), super(nullptr)
3657
{
37-
const char* name;
38-
const TypeInfo* super;
39-
40-
TypeInfoData(const char* name) :
41-
name(name), super(nullptr)
58+
if constexpr (HasSuper<T>())
4259
{
43-
if constexpr (HasSuper<T>())
44-
{
45-
super = &(T::Super::GetStaticTypeInfo());
46-
}
60+
super = &(T::Super::GetStaticType());
4761
}
48-
};
49-
50-
class SH_CORE_API TypeInfo {
51-
private:
52-
const char* name;
53-
const TypeInfo* super;
54-
const size_t hash;
55-
public:
56-
template<typename T>
57-
explicit TypeInfo(TypeInfoData<T> data) :
58-
name(data.name), super(data.super), hash(typeid(T).hash_code()) {}
59-
60-
auto GetName() const -> const char*;
61-
auto GetSuper() const -> const TypeInfo*;
62-
//other와 자신이 같은 타입인지
63-
bool IsA(const TypeInfo& other) const;
64-
//현재 타입이 other의 자식인지
65-
bool IsChild(const TypeInfo& other) const;
66-
};
62+
}
63+
};
64+
65+
class TypeInfo {
66+
private:
67+
const char* name;
68+
const TypeInfo* super;
69+
const size_t hash;
70+
71+
std::map<std::string, Property> properties;
6772
public:
68-
template<typename T, typename U = void>
69-
struct MakeSuper {
70-
using type = U;
71-
};
72-
template<typename T>
73-
struct MakeSuper<T, std::void_t<typename T::This>> {
74-
using type = typename T::This;
75-
};
76-
77-
//기본 HasSuper 구조체
78-
template<typename T, typename U = void>
79-
struct HasSuper :
80-
std::bool_constant<false> {};
81-
//T가 Super을 가지고 있다면 오버로딩 된다(SFINAE). 없으면 기본HasSuper
8273
template<typename T>
83-
struct HasSuper<T, std::void_t<typename T::Super>> :
84-
std::bool_constant<!std::is_same_v<typename T::Super, void>> {};
74+
explicit TypeInfo(TypeInfoData<T> data) :
75+
name(data.name), super(data.super), hash(typeid(T).hash_code()) {}
8576

86-
template<typename T, typename U = void>
87-
struct HasThis :
88-
std::bool_constant<false> {};
77+
SH_CORE_API auto GetName() const -> const char*;
78+
SH_CORE_API auto GetSuper() const -> const TypeInfo*;
79+
//other와 자신이 같은 타입인지
80+
SH_CORE_API bool IsA(const TypeInfo& other) const;
81+
//현재 타입이 other의 자식인지
82+
SH_CORE_API bool IsChild(const TypeInfo& other) const;
8983

90-
template<typename T>
91-
struct HasThis<T, std::void_t<typename T::This>> :
92-
std::bool_constant<!std::is_same_v<typename T::This, void>> {};
84+
SH_CORE_API void AddProperty(const std::string& name, const Property& prop);
85+
SH_CORE_API auto GetProperty(const std::string& name) const -> const Property*;
86+
SH_CORE_API auto GetProperties(const std::string& name) const -> const std::map<std::string, Property>&;
87+
};//TypeInfo
9388

94-
template<typename T>
95-
struct IsSClass : std::bool_constant<HasThis<T>::value> {};
89+
class PropertyDataBase
90+
{
91+
};
92+
93+
template<typename T>
94+
class IPropertyData : public PropertyDataBase
95+
{
96+
public:
97+
virtual auto Get(void* sobject) const -> T& = 0;
9698
};
99+
100+
template<typename ThisType, typename T>
101+
class PropertyData : public IPropertyData<T>
102+
{
103+
private:
104+
T ThisType::* ptr; //맴버변수 포인터
105+
public:
106+
PropertyData(T ThisType::* ptr):
107+
ptr(ptr)
108+
{
109+
}
110+
111+
auto Get(void* sobject) const -> T& override
112+
{
113+
return static_cast<ThisType*>(sobject)->*ptr;
114+
}
115+
};
116+
117+
template<typename ThisType, typename T, typename VariablePointer, VariablePointer ptr>
118+
class PropertyInfo
119+
{
120+
private:
121+
const char* name;
122+
TypeInfo& owner;
123+
VariablePointer test;
124+
public:
125+
PropertyInfo(const char* name) :
126+
name(name), owner(ThisType::GetStaticType())
127+
{
128+
129+
static PropertyData<ThisType, T> data{ ptr };
130+
Property property{ &data };
131+
owner.AddProperty(name, property);
132+
}
133+
};
134+
135+
class Property
136+
{
137+
private:
138+
PropertyDataBase* data;
139+
public:
140+
Property(PropertyDataBase* data) :
141+
data(data)
142+
{
143+
144+
}
145+
146+
template<typename T, typename ThisType>
147+
auto Get(ThisType* sobject) const -> T&
148+
{
149+
return static_cast<IPropertyData<T>*>(data)->Get(sobject);
150+
}
151+
};
152+
153+
template<typename T, typename U = void>
154+
struct MakeSuper {
155+
using type = U;
156+
};
157+
template<typename T>
158+
struct MakeSuper<T, std::void_t<typename T::This>> {
159+
using type = typename T::This;
160+
};
161+
162+
//기본 HasSuper 구조체
163+
template<typename T, typename U = void>
164+
struct HasSuper :
165+
std::bool_constant<false> {};
166+
//T가 Super을 가지고 있다면 오버로딩 된다(SFINAE). 없으면 기본HasSuper
167+
template<typename T>
168+
struct HasSuper<T, std::void_t<typename T::Super>> :
169+
std::bool_constant<!std::is_same_v<typename T::Super, void>> {};
170+
171+
template<typename T, typename U = void>
172+
struct HasThis :
173+
std::bool_constant<false> {};
174+
175+
template<typename T>
176+
struct HasThis<T, std::void_t<typename T::This>> :
177+
std::bool_constant<!std::is_same_v<typename T::This, void>> {};
178+
179+
template<typename T>
180+
struct IsSClass : std::bool_constant<HasThis<T>::value> {};
97181
}

include/Core/SObject.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
namespace sh::core
4+
{
5+
class ISObject
6+
{
7+
public:
8+
virtual void Awake() = 0;
9+
virtual void Start() = 0;
10+
virtual void OnEnable() = 0;
11+
virtual void Update() = 0;
12+
virtual void LateUpdate() = 0;
13+
};
14+
}

include/Core/Util.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ namespace sh::core {
3939
/// 둘 다 SCLASS매크로가 선언 돼 있어야한다.
4040
template<typename To, typename From>
4141
static auto Cast(From* src) -> std::enable_if_t<
42-
sh::core::Reflection::IsSClass<To>::value &&
43-
sh::core::Reflection::IsSClass<From>::value, To*>
42+
sh::core::reflection::IsSClass<To>::value &&
43+
sh::core::reflection::IsSClass<From>::value, To*>
4444
{
4545
if (!src) return nullptr;
46-
if (src->GetTypeInfo().IsChild(To::GetStaticTypeInfo()))
46+
if (src->GetType().IsChild(To::GetStaticType()))
4747
return reinterpret_cast<To*>(src);
4848
return nullptr;
4949
}

include/Game/Component/Component.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include "Game/Export.h"
44

5-
#include "Game/SObject.h"
5+
#include "Core/SObject.h"
66

77
#include "Core/Reflaction.hpp"
88
#include "Core/Util.h"
@@ -13,7 +13,7 @@ namespace sh::game
1313
{
1414
class GameObject;
1515

16-
class Component : public ISObject
16+
class Component : public sh::core::ISObject
1717
{
1818
SCLASS(Component)
1919
private:

include/Game/GameObject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include "Export.h"
44

5-
#include "SObject.h"
5+
#include "Core/SObject.h"
66
#include "Component/Component.h"
77
#include "World.h"
88

@@ -14,7 +14,7 @@
1414

1515
namespace sh::game
1616
{
17-
class GameObject : public ISObject
17+
class GameObject : public sh::core::ISObject
1818
{
1919
SCLASS(GameObject)
2020
private:

include/Game/SObject.h

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/Core/Reflaction.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
#include "Reflaction.hpp"
22

3-
namespace sh::core
3+
namespace sh::core::reflection
44
{
5-
auto Reflection::TypeInfo::GetName() const -> const char*
5+
auto TypeInfo::GetName() const -> const char*
66
{
77
return name;
88
}
99

10-
auto Reflection::TypeInfo::GetSuper() const -> const TypeInfo*
10+
auto TypeInfo::GetSuper() const -> const TypeInfo*
1111
{
1212
return super;
1313
}
1414

15-
bool Reflection::TypeInfo::IsA(const TypeInfo& other) const
15+
bool TypeInfo::IsA(const TypeInfo& other) const
1616
{
1717
if (this == &other)
1818
return true;
1919

2020
return this->hash == other.hash;
2121
}
2222

23-
bool Reflection::TypeInfo::IsChild(const TypeInfo& other) const
23+
bool TypeInfo::IsChild(const TypeInfo& other) const
2424
{
2525
if (IsA(other))
2626
return true;
@@ -34,4 +34,22 @@ namespace sh::core
3434
}
3535
return false;
3636
}
37-
}
37+
38+
void TypeInfo::AddProperty(const std::string& name, const Property& prop)
39+
{
40+
properties.insert({ name, prop });
41+
}
42+
43+
auto TypeInfo::GetProperty(const std::string& name) const -> const Property*
44+
{
45+
auto it = properties.find(name);
46+
if (it == properties.end())
47+
return nullptr;
48+
return &it->second;
49+
}
50+
51+
auto TypeInfo::GetProperties(const std::string& name) const -> const std::map<std::string, Property>&
52+
{
53+
return properties;
54+
}
55+
;}

src/Game/GameObject.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "GameObject.h"
22

3-
#include "SObject.h"
43
#include "Component/Component.h"
54

65
namespace sh::game

0 commit comments

Comments
 (0)