reflect.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "pch.h"
  2. #ifndef XG_REFLECT_CPP
  3. #define XG_REFLECT_CPP
  4. ///////////////////////////////////////////////////////////////////
  5. #include "Reflect.h"
  6. Object::~Object()
  7. {
  8. }
  9. string Object::toString() const
  10. {
  11. char buffer[16];
  12. sprintf(buffer, "%p", this);
  13. return buffer;
  14. }
  15. const char* Object::getClassName() const
  16. {
  17. #ifdef _MSC_VER
  18. return typeid(*this).name() + 6;
  19. #else
  20. const char* str = typeid(*this).name();
  21. while (*str >= '0' && *str <= '9') str++;
  22. return str;
  23. #endif
  24. }
  25. class ReflectAttrMap
  26. {
  27. friend class ReflectHelper;
  28. public:
  29. class Item
  30. {
  31. public:
  32. const char* type;
  33. const char* name;
  34. Item() : type(NULL), name(NULL)
  35. {
  36. }
  37. };
  38. class Data : public SpinMutex
  39. {
  40. public:
  41. int ofs;
  42. int end;
  43. ReflectKey key;
  44. mutable Item arr[10000];
  45. vector<ReflectItem> vec;
  46. public:
  47. Data(const Data& obj)
  48. {
  49. ofs = obj.ofs;
  50. end = obj.end;
  51. key = obj.key;
  52. }
  53. Data(ReflectKey _key = 0) : ofs(-1), end(-1), key(_key)
  54. {
  55. }
  56. public:
  57. vector<ReflectItem> getArrList()
  58. {
  59. if (end >= ofs) return vec;
  60. lock();
  61. vector<ReflectItem> res;
  62. for (int i = 0; i <= ofs; i++)
  63. {
  64. const Item& item = arr[i];
  65. if (item.name) res.push_back(ReflectItem(i, item.type, item.name));
  66. }
  67. vec = res;
  68. end = ofs;
  69. unlock();
  70. return res;
  71. }
  72. void add(int offset, const char* type, const char* name)
  73. {
  74. if (ofs >= offset) return;
  75. if (strcmp(type, "int") && strcmp(type, "bool") && strcmp(type, "float") && strcmp(type, "double") && strcmp(type, "string")) type = "object";
  76. assert(offset < ARR_LEN(arr));
  77. Item& item = arr[offset];
  78. lock();
  79. ofs = offset;
  80. item.type = type;
  81. item.name = name;
  82. unlock();
  83. }
  84. };
  85. protected:
  86. SpinMutex mtx;
  87. vector<Data> arr[10000];
  88. vector<ReflectItem> getAttrList(ReflectKey key)
  89. {
  90. vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
  91. for (Data& item : vec) if (key == item.key) return item.getArrList();
  92. return vector<ReflectItem>();
  93. }
  94. void add(Object* self, void* data, const char* type, const char* name)
  95. {
  96. ReflectKey key = ReflectHelper::GetKey(self);
  97. vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
  98. for (Data& item : vec)
  99. {
  100. if (key == item.key)
  101. {
  102. item.add((char*)(data) - (char*)(self), type, name);
  103. return;
  104. }
  105. }
  106. {
  107. SpinLocker lk(mtx);
  108. for (Data& item : vec)
  109. {
  110. if (key == item.key)
  111. {
  112. item.add((char*)(data) - (char*)(self), type, name);
  113. return;
  114. }
  115. }
  116. vec.push_back(Data(key));
  117. vec.back().add((char*)(data) - (char*)(self), type, name);
  118. }
  119. }
  120. void add(Object* self, Object* data, const char* type, const char* name)
  121. {
  122. ReflectKey key = ReflectHelper::GetKey(data);
  123. vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
  124. if (vec.size() > 0) add(self, (void*)(data), type, name);
  125. }
  126. };
  127. string ReflectItem::get(const void* obj) const
  128. {
  129. char* dest = (char*)(obj) + offset;
  130. if (type == NULL || strcmp(type, "object") == 0) return "";
  131. if (strcmp(type, "int") == 0) return to_string(*(int*)(dest));
  132. if (strcmp(type, "bool") == 0) return *(bool*)(dest) ? "true" : "false";
  133. if (strcmp(type, "float") == 0) return to_string(*(float*)(dest));
  134. if (strcmp(type, "double") == 0) return to_string(*(double*)(dest));
  135. return *(string*)(dest);
  136. }
  137. bool ReflectItem::set(void* obj, int val) const
  138. {
  139. char* dest = (char*)(obj) + offset;
  140. if (type == NULL || strcmp(type, "object") == 0) return false;
  141. if (strcmp(type, "int") == 0)
  142. {
  143. *(int*)(dest) = val;
  144. }
  145. else if (strcmp(type, "bool") == 0)
  146. {
  147. *(bool*)(dest) = val ? true : false;
  148. }
  149. else if (strcmp(type, "float") == 0)
  150. {
  151. *(float*)(dest) = val;
  152. }
  153. else if (strcmp(type, "double") == 0)
  154. {
  155. *(double*)(dest) = val;
  156. }
  157. else
  158. {
  159. *(string*)(dest) = to_string(val);
  160. }
  161. return true;
  162. }
  163. bool ReflectItem::set(void* obj, double val) const
  164. {
  165. char* dest = (char*)(obj) + offset;
  166. if (type == NULL || strcmp(type, "object") == 0) return false;
  167. if (strcmp(type, "int") == 0)
  168. {
  169. *(int*)(dest) = val;
  170. }
  171. else if (strcmp(type, "bool") == 0)
  172. {
  173. *(bool*)(dest) = val < -0.000001 || val > 0.000001;
  174. }
  175. else if (strcmp(type, "float") == 0)
  176. {
  177. *(float*)(dest) = val;
  178. }
  179. else if (strcmp(type, "double") == 0)
  180. {
  181. *(double*)(dest) = val;
  182. }
  183. else
  184. {
  185. *(string*)(dest) = to_string(val);
  186. }
  187. return true;
  188. }
  189. bool ReflectItem::set(void* obj, const char* val) const
  190. {
  191. char* dest = (char*)(obj) + offset;
  192. if (val == NULL || type == NULL || strcmp(type, "object") == 0) return false;
  193. if (strcmp(type, "string") == 0)
  194. {
  195. *(string*)(dest) = val;
  196. }
  197. else
  198. {
  199. if (*val == 0) return true;
  200. if (strcmp(type, "int") == 0)
  201. {
  202. *(int*)(dest) = atoi(val);
  203. }
  204. else if (strcmp(type, "bool") == 0)
  205. {
  206. *(bool*)(dest) = strcasecmp(val, "true") == 0;
  207. }
  208. else if (strcmp(type, "float") == 0)
  209. {
  210. *(float*)(dest) = atof(val);
  211. }
  212. else
  213. {
  214. *(double*)(dest) = atof(val);
  215. }
  216. }
  217. return true;
  218. }
  219. static ReflectAttrMap attrmap;
  220. string ReflectHelper::GetAttrString(ReflectKey key)
  221. {
  222. string res;
  223. string gap = ",";
  224. vector<ReflectItem> vec = attrmap.getAttrList(key);
  225. if (vec.empty()) return res;
  226. for (auto& item : vec) res += gap + item.getName();
  227. return res.substr(gap.length());
  228. }
  229. vector<ReflectItem> ReflectHelper::GetAttrList(ReflectKey key)
  230. {
  231. return attrmap.getAttrList(key);
  232. }
  233. ReflectHelper::ReflectHelper(Object* self, void* data, const char* type, const char* name)
  234. {
  235. attrmap.add(self, data, type, name);
  236. }
  237. ReflectHelper::ReflectHelper(Object* self, Object* data, const char* type, const char* name)
  238. {
  239. attrmap.add(self, data, type, name);
  240. }
  241. ///////////////////////////////////////////////////////////////////
  242. #endif