support refl method default value
This commit is contained in:
parent
deba7160c2
commit
1358747979
36
engine/3rdparty/zlib/include/refl/detail/field.h
vendored
36
engine/3rdparty/zlib/include/refl/detail/field.h
vendored
@ -6,22 +6,42 @@ using Ubpa::Name;
|
|||||||
using Ubpa::type_name;
|
using Ubpa::type_name;
|
||||||
namespace refl {
|
namespace refl {
|
||||||
class UClass;
|
class UClass;
|
||||||
|
class ArgsView;
|
||||||
|
|
||||||
using Offset = uint32_t;
|
using Offset = uint32_t;
|
||||||
using Method = void(*)(...);
|
using Method = void(*)(...);
|
||||||
|
|
||||||
|
using DefaultMember = const ArgsView (*)();
|
||||||
|
using DefaultMethod = std::pair<ArgsView*, int>(*)();
|
||||||
|
|
||||||
enum FieldFlag:uint32_t {
|
enum FieldFlag:uint32_t {
|
||||||
FIELD_NONE_FLAG = 0,
|
FIELD_NONE_FLAG = 0,
|
||||||
FIELD_MEMBER_FLAG = 1 << 0,
|
FIELD_MEMBER_FLAG = 1 << 0,
|
||||||
FIELD_ATTRIBUTE_FLAG = 1 << 1,
|
FIELD_ATTRIBUTE_FLAG = 1 << 1,
|
||||||
FIELD_METHOD_FLAG = 1 << 2,
|
FIELD_METHOD_FLAG = 1 << 2,
|
||||||
|
FIELD_METHOD_VALUE_FLAG = 1 << 3
|
||||||
};
|
};
|
||||||
struct FieldPtr {
|
struct FieldPtr {
|
||||||
using Data = std::variant<
|
union Data
|
||||||
Offset, // offset
|
{
|
||||||
Method // method
|
Offset offset;
|
||||||
>;
|
Method method;
|
||||||
|
Data() : method(nullptr) {}
|
||||||
|
Data(Offset& offset) : offset(offset) {}
|
||||||
|
Data(Method& method) : method(method) {}
|
||||||
|
};
|
||||||
|
union Default {
|
||||||
|
DefaultMember member;
|
||||||
|
DefaultMethod method;
|
||||||
|
Default(): method(nullptr) {}
|
||||||
|
Default(DefaultMember& member) : member(member) {}
|
||||||
|
Default(DefaultMethod& method) : method(method) {}
|
||||||
|
};
|
||||||
Name name;
|
Name name;
|
||||||
const UClass* type;
|
const UClass* type;
|
||||||
Data data;
|
Data data;
|
||||||
|
Default value;
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,20 +4,13 @@ namespace refl {
|
|||||||
template <class T>
|
template <class T>
|
||||||
concept _ReflCheck_Ctor = requires { T(); };
|
concept _ReflCheck_Ctor = requires { T(); };
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _ReflCheck_UClass = requires{{T::BuildClass()} -> std::same_as<typename T::MyUClass>; };
|
concept _ReflCheck_UClass = requires(typename T::MyUClass& cls) { T::BuildClass(cls); } ;
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
|
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
|
||||||
|
|
||||||
//类型接口
|
//类型接口
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct TypeInfoImpl;
|
struct TypeInfoImpl;
|
||||||
|
|
||||||
template<_ReflCheck_UClass T>
|
|
||||||
struct TypeInfoImpl<T> {
|
|
||||||
using MyUClass = typename T::MyUClass;
|
|
||||||
inline static MyUClass StaticClass = T::BuildClass();
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct RealTypeImpl {
|
struct RealTypeImpl {
|
||||||
using type = std::remove_cv_t<std::remove_reference_t<T>>;
|
using type = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
namespace refl {
|
namespace refl {
|
||||||
struct vtable_uclass
|
struct vtable_uclass
|
||||||
{
|
{
|
||||||
//object
|
|
||||||
void (*InitObject)(void*);
|
|
||||||
//class
|
//class
|
||||||
const FieldPtr* (*GetField)(const UClass*, const Name&, bool);
|
const FieldPtr* (*GetField)(const UClass*, const Name&, bool);
|
||||||
//function
|
//function
|
||||||
@ -14,6 +12,10 @@ namespace refl {
|
|||||||
//function
|
//function
|
||||||
void (*Call)(const FieldPtr&, std::vector<ArgsView>&);
|
void (*Call)(const FieldPtr&, std::vector<ArgsView>&);
|
||||||
|
|
||||||
|
//object
|
||||||
|
void (*InitObject)(void*);
|
||||||
|
void (*CopyObject)(void*, const void*);
|
||||||
|
void (*DestObject)(void*);
|
||||||
};
|
};
|
||||||
class UClass{
|
class UClass{
|
||||||
using enum FieldFlag;
|
using enum FieldFlag;
|
||||||
@ -70,20 +72,6 @@ namespace refl {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
template<_ReflCheck_Ctor T>
|
|
||||||
static void InitObject(void* ptr) {
|
|
||||||
T obj{};
|
|
||||||
std::construct_at((T*)ptr, obj);
|
|
||||||
}
|
|
||||||
//unsafe if called by other, need check class && size
|
|
||||||
void InitObject(void* ptr)const {
|
|
||||||
if (vtable.InitObject) {
|
|
||||||
vtable.InitObject(ptr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memset(ptr, 0, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const FieldPtr* GetField(const Name& name, bool isMethod)const {
|
const FieldPtr* GetField(const Name& name, bool isMethod)const {
|
||||||
if (vtable.GetField) {
|
if (vtable.GetField) {
|
||||||
return vtable.GetField(this, name, isMethod);
|
return vtable.GetField(this, name, isMethod);
|
||||||
@ -101,24 +89,36 @@ namespace refl {
|
|||||||
return vtable.Call(field, ArgsList);
|
return vtable.Call(field, ArgsList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void InitObject(void* ptr)const {
|
||||||
|
if (vtable.InitObject) {
|
||||||
|
vtable.InitObject(ptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(ptr, 0, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CopyObject(void* dst, const void* src)const {
|
||||||
|
if (vtable.CopyObject) {
|
||||||
|
vtable.CopyObject(dst, src);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(dst, src, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DestObject(void* ptr)const {
|
||||||
|
if (vtable.DestObject) {
|
||||||
|
vtable.DestObject(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
template<Offset offset>
|
template<_ReflCheck_Ctor T>
|
||||||
constexpr static FieldPtr MakeMemberField(Name name, const UClass* cls) {
|
static void InitObject(void* ptr) {
|
||||||
FieldPtr::Data member = { offset };
|
T obj{};
|
||||||
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
std::construct_at((T*)ptr, obj);
|
||||||
return { name, cls, {member}, flag };
|
|
||||||
}
|
}
|
||||||
template<typename R, typename ...Args>
|
template<typename T>
|
||||||
static FieldPtr MakeMethodField(R (* ptr)(Args...), Name name) {
|
static void CopyObject(void* dst, const void* src) {
|
||||||
FieldPtr::Data member = { *(Method*)&ptr};
|
*(T*)dst = *(T*)src;
|
||||||
constexpr uint32_t flag = FIELD_METHOD_FLAG;
|
|
||||||
return { name, &TypeInfo<R(*)(typename RealTypeImpl<Args>::type...)>::StaticClass, {member},flag };
|
|
||||||
}
|
|
||||||
template<typename T, typename R, typename ...Args>
|
|
||||||
static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name) {
|
|
||||||
FieldPtr::Data member = { *(Method*)&ptr };
|
|
||||||
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
|
||||||
return { name, &TypeInfo<R(*)(const void*, typename RealTypeImpl<Args>::type...)>::StaticClass, {member},flag };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -5,12 +5,13 @@ namespace refl {
|
|||||||
class UClass_Auto : public UClass {
|
class UClass_Auto : public UClass {
|
||||||
public:
|
public:
|
||||||
using UClass::UClass;
|
using UClass::UClass;
|
||||||
using UClassType = UClass_Auto<T>;
|
using MyUClass = UClass_Auto<T>;
|
||||||
public:
|
public:
|
||||||
constexpr static UClassType BuildClass() {
|
constexpr static MyUClass BuildClass() {
|
||||||
UClassType cls(type_name<T>().View(), sizeof(T));
|
MyUClass cls(type_name<T>().View(), sizeof(T));
|
||||||
if constexpr (!std::is_trivially_copyable_v<T>) {
|
if constexpr (!std::is_trivially_copyable_v<T>) {
|
||||||
cls.vtable.InitObject = &UClass::InitObject<T>;
|
cls.vtable.InitObject = &MyUClass::InitObject<T>;
|
||||||
|
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
|
||||||
}
|
}
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
@ -25,22 +26,22 @@ namespace refl {
|
|||||||
class UMethod_Auto : public UClass {
|
class UMethod_Auto : public UClass {
|
||||||
using UClass::UClass;
|
using UClass::UClass;
|
||||||
using MethodType = R(*)(Args...);
|
using MethodType = R(*)(Args...);
|
||||||
using UClassType = UMethod_Auto<R, Args...>;
|
using MyUClass = UMethod_Auto<R, Args...>;
|
||||||
public:
|
public:
|
||||||
std::array<const UClass*, sizeof...(Args) + 1> UList{};
|
std::array<const UClass*, sizeof...(Args) + 1> UList{};
|
||||||
|
|
||||||
static std::vector<const UClass*> GetParams(const UClass* cls) {
|
static std::vector<const UClass*> GetParams(const UClass* cls) {
|
||||||
auto& UList = static_cast<const UClassType*>(cls)->UList;
|
auto& UList = static_cast<const MyUClass*>(cls)->UList;
|
||||||
return { UList.data(), UList.data() + UList.size() };
|
return { UList.data(), UList.data() + UList.size() };
|
||||||
}
|
}
|
||||||
static void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList) {
|
static void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList) {
|
||||||
if constexpr (std::is_same_v<R, void>) {
|
if constexpr (std::is_same_v<R, void>) {
|
||||||
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
MethodType fptr = (MethodType)field.data.method;
|
||||||
auto param = ArgsList.rbegin();
|
auto param = ArgsList.rbegin();
|
||||||
fptr(param++->cast_to<Args>()...);
|
fptr(param++->cast_to<Args>()...);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MethodType fptr = (MethodType)std::get<Method>(field.data);
|
MethodType fptr = (MethodType)field.data.method;
|
||||||
auto param = ArgsList.rbegin();
|
auto param = ArgsList.rbegin();
|
||||||
auto ret = ArgsList.begin();
|
auto ret = ArgsList.begin();
|
||||||
if (ret->cls == &TypeInfo<R>::StaticClass) {
|
if (ret->cls == &TypeInfo<R>::StaticClass) {
|
||||||
@ -63,10 +64,10 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
//为了简化判断,cls 对象 统统指向 T*
|
//为了简化判断,cls 对象 统统指向 T*
|
||||||
constexpr static UClassType BuildClass() {
|
constexpr static MyUClass BuildClass() {
|
||||||
UClassType cls(type_name<MethodType>().View(), sizeof(MethodType));
|
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
|
||||||
cls.vtable.GetParams = &UClassType::GetParams;
|
cls.vtable.GetParams = &MyUClass::GetParams;
|
||||||
cls.vtable.Call = &UClassType::Call;
|
cls.vtable.Call = &MyUClass::Call;
|
||||||
cls.BuildUList();
|
cls.BuildUList();
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
@ -93,9 +94,12 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void BuildClass() {
|
void BuildClass() {
|
||||||
|
FList.shrink_to_fit();//缩减容量,FList大小不再改变了
|
||||||
vtable.GetField = &UClass_Custom::GetField;
|
vtable.GetField = &UClass_Custom::GetField;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
//基础类型的偏特化
|
//基础类型的偏特化
|
||||||
template<_ReflCheck_Ctor_NoUClass T>
|
template<_ReflCheck_Ctor_NoUClass T>
|
||||||
@ -110,4 +114,28 @@ namespace refl {
|
|||||||
using UClass = UMethod_Auto<R, Args...>;
|
using UClass = UMethod_Auto<R, Args...>;
|
||||||
inline constexpr static UClass StaticClass = UClass::BuildClass();
|
inline constexpr static UClass StaticClass = UClass::BuildClass();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<_ReflCheck_UClass T>
|
||||||
|
struct TypeInfoImpl<T> {
|
||||||
|
using MyUClass = typename T::MyUClass;
|
||||||
|
inline static MyUClass StaticClass = []()->MyUClass {
|
||||||
|
MyUClass cls(type_name<T>().View(), sizeof(T));
|
||||||
|
T::BuildClass(cls);
|
||||||
|
auto& vtable = cls.vtable;
|
||||||
|
if (!vtable.GetField) {
|
||||||
|
vtable.GetField = &MyUClass::GetField;
|
||||||
|
}
|
||||||
|
if constexpr (!std::is_trivially_copyable_v<T>) {
|
||||||
|
if (!vtable.InitObject) {
|
||||||
|
//这里一定会创建一个InitObject<T> 模板函数,如何优化
|
||||||
|
vtable.InitObject = &UClass::InitObject<T>;
|
||||||
|
}
|
||||||
|
if (!vtable.CopyObject) {
|
||||||
|
//这里一定会创建一个CopyObject<T> 模板函数,如何优化
|
||||||
|
vtable.CopyObject = &UClass::CopyObject<T>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cls;
|
||||||
|
}();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
27
engine/3rdparty/zlib/include/refl/detail/view.h
vendored
27
engine/3rdparty/zlib/include/refl/detail/view.h
vendored
@ -26,14 +26,22 @@ namespace refl {
|
|||||||
|
|
||||||
ObjectView Parent();
|
ObjectView Parent();
|
||||||
};
|
};
|
||||||
class ArgsView {
|
//生命周期短,适用于传参,不建议保存数据
|
||||||
|
//这里类型丢失了呀,存入的都是指针数据
|
||||||
|
struct ArgsView {
|
||||||
public:
|
public:
|
||||||
const void* val;
|
const void* val;
|
||||||
const UClass* cls;
|
const UClass* cls;
|
||||||
ArgsView(const void* val = nullptr, const UClass* cls = nullptr) : val(val), cls(cls) {}
|
ArgsView(const void* val = nullptr, const UClass* cls = nullptr) : val(val), cls(cls) {}
|
||||||
|
//右值=>右值压入栈,caller入栈地址
|
||||||
|
//左值=>caller变量地址
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ArgsView(T&& v): val(&v), cls(&TypeInfo<typename std::remove_reference_t<T>*>::StaticClass){}
|
ArgsView(T&& v): val(&v), cls(&TypeInfo<typename std::remove_reference_t<T>*>::StaticClass){
|
||||||
|
if constexpr (std::is_same_v<std::remove_reference_t<T>, ArgsView>) {
|
||||||
|
val = v.val;
|
||||||
|
cls = v.cls;
|
||||||
|
}
|
||||||
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr inline T cast_to() {
|
constexpr inline T cast_to() {
|
||||||
if constexpr (std::is_pointer_v<T>) {
|
if constexpr (std::is_pointer_v<T>) {
|
||||||
@ -48,4 +56,17 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
bool ConvertTo(const UClass* toClass);
|
bool ConvertTo(const UClass* toClass);
|
||||||
};
|
};
|
||||||
|
//存入的是真实的数据类型,type用于拷贝数据
|
||||||
|
struct ArgsValue : public ArgsView {
|
||||||
|
const UClass* type;
|
||||||
|
template<typename T>
|
||||||
|
ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo<T>::StaticClass){}
|
||||||
|
};
|
||||||
|
struct ArgsValueList{
|
||||||
|
void* data{ nullptr };
|
||||||
|
ArgsView* ptr{nullptr};
|
||||||
|
int num{ 0 };
|
||||||
|
ArgsValueList(const std::vector<ArgsValue>& args);
|
||||||
|
~ArgsValueList();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -7,7 +7,7 @@ namespace refl {
|
|||||||
if (cache && cache->name == name) {
|
if (cache && cache->name == name) {
|
||||||
_cache_get: bool isChild = cache->type->IsChildOf<T>(true);
|
_cache_get: bool isChild = cache->type->IsChildOf<T>(true);
|
||||||
if (isChild) {
|
if (isChild) {
|
||||||
t = *(T*)(ptr + std::get<uint32_t>(cache->data));
|
t = *(T*)(ptr + cache->data.offset);
|
||||||
}
|
}
|
||||||
return isChild;
|
return isChild;
|
||||||
}
|
}
|
||||||
@ -25,10 +25,9 @@ namespace refl {
|
|||||||
inline bool ObjectView::Set(const Name& name, const T& t)
|
inline bool ObjectView::Set(const Name& name, const T& t)
|
||||||
{
|
{
|
||||||
if (cache && cache->name == name) {
|
if (cache && cache->name == name) {
|
||||||
|
|
||||||
_cache_set: bool isChild = cache->type->IsChildOf<T>(true);
|
_cache_set: bool isChild = cache->type->IsChildOf<T>(true);
|
||||||
if (isChild) {
|
if (isChild) {
|
||||||
*(T*)(ptr + std::get<uint32_t>(cache->data)) = t;
|
*(T*)(ptr + cache->data.offset) = t;
|
||||||
}
|
}
|
||||||
return isChild;
|
return isChild;
|
||||||
}
|
}
|
||||||
@ -55,17 +54,33 @@ namespace refl {
|
|||||||
constexpr int inputSize = sizeof...(Args);
|
constexpr int inputSize = sizeof...(Args);
|
||||||
auto params = field->type->GetParams();
|
auto params = field->type->GetParams();
|
||||||
int paramsSize = params.size();
|
int paramsSize = params.size();
|
||||||
bool member = field->flag & FIELD_MEMBER_FLAG;
|
|
||||||
if (inputSize + member >= paramsSize) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::vector<ArgsView> ArgsList;
|
std::vector<ArgsView> ArgsList;
|
||||||
ArgsList.reserve(paramsSize);
|
ArgsList.reserve(paramsSize);
|
||||||
ArgsList.emplace_back();
|
ArgsList.emplace_back();
|
||||||
|
|
||||||
|
bool member = field->flag & FIELD_MEMBER_FLAG;
|
||||||
if (member) {
|
if (member) {
|
||||||
ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass);
|
ArgsList.emplace_back(ptr, &TypeInfo<const void*>::StaticClass);
|
||||||
}
|
}
|
||||||
(..., (ArgsList.emplace_back(args)));
|
(..., (ArgsList.emplace_back(args)));
|
||||||
|
|
||||||
|
|
||||||
|
int argsSize = ArgsList.size();
|
||||||
|
if (argsSize < paramsSize && field->flag & FIELD_METHOD_VALUE_FLAG) {
|
||||||
|
auto [argsPtr, valueSize] = field->value.method();
|
||||||
|
if (argsSize + valueSize >= paramsSize) {
|
||||||
|
for (int i = valueSize + argsSize - paramsSize; i < valueSize; i++) {
|
||||||
|
ArgsList.push_back(*(argsPtr + i));
|
||||||
|
}
|
||||||
|
argsSize = paramsSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argsSize < paramsSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = member + 1; i < paramsSize; i++) {
|
for (int i = member + 1; i < paramsSize; i++) {
|
||||||
if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) {
|
if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) {
|
||||||
return false;
|
return false;
|
||||||
@ -123,4 +138,35 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
ArgsValueList::ArgsValueList(const std::vector<ArgsValue>& args) {
|
||||||
|
num = args.size();
|
||||||
|
int size = num * sizeof(ArgsView);
|
||||||
|
for (auto& arg : args) {
|
||||||
|
size += arg.cls->size;
|
||||||
|
}
|
||||||
|
data = (void*)malloc(size);
|
||||||
|
ptr = (ArgsView*)data;
|
||||||
|
char* pData = ((char*)data) + num * sizeof(ArgsView);
|
||||||
|
for (auto& arg : args) {
|
||||||
|
arg.type->InitObject(pData);
|
||||||
|
arg.type->CopyObject(pData, arg.val);
|
||||||
|
ptr->cls = arg.cls;
|
||||||
|
ptr->val = pData;
|
||||||
|
ptr++;
|
||||||
|
pData += arg.cls->size;
|
||||||
|
}
|
||||||
|
ptr = (ArgsView*)data;
|
||||||
|
}
|
||||||
|
inline ArgsValueList::~ArgsValueList()
|
||||||
|
{
|
||||||
|
if (num == 0 || !data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
ptr->cls->DestObject((void*)ptr->val);
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
num = 0;
|
||||||
|
data = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
39
engine/3rdparty/zlib/include/refl/refl.h
vendored
39
engine/3rdparty/zlib/include/refl/refl.h
vendored
@ -1,2 +1,41 @@
|
|||||||
#include "detail/uclass.inl"
|
#include "detail/uclass.inl"
|
||||||
#include "detail/view.inl"
|
#include "detail/view.inl"
|
||||||
|
namespace refl {
|
||||||
|
/* 成员变量需要定义默认值吗?那为什么不在initObjec里初始化?*/
|
||||||
|
template<typename T, typename Obj>
|
||||||
|
static FieldPtr MakeMemberField(T Obj::* ptr, Name name) {
|
||||||
|
FieldPtr::Default value;
|
||||||
|
Offset offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const Obj*>(0)->*ptr));
|
||||||
|
FieldPtr::Data member = { offset };
|
||||||
|
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
||||||
|
return { name, &TypeInfo<T>::StaticClass, member, value, flag };
|
||||||
|
}
|
||||||
|
template<typename R, typename ...Args>
|
||||||
|
static FieldPtr MakeMethodField(R(*ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) {
|
||||||
|
uint32_t flag = FIELD_METHOD_FLAG;
|
||||||
|
FieldPtr::Default value;
|
||||||
|
if (args.size() > 0) {
|
||||||
|
flag |= FIELD_METHOD_VALUE_FLAG;
|
||||||
|
static const ArgsValueList argsValue(args);
|
||||||
|
value.method = []() ->std::pair<ArgsView*, int> {
|
||||||
|
return { argsValue.ptr , argsValue.num };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
FieldPtr::Data method = { *(Method*)&ptr };
|
||||||
|
return { name, &TypeInfo<R(*)(typename RealTypeImpl<Args>::type...)>::StaticClass, method, value, flag };
|
||||||
|
}
|
||||||
|
template<typename T, typename R, typename ...Args>
|
||||||
|
static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) {
|
||||||
|
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
||||||
|
FieldPtr::Default value;
|
||||||
|
if (args.size() > 0) {
|
||||||
|
flag |= FIELD_METHOD_VALUE_FLAG;
|
||||||
|
static const ArgsValueList argsValue(args);
|
||||||
|
value.method = []() ->std::pair<ArgsView*, int> {
|
||||||
|
return { argsValue.ptr , argsValue.num };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
FieldPtr::Data method = { *(Method*)&ptr };
|
||||||
|
return { name, &TypeInfo<R(*)(const void*, typename RealTypeImpl<Args>::type...)>::StaticClass, method, value,flag };
|
||||||
|
}
|
||||||
|
}
|
||||||
30
engine/3rdparty/zlib/test/refl_01.cpp
vendored
30
engine/3rdparty/zlib/test/refl_01.cpp
vendored
@ -33,27 +33,29 @@ struct vec3 : public vec3_parent {
|
|||||||
cout << x1 << "::norm3" << endl;
|
cout << x1 << "::norm3" << endl;
|
||||||
}
|
}
|
||||||
using MyUClass = UClass_Custom;
|
using MyUClass = UClass_Custom;
|
||||||
static MyUClass BuildClass() {
|
static void BuildClass(MyUClass& cls) {
|
||||||
MyUClass cls(type_name<vec3>().View(), sizeof(vec3), &TypeInfo<vec3_parent>::StaticClass);
|
cls.parent = &TypeInfo<vec3_parent>::StaticClass;
|
||||||
auto& FList = cls.FList;
|
cls.AttrNum = 3;
|
||||||
FList.reserve(6);
|
cls.FList = {
|
||||||
FList.push_back(cls.MakeMemberField<offsetof(vec3, x)>("x", &TypeInfo<float>::StaticClass));
|
MakeMemberField(&vec3::x, "x"),
|
||||||
FList.push_back(cls.MakeMemberField<offsetof(vec3, y)>("y", &TypeInfo<float>::StaticClass));
|
MakeMemberField(&vec3::y, "y"),
|
||||||
FList.push_back(cls.MakeMemberField<offsetof(vec3, z)>("z", &TypeInfo<float>::StaticClass));
|
MakeMemberField(&vec3::z, "z"),
|
||||||
cls.AttrNum = FList.size();
|
MakeMethodField(&vec3::norm, "norm", {8, 9}),
|
||||||
FList.push_back(cls.MakeMethodField(&vec3::norm, "norm"));
|
MakeMethodField(&vec3::norm1, "norm1",{2})
|
||||||
FList.push_back(cls.MakeMethodField(&vec3::norm, "norm1"));
|
};
|
||||||
cls.vtable.InitObject = &UClass::InitObject<vec3>;
|
|
||||||
cls.BuildClass();
|
|
||||||
return cls;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
int main() {
|
int main() {
|
||||||
auto cls = &TypeInfo<vec3>::StaticClass;
|
auto cls = &TypeInfo<vec3>::StaticClass;
|
||||||
int x = 100, y = 2;
|
int x = 2, y = 3;
|
||||||
auto ov = cls->New();
|
auto ov = cls->New();
|
||||||
|
ov.Invoke("norm", x);
|
||||||
|
ov.Invoke("norm", x);
|
||||||
ov.Invoke("norm", x, y);
|
ov.Invoke("norm", x, y);
|
||||||
|
ov.Invoke("norm1", y);
|
||||||
vec3* v = (vec3*)ov.ptr;
|
vec3* v = (vec3*)ov.ptr;
|
||||||
|
v->norm1(y);
|
||||||
|
ov.Invoke("norm1", y);
|
||||||
delete v;
|
delete v;
|
||||||
cout << "hello world\n";
|
cout << "hello world\n";
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user