#ifndef XG_REFLECT_H #define XG_REFLECT_H ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define reflect_object(type, name) \ type name; \ ReflectHelper __##name = ReflectHelper(this, &this->name, #type, #name) #define reflect_attr(type, name, defval) \ type name = defval; \ ReflectHelper __##name = ReflectHelper(this, &this->name, #type, #name) #define rint(name) reflect_attr(int, name, 0) #define rbool(name) reflect_attr(bool, name, false) #define rfloat(name) reflect_attr(float, name, 0.0F) #define rdouble(name) reflect_attr(double, name, 0.0F) #define reflect_int(name) reflect_attr(int, name, 0) #define reflect_bool(name) reflect_attr(bool, name, false) #define reflect_float(name) reflect_attr(float, name, 0.0F) #define reflect_double(name) reflect_attr(double, name, 0.0F) #define rstring(name) reflect_object(string, name) #define robject(type, name) reflect_object(type, name) #define reflect_string(name) reflect_object(string, name) #define sp shared_ptr #define newsp make_shared #define ARR_LEN(arr) (sizeof(arr)/sizeof(arr[0])) #define CHECK_FALSE_RETURN(FUNC) if (FUNC){} else return false #ifdef _MSC_VER #define strcasecmp stricmp #pragma warning(disable:4996) #endif using namespace std; typedef unsigned long long ReflectKey; class Object { public: virtual ~Object(); virtual string toString() const; virtual const char* getClassName() const; }; class SpinMutex : public Object { private: atomic_flag flag = ATOMIC_FLAG_INIT; public: void lock() { while (flag.test_and_set(memory_order_acquire)); } void unlock() { flag.clear(std::memory_order_release); } }; typedef lock_guard SpinLocker; class ReflectItem { friend class JsonReflect; protected: int offset; const char* name; const char* type; public: ReflectItem() : offset(0), type(NULL) { } ReflectItem(int _offset, const char* _type, const char* _name) : offset(_offset), type(_type), name(_name) { } public: bool operator < (const ReflectItem& obj) const { return offset < obj.offset; } bool operator == (const ReflectItem& obj) const { return offset == obj.offset; } public: string get(const void* obj) const; bool set(void* obj, int val) const; bool set(void* obj, double val) const; bool set(void* obj, const char* val) const; bool canUse() const { return type ? true : false; } int getOffset() const { return offset; } const char* getName() const { return name; } const char* getType() const { return type; } bool set(void* obj, bool val) const { return set(obj, val ? 1 : 0); } bool set(void* obj, float val) const { return set(obj, (double)(val)); } bool set(void* obj, const string& val) const { return set(obj, val.c_str()); } }; class ReflectHelper { public: static string GetAttrString(ReflectKey key); static vector GetAttrList(ReflectKey key); ReflectHelper(Object* self, void* data, const char* type, const char* name); ReflectHelper(Object* self, Object* data, const char* type, const char* name); static ReflectKey GetKey(const Object* obj) { return (ReflectKey)(typeid(*obj).name()); } template static ReflectKey GetKey() { return (ReflectKey)(typeid(REFLECT_TYPE).name()); } static string GetAttrString(const Object* obj) { return GetAttrString(GetKey(obj)); } template static string GetAttrString() { string res = GetAttrString(GetKey()); if (res.length() > 0) return res; REFLECT_TYPE item; return GetAttrString(&item); } static vector GetAttrList(const Object* obj) { return GetAttrList(GetKey(obj)); } template static vector GetAttrList() { vector vec = GetAttrList(GetKey()); if (vec.size() > 0) return std::move(vec); REFLECT_TYPE item; return GetAttrList(&item); } }; ////////////////////////////////////////////////////////////////////////////// #endif