rebuild refl
This commit is contained in:
parent
a960cb0098
commit
5814d973d7
27
engine/3rdparty/zlib/include/refl/detail/field.h
vendored
27
engine/3rdparty/zlib/include/refl/detail/field.h
vendored
@ -46,16 +46,35 @@ namespace refl {
|
||||
Default value{};
|
||||
uint32_t flag{};
|
||||
|
||||
//unsafe
|
||||
bool Invoke(const sarray<ArgsView>& ArgsList)const;
|
||||
//safe
|
||||
bool Invoke(std::vector<ArgsView>& ArgsList)const;
|
||||
//unsafe
|
||||
bool Invoke(const std::vector<ArgsView>& ArgsList)const;
|
||||
|
||||
template<typename R, typename... Args>
|
||||
R Call(Args&&... args)const;
|
||||
template<typename Func, typename... Args>
|
||||
auto Call(Func func, Args&&... args)const;
|
||||
|
||||
std::vector<const UClass*> GetParams() const;
|
||||
};
|
||||
template<typename T, typename R, typename ...Args>
|
||||
consteval auto fetch_method_t(R(T::*)(Args...)) {
|
||||
using MethodType = R(*)(const void*, Args...);
|
||||
return MethodType{ nullptr };
|
||||
}
|
||||
template<typename R, typename ...Args>
|
||||
consteval auto fetch_method_t(R(*)(Args...)) {
|
||||
using MethodType = R(*)(Args...);
|
||||
return MethodType{ nullptr };
|
||||
}
|
||||
template<typename T>
|
||||
consteval int fetch_args_size() {
|
||||
auto fields = T::__MakeStaticFields();
|
||||
int size = 0;
|
||||
for (auto& field : fields) {
|
||||
size += field.data.offset;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
template<typename T>
|
||||
class Field;
|
||||
/*
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
#include "uclass.h"
|
||||
namespace refl {
|
||||
template<typename R, typename ...Args>
|
||||
inline R FieldPtr::Call(Args&& ...args)const
|
||||
template<typename Func, typename... Args>
|
||||
inline auto FieldPtr::Call(Func func, Args&& ...args)const
|
||||
{
|
||||
using MethodType = R(*)(Args...);
|
||||
MethodType fptr = (MethodType)data.method;
|
||||
if constexpr (std::is_same_v<R, void>) {
|
||||
fptr(std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
using MemberFunc = decltype(fetch_method_t(func));
|
||||
MemberFunc fptr = (MemberFunc)data.method;
|
||||
return fptr(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
bool FieldPtr::Invoke(const std::vector<ArgsView>& ArgsList)const{
|
||||
bool FieldPtr::Invoke(const sarray<ArgsView>& ArgsList)const{
|
||||
auto Call = type->vtable.Call;
|
||||
if (Call) {
|
||||
Call(this, ArgsList);
|
||||
@ -55,18 +50,9 @@ namespace refl {
|
||||
return{};
|
||||
}
|
||||
template<typename T>
|
||||
consteval int GetArgsSize() {
|
||||
auto fields = T::__MakeStaticFields();
|
||||
int size = 0;
|
||||
for (auto& field : fields) {
|
||||
size += field.data.offset;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
template<typename T>
|
||||
class Field {
|
||||
public:
|
||||
inline static char data[GetArgsSize<T>()]{};
|
||||
inline static char data[fetch_args_size<T>()]{};
|
||||
inline static int index{0};
|
||||
template<typename V>
|
||||
static FieldPtr MakeField(V T::* ptr, Name name)
|
||||
|
||||
@ -15,19 +15,26 @@ namespace refl {
|
||||
template<typename T>
|
||||
struct has_init_object<T, std::void_t<decltype(&T::__InitObject)>> : std::true_type {};
|
||||
|
||||
//template<typename T>error::"expected unqualified-id"
|
||||
//using has_init_object_v = has_init_object<T>::value;
|
||||
|
||||
//类型接口
|
||||
template<typename T>
|
||||
struct TypeInfoImpl;
|
||||
|
||||
template<typename T>
|
||||
struct real_type {
|
||||
using type = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
using type = std::remove_cv_t<T>;
|
||||
};
|
||||
template<typename T>
|
||||
struct real_type<T&> {
|
||||
using type = std::remove_cv_t<T>*;
|
||||
};
|
||||
template<typename T>
|
||||
struct real_type<T*> {
|
||||
using type = std::remove_cv_t<T>*;
|
||||
};
|
||||
template<typename T>
|
||||
using real_type_t = real_type<T>::type;
|
||||
|
||||
//转化为指针类型
|
||||
|
||||
@ -3,6 +3,10 @@
|
||||
#include "field.h"
|
||||
#include "view.h"
|
||||
namespace refl {
|
||||
enum ClassFlag :uint32_t {
|
||||
CLASS_NONE_FLAG = 0,
|
||||
CLASS_TRIVIAL_FLAG = 1 << 0,
|
||||
};
|
||||
struct vtable_uclass
|
||||
{
|
||||
//class
|
||||
@ -10,7 +14,7 @@ namespace refl {
|
||||
//function
|
||||
std::vector<const UClass*>(*GetParams)(const UClass*);
|
||||
//function
|
||||
void (*Call)(const FieldPtr*, const std::vector<ArgsView>&);
|
||||
void (*Call)(const FieldPtr*, const sarray<ArgsView>& ArgsList);
|
||||
|
||||
//object
|
||||
void (*InitObject)(void*);
|
||||
@ -18,11 +22,12 @@ namespace refl {
|
||||
void (*DestObject)(void*);
|
||||
};
|
||||
class UClass{
|
||||
using enum FieldFlag;
|
||||
public:
|
||||
using enum FieldFlag;
|
||||
using enum ClassFlag;
|
||||
Name name;
|
||||
uint32_t size;
|
||||
//uint32_t flag;
|
||||
uint32_t flag{0};
|
||||
const UClass* parent;
|
||||
vtable_uclass vtable{};
|
||||
public:
|
||||
|
||||
@ -14,6 +14,9 @@ namespace refl {
|
||||
cls.vtable.InitObject = &MyUClass::InitObject<T>;
|
||||
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
|
||||
}
|
||||
else {
|
||||
cls.flag = CLASS_TRIVIAL_FLAG;
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
void Set(void* ptr,const T& t) {
|
||||
@ -42,30 +45,25 @@ namespace refl {
|
||||
auto& UList = static_cast<const MyUClass*>(cls)->UList;
|
||||
return { UList.data(), UList.data() + UList.size() };
|
||||
}
|
||||
static R Call(const FieldPtr* field, Args... args) {
|
||||
MethodType fptr = (MethodType)field->data.method;
|
||||
if constexpr (std::is_same_v<R, void>) {
|
||||
fptr(args...);
|
||||
}
|
||||
else {
|
||||
return fptr(args...);
|
||||
}
|
||||
}
|
||||
static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) {
|
||||
//这里顺序似乎是不确定的,但是我实际运用是对的
|
||||
//如果使用make_index_sequence,会多一次函数调用
|
||||
//为什么包裹一层迭代器,就不会出现警告了
|
||||
static void Call(const FieldPtr* field, const sarray<ArgsView>& ArgsList) {
|
||||
assert(sizeof...(Args) <= ArgsList.size());
|
||||
if constexpr (std::is_same_v<R, void>) {
|
||||
MethodType fptr = (MethodType)field->data.method;
|
||||
auto param = ArgsList.rbegin();
|
||||
fptr(param++->cast_to<Args>()...);
|
||||
auto param = ArgsList.end();
|
||||
fptr((param--->cast_to<Args>())...);
|
||||
}
|
||||
else {
|
||||
MethodType fptr = (MethodType)field->data.method;
|
||||
auto param = ArgsList.rbegin();
|
||||
auto ret = ArgsList.begin();
|
||||
auto param = ArgsList.end();
|
||||
auto ret = ArgsList.get();
|
||||
if (ret->cls == &TypeInfo<R*>::StaticClass) {
|
||||
*(R*)ret->val = fptr(param++->cast_to<Args>()...);
|
||||
*(R*)ret->val = fptr((param--->cast_to<Args>())...);
|
||||
}
|
||||
else {
|
||||
fptr(param++->cast_to<Args>()...);
|
||||
fptr((param--->cast_to<Args>())...);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,7 +74,7 @@ namespace refl {
|
||||
}
|
||||
if constexpr (sizeof...(Args) > 0) {
|
||||
auto ptr = &UList[1];
|
||||
(..., (*ptr = &TypeInfo<std::remove_pointer_t<Args>*>::StaticClass, ptr++));
|
||||
(..., (*ptr = &TypeInfo<std::remove_cv_t<std::remove_pointer_t<Args>>*>::StaticClass, ptr++));
|
||||
}
|
||||
}
|
||||
public:
|
||||
@ -85,48 +83,20 @@ namespace refl {
|
||||
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
|
||||
cls.vtable.GetParams = &MyUClass::GetParams;
|
||||
cls.vtable.Call = &MyUClass::Call;
|
||||
cls.flag = CLASS_TRIVIAL_FLAG;
|
||||
cls.BuildUList();
|
||||
return cls;
|
||||
}
|
||||
};
|
||||
/*
|
||||
class UClass_Custom : public UClass {
|
||||
public:
|
||||
using UClass::UClass;
|
||||
std::vector<FieldPtr> FList{};
|
||||
int32_t AttrNum{ 0 };
|
||||
|
||||
static const FieldPtr* GetField(const UClass* _cls,const Name& name, bool isMethod){
|
||||
auto cls = static_cast<const UClass_Custom*>(_cls);
|
||||
auto& FList = cls->FList;
|
||||
// 指定开始位置的迭代器
|
||||
auto start = FList.begin();
|
||||
if (isMethod) {
|
||||
start += cls->AttrNum;
|
||||
}
|
||||
auto end = FList.end();
|
||||
for (auto it = start; it != end; ++it) {
|
||||
if (it->name == name) {
|
||||
return &*it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BuildClass() {
|
||||
FList.shrink_to_fit();//缩减容量,FList大小不再改变了
|
||||
vtable.GetField = &UClass_Custom::GetField;
|
||||
}
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
template<typename T, typename P = void>
|
||||
class UClass_Meta : public UClass {
|
||||
public:
|
||||
using FieldsType = decltype(T::__MakeFields());
|
||||
FieldsType Fields{ T::__MakeFields() };
|
||||
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
|
||||
if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
flag = CLASS_TRIVIAL_FLAG;
|
||||
}
|
||||
if constexpr (!std::is_same_v<P, void>) {
|
||||
parent = &TypeInfo<P>::StaticClass;
|
||||
}
|
||||
|
||||
17
engine/3rdparty/zlib/include/refl/detail/view.h
vendored
17
engine/3rdparty/zlib/include/refl/detail/view.h
vendored
@ -16,15 +16,14 @@ namespace refl {
|
||||
//左值=>caller变量地址
|
||||
template<typename T>
|
||||
constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){
|
||||
if constexpr (std::is_same_v<args_type_t<T>, void*>) {
|
||||
val = v;
|
||||
cls = &TypeInfo<args_type_t<T>>::StaticClass;
|
||||
}
|
||||
else if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
|
||||
if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
|
||||
val = v.val;
|
||||
cls = v.cls;
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
constexpr ArgsView(T* v) : val(v), cls(&TypeInfo<args_type_t<T>*>::StaticClass) {
|
||||
}
|
||||
template<typename T>//参数 T* => T*
|
||||
constexpr inline T cast_to() const {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
@ -61,7 +60,7 @@ namespace refl {
|
||||
struct ArgsValueList{
|
||||
void* data;
|
||||
ArgsView* ptr;
|
||||
int num{0};
|
||||
int num;
|
||||
bool isMemoryOwner{false};
|
||||
ArgsValueList(const sarray<ArgsValue>& args,void* memory = nullptr);
|
||||
~ArgsValueList();
|
||||
@ -69,10 +68,10 @@ namespace refl {
|
||||
};
|
||||
class ObjectView {
|
||||
public:
|
||||
const char* ptr;
|
||||
const void* ptr;
|
||||
const UClass* cls;
|
||||
const FieldPtr* cache{ nullptr };
|
||||
ObjectView(const void* ptr, const UClass* cls) : ptr((const char*)ptr), cls(cls) {}
|
||||
ObjectView(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) {}
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
@ -81,7 +80,7 @@ namespace refl {
|
||||
template<typename T>
|
||||
bool Set(const Name& name, const T& t);
|
||||
|
||||
bool Invoke(const Name& name,const std::vector<ArgsView>& ArgsList);//这里是内存分配慢呀,这里是可以改成栈容器的
|
||||
bool Invoke(const Name& name,const sarray<ArgsView>& ArgsList);//这里是内存分配慢呀,这里是可以改成栈容器的
|
||||
|
||||
bool Invoke(const Name& name,std::vector<ArgsView>& ArgsList);
|
||||
|
||||
|
||||
@ -7,12 +7,17 @@ namespace refl {
|
||||
* 对象从小到大
|
||||
* 对象从大到小
|
||||
*/
|
||||
using enum ClassFlag;
|
||||
bool ArgsView::ConvertTo(const UClass* toClass) {
|
||||
//子类转父类
|
||||
if (cls->IsChildOf(toClass)) {
|
||||
cls = toClass;
|
||||
return true;
|
||||
}
|
||||
if (cls->flag & CLASS_TRIVIAL_FLAG && toClass->flag & CLASS_TRIVIAL_FLAG) {
|
||||
cls = toClass;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ArgsValueList::ArgsValueList(const sarray<ArgsValue>& args, void* memory)
|
||||
@ -62,7 +67,7 @@ namespace refl {
|
||||
if (cache && cache->name == name) {
|
||||
_cache_get: bool isChild = cache->type->IsChildOf<T>(true);
|
||||
if (isChild) {
|
||||
t = *(T*)(ptr + cache->data.offset);
|
||||
t = *(T*)((const char*)ptr + cache->data.offset);
|
||||
}
|
||||
return isChild;
|
||||
}
|
||||
@ -82,7 +87,7 @@ namespace refl {
|
||||
if (cache && cache->name == name) {
|
||||
_cache_set: bool isChild = cache->type->IsChildOf<T>(true);
|
||||
if (isChild) {
|
||||
*(T*)(ptr + cache->data.offset) = t;
|
||||
*(T*)((const char*)ptr + cache->data.offset) = t;
|
||||
}
|
||||
return isChild;
|
||||
}
|
||||
@ -96,7 +101,7 @@ namespace refl {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ObjectView::Invoke(const Name& name,const std::vector<ArgsView>& ArgsList)
|
||||
bool ObjectView::Invoke(const Name& name,const sarray<ArgsView>& ArgsList)
|
||||
{
|
||||
auto field = cls->GetField(name, true);
|
||||
if (!field) {
|
||||
|
||||
18
engine/3rdparty/zlib/include/refl/refl.h
vendored
18
engine/3rdparty/zlib/include/refl/refl.h
vendored
@ -27,8 +27,9 @@ namespace refl {
|
||||
FieldPtr::Data method = { offset };
|
||||
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
|
||||
}
|
||||
//用处不大---------------begin
|
||||
template<typename T>
|
||||
consteval int GetStaticField(Name name) {
|
||||
consteval int GetStaticFieldID(Name name) {
|
||||
auto fields = T::__MakeStaticFields();
|
||||
auto first = fields.begin();
|
||||
for (auto& field : fields) {
|
||||
@ -39,7 +40,7 @@ namespace refl {
|
||||
return 0;
|
||||
}
|
||||
template<typename T>
|
||||
consteval int GetStaticField(bool(* fptr)(FieldPtr)) {
|
||||
consteval int GetStaticFieldID(bool(* fptr)(FieldPtr)) {
|
||||
auto fields = T::__MakeStaticFields();
|
||||
auto first = fields.begin();
|
||||
for (auto& field : fields) {
|
||||
@ -49,4 +50,17 @@ namespace refl {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
template<typename T, auto name>
|
||||
consteval auto GetStaticField() {
|
||||
constexpr auto fields = T::__StaticFields();
|
||||
using AutoType = decltype(name);
|
||||
if constexpr (std::is_same_v<AutoType, int>) {
|
||||
return std::get<name>(fields);
|
||||
}
|
||||
else {
|
||||
constexpr auto id = GetStaticFieldID<T>(Name(name.Data()));
|
||||
return std::get<id>(fields);
|
||||
}
|
||||
}
|
||||
//用处不大---------------end
|
||||
}
|
||||
32
engine/3rdparty/zlib/include/refl/std/sarray.h
vendored
32
engine/3rdparty/zlib/include/refl/std/sarray.h
vendored
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <concepts>
|
||||
namespace refl {
|
||||
template<typename T>
|
||||
@ -7,26 +8,32 @@ namespace refl {
|
||||
const T* m_ptr;
|
||||
int m_size;
|
||||
public:
|
||||
constexpr sarray(const std::vector<T>& list) : m_ptr(&list.front()), m_size(list.size()) {}
|
||||
constexpr sarray() :m_ptr(nullptr), m_size(0) {}
|
||||
constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_size(list.size()) {}
|
||||
template<int N>
|
||||
constexpr sarray(const std::array<T, N>& arr):m_ptr(&arr[0]), m_size(arr.size()){}
|
||||
const T* get() const{
|
||||
const T* get() const noexcept {
|
||||
return m_ptr;
|
||||
}
|
||||
const T* at(int i) const {
|
||||
const T* last()const noexcept {
|
||||
if (m_size > 0)
|
||||
return m_ptr + m_size - 1;
|
||||
return m_ptr;
|
||||
}
|
||||
const T* at(int i) const noexcept {
|
||||
if (i < m_size) {
|
||||
return m_ptr + i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
constexpr int size() const {
|
||||
constexpr int size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
constexpr const auto begin()const {
|
||||
constexpr auto begin()const noexcept {
|
||||
return iterator{ m_ptr };
|
||||
}
|
||||
constexpr const auto end() const {
|
||||
constexpr auto end() const noexcept {
|
||||
return iterator{ m_ptr + m_size};
|
||||
}
|
||||
// Iterator class
|
||||
@ -38,18 +45,25 @@ namespace refl {
|
||||
constexpr iterator(const T* p) : ptr(p) {}
|
||||
|
||||
// Overload ++ to move to next element
|
||||
constexpr iterator& operator++() {
|
||||
constexpr iterator& operator++() noexcept{
|
||||
++ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//这里其实是--it,而不是it--
|
||||
constexpr iterator& operator--(int) noexcept {
|
||||
--ptr;
|
||||
return *this;
|
||||
}
|
||||
constexpr const T* operator->() const noexcept {
|
||||
return ptr;
|
||||
}
|
||||
// Overload * to dereference iterator
|
||||
constexpr const T& operator*() const {
|
||||
constexpr const T& operator*() const noexcept {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
// Overload != to compare iterators
|
||||
constexpr bool operator!=(const iterator& other) const {
|
||||
constexpr bool operator!=(const iterator& other) const noexcept {
|
||||
return ptr != other.ptr;
|
||||
}
|
||||
};
|
||||
|
||||
14
engine/3rdparty/zlib/test/refl/vertex.h
vendored
14
engine/3rdparty/zlib/test/refl/vertex.h
vendored
@ -14,11 +14,11 @@ struct vec3 : public vec3_parent {
|
||||
float z = 3;
|
||||
string name{ "hellohellohellohellohellohello" };
|
||||
void norm(int x1, int& x2)override {
|
||||
//x2 = x1 * x2;
|
||||
//cout << x2 << "vec3::norm" << endl;
|
||||
x2 = x1 * x2;
|
||||
cout << x2 << "vec3::norm" << endl;
|
||||
}
|
||||
virtual float norm1(int& x1) {
|
||||
//x1 = x1 * x * y * z;
|
||||
x1 = x1 * x * y * z;
|
||||
//x = x1;
|
||||
//y = x1 - 1;
|
||||
//z = x1 - 10;
|
||||
@ -26,13 +26,17 @@ struct vec3 : public vec3_parent {
|
||||
return x1;
|
||||
}
|
||||
static void norm2(int x1 = 10) {
|
||||
//cout << x1 << "::norm2" << endl;
|
||||
cout << x1 << "::norm2" << endl;
|
||||
}
|
||||
static void norm3(int x1 = 10) {
|
||||
x1 = x1 * 10;
|
||||
//cout << x1 << "::norm3" << endl;
|
||||
cout << x1 << "::norm3" << endl;
|
||||
}
|
||||
using MyUClass = UClass_Meta<vec3, vec3_parent>;
|
||||
//这里好像不需要
|
||||
consteval static auto __StaticFields() {
|
||||
return std::make_tuple(&vec3::x, &vec3::y, &vec3::z, &vec3::norm, &vec3::norm1, &vec3::norm2);
|
||||
};
|
||||
consteval static auto __MakeStaticFields() {
|
||||
return std::array{
|
||||
MakeStaticField(&vec3::x, "x"),
|
||||
|
||||
28
engine/3rdparty/zlib/test/refl_01.cpp
vendored
28
engine/3rdparty/zlib/test/refl_01.cpp
vendored
@ -1,23 +1,23 @@
|
||||
#include "refl/vertex.h"
|
||||
#include "refl/std/sarray.h"
|
||||
#include <array>
|
||||
struct object {
|
||||
|
||||
};
|
||||
template<typename T>
|
||||
void testInitObject(){
|
||||
if constexpr (has_init_object<T>::value){
|
||||
auto InitObject = &T::__InitObject;
|
||||
}
|
||||
}
|
||||
int main() {
|
||||
testInitObject<object>();
|
||||
auto cls1 = &TypeInfo<void*>::StaticClass;
|
||||
auto cls2 = &TypeInfo<const void*>::StaticClass;
|
||||
using type1 = real_type_t<const void*>;
|
||||
auto& cls = TypeInfo<vec3>::StaticClass;
|
||||
auto field = cls.GetField(GetStaticField<vec3>("norm"));
|
||||
auto field = cls.GetField(GetStaticFieldID<vec3>("norm"));
|
||||
auto ov = cls.New();
|
||||
|
||||
int x = 10;
|
||||
auto ov = cls.New<vec3>();
|
||||
ov->norm(x, x);
|
||||
field->Call<void>((void*)ov, 10, x);
|
||||
field->Call(&vec3::norm, ov.ptr, x, x);
|
||||
field->Invoke({ov.ptr, x, x});
|
||||
std::vector<ArgsView> ArgsList{{}, ov.ptr, x, x};
|
||||
field->Invoke(ArgsList);
|
||||
sarray<ArgsView> sa(ArgsList);
|
||||
field->Invoke(sa);
|
||||
UMethod_Auto<void, const void*, int, int*>::Call(field, { ov.ptr, x, x });
|
||||
//fetchUMethod(&vec3::norm)->Call(field, ov.ptr, x, &x);
|
||||
std::cout << "hello world\n";
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user