reflection - functions
This commit is contained in:
parent
d14cc8bd69
commit
9d1d973732
4 changed files with 133 additions and 27 deletions
|
@ -34,30 +34,8 @@ struct IsSame<T, T>
|
|||
enum { result = true };
|
||||
};
|
||||
|
||||
template <typename T> struct ResultOf;
|
||||
template <typename R, typename C, typename... Args> struct ResultOf<R(C::*)(Args...)> { using Type = R; };
|
||||
template <typename R, typename C, typename... Args> struct ResultOf<R(C::*)(Args...)const> { using Type = R; };
|
||||
|
||||
template <typename T> struct Arg1Type;
|
||||
template <typename R, typename C, typename A0, typename A1, typename... Args> struct Arg1Type<R(C::*)(A0, A1, Args...)> { using Type = A1; };
|
||||
template <typename R, typename C, typename A0, typename A1, typename... Args> struct Arg1Type<R(C::*)(A0, A1, Args...)const> { using Type = A1; };
|
||||
|
||||
template <typename T> struct ClassOf;
|
||||
template <typename R, typename C, typename... Args>
|
||||
struct ClassOf<R(C::*)(Args...)>
|
||||
{
|
||||
using Type = C;
|
||||
};
|
||||
template <typename R, typename C>
|
||||
struct ClassOf<R(C::*)>
|
||||
{
|
||||
using Type = C;
|
||||
};
|
||||
|
||||
|
||||
template <int... T> struct Indices {};
|
||||
|
||||
|
||||
template <int offset, int size, int... T>
|
||||
struct BuildIndices
|
||||
{
|
||||
|
@ -198,4 +176,23 @@ constexpr void apply(const F& f, Tuple& t)
|
|||
apply_impl(f, t, typename BuildIndices<-1, TupleSize<Tuple>::result>::result{});
|
||||
}
|
||||
|
||||
|
||||
template <typename T> struct ResultOf;
|
||||
template <typename R, typename C, typename... Args> struct ResultOf<R(C::*)(Args...)> { using Type = R; };
|
||||
template <typename R, typename C, typename... Args> struct ResultOf<R(C::*)(Args...)const> { using Type = R; };
|
||||
|
||||
template <typename T> struct ArgCount;
|
||||
template <typename R, typename C, typename... Args> struct ArgCount<R(C::*)(Args...)> { static const int result = sizeof...(Args); };
|
||||
template <typename R, typename C, typename... Args> struct ArgCount<R(C::*)(Args...) const> { static const int result = sizeof...(Args); };
|
||||
|
||||
template <int N, typename T> struct ArgNType;
|
||||
template <int N, typename R, typename C, typename... Args> struct ArgNType<N, R(C::*)(Args...)> { using Type = typename TupleElement<N, Tuple<Args...>>::Head; };
|
||||
template <int N, typename R, typename C, typename... Args> struct ArgNType<N, R(C::*)(Args...) const> { using Type = typename TupleElement<N, Tuple<Args...>>::Head; };
|
||||
|
||||
template <typename T> struct ClassOf;
|
||||
template <typename R, typename C, typename... Args> struct ClassOf<R(C::*)(Args...)> { using Type = C; };
|
||||
template <typename R, typename C, typename... Args> struct ClassOf<R(C::*)(Args...)const > { using Type = C; };
|
||||
template <typename R, typename C> struct ClassOf<R(C::*)> { using Type = C; };
|
||||
|
||||
|
||||
} // namespace Lumix
|
|
@ -11,6 +11,8 @@
|
|||
#define LUMIX_PROP(Scene, Getter, Setter) \
|
||||
&Scene::Getter, #Scene "::" #Getter, &Scene::Setter, #Scene "::" #Setter
|
||||
|
||||
#define LUMIX_FUNC(Func)\
|
||||
&Func, #Func
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
|
@ -278,10 +280,18 @@ struct ISimpleComponentVisitor : IComponentVisitor
|
|||
};
|
||||
|
||||
|
||||
struct IFunctionVisitor
|
||||
{
|
||||
virtual void visit(const struct FunctionBase& func) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct ComponentBase
|
||||
{
|
||||
virtual int getPropertyCount() const = 0;
|
||||
virtual int getFunctionCount() const = 0;
|
||||
virtual void visit(IComponentVisitor&) const = 0;
|
||||
virtual void visit(IFunctionVisitor&) const = 0;
|
||||
|
||||
const char* name;
|
||||
ComponentType component_type;
|
||||
|
@ -682,10 +692,11 @@ struct Scene
|
|||
};
|
||||
|
||||
|
||||
template <typename... Props>
|
||||
template <typename Funcs, typename Props>
|
||||
struct Component : ComponentBase
|
||||
{
|
||||
int getPropertyCount() const override { return sizeof...(Props); }
|
||||
int getPropertyCount() const override { return TupleSize<Props>::result; }
|
||||
int getFunctionCount() const override { return TupleSize<Funcs>::result; }
|
||||
|
||||
|
||||
void visit(IComponentVisitor& visitor) const override
|
||||
|
@ -696,7 +707,14 @@ struct Component : ComponentBase
|
|||
}
|
||||
|
||||
|
||||
Tuple<Props...> properties;
|
||||
void visit(IFunctionVisitor& visitor) const override
|
||||
{
|
||||
apply([&](auto& x) { visitor.visit(x); }, functions);
|
||||
}
|
||||
|
||||
|
||||
Props properties;
|
||||
Funcs functions;
|
||||
};
|
||||
|
||||
|
||||
|
@ -710,10 +728,99 @@ auto scene(const char* name, Components... components)
|
|||
}
|
||||
|
||||
|
||||
struct FunctionBase
|
||||
{
|
||||
const char* decl_code;
|
||||
|
||||
virtual int getArgCount() const = 0;
|
||||
virtual const char* getReturnType() const = 0;
|
||||
virtual const char* getArgType(int i) const = 0;
|
||||
};
|
||||
|
||||
|
||||
namespace internal
|
||||
{
|
||||
static const unsigned int FRONT_SIZE = sizeof("Lumix::Properties::internal::GetTypeNameHelper<") - 1u;
|
||||
static const unsigned int BACK_SIZE = sizeof(">::GetTypeName") - 1u;
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeNameHelper
|
||||
{
|
||||
static const char* GetTypeName(void)
|
||||
{
|
||||
static const size_t size = sizeof(__FUNCTION__) - FRONT_SIZE - BACK_SIZE;
|
||||
static char typeName[size] = {};
|
||||
memcpy(typeName, __FUNCTION__ + FRONT_SIZE, size - 1u);
|
||||
|
||||
return typeName;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
const char* getTypeName(void)
|
||||
{
|
||||
return internal::GetTypeNameHelper<T>::GetTypeName();
|
||||
}
|
||||
|
||||
|
||||
template <typename F> struct Function;
|
||||
|
||||
|
||||
template <typename R, typename C, typename... Args>
|
||||
struct Function<R (C::*)(Args...)> : FunctionBase
|
||||
{
|
||||
using F = R(C::*)(Args...);
|
||||
F function;
|
||||
|
||||
int getArgCount() const override { return ArgCount<F>::result; }
|
||||
const char* getReturnType() const override { return getTypeName<typename ResultOf<F>::Type>(); }
|
||||
|
||||
const char* getArgType(int i) const override
|
||||
{
|
||||
const char* expand[] = {
|
||||
getTypeName<Args>()...
|
||||
};
|
||||
return expand[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename F>
|
||||
auto function(F func, const char* decl_code)
|
||||
{
|
||||
Function<F> ret;
|
||||
ret.function = func;
|
||||
ret.decl_code = decl_code;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
template <typename... F>
|
||||
auto functions(F... functions)
|
||||
{
|
||||
Tuple<F...> f = makeTuple(functions...);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
template <typename... Props, typename... Funcs>
|
||||
auto component(const char* name, Tuple<Funcs...> functions, Props... props)
|
||||
{
|
||||
Component<Tuple<Funcs...>, Tuple<Props...>> cmp;
|
||||
cmp.name = name;
|
||||
cmp.functions = functions;
|
||||
cmp.properties = makeTuple(props...);
|
||||
cmp.component_type = getComponentType(name);
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
||||
template <typename... Props>
|
||||
auto component(const char* name, Props... props)
|
||||
{
|
||||
Component<Props...> cmp;
|
||||
Component<Tuple<>, Tuple<Props...>> cmp;
|
||||
cmp.name = name;
|
||||
cmp.properties = makeTuple(props...);
|
||||
cmp.component_type = getComponentType(name);
|
||||
|
|
|
@ -118,6 +118,9 @@ namespace Lumix
|
|||
RadiansAttribute())
|
||||
),
|
||||
component("physical_controller",
|
||||
functions(
|
||||
function(LUMIX_FUNC(PhysicsScene::moveController))
|
||||
),
|
||||
property("Layer", LUMIX_PROP(PhysicsScene, getControllerLayer, setControllerLayer))
|
||||
),
|
||||
component("rigid_actor",
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#define MF_RESOURCE_DONT_INCLUDE_WINDOWS_H
|
||||
#include "stb/mf_resource.h"
|
||||
|
||||
|
||||
INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
|
||||
{
|
||||
SetProcessDPIAware();
|
||||
|
|
Loading…
Reference in a new issue