add relect
This commit is contained in:
parent
5c144d4357
commit
966f7119e7
276
a8/reflect.h
Normal file
276
a8/reflect.h
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace a8
|
||||||
|
{
|
||||||
|
namespace reflect
|
||||||
|
{
|
||||||
|
|
||||||
|
enum FieldType
|
||||||
|
{
|
||||||
|
ET_INT32 = 1,
|
||||||
|
ET_UINT32 = 2,
|
||||||
|
ET_INT64 = 3,
|
||||||
|
ET_UINT64 = 4,
|
||||||
|
ET_DOUBLE = 5,
|
||||||
|
ET_STRING = 6,
|
||||||
|
ET_CLASS = 7,
|
||||||
|
ET_INTERFACE = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FieldSubType
|
||||||
|
{
|
||||||
|
EST_SIMPLE = 1,
|
||||||
|
EST_SIMPLE_POINTER = 2,
|
||||||
|
EST_CONTAINRER = 3,
|
||||||
|
EST_CONTAINRER_POINTER = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Field;
|
||||||
|
class Class;
|
||||||
|
typedef bool (*FIELD_FOR_EACH_FUNC)(a8::reflect::Field*, void*, void*);
|
||||||
|
|
||||||
|
struct Field
|
||||||
|
{
|
||||||
|
const char* field_name = nullptr;
|
||||||
|
int type = 0; //int uint int64 uint64 double string class interface class_pointer
|
||||||
|
int subtype = 0; //std::vector<x> std::list<x>
|
||||||
|
int offset = 0;
|
||||||
|
a8::reflect::Class **pp_generic_class = nullptr; //泛型容器类型指针的指针
|
||||||
|
void* (*create)() = nullptr;
|
||||||
|
void (*destroy)(void*) = nullptr;
|
||||||
|
int (*size)(void*) = nullptr;
|
||||||
|
void (*for_each)(a8::reflect::Field*, void*, void* , FIELD_FOR_EACH_FUNC) = nullptr;
|
||||||
|
char* (*push_back)(void*) = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void* (*create)() = nullptr;
|
||||||
|
void (*destroy)(void*) = nullptr;
|
||||||
|
void (*copy)(void*, void*) = nullptr;
|
||||||
|
|
||||||
|
Class(const char* classname, int fieldnum, int tag)
|
||||||
|
{
|
||||||
|
class_name_ = classname;
|
||||||
|
tag_ = tag;
|
||||||
|
fields_ = new a8::reflect::Field[fieldnum];
|
||||||
|
fieldnum_ = fieldnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
a8::reflect::Field* GetDeclaredFields()
|
||||||
|
{
|
||||||
|
return fields_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FieldNum()
|
||||||
|
{
|
||||||
|
return fieldnum_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClassId()
|
||||||
|
{
|
||||||
|
return class_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tag()
|
||||||
|
{
|
||||||
|
return tag_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetField(int fieldidx,
|
||||||
|
const char* fieldname,
|
||||||
|
int type,
|
||||||
|
int subtype,
|
||||||
|
int offset,
|
||||||
|
a8::reflect::Class **pp_generic_class,
|
||||||
|
void* (*create)(),
|
||||||
|
void (*destroy)(void*),
|
||||||
|
int (*size)(void*),
|
||||||
|
void (*for_each)(a8::reflect::Field*, void*, void*, FIELD_FOR_EACH_FUNC),
|
||||||
|
char* (*push_back)(void*)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
a8::reflect::Field *p = fields_ + fieldidx;
|
||||||
|
p->field_name = fieldname;
|
||||||
|
p->type = type;
|
||||||
|
p->subtype = subtype;
|
||||||
|
p->offset = offset;
|
||||||
|
p->pp_generic_class = pp_generic_class;
|
||||||
|
p->create = create;
|
||||||
|
p->destroy = destroy;
|
||||||
|
p->size = size;
|
||||||
|
p->for_each = for_each;
|
||||||
|
p->push_back = push_back;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetFieldIdx(int offset)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fieldnum_; i++) {
|
||||||
|
if (fields_[i].offset == offset) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ClassName()
|
||||||
|
{
|
||||||
|
return class_name_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int class_id_ = 0;
|
||||||
|
int tag_ = 0;
|
||||||
|
int fieldnum_ = 0;
|
||||||
|
const char* class_name_ = nullptr;
|
||||||
|
a8::reflect::Field* fields_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void* _create()
|
||||||
|
{
|
||||||
|
return (void*) new T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void _destroy(void* instance)
|
||||||
|
{
|
||||||
|
T* p = (T*)instance;
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void _copy(void* a, void* b)
|
||||||
|
{
|
||||||
|
*(T*)a = *(T*)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static int _size(void* instance)
|
||||||
|
{
|
||||||
|
T* p = (T*)instance;
|
||||||
|
return p->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void _for_each(a8::reflect::Field* field, void* instance, void* userdata,
|
||||||
|
FIELD_FOR_EACH_FUNC callback)
|
||||||
|
{
|
||||||
|
T* p = (T*)instance;
|
||||||
|
for (auto &itr : *p) {
|
||||||
|
if (callback && !callback(field, userdata, (void*)&itr)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static char* _push_back(void* instance)
|
||||||
|
{
|
||||||
|
T* p = (T*)instance;
|
||||||
|
return (char*)&a8::FastAppend(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline a8::reflect::Class** get_pp_generic_class(a8::ReflectibleObject& obj)
|
||||||
|
{
|
||||||
|
return &T::__metaclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline a8::reflect::Class** get_pp_generic_class(const T& obj)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define my_offsetof2(TYPE, MEMBER) \
|
||||||
|
((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
|
||||||
|
|
||||||
|
#define container_of2(ptr, type, member) ({ \
|
||||||
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||||
|
(type *)( (char *)__mptr - my_offsetof2(type,member) );})
|
||||||
|
|
||||||
|
#define BEGIN_MSG_CLASS(classname, fieldnum) \
|
||||||
|
{ \
|
||||||
|
a8::reflect::Class *metaclass = new a8::reflect::Class(#classname, fieldnum, classname::CLSID); \
|
||||||
|
metaclass->create =&a8::reflect::_create<classname>; \
|
||||||
|
metaclass->destroy =&a8::reflect::_destroy<classname>; \
|
||||||
|
metaclass->copy =&a8::reflect::_copy<classname>; \
|
||||||
|
classname::__metaclass = metaclass; \
|
||||||
|
classname p;
|
||||||
|
|
||||||
|
#define END_MSG_CLASS() \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BEGIN_MFMSG_CLASS(classname, fieldnum) \
|
||||||
|
{ \
|
||||||
|
a8::reflect::Class *metaclass = new a8::reflect::Class(#classname, fieldnum, classname::CLSID); \
|
||||||
|
metaclass->create =&a8::reflect::_create<classname>; \
|
||||||
|
metaclass->destroy =&a8::reflect::_destroy<classname>; \
|
||||||
|
metaclass->copy =&a8::reflect::_copy<classname>; \
|
||||||
|
classname::__metaclass = metaclass; \
|
||||||
|
assert(classname::CLSID < 1024); \
|
||||||
|
s_mfclass_metaclasses[classname::CLSID] = metaclass; \
|
||||||
|
classname p;
|
||||||
|
|
||||||
|
#define END_MFMSG_CLASS() \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_SIMPLE_FIELD(fieldidx, fieldname, type) \
|
||||||
|
metaclass->SetField(fieldidx, \
|
||||||
|
#fieldname, \
|
||||||
|
type, \
|
||||||
|
a8::reflect::EST_SIMPLE, \
|
||||||
|
my_offsetof2(decltype(p), fieldname), \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
#define DEFINE_SIMPLE_POINTER_FIELD(fieldidx, fieldname, type) \
|
||||||
|
metaclass->SetField(fieldidx, \
|
||||||
|
#fieldname, \
|
||||||
|
type, \
|
||||||
|
a8::reflect::EST_SIMPLE_POINTER, \
|
||||||
|
my_offsetof2(decltype(p), fieldname), \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
#define DEFINE_CONTAINRER_FIELD(fieldidx, fieldname, type) \
|
||||||
|
metaclass->SetField(fieldidx, \
|
||||||
|
#fieldname, \
|
||||||
|
type, \
|
||||||
|
a8::reflect::EST_CONTAINRER, \
|
||||||
|
my_offsetof2(decltype(p), fieldname), \
|
||||||
|
a8::reflect::get_pp_generic_class<decltype(p.fieldname)>(p.fieldname), \
|
||||||
|
&a8::reflect::_create<decltype(p.fieldname)>, \
|
||||||
|
&a8::reflect::_destroy<decltype(p.fieldname)>, \
|
||||||
|
&a8::reflect::_size<decltype(p.fieldname)>, \
|
||||||
|
&a8::reflect::_for_each<decltype(p.fieldname)> , \
|
||||||
|
&a8::reflect::_push_back<decltype(p.fieldname)> \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define DEFINE_CONTAINRER_POINTER_FIELD(fieldidx, fieldname, type) \
|
||||||
|
metaclass->SetField(fieldidx, \
|
||||||
|
#fieldname, \
|
||||||
|
type, \
|
||||||
|
a8::reflect::EST_CONTAINRER_POINTER, \
|
||||||
|
my_offsetof2(decltype(p), fieldname), \
|
||||||
|
a8::reflect::get_pp_generic_class<decltype(p.fieldname)>(p.fieldname), \
|
||||||
|
&a8::reflect::_create<decltype(p.fieldname)>, \
|
||||||
|
&a8::reflect::_destroy<decltype(p.fieldname)>, \
|
||||||
|
&a8::reflect::_size<decltype(p.fieldname)>, \
|
||||||
|
&a8::reflect::_for_each<decltype(p.fieldname)> , \
|
||||||
|
&a8::reflect::_push_back<decltype(p.fieldname)> \
|
||||||
|
);
|
Loading…
x
Reference in New Issue
Block a user