-
-
Notifications
You must be signed in to change notification settings - Fork 80
/
Copy pathexample-custom-rtti.cpp
116 lines (95 loc) · 2.62 KB
/
example-custom-rtti.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
* ***README***
* This example showcases how a runtime reflection system can be implemented on
* top of refl-cpp (here only the name of the type is being stored, but this can be extended).
*
* We are storing the runtime information in TypeInfo. TypeInfo also has a factory method called
* Get<T>, which creates an instance of TypeInfo by using metadata from refl-cpp.
*/
#include <cassert>
#include "refl.hpp"
// create a class to hold runtime type information
class TypeInfo
{
public:
// instances can be obtained only through calls to Get()
template <typename T>
static const TypeInfo& Get()
{
// here we create the singleton instance for this particular type
static const TypeInfo ti(refl::reflect<T>());
return ti;
}
const std::string& Name() const
{
return name_;
}
private:
// were only storing the name for demonstration purposes,
// but this can be extended to hold other properties as well
std::string name_;
// given a type_descriptor, we construct a TypeInfo
// with all the metadata we care about (currently only name)
template <typename T, typename... Fields>
TypeInfo(refl::type_descriptor<T> td)
: name_(td.name)
{
}
};
// we will be using this base interface to specify that a type is
// reflectable at runtime using our custom system above
class Reflectable
{
public:
virtual const TypeInfo& GetTypeInfo() const = 0;
};
// define a convenience macro to autoimplement GetTypeInfo()
#define MYLIB_REFLECTABLE() \
virtual const TypeInfo& GetTypeInfo() const override \
{ \
return TypeInfo::Get<::refl::trait::remove_qualifiers_t<decltype(*this)>>(); \
}
class Actor : Reflectable
{
public:
// inject GetTypeInfo impl
MYLIB_REFLECTABLE()
virtual ~Actor() noexcept
{
}
};
// create refl-cpp metadata
REFL_AUTO(type(Actor))
// inherit reflectable type
class Pawn : public Actor
{
public:
// override GetTypeInfo with derived impl
MYLIB_REFLECTABLE()
virtual ~Pawn() noexcept
{
}
};
REFL_AUTO(type(Pawn))
class FirstPersonController : public Pawn
{
public:
// again, override GetTypeInfo with proper impl
MYLIB_REFLECTABLE()
int health = 100;
virtual ~FirstPersonController() noexcept
{
}
};
REFL_AUTO(
type(FirstPersonController),
field(health)
)
int main()
{
FirstPersonController fpc;
Pawn& pawn = fpc; // refer through parent type
const TypeInfo& pawnTypeInfo = pawn.GetTypeInfo(); // get custom type info
// access the name through our TypeInfo object
assert(pawnTypeInfo.Name() == "FirstPersonController");
}