#pragma once #include #include namespace a8 { namespace reflect { class Class; } struct ReflectibleObject { a8::reflect::Class *metaclass = NULL; }; namespace reflect { enum FieldType { ET_INT32 = 1, ET_UINT32 = 2, ET_INT64 = 3, ET_UINT64 = 4, ET_FLOAT = 5, ET_DOUBLE = 6, ET_STRING = 7, ET_CLASS = 8, ET_INTERFACE = 9, }; 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 std::list 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_; } const char* ClassName() { return class_name_; } Field* GetFieldByName(const std::string& name); long long GetFieldValueAsInt64(a8::reflect::Field* field, char* p); std::string GetFieldValueAsString(a8::reflect::Field* field, char* p); void SetSimpleField( int fieldidx, const char* fieldname, int type, int offset ); 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*) ); int GetFieldIdx(int offset); private: int class_id_ = 0; int tag_ = 0; int fieldnum_ = 0; const char* class_name_ = nullptr; a8::reflect::Field* fields_ = nullptr; }; template static void* _create() { return (void*) new T(); } template static void _destroy(void* instance) { T* p = (T*)instance; delete p; } template static void _copy(void* a, void* b) { *(T*)a = *(T*)b; } template static int _size(void* instance) { T* p = (T*)instance; return p->size(); } template 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 static char* _push_back(void* instance) { T* p = (T*)instance; return (char*)&a8::FastAppend(*p); } template inline a8::reflect::Class** get_pp_generic_class(a8::ReflectibleObject& obj) { return &T::__metaclass; } template 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, 0); \ metaclass->create =&a8::reflect::_create; \ metaclass->destroy =&a8::reflect::_destroy; \ metaclass->copy =&a8::reflect::_copy; \ 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, 0); \ metaclass->create =&a8::reflect::_create; \ metaclass->destroy =&a8::reflect::_destroy; \ metaclass->copy =&a8::reflect::_copy; \ /*classname::__metaclass = metaclass;*/ \ /*assert(classname::CLSID < 1024);*/ \ /*s_mfclass_metaclasses[0] = 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(p.fieldname), \ &a8::reflect::_create, \ &a8::reflect::_destroy, \ &a8::reflect::_size, \ &a8::reflect::_for_each , \ &a8::reflect::_push_back \ ); #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(p.fieldname), \ &a8::reflect::_create, \ &a8::reflect::_destroy, \ &a8::reflect::_size, \ &a8::reflect::_for_each , \ &a8::reflect::_push_back \ );