reflection - functions

This commit is contained in:
Mikulas Florek 2017-11-19 13:55:12 +01:00
parent d14cc8bd69
commit 9d1d973732
4 changed files with 133 additions and 27 deletions

View file

@ -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

View file

@ -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);

View file

@ -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",

View file

@ -5,7 +5,6 @@
#define MF_RESOURCE_DONT_INCLUDE_WINDOWS_H
#include "stb/mf_resource.h"
INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
{
SetProcessDPIAware();