后续:后续还会继续添加新的功能,类反射还没写,后续内容不限于类反射!!!
注意啊:
你在通过子类实例对象访问父类的函数或者属性的时候,会自动进行this指针调整的,现在自己在通过直接操作内存修改属性,不会帮你自动进行this指针调整,使用需要自己来实现。只有这样才可以进行正确的属性修改。
第一版:
1:这个C++ 反射库功能比较少,但是使用起来比较简单。
2:功能:支持属性类型信息查看,属性值获取,属性值设置,成员函数反射,成员函 数类型信息查看。
第二版:
1:在第一版的基础上新增可以通过子类反射父类的成员变量,可以根据字段所属类进行this指针调整来修改和获取字段值。
2:对适用于反射的Object对象进行安全处理,加强安全性,即使你转换类型不一致也不会崩溃。
1:Reflect.h
#ifndef REFLECT_H
#define REFLECT_H
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#ifdef _WIN32
#define REFLECT_EXPORT __declspec(dllexport)
//windows x86 or x68
#ifdef _WIN64 //x64 windows
typedef signed long long pointer_int;
#else //x86 windows
typedef signed int pointer_int;
#endif //end of _WIN64
#else //unix
#define REFLECT_EXPORT
#ifdef __x86_64__ //x64 unix
typedef signed long long pointer_int;
#elif __i386__ //x86 unix
typedef signed int pointer_int;
#endif //end of __x86_64__
#endif //end of _WIN32
#define LocalOffset(func) *(pointer_int*)((pointer_int)&func)
namespace Trds {
namespace Reflect {
class TrdsObject;
// 是否启用C++17
#if __cplusplus >= 201703L
#define CPP_HAS_17 1
#endif
// Error id
constexpr int error_id_0_Unclear = 0;
constexpr int error_id_1_too_few_parameters = 1;
constexpr int error_id_2_too_many_parameters = 2;
constexpr int error_id_3_types_do_not_match = 3;
static const char* error_buffer[]
{
"Unknown exception. Please carefully check whether the number of parameter bindings or the types of parameter bindings are correct. Note that the type of the incoming parameters needs to strictly correspond.",
"Too few parameters are passed in",
"Too many parameters are passed in",
"The parameter types do not match"
};
class ICallBackException : public std::exception {
public:
ICallBackException(int error_id = 0)
{
m_error_id = error_id;
}
virtual const char* what()const override
{
return error_buffer[m_error_id];
}
private:
int m_error_id{ 0 };
};
class CallBackExceptionUnClear : public ICallBackException
{
public:
CallBackExceptionUnClear()
:ICallBackException(error_id_0_Unclear)
{
}
};
class CallBackExceptionFewParameters : public ICallBackException
{
public:
CallBackExceptionFewParameters()
:ICallBackException(error_id_1_too_few_parameters)
{
}
};
class CallBackExceptionManyParameters : public ICallBackException
{
public:
CallBackExceptionManyParameters()
:ICallBackException(error_id_2_too_many_parameters)
{
}
};
class CallBackExceptionNotMatch : public ICallBackException
{
public:
CallBackExceptionNotMatch()
:ICallBackException(error_id_3_types_do_not_match)
{
}
};
template<typename T> struct Array { using type = T*; };
template<typename T> struct Array<T*> { using type = T(*)[1]; };
template<> struct Array<void*> { using type = void**; };
template<typename T> struct Array<T[]> { using type = T(*)[1]; };
template<typename T> struct function_traits;
template<typename R, typename ...Args>
struct function_traits<R(Args...)>
{
enum
{
arity = sizeof...(Args)
};
static const char* typeinfos[arity + 1];
typedef R Ret;
typedef R function(Args...);
typedef R(*function_pointer)(Args...);
using args_tuple_pointer = std::tuple<typename Array<std::remove_cv_t<std::remove_reference_t<Args>>>::type...>;
};
template<typename R, typename ...Args>
const char* function_traits<R(Args...)>::typeinfos[arity + 1] = { typeid(Args).name()... };
template<typename R, typename Type, typename ...Args> struct function_traits<R(Type::*)(Args...)> : public function_traits<R(Args...)> { using object = Type; using object_pointer = Type*; };
template<typename R, typename Type, typename ...Args> struct function_traits<R(Type::*)(Args...)const> : public function_traits<R(Args...)> { using object = Type; using object_pointer = Type*; };
class Object final
{
public:
Object()
{
data_.reset();
}
template <typename T>
Object(T* data, bool isHeap = true)
{
data_.reset(new ObjectTemplat<T>(data, isHeap));
}
template <typename T>
Object(const T& data)
{
data_.reset(new ObjectTemplat<T>(data));
}
Object(const Object& rvalue) noexcept
{
data_ = rvalue.data_;
}
Object(Object&& rvalue) noexcept
{
data_.swap(const_cast<Object&>(rvalue).data_);
}
Object& operator=(const Object& rvalue) noexcept
{
data_ = rvalue.data_;
return*this;
}
Object& operator=(Object&& rvalue) noexcept
{
data_.swap(const_cast<Object&>(rvalue).data_);
return*this;
}
void Release()
{
data_->Release();
}
operator bool()const
{
return data_.get();
}
char* GetCharPtr()const
{
return data_->GetCharPtr();
}
int GetSize()const
{
return data_->GetSize();
}
bool IsPtr()const
{
return data_->IsPtr();
}
void SetSize(int size)
{
data_->SetSize(size);
}
template <typename T, typename U = char>
T Value()
{
if (GetSize() != sizeof(T))
{
return T();
}
ObjectTemplat<U>* vptr = dynamic_cast<ObjectTemplat<U>*>(data_.get());
return *(T*)vptr->Get();
}
class IBaseVlaue
{
public:
virtual void SetSize(int size) = 0;
virtual void Release() = 0;
virtual bool IsPtr()const = 0;
virtual ~IBaseVlaue() = default;
virtual char* GetCharPtr()const = 0;
virtual int GetSize()const = 0;
};
template <typename T> class ObjectTemplat : public IBaseVlaue
{
public:
ObjectTemplat(const T& data)
: isHeap(true)
{
#ifdef CPP_HAS_17
if constexpr (std::is_void_v<T>)
{
data_ = data;
}
else
{
#endif
data_ = new T(data);
#ifdef CPP_HAS_17
}
#endif
size_ = sizeof(T);
isPointer = false;
}
ObjectTemplat(const T* data)
: isHeap(true)
{
data_ = const_cast<T*>(data);
size_ = sizeof(T*);
isPointer = true;
}
ObjectTemplat(T* data, bool isHeap)
: isHeap(isHeap), data_(data)
{
size_ = sizeof(T*);
isPointer = true;
}
~ObjectTemplat()
{
if (isHeap && data_)
{
delete data_;
}
data_ = nullptr;
}
virtual char* GetCharPtr()const
{
return reinterpret_cast<char*>(data_);
}
virtual int GetSize()const override
{
return size_;
}
virtual bool IsPtr()const
{
return isPointer;
}
virtual void Release() override
{
isHeap = false;
}
virtual void SetSize(int size) override
{
size_ = size;
}
T* Get()
{
return data_;
}
private:
bool isPointer = false;
bool isHeap;
T* data_;
int size_ = 0;
};
template <> class ObjectTemplat<void> : public IBaseVlaue
{
public:
ObjectTemplat(void* data)
: isHeap(true)
{
data_ = data;
size_ = sizeof(void*);
}
ObjectTemplat(void* data, bool isHeap)
: isHeap(isHeap), data_(data)
{
size_ = sizeof(void*);
}
~ObjectTemplat()
{
if (isHeap && data_)
{
::free(data_);
}
data_ = nullptr;
}
virtual char* GetCharPtr()const
{
return reinterpret_cast<char*>(data_);
}
virtual int GetSize()const override
{
return size_;
}
virtual bool IsPtr()const
{
return true;
}
virtual void Release() override
{
isHeap = false;
}
virtual void SetSize(int size) override
{
size_ = size;
}
void* Get()
{
return data_;
}
private:
bool isHeap;
void* data_;
int size_ = 0;
};
private:
std::shared_ptr<IBaseVlaue> data_;
};
class MetaFunction
{
public:
MetaFunction()
{
pBinder.reset();
mObj = nullptr;
}
template <typename R, typename Cla, typename... Args>
MetaFunction(const std::string& function_, R(Cla::* Call)(Args...))
{
pBinder.reset(new CPFunction<R(Cla::*)(Args...)>(function_, Call));
mObj = nullptr;
}
template <typename R, typename Cla, typename... Args>
MetaFunction(const std::string& function_, R(Cla::* Call)(Args...)const)
{
pBinder.reset(new CPFunction<R(Cla::*)(Args...)const>(function_, Call));
mObj = nullptr;
}
MetaFunction(const MetaFunction& ot) noexcept
{
pBinder = ot.pBinder;
mObj = ot.mObj;
}
MetaFunction(MetaFunction&& ot) noexcept
{
pBinder.swap(ot.pBinder);
mObj = ot.mObj;
}
MetaFunction& operator=(const MetaFunction& ot) noexcept
{
pBinder = ot.pBinder;
mObj = ot.mObj;
return*this;
}
MetaFunction& operator=(MetaFunction&& ot) noexcept
{
pBinder.swap(ot.pBinder);
mObj = ot.mObj;
return*this;
}
void setTrdsObject(TrdsObject* obj_)
{
mObj = obj_;
}
std::string GetName()const
{
return pBinder->GetName();
}
int GetLocalOffset()const
{
return pBinder->GetLocalOffset();
}
template <typename... Args>
Object operator()(Args&&... args) const& noexcept
{
auto& args_tuple = std::make_tuple(std::addressof(args)...);
const char* in[] = { 0, typeid(Args).name()... };
return pBinder->Call(mObj, &args_tuple, sizeof...(Args), in);
}
operator bool()
{
return pBinder.get() != nullptr;
}
protected:
class IBinderTemplate
{
private:
const std::string mName;
const pointer_int local_offset;
public:
IBinderTemplate(const std::string& mName, pointer_int local_offset) : mName(mName), local_offset(local_offset){}
virtual Object Call(TrdsObject* mObj, void* args, int count, const char** in) = 0;
int GetLocalOffset()const { return local_offset; }
virtual std::string GetName()const
{
return mName;
}
void Check(const char** need, const char** real, int nneed, int nreal)
{
if (nneed < nreal)
{
throw CallBackExceptionManyParameters();
}
if (nneed > nreal)
{
throw CallBackExceptionFewParameters();
}
for (int index_ = 0; index_ < nreal; ++index_)
{
if (strcmp(real[index_ + 1], need[index_]) != 0)
{
throw CallBackExceptionNotMatch();
}
}
}
virtual ~IBinderTemplate()
{
}
#ifdef CPP_HAS_17
template<typename RS, typename Function, typename Caller, typename Cla, size_t ...II>
Object CallBack(void* args, Cla* obj, Caller& caller, const std::index_sequence<II...>&)
{
using tupleArgs = typename function_traits<Function>::args_tuple_pointer;
tupleArgs& tuple = *reinterpret_cast<tupleArgs*>(args);
if constexpr (std::is_void_v<RS>)
{
(obj->*caller)(*std::get<II>(tuple)...);
return Object();
}
else
{
return (obj->*caller)(*std::get<II>(tuple)...);
}
}
};
#else
template<typename RS, typename Function, typename Caller, typename Cla, size_t ...II>
Object CallBack(RS*&, void* args, Cla* obj, Caller& caller, const std::index_sequence<II...>&)
{
using tupleArgs = typename function_traits<Function>::args_tuple_pointer;
tupleArgs& tuple = *reinterpret_cast<tupleArgs*>(args);
return (obj->*caller)(*std::get<II>(tuple)...);
}
template<typename RS, typename Function, typename Caller, typename Cla, size_t ...II>
Object CallBack(void*&, void* args, Cla* obj, Caller& caller, const std::index_sequence<II...>&)
{
using tupleArgs = typename function_traits<Function>::args_tuple_pointer;
tupleArgs& tuple = *reinterpret_cast<tupleArgs*>(args);
(obj->*caller)(*std::get<II>(tuple)...);
return Object();
}
};
#endif
template <typename CallAble, typename... BindArgs> class CPFunction;
template <typename R, typename Cla, typename... Args>
class CPFunction<R(Cla::*)(Args...)> : public IBinderTemplate
{
using Function = R(Cla::*)(Args...);
public:
CPFunction(const std::string& function_, Function func)
: mCall(func), IBinderTemplate(function_, LocalOffset(func))
{
}
virtual Object Call(TrdsObject* mObj, void* args, int count, const char** in) override
{
Check(function_traits<Function>::typeinfos, in, function_traits<Function>::arity, count);
using Ret = typename function_traits<Function>::Ret;
#ifdef CPP_HAS_17
return CallBack<Ret, Function, Function, Cla>(args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence<function_traits<Function>::arity>());
#else
Ret* temp = 0;
return CallBack<Ret, Function, Function, Cla>(temp, args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence<function_traits<Function>::arity>());
#endif
}
private:
Function mCall;
};
template <typename R, typename Cla, typename... Args>
class CPFunction<R(Cla::*)(Args...)const> : public IBinderTemplate
{
using Function = R(Cla::*)(Args...)const;
public:
CPFunction(const std::string& function_, Function func)
: mCall(func), IBinderTemplate(function_, LocalOffset(func))
{
}
virtual Object Call(TrdsObject* mObj, void* args, int count, const char** in) override
{
Check(function_traits<Function>::typeinfos, in, function_traits<Function>::arity, count);
using Ret = typename function_traits<Function>::Ret;
#ifdef CPP_HAS_17
return CallBack<Ret, Function, Function, Cla>(args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence<function_traits<Function>::arity>());
#else
Ret* temp = 0;
return CallBack<Ret, Function, Function, Cla>(temp, args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence < function_traits<Function>::arity>());
#endif
}
private:
Function mCall;
};
private:
std::shared_ptr<IBinderTemplate> pBinder;
TrdsObject* mObj;
};
class Field;
class MetaObject;
class MetaObjectImpl;
class MetaImpl;
class FieldImpl;
class SGenerateClassOffset;
class RegisterHelper;
using Supers = std::map<std::string, std::vector<SGenerateClassOffset>>;
using News = std::map<std::string, MetaFunction>;
using Invokes = std::map<std::string, std::vector<MetaFunction>>;
using Fields = std::map<std::string, std::vector<std::shared_ptr<Field>>>;
using MetaObjectPtr = std::shared_ptr<MetaObject>;
using TrdsObjectPtr = std::shared_ptr<TrdsObject>;
using FieldPtr = std::shared_ptr<Field>;
#define MEMBER_OFFSET(class, field) (pointer_int)(&((class*)0)->field)
#define MEMBER_SIZEOF(class, field) sizeof((((class*)0)->field))
#define CLASS_NAME(class) virtual std::string GetClassName()const { return #class; }
#define OBJECT_NAME public: virtual std::string GetObjName()const { return mName; } virtual std::string SetObjName(const std::string& name) { return mName = name; } private: std::string mName = "default";
#define TRDS_RELECT(class) public: virtual MetaObjectPtr Meta(){ if(!metaobj_) { metaobj_.swap(Meta::GetInstance()->GetMetaObject(this, #class));} return metaobj_; } CLASS_NAME(class)
#define REGISTER_FIELD(class, name) RegisterHelper class##_##name##_Register(#class, #name, MEMBER_OFFSET(class, name), MEMBER_SIZEOF(class, name), SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" });
#define REGISTER_INVOKE(class, name) RegisterHelper class##_##name##_function_Register(#class, MetaFunction(#name, &class::name));
#define REGISTER_MULTI_SUPER_1(class, _1) RegisterHelper _1_##class##_##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }});
#define REGISTER_MULTI_SUPER_2(class, _1, _2) RegisterHelper _2_##class##_##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 }});
#define REGISTER_MULTI_SUPER_3(class, _1, _2, _3) RegisterHelper _3_##class##_##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 }\
});
#define REGISTER_MULTI_SUPER_4(class, _1, _2, _3, _4) RegisterHelper _4_##class##_##_4##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 }\
});
#define REGISTER_MULTI_SUPER_5(class, _1, _2, _3, _4, _5) RegisterHelper _5_##class##_##_5##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 },\
SGenerateClassOffset{ GenerateClassOffset<class, _5>().offset(), #_5 } \
});
#define REGISTER_MULTI_SUPER_6(class, _1, _2, _3, _4, _5, _6) RegisterHelper _6_##class##_##_6##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 },\
SGenerateClassOffset{ GenerateClassOffset<class, _5>().offset(), #_5 },\
SGenerateClassOffset{ GenerateClassOffset<class, _6>().offset(), #_6 }\
});
#define REGISTER_MULTI_SUPER_7(class, _1, _2, _3, _4, _5, _6, _7) RegisterHelper _7_##class##_##_7##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 },\
SGenerateClassOffset{ GenerateClassOffset<class, _5>().offset(), #_5 },\
SGenerateClassOffset{ GenerateClassOffset<class, _6>().offset(), #_6 },\
SGenerateClassOffset{ GenerateClassOffset<class, _7>().offset(), #_7 }\
});
#define REGISTER_MULTI_SUPER_8(class, _1, _2, _3, _4, _5, _6, _7, _8) RegisterHelper _8_##class##_##_8##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 }, \
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 },\
SGenerateClassOffset{ GenerateClassOffset<class, _5>().offset(), #_5 },\
SGenerateClassOffset{ GenerateClassOffset<class, _6>().offset(), #_6 },\
SGenerateClassOffset{ GenerateClassOffset<class, _7>().offset(), #_7 },\
SGenerateClassOffset{ GenerateClassOffset<class, _8>().offset(), #_8 }\
});
#define REGISTER_MULTI_SUPER_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9) RegisterHelper _9_##class##_##_9##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 },\
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 },\
SGenerateClassOffset{ GenerateClassOffset<class, _5>().offset(), #_5 },\
SGenerateClassOffset{ GenerateClassOffset<class, _6>().offset(), #_6 },\
SGenerateClassOffset{ GenerateClassOffset<class, _7>().offset(), #_7 },\
SGenerateClassOffset{ GenerateClassOffset<class, _8>().offset(), #_8 },\
SGenerateClassOffset{ GenerateClassOffset<class, _9>().offset(), #_9 }\
});
#define REGISTER_MULTI_SUPER_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) RegisterHelper _10_##class##_##_10##_Superdata(#class, std::vector<SGenerateClassOffset>{ \
SGenerateClassOffset{ GenerateClassOffset<class, TrdsObject>().offset(), "TrdsObject" },\
SGenerateClassOffset{ GenerateClassOffset<class, _1>().offset(), #_1 },\
SGenerateClassOffset{ GenerateClassOffset<class, _2>().offset(), #_2 },\
SGenerateClassOffset{ GenerateClassOffset<class, _3>().offset(), #_3 },\
SGenerateClassOffset{ GenerateClassOffset<class, _4>().offset(), #_4 },\
SGenerateClassOffset{ GenerateClassOffset<class, _5>().offset(), #_5 },\
SGenerateClassOffset{ GenerateClassOffset<class, _6>().offset(), #_6 },\
SGenerateClassOffset{ GenerateClassOffset<class, _7>().offset(), #_7 },\
SGenerateClassOffset{ GenerateClassOffset<class, _8>().offset(), #_8 },\
SGenerateClassOffset{ GenerateClassOffset<class, _9>().offset(), #_9 },\
SGenerateClassOffset{ GenerateClassOffset<class, _10>().offset(), #_10 }\
});
#define REGISTER_MULTI_FIELD_1(class, _1) REGISTER_FIELD(class, _1)
#define REGISTER_MULTI_FIELD_2(class, _1, _2) REGISTER_MULTI_FIELD_1(class, _1) REGISTER_FIELD(class, _2)
#define REGISTER_MULTI_FIELD_3(class, _1, _2, _3) REGISTER_MULTI_FIELD_2(class, _1, _2) REGISTER_FIELD(class, _3)
#define REGISTER_MULTI_FIELD_4(class, _1, _2, _3, _4) REGISTER_MULTI_FIELD_3(class, _1, _2, _3) REGISTER_FIELD(class, _4)
#define REGISTER_MULTI_FIELD_5(class, _1, _2, _3, _4, _5) REGISTER_MULTI_FIELD_4(class, _1, _2, _3, _4) REGISTER_FIELD(class, _5)
#define REGISTER_MULTI_FIELD_6(class, _1, _2, _3, _4, _5, _6) REGISTER_MULTI_FIELD_5(class, _1, _2, _3, _4, _5) REGISTER_FIELD(class, _6)
#define REGISTER_MULTI_FIELD_7(class, _1, _2, _3, _4, _5, _6, _7) REGISTER_MULTI_FIELD_6(class, _1, _2, _3, _4, _5, _6) REGISTER_FIELD(class, _7)
#define REGISTER_MULTI_FIELD_8(class, _1, _2, _3, _4, _5, _6, _7, _8) REGISTER_MULTI_FIELD_7(class, _1, _2, _3, _4, _5, _6, _7) REGISTER_FIELD(class, _8)
#define REGISTER_MULTI_FIELD_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9) REGISTER_MULTI_FIELD_8(class, _1, _2, _3, _4, _5, _6, _7, _8) REGISTER_FIELD(class, _9)
#define REGISTER_MULTI_FIELD_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) REGISTER_MULTI_FIELD_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9) REGISTER_FIELD(class, _10)
#define REGISTER_MULTI_FIELD_11(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) REGISTER_MULTI_FIELD_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) REGISTER_FIELD(class, _11)
#define REGISTER_MULTI_FIELD_12(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) REGISTER_MULTI_FIELD_11(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) REGISTER_FIELD(class, _12)
#define REGISTER_MULTI_FIELD_13(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) REGISTER_MULTI_FIELD_12(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) REGISTER_FIELD(class, _13)
#define REGISTER_MULTI_FIELD_14(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) REGISTER_MULTI_FIELD_13(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) REGISTER_FIELD(class, _14)
#define REGISTER_MULTI_FIELD_15(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) REGISTER_MULTI_FIELD_14(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) REGISTER_FIELD(class, _15)
#define REGISTER_MULTI_FIELD_16(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) REGISTER_MULTI_FIELD_15(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) REGISTER_FIELD(class, _16)
#define REGISTER_MULTI_FIELD_17(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) REGISTER_MULTI_FIELD_16(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) REGISTER_FIELD(class, _17)
#define REGISTER_MULTI_FIELD_18(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) REGISTER_MULTI_FIELD_17(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) REGISTER_FIELD(class, _18)
#define REGISTER_MULTI_FIELD_19(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) REGISTER_MULTI_FIELD_18(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) REGISTER_FIELD(class, _19)
#define REGISTER_MULTI_FIELD_20(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20) REGISTER_MULTI_FIELD_19(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) REGISTER_FIELD(class, _20)
#define REGISTER_MULTI_FUNCTION_1(class, _1) REGISTER_INVOKE(class, _1)
#define REGISTER_MULTI_FUNCTION_2(class, _1, _2) REGISTER_MULTI_FUNCTION_1(class, _1) REGISTER_INVOKE(class, _2)
#define REGISTER_MULTI_FUNCTION_3(class, _1, _2, _3) REGISTER_MULTI_FUNCTION_2(class, _1, _2) REGISTER_INVOKE(class, _3)
#define REGISTER_MULTI_FUNCTION_4(class, _1, _2, _3, _4) REGISTER_MULTI_FUNCTION_3(class, _1, _2, _3) REGISTER_INVOKE(class, _4)
#define REGISTER_MULTI_FUNCTION_5(class, _1, _2, _3, _4, _5) REGISTER_MULTI_FUNCTION_4(class, _1, _2, _3, _4) REGISTER_INVOKE(class, _5)
#define REGISTER_MULTI_FUNCTION_6(class, _1, _2, _3, _4, _5, _6) REGISTER_MULTI_FUNCTION_5(class, _1, _2, _3, _4, _5) REGISTER_INVOKE(class, _6)
#define REGISTER_MULTI_FUNCTION_7(class, _1, _2, _3, _4, _5, _6, _7) REGISTER_MULTI_FUNCTION_6(class, _1, _2, _3, _4, _5, _6) REGISTER_INVOKE(class, _7)
#define REGISTER_MULTI_FUNCTION_8(class, _1, _2, _3, _4, _5, _6, _7, _8) REGISTER_MULTI_FUNCTION_7(class, _1, _2, _3, _4, _5, _6, _7) REGISTER_INVOKE(class, _8)
#define REGISTER_MULTI_FUNCTION_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9) REGISTER_MULTI_FUNCTION_8(class, _1, _2, _3, _4, _5, _6, _7, _8) REGISTER_INVOKE(class, _9)
#define REGISTER_MULTI_FUNCTION_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) REGISTER_MULTI_FUNCTION_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9) REGISTER_INVOKE(class, _10)
#define REGISTER_MULTI_FUNCTION_11(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) REGISTER_MULTI_FUNCTION_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) REGISTER_INVOKE(class, _11)
#define REGISTER_MULTI_FUNCTION_12(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) REGISTER_MULTI_FUNCTION_11(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) REGISTER_INVOKE(class, _12)
#define REGISTER_MULTI_FUNCTION_13(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) REGISTER_MULTI_FUNCTION_12(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) REGISTER_INVOKE(class, _13)
#define REGISTER_MULTI_FUNCTION_14(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) REGISTER_MULTI_FUNCTION_13(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) REGISTER_INVOKE(class, _14)
#define REGISTER_MULTI_FUNCTION_15(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) REGISTER_MULTI_FUNCTION_14(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) REGISTER_INVOKE(class, _15)
#define REGISTER_MULTI_FUNCTION_16(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) REGISTER_MULTI_FUNCTION_15(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) REGISTER_INVOKE(class, _16)
#define REGISTER_MULTI_FUNCTION_17(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) REGISTER_MULTI_FUNCTION_16(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) REGISTER_INVOKE(class, _17)
#define REGISTER_MULTI_FUNCTION_18(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) REGISTER_MULTI_FUNCTION_17(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) REGISTER_INVOKE(class, _18)
#define REGISTER_MULTI_FUNCTION_19(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) REGISTER_MULTI_FUNCTION_18(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) REGISTER_INVOKE(class, _19)
#define REGISTER_MULTI_FUNCTION_20(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20) REGISTER_MULTI_FUNCTION_19(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) REGISTER_INVOKE(class, _20)
#define REFLECT_COUNT_OF_N_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define REFLECT_COUNT_OF_N(...) REFLECT_COUNT_OF_N_IMPL(##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define REFLECT_EXPAND_2(x) x
#define REFLECT_EXPAND(x) REFLECT_EXPAND_2(x)
#define REFLECT_CONTACT_2(x, y) x##y
#define REFLECT_CONTACT(x, y) REFLECT_CONTACT_2(x, y)
#define REGISTER_SUPER(class, ...) REFLECT_EXPAND(REFLECT_CONTACT(REGISTER_MULTI_SUPER_, REFLECT_COUNT_OF_N(__VA_ARGS__)))(class, __VA_ARGS__)
#define REGISTER_FIELDS(class, ...) REFLECT_EXPAND(REFLECT_CONTACT(REGISTER_MULTI_FIELD_, REFLECT_COUNT_OF_N(__VA_ARGS__)))(class, __VA_ARGS__)
#define REGISTER_INVOKES(class, ...) REFLECT_EXPAND(REFLECT_CONTACT(REGISTER_MULTI_FUNCTION_, REFLECT_COUNT_OF_N(__VA_ARGS__)))(class, __VA_ARGS__)
class REFLECT_EXPORT GenerateClassOffsetBase
{
public:
virtual int offset()const = 0;
};
template<typename Sub, typename Base>
class GenerateClassOffset : public GenerateClassOffsetBase
{
public:
virtual int offset() const override
{
Sub sub;
Base* base = static_cast<Base*>(&sub);
return (char*)(base) - (char*)(dynamic_cast<Sub*>(base));
}
};
using GenerateClassOffsetBasePtr = std::shared_ptr<GenerateClassOffsetBase>;
struct REFLECT_EXPORT SGenerateClassOffset
{
int offset_;
std::string name_;
};
class REFLECT_EXPORT Meta
{
public:
static Meta* GetInstance();
MetaObjectPtr GetMetaObject(const void* _o, const std::string& _class);
TrdsObjectPtr NewInstance(const std::string& _class);
void RegisterNew(const std::string& _class, const MetaFunction& newc);
void RegisterInvoke(const std::string& _class, const MetaFunction& newc);
void RegisterField(const std::string& _class, FieldPtr _filed);
void RegisterSupers(const std::string& sub, std::vector<SGenerateClassOffset>& supers);
protected:
protected:
Meta();
Meta(const Meta&) = delete;
Meta(Meta&&) = delete;
Meta& operator=(const Meta&) = delete;
Meta& operator=(Meta&&) = delete;
private:
std::shared_ptr<MetaImpl> meta_;
};
class REFLECT_EXPORT RegisterHelper
{
public:
RegisterHelper(const std::string& clas_, const std::string& filed_, int offset_, int size_, const SGenerateClassOffset& toTrdsOffset);
RegisterHelper(const std::string& clas_, const MetaFunction& function, bool creator = false);
RegisterHelper(const std::string& clas_, std::vector<SGenerateClassOffset>& supers);
};
class REFLECT_EXPORT TrdsObject
{
OBJECT_NAME
TRDS_RELECT(TrdsObject)
public:
template<typename SubType>
SubType* Dynamic_cast()
{
return dynamic_cast<SubType*>(this);
}
protected:
MetaObjectPtr metaobj_;
std::vector<MetaObjectPtr> superObj_;
};
REGISTER_INVOKES(TrdsObject, GetObjName, SetObjName, Meta)
class REFLECT_EXPORT MetaObject
{
friend MetaImpl;
public:
MetaObject(void* _o, const std::string& _class, const Invokes& invokes, const Fields& fields, const News& news, const Supers& supers);
FieldPtr GetField(int _d)const;
FieldPtr GetField(const std::string& _d)const;
MetaFunction GetMethod(const std::string& _d)const;
MetaFunction GetMethod(int _d)const;
int GetMethodCount()const;
int GetFieldCount()const;
std::string GetClassName()const;
protected:
std::shared_ptr<MetaObjectImpl> meta_;
};
class REFLECT_EXPORT Field
{
public:
std::string FieldName()const;
int FieldSize()const;
int Offset()const;
std::string ClassName()const;
TrdsObject* GetInstance()const;
void SetValue(const Object& _val);
Object GetValue()const;
SGenerateClassOffset GetToTrdsOvjOffset()const;
Field(int _offset, int size, const std::string& field, const std::string& class_, const SGenerateClassOffset& toTrdsOffset);
Field(void* _o, int _offset, int size, const std::string& field, const std::string& class_, const SGenerateClassOffset& toTrdsOffset);
private:
std::shared_ptr<FieldImpl> meta_;
};
//end
}
}
#endif//REFLECT_H
2:Reflect.cpp
#include "reflect.h"
#include <algorithm>
namespace Trds { namespace Reflect {
class REFLECT_EXPORT MetaImpl
{
public:
MetaObjectPtr GetMetaObject(void* _o, const std::string& _class)
{
return MetaObjectPtr(new MetaObject(_o, _class, reflect_call, reflect_field, reflect_new, reflect_supers));
}
TrdsObjectPtr NewInstance(const std::string& _class)
{
if (reflect_new.find(_class) == reflect_new.end())
{
return nullptr;
}
TrdsObject* trds = reflect_new[_class]().Value<TrdsObject*>();
return TrdsObjectPtr(trds);
}
void RegisterNew(const std::string& _class, const MetaFunction& newc)
{
reflect_new[_class] = newc;
}
void RegisterInvoke(const std::string& _class, const MetaFunction& newc)
{
reflect_call[_class].push_back(newc);
}
void RegisterField(const std::string& _class, FieldPtr _filed)
{
reflect_field[_class].push_back(_filed);
}
void RegisterSupers(const std::string& sub, std::vector<SGenerateClassOffset>& supers)
{
reflect_supers[sub].swap(supers);
}
private:
Supers reflect_supers;
News reflect_new;
Invokes reflect_call;
Fields reflect_field;
};
class REFLECT_EXPORT MetaObjectImpl
{
public:
MetaObjectImpl(void* _o, const std::string& _class, const Invokes& invokes, const Fields& fields, const News& news, const Supers& supers)
:_o(_o),_invokes(invokes), _fields(fields),_news(news),_supers(supers), _class(_class)
{
/*using FieldVector = std::vector<std::shared_ptr<Field>>;
auto pobj_ = (TrdsObject*)_o;
Fields::const_iterator iter = _fields.find((pobj_)->GetClassName());
if (iter != _fields.cend())
{
FieldVector& fields_ = const_cast<FieldVector&>(iter->second);
std::sort(fields_.begin(), fields_.end(), [](const FieldPtr& f, const FieldPtr& s)
{
return f->Offset() < s->Offset();
});
}
using MetaFunctionVector = std::vector<MetaFunction>;
Invokes::const_iterator iter1 = _invokes.find(((TrdsObject*)_o)->GetClassName());
if (iter1 != _invokes.cend())
{
MetaFunctionVector& metafunction_ = const_cast<MetaFunctionVector&>(iter1->second);
std::sort(metafunction_.begin(), metafunction_.end(), [](const MetaFunction& f, const MetaFunction& s)
{
return f.GetLocalOffset() < s.GetLocalOffset();
});
}*/
}
TrdsObject* GetTrdsObject()const
{
TrdsObject* trdsobj_ = (TrdsObject*)((char*)_o + _supers.at(_class)[0].offset_);
return trdsobj_;
}
std::string GetClassName()const
{
return _class;
}
int GetMethodCount()const
{
if (_MethodCount == -1)
{
TrdsObject* trdsobj_ = GetTrdsObject();
auto name = (trdsobj_)->GetClassName();
for (auto pair : _invokes)
{
if (pair.first == name)
{
_MethodCount = pair.second.size();
break;
}
}
}
return _MethodCount;
}
MetaFunction GetMetaFunctionOf(const std::string& class_, const std::string& method_)const
{
auto iter = _invokes.find(class_);
if (iter == _invokes.end())
{
return MetaFunction();
}
auto& vct = iter->second;
for (int i_ = 0; i_ < vct.size(); ++i_)
{
if (method_ == vct[i_].GetName())
{
return vct[i_];
}
}
return MetaFunction();
}
MetaFunction SeekMetaFunction(const std::string& class_, const std::string& method_)const
{
MetaFunction result = GetMetaFunctionOf(class_, method_);
if (result)
{
return result;
}
const auto& vect = _supers.at(class_);
for (const auto& super : vect)
{
MetaFunction result = SeekMetaFunction(super.name_, method_);
if (result)
{
return result;
}
}
return MetaFunction();
}
MetaFunction GetMethod(const std::string& _d)const
{
TrdsObject* trdsobj_ = GetTrdsObject();
auto name = trdsobj_->GetClassName();
MetaFunction method_ = SeekMetaFunction(trdsobj_->GetClassName(), _d);
if (method_)
{
method_.setTrdsObject(trdsobj_);
return method_;
}
return MetaFunction();
}
MetaFunction GetMethod(int _d)const
{
TrdsObject* trdsobj_ = GetTrdsObject();
auto& vect = _invokes.find(trdsobj_->GetClassName());
if (_d >= vect->second.size())
{
return MetaFunction();
}
return vect->second[_d];
}
int GetFieldCount()const
{
if (_FieldCount == -1)
{
TrdsObject* trdsobj_ = GetTrdsObject();
auto name = trdsobj_->GetClassName();
for (auto pair : _fields)
{
if (pair.first == name)
{
_FieldCount = pair.second.size();
break;
}
}
}
return _FieldCount;
}
FieldPtr GetField(int _d)const
{
TrdsObject* trdsobj_ = GetTrdsObject();
auto& vect = _fields.find(trdsobj_->GetClassName());
if (_d >= vect->second.size())
{
return 0;
}
return vect->second[_d];
}
struct SFlagIndexPathNode
{
int offset = -1;
std::string class_ = "TrdsObject";
};
using SFlagIndexPath = std::vector<SFlagIndexPathNode>;
FieldPtr GetFieldOf(const std::string& class_, const std::string& field_)const
{
auto iter = _fields.find(class_);
if (iter == _fields.end())
{
return FieldPtr();
}
auto& vct = iter->second;
for (int i_ = 0; i_ < vct.size(); ++i_)
{
if (field_ == vct[i_]->FieldName())
{
return vct[i_];
}
}
return FieldPtr();
}
FieldPtr SeekField(SFlagIndexPath& NodePath, const std::string& class_, const std::string& field_)const
{
if (class_ == "TrdsObject")
{
return FieldPtr();
}
FieldPtr resultPrt = GetFieldOf(class_, field_);
if (resultPrt)
{
return resultPrt;
}
const auto& vect = _supers.at(class_);
for (const auto& super : vect)
{
FieldPtr resultPrt = SeekField(NodePath, super.name_, field_);
if (resultPrt)
{
NodePath.push_back({ super.offset_, super.name_ });
return resultPrt;
}
}
return FieldPtr();
}
FieldPtr GetField(const std::string& _d)const
{
SFlagIndexPath node_path;
TrdsObject* trdsobj_ = GetTrdsObject();
FieldPtr resultPrt = SeekField(node_path, trdsobj_->GetClassName(), _d);
if (!resultPrt)
{
return FieldPtr();
}
char* obj_ = reinterpret_cast<char*>(_o);
for (int i = 0; i < node_path.size(); ++i)
{
const SFlagIndexPathNode& node = node_path[i];
obj_ += node.offset;
}
std::string name = node_path.size() > 0 ? node_path.back().class_ : trdsobj_->GetClassName();
return FieldPtr(new Field(obj_, resultPrt->Offset(), resultPrt->FieldSize(), resultPrt->FieldName(), resultPrt->ClassName(), resultPrt->GetToTrdsOvjOffset()));
}
private:
void* _o{ nullptr };
const std::string _class;
const Supers& _supers;
const Invokes& _invokes;
const Fields& _fields;
const News& _news;
mutable int _FieldCount = -1;
mutable int _MethodCount = -1;
};
class FieldImpl
{
public:
FieldImpl(int offset_, int size_, const std::string& field_, const std::string& class_, const SGenerateClassOffset& toTrdsOffset, void* o_)
:offset_(offset_), size_(size_), field_(field_), o_(o_), class_(class_), toTrdsObjectOffset_(toTrdsOffset)
{
}
FieldImpl(int offset_, int size_, const std::string& field_, const std::string& class_, const SGenerateClassOffset& toTrdsOffset)
:offset_(offset_), size_(size_), field_(field_), class_(class_), o_(0), toTrdsObjectOffset_(toTrdsOffset)
{
}
int offset_;
int size_;
const std::string field_;
const std::string class_;
const void* o_;
const SGenerateClassOffset toTrdsObjectOffset_;
};
Meta* Meta::GetInstance() {
static Meta _meta;
return &_meta;
}
MetaObjectPtr Meta::GetMetaObject(const void* _o, const std::string& _class)
{
return meta_->GetMetaObject(const_cast<void*>(_o), _class);
}
TrdsObjectPtr Meta::NewInstance(const std::string& _class)
{
return meta_->NewInstance(_class);
}
void Meta::RegisterNew(const std::string& _class, const MetaFunction& newc)
{
meta_->RegisterNew(_class, newc);
}
void Meta::RegisterInvoke(const std::string& _class, const MetaFunction& newc)
{
meta_->RegisterInvoke(_class, newc);
}
void Meta::RegisterField(const std::string& _class, FieldPtr _filed)
{
meta_->RegisterField(_class, _filed);
}
void Meta::RegisterSupers(const std::string& sub, std::vector<SGenerateClassOffset>& supers)
{
meta_->RegisterSupers(sub, supers);
}
Meta::Meta()
{
meta_.reset(new MetaImpl());
}
FieldPtr MetaObject::GetField(int _d)const
{
return meta_->GetField(_d);
}
FieldPtr MetaObject::GetField(const std::string& _d) const
{
return meta_->GetField(_d);
}
MetaFunction MetaObject::GetMethod(const std::string& _d) const
{
return meta_->GetMethod(_d);
}
MetaFunction MetaObject::GetMethod(int _d) const
{
return meta_->GetMethod(_d);
}
int MetaObject::GetMethodCount() const
{
return meta_->GetMethodCount();
}
int MetaObject::GetFieldCount() const
{
return meta_->GetFieldCount();
}
std::string MetaObject::GetClassName() const
{
return meta_->GetClassName();
}
MetaObject::MetaObject(void* _o, const std::string& _class, const Invokes& invokes, const Fields& fields, const News& news, const Supers& supers)
{
meta_.reset(new MetaObjectImpl(_o, _class, invokes, fields, news, supers));
}
std::string Field::FieldName() const
{
return meta_->field_;
}
int Field::FieldSize() const
{
return meta_->size_;
}
int Field::Offset() const
{
return meta_->offset_;
}
std::string Field::ClassName() const
{
return meta_->class_;
}
TrdsObject* Field::GetInstance() const
{
return const_cast<TrdsObject*>((TrdsObject*)((const char*)(meta_->o_) + meta_->toTrdsObjectOffset_.offset_));
}
void Field::SetValue(const Object& _val)
{
if (!_val || _val.GetSize() != meta_->size_)
{
return;
}
const_cast<Object&>(_val).Release();
char* ptr = const_cast<Object&>(_val).GetCharPtr();
char* field = (char*)(meta_->o_) + meta_->offset_;
if (_val.IsPtr())
{
memcpy(field, &ptr, meta_->size_);
}
else
{
memcpy(field, ptr, meta_->size_);
}
}
Object Field::GetValue() const
{
char* ptr = (char*)(meta_->o_) + meta_->offset_;
auto obj = Object(ptr, false);
obj.SetSize(meta_->size_);
return obj;
}
SGenerateClassOffset Field::GetToTrdsOvjOffset() const
{
return meta_->toTrdsObjectOffset_;
}
Field::Field(void* _o, int _offset, int size, const std::string& field, const std::string& class_, const SGenerateClassOffset& toTrdsOffset)
{
meta_.reset(new FieldImpl(_offset, size, field, class_, toTrdsOffset, _o));
}
Field::Field(int _offset, int size, const std::string& field, const std::string& class_, const SGenerateClassOffset& toTrdsOffset)
{
meta_.reset(new FieldImpl(_offset, size, field, class_, toTrdsOffset));
}
RegisterHelper::RegisterHelper(const std::string& clas, const std::string& filed_, int offset_, int size_, const SGenerateClassOffset& toTrdsOffset)
{
Meta::GetInstance()->RegisterField(clas, FieldPtr(new Field(offset_, size_, filed_, clas, toTrdsOffset)));
}
RegisterHelper::RegisterHelper(const std::string& clas_, const MetaFunction& function, bool creator)
{
if (creator)
{
Meta::GetInstance()->RegisterNew(clas_, function);
}
else
{
Meta::GetInstance()->RegisterInvoke(clas_, function);
}
}
RegisterHelper::RegisterHelper(const std::string& clas_, std::vector<SGenerateClassOffset>& supers)
{
Meta::GetInstance()->RegisterSupers(clas_, supers);
}
//end
}
}
3:案例
#include <iostream>
#include "./cp_core/reflect.h"
using namespace Trds::Reflect;
class _10 { virtual void get() {} };
class _12{virtual void get() {}};
class _11{virtual void get() {}};
class _13{virtual void get() {}};
class _14{virtual void get() {}};
class _15{virtual void get() {}};
class _16 { int a = 90; virtual void get() {}};
class _17 { int a = 90; virtual void get() {}};
class _18{ virtual void get() {} };
struct CPData : public Trds::Reflect::TrdsObject,
public _10, public _11, public _12, public _13, public _14, public _15, public _16, public _17, public _18
{
TRDS_RELECT(CPData)
long long a = 999;
void* pvoid = 0;
};
REGISTER_SUPER(CPData, _10, _11, _12, _13, _14, _15, _16, _17, _18)
REGISTER_FIELDS(CPData, a, pvoid) // 需要注册多少个,你就加多少个属性,就这么简单
class CPTest : public CPData
{
TRDS_RELECT(CPTest)
public:
void show(const std::string& msg)
{
std::cout << "msg = " << msg << std::endl;
}
public:
int ma = 90;
char ch = 'a';
};
REGISTER_SUPER(CPTest, CPData)
REGISTER_FIELDS(CPTest, ma, ch) // 需要注册多少个,你就加多少个属性,就这么简单
REGISTER_INVOKES(CPTest, show) // 需要注册多少个,你就加多少个函数,就这么简单
int main(int argc, char** argv)
{
CPTest test;
test.SetObjName("test");
MetaObjectPtr metaPtr = test.Meta();
FieldPtr vptr = metaPtr->GetField("a");
FieldPtr vptrVoid = metaPtr->GetField("pvoid");
FieldPtr maptr = metaPtr->GetField("ma");
FieldPtr chptr = metaPtr->GetField("ch");
vptr->SetValue((long long)0x10111213);
auto pp = vptr->GetValue().Value<long long>();
auto maptrint = maptr->GetValue().Value<int>();
maptr->SetValue(987654321);
{
auto chvbalure = chptr->GetValue();
auto jjj = chvbalure.Value<char>();
chptr->SetValue('A');
}
void* pVoid = new CPTest;
vptrVoid->SetValue(pVoid);
void* vvv = vptrVoid->GetValue().Value<void*>();
((CPTest*)(vvv))->a = 0X1010101010101010;
TrdsObject* obj__ = vptr->GetInstance();
auto anem = obj__->GetClassName();
metaPtr->GetMethod("show")(std::string("Hello, da sha bi"));
auto poooo = metaPtr->GetMethod("GetObjName")();
metaPtr->GetMethod("SetObjName")(std::string("WTF"));
return 0;
}