123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- #include "pch.h"
- #ifndef XG_REFLECT_CPP
- #define XG_REFLECT_CPP
- ///////////////////////////////////////////////////////////////////
- #include "Reflect.h"
- Object::~Object()
- {
- }
- string Object::toString() const
- {
- char buffer[16];
- sprintf(buffer, "%p", this);
- return buffer;
- }
- const char* Object::getClassName() const
- {
- #ifdef _MSC_VER
- return typeid(*this).name() + 6;
- #else
- const char* str = typeid(*this).name();
- while (*str >= '0' && *str <= '9') str++;
- return str;
- #endif
- }
- class ReflectAttrMap
- {
- friend class ReflectHelper;
- public:
- class Item
- {
- public:
- const char* type;
- const char* name;
- Item() : type(NULL), name(NULL)
- {
- }
- };
- class Data : public SpinMutex
- {
- public:
- int ofs;
- int end;
- ReflectKey key;
- mutable Item arr[10000];
- vector<ReflectItem> vec;
- public:
- Data(const Data& obj)
- {
- ofs = obj.ofs;
- end = obj.end;
- key = obj.key;
- }
- Data(ReflectKey _key = 0) : ofs(-1), end(-1), key(_key)
- {
- }
- public:
- vector<ReflectItem> getArrList()
- {
- if (end >= ofs) return vec;
- lock();
- vector<ReflectItem> res;
- for (int i = 0; i <= ofs; i++)
- {
- const Item& item = arr[i];
- if (item.name) res.push_back(ReflectItem(i, item.type, item.name));
- }
- vec = res;
- end = ofs;
- unlock();
- return res;
- }
- void add(int offset, const char* type, const char* name)
- {
- if (ofs >= offset) return;
- if (strcmp(type, "int") && strcmp(type, "bool") && strcmp(type, "float") && strcmp(type, "double") && strcmp(type, "string")) type = "object";
- assert(offset < ARR_LEN(arr));
- Item& item = arr[offset];
- lock();
- ofs = offset;
- item.type = type;
- item.name = name;
- unlock();
- }
- };
- protected:
- SpinMutex mtx;
- vector<Data> arr[10000];
- vector<ReflectItem> getAttrList(ReflectKey key)
- {
- vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
- for (Data& item : vec) if (key == item.key) return item.getArrList();
- return vector<ReflectItem>();
- }
- void add(Object* self, void* data, const char* type, const char* name)
- {
- ReflectKey key = ReflectHelper::GetKey(self);
- vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
- for (Data& item : vec)
- {
- if (key == item.key)
- {
- item.add((char*)(data) - (char*)(self), type, name);
- return;
- }
- }
- {
- SpinLocker lk(mtx);
- for (Data& item : vec)
- {
- if (key == item.key)
- {
- item.add((char*)(data) - (char*)(self), type, name);
- return;
- }
- }
- vec.push_back(Data(key));
- vec.back().add((char*)(data) - (char*)(self), type, name);
- }
- }
- void add(Object* self, Object* data, const char* type, const char* name)
- {
- ReflectKey key = ReflectHelper::GetKey(data);
- vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
- if (vec.size() > 0) add(self, (void*)(data), type, name);
- }
- };
- string ReflectItem::get(const void* obj) const
- {
- char* dest = (char*)(obj) + offset;
- if (type == NULL || strcmp(type, "object") == 0) return "";
- if (strcmp(type, "int") == 0) return to_string(*(int*)(dest));
- if (strcmp(type, "bool") == 0) return *(bool*)(dest) ? "true" : "false";
- if (strcmp(type, "float") == 0) return to_string(*(float*)(dest));
- if (strcmp(type, "double") == 0) return to_string(*(double*)(dest));
- return *(string*)(dest);
- }
- bool ReflectItem::set(void* obj, int val) const
- {
- char* dest = (char*)(obj) + offset;
- if (type == NULL || strcmp(type, "object") == 0) return false;
- if (strcmp(type, "int") == 0)
- {
- *(int*)(dest) = val;
- }
- else if (strcmp(type, "bool") == 0)
- {
- *(bool*)(dest) = val ? true : false;
- }
- else if (strcmp(type, "float") == 0)
- {
- *(float*)(dest) = val;
- }
- else if (strcmp(type, "double") == 0)
- {
- *(double*)(dest) = val;
- }
- else
- {
- *(string*)(dest) = to_string(val);
- }
- return true;
- }
- bool ReflectItem::set(void* obj, double val) const
- {
- char* dest = (char*)(obj) + offset;
- if (type == NULL || strcmp(type, "object") == 0) return false;
- if (strcmp(type, "int") == 0)
- {
- *(int*)(dest) = val;
- }
- else if (strcmp(type, "bool") == 0)
- {
- *(bool*)(dest) = val < -0.000001 || val > 0.000001;
- }
- else if (strcmp(type, "float") == 0)
- {
- *(float*)(dest) = val;
- }
- else if (strcmp(type, "double") == 0)
- {
- *(double*)(dest) = val;
- }
- else
- {
- *(string*)(dest) = to_string(val);
- }
- return true;
- }
- bool ReflectItem::set(void* obj, const char* val) const
- {
- char* dest = (char*)(obj) + offset;
- if (val == NULL || type == NULL || strcmp(type, "object") == 0) return false;
- if (strcmp(type, "string") == 0)
- {
- *(string*)(dest) = val;
- }
- else
- {
- if (*val == 0) return true;
- if (strcmp(type, "int") == 0)
- {
- *(int*)(dest) = atoi(val);
- }
- else if (strcmp(type, "bool") == 0)
- {
- *(bool*)(dest) = strcasecmp(val, "true") == 0;
- }
- else if (strcmp(type, "float") == 0)
- {
- *(float*)(dest) = atof(val);
- }
- else
- {
- *(double*)(dest) = atof(val);
- }
- }
- return true;
- }
- static ReflectAttrMap attrmap;
- string ReflectHelper::GetAttrString(ReflectKey key)
- {
- string res;
- string gap = ",";
- vector<ReflectItem> vec = attrmap.getAttrList(key);
- if (vec.empty()) return res;
- for (auto& item : vec) res += gap + item.getName();
- return res.substr(gap.length());
- }
- vector<ReflectItem> ReflectHelper::GetAttrList(ReflectKey key)
- {
- return attrmap.getAttrList(key);
- }
- ReflectHelper::ReflectHelper(Object* self, void* data, const char* type, const char* name)
- {
- attrmap.add(self, data, type, name);
- }
- ReflectHelper::ReflectHelper(Object* self, Object* data, const char* type, const char* name)
- {
- attrmap.add(self, data, type, name);
- }
- ///////////////////////////////////////////////////////////////////
- #endif
|