-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreflection.h
99 lines (82 loc) · 3.3 KB
/
reflection.h
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
#ifndef __RUNTIME_REFLECT_H__
#define __RUNTIME_REFLECT_H__
/*!
example:
class CRecordSuper {
DECLARE_REFLECT_BASE(CRecordSuper)
};
IMPLEMENT_REFLECT_BASE(CRecordSuper)
class CRecordPass : public CRecordSuper {
DECLARE_RUNTIME_REFLECT(CRecordPass, CRecordSuper)
};
IMPLEMENT_RUNTIME_REFLECT(CRecordPass, CRecordSuper)
CRecordSuper * super = CRuntimeReflect<CRecordSuper>::CreateObject(L"CRecordPass");
if (NULL == super) ...
...
delete super, super = NULL;
*/
//! author : chenyao ([email protected])
#undef RUNTIME_REFLECT
#define RUNTIME_REFLECT(class_name, class_base) \
((CRuntimeReflect<class_base> *)(&class_name::reflect##class_name))
#undef DECLARE_REFLECT_BASE
#define DECLARE_REFLECT_BASE(class_name) \
public: \
static CRuntimeReflect<class_name> reflect##class_name; \
virtual CRuntimeReflect<class_name> * GetRuntimeReflect();
#undef IMPLEMENT_REFLECT_BASE
#define IMPLEMENT_REFLECT_BASE(class_name) \
CRuntimeReflect<class_name> class_name::reflect##class_name = \
{ L###class_name, NULL, NULL }; \
CRuntimeReflect<class_name> * class_name::GetRuntimeReflect() \
{ return RUNTIME_REFLECT(class_name, class_name); } \
RUNTIME_REFLECT_INIT<class_name> _init_reflect_##class_name(RUNTIME_REFLECT(class_name, class_name));
#undef DECLARE_RUNTIME_REFLECT
#define DECLARE_RUNTIME_REFLECT(class_name, class_base) \
public: \
static class_base * CreateReflect(); \
static CRuntimeReflect<class_base> reflect##class_name; \
virtual CRuntimeReflect<class_base> * GetRuntimeReflect();
#undef IMPLEMENT_RUNTIME_REFLECT
#define IMPLEMENT_RUNTIME_REFLECT(class_name, class_base) \
class_base * class_name::CreateReflect() \
{ return dynamic_cast<class_base *>(new class_name); } \
CRuntimeReflect<class_base> class_name::reflect##class_name = \
{ L###class_name, class_name::CreateReflect, NULL }; \
CRuntimeReflect<class_base> * class_name::GetRuntimeReflect() \
{ return RUNTIME_REFLECT(class_name, class_base); } \
RUNTIME_REFLECT_INIT<class_base> _init_reflect_##class_name(RUNTIME_REFLECT(class_name, class_base));
template <class T> struct CRuntimeReflect {
const wchar_t * m_className;
T * (* m_createObject)();
T * CreateObject();
static CRuntimeReflect * FromName(const wchar_t * className);
static T * CreateObject(const wchar_t * className);
static CRuntimeReflect * m_firstClass;
CRuntimeReflect * m_nextClass; // linked list of registered classes
};
template <class T> struct RUNTIME_REFLECT_INIT {
RUNTIME_REFLECT_INIT(CRuntimeReflect<T> * newClass) {
newClass->m_nextClass = CRuntimeReflect<T>::m_firstClass;
CRuntimeReflect<T>::m_firstClass = newClass;
}
};
template <class T>
CRuntimeReflect<T> * CRuntimeReflect<T>::m_firstClass = NULL;
template <class T>
T * CRuntimeReflect<T>::CreateObject() {
return NULL == m_createObject ? NULL : (* m_createObject)();
}
template <class T>
CRuntimeReflect<T> * CRuntimeReflect<T>::FromName(const wchar_t * className) {
for (CRuntimeReflect * iter = CRuntimeReflect::m_firstClass;
NULL != iter; iter = iter->m_nextClass)
if (0 == wcscmp(className, iter->m_className)) return iter;
return NULL;
}
template <class T>
T * CRuntimeReflect<T>::CreateObject(const wchar_t * className) {
CRuntimeReflect * runtime = FromName(className);
return NULL == runtime ? NULL : runtime->CreateObject();
}
#endif