add relect

This commit is contained in:
aozhiwei 2022-12-20 21:23:41 +08:00
parent 5c144d4357
commit 966f7119e7

276
a8/reflect.h Normal file
View 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)> \
);