99 lines
3.2 KiB
C++
99 lines
3.2 KiB
C++
#include "uclass.h"
|
|
namespace refl {
|
|
template<typename Func, typename... Args>
|
|
inline auto FieldPtr::Call(Func func, Args&& ...args)const
|
|
{
|
|
using MemberFunc = decltype(fetch_method_t(func));
|
|
MemberFunc fptr = (MemberFunc)data.method;
|
|
return fptr(std::forward<Args>(args)...);
|
|
}
|
|
bool FieldPtr::Invoke(const sarray<ArgsView>& ArgsList)const{
|
|
auto Call = type->vtable.Call;
|
|
if (Call) {
|
|
Call(this, ArgsList);
|
|
}
|
|
return Call;
|
|
}
|
|
bool FieldPtr::Invoke(svector<ArgsView>& ArgsList)const {
|
|
auto Call = type->vtable.Call;
|
|
if (Call) {
|
|
auto params = GetParams();
|
|
int paramsSize = params.size();
|
|
int argsSize = ArgsList.size();
|
|
if (argsSize < paramsSize && flag & FIELD_METHOD_VALUE_FLAG) {
|
|
auto [argsPtr, valueSize] = 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;
|
|
}
|
|
|
|
auto a = ArgsList.front();
|
|
auto p = params.front();
|
|
for (auto e = params.back(); p < e; ++p, ++a) {
|
|
if (a->cls != *p && !a->ConvertTo(*p)) {
|
|
return false;
|
|
}
|
|
}
|
|
Call(this, ArgsList);
|
|
}
|
|
return Call;
|
|
}
|
|
sarray<const UClass*> FieldPtr::GetParams() const {
|
|
auto GetParams = type->vtable.GetParams;
|
|
if (GetParams) {
|
|
return GetParams(type);
|
|
}
|
|
return{};
|
|
}
|
|
template<typename T>
|
|
class Field {
|
|
public:
|
|
inline static char s_data[fetch_args_size<T>()]{};
|
|
inline static int s_index{0};
|
|
template<typename V>
|
|
static FieldPtr MakeField(V T::* ptr, Name name)
|
|
{
|
|
FieldPtr::Default value;
|
|
Offset offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const T*>(0)->*ptr));
|
|
FieldPtr::Data member = { offset };
|
|
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
|
return { name, &TypeInfo<V>::StaticClass, member, value, flag };
|
|
}
|
|
template<typename R, typename ...Args>
|
|
static FieldPtr MakeField(R(*ptr)(Args...), Name name, const sarray<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, &Field<T>::s_data[Field<T>::s_index]);
|
|
Field<T>::s_index += ArgsValueList::GetArgsSize(args);
|
|
value.method = []() ->std::pair<ArgsView*, int> {
|
|
return { argsValue.ptr , argsValue.num };
|
|
};
|
|
}
|
|
FieldPtr::Data method = { *(Method*)&ptr };
|
|
return { name, &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass, method, value, flag };
|
|
}
|
|
template<typename R, typename ...Args>
|
|
static FieldPtr MakeField(R(T::* ptr)(Args...), Name name, const sarray<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, &s_data[s_index]);
|
|
s_index += ArgsValueList::GetArgsSize(args);
|
|
value.method = []() ->std::pair<ArgsView*, int> {
|
|
return { argsValue.ptr , argsValue.num };
|
|
};
|
|
}
|
|
FieldPtr::Data method = { *(Method*)&ptr };
|
|
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
|
|
}
|
|
};
|
|
} |