代码拉取完成,页面将自动刷新
#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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。