mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Less ugly API declarations
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "api/Registry.h"
|
||||
#include "LuaStack.h"
|
||||
#include "LuaFunctor.h"
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
@@ -20,8 +19,83 @@ namespace scripting
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<int ...>
|
||||
struct Seq {};
|
||||
|
||||
template<int N, int ...S>
|
||||
struct Gens : Gens<N-1, N-1, S...> {};
|
||||
|
||||
template<int ...S>
|
||||
struct Gens<0, S...>
|
||||
{
|
||||
typedef Seq<S...> type;
|
||||
};
|
||||
|
||||
template <typename R, typename ... Args>
|
||||
class LuaArgumentsTuple
|
||||
{
|
||||
public:
|
||||
using TupleData = std::tuple<Args ...>;
|
||||
using Functor = R(*)(Args ...);
|
||||
|
||||
TupleData args;
|
||||
Functor f;
|
||||
|
||||
LuaArgumentsTuple(Functor _f)
|
||||
:f(_f),
|
||||
args()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
STRONG_INLINE int invoke(lua_State * L)
|
||||
{
|
||||
return callFunc(L, typename Gens<sizeof...(Args)>::type());
|
||||
}
|
||||
private:
|
||||
template<int ...N>
|
||||
int callFunc(lua_State * L, Seq<N...>)
|
||||
{
|
||||
LuaStack S(L);
|
||||
|
||||
bool ok[sizeof...(Args)] = {(S.tryGet(N+1, std::get<N>(args)))...};
|
||||
|
||||
if(std::count(std::begin(ok), std::end(ok), false) > 0)
|
||||
return S.retVoid();
|
||||
|
||||
|
||||
R ret = f(std::get<N>(args) ...);
|
||||
S.clear();
|
||||
S.push(ret);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class LuaFunctionInvoker
|
||||
{
|
||||
public:
|
||||
template<typename R, typename ... Args>
|
||||
static STRONG_INLINE int invoke(lua_State * L, R(*f)(Args ...))
|
||||
{
|
||||
LuaArgumentsTuple<R, Args ...> args(f);
|
||||
return args.invoke(L);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename F, F f>
|
||||
class LuaFunctionWrapper
|
||||
{
|
||||
public:
|
||||
static int invoke(lua_State * L)
|
||||
{
|
||||
return detail::LuaFunctionInvoker::invoke(L, f);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//TODO: this should be the only one wrapper type
|
||||
//
|
||||
template <typename U, typename M, M m>
|
||||
@@ -50,6 +124,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, typename R, R(T:: * method)()>
|
||||
class LuaMethodWrapper <U, R(T:: *)(), method>
|
||||
{
|
||||
public:
|
||||
static int invoke(lua_State * L)
|
||||
{
|
||||
LuaStack S(L);
|
||||
U * obj = nullptr;
|
||||
|
||||
if(!S.tryGet(1,obj))
|
||||
return S.retVoid();
|
||||
|
||||
static auto functor = std::mem_fn(method);
|
||||
|
||||
S.clear();
|
||||
S.push(functor(obj));
|
||||
return S.retPushed();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, void(T:: * method)()const>
|
||||
class LuaMethodWrapper <U, void(T:: *)()const, method>
|
||||
{
|
||||
@@ -69,6 +163,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, void(T:: * method)()>
|
||||
class LuaMethodWrapper <U, void(T:: *)(), method>
|
||||
{
|
||||
public:
|
||||
static int invoke(lua_State * L)
|
||||
{
|
||||
LuaStack S(L);
|
||||
U * obj = nullptr;
|
||||
|
||||
if(!S.tryGet(1,obj))
|
||||
return S.retVoid();
|
||||
|
||||
static auto functor = std::mem_fn(method);
|
||||
S.clear();
|
||||
functor(obj);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, typename R, typename P1, R(T:: * method)(P1)const>
|
||||
class LuaMethodWrapper <U, R(T:: *)(P1)const, method>
|
||||
{
|
||||
@@ -92,6 +205,29 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, typename R, typename P1, R(T:: * method)(P1)>
|
||||
class LuaMethodWrapper <U, R(T:: *)(P1), method>
|
||||
{
|
||||
public:
|
||||
static int invoke(lua_State * L)
|
||||
{
|
||||
LuaStack S(L);
|
||||
U * obj = nullptr;
|
||||
|
||||
if(!S.tryGet(1,obj))
|
||||
return S.retVoid();
|
||||
|
||||
P1 p1;
|
||||
if(!S.tryGet(2, p1))
|
||||
return S.retVoid();
|
||||
|
||||
static auto functor = std::mem_fn(method);
|
||||
S.clear();
|
||||
S.push(functor(obj, p1));
|
||||
return S.retPushed();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, typename P1, void(T:: * method)(P1)const>
|
||||
class LuaMethodWrapper <U, void(T:: *)(P1)const, method>
|
||||
{
|
||||
@@ -115,6 +251,28 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, typename P1, void(T:: * method)(P1)>
|
||||
class LuaMethodWrapper <U, void(T:: *)(P1), method>
|
||||
{
|
||||
public:
|
||||
static int invoke(lua_State * L)
|
||||
{
|
||||
LuaStack S(L);
|
||||
U * obj = nullptr;
|
||||
|
||||
if(!S.tryGet(1,obj))
|
||||
return S.retVoid();
|
||||
|
||||
P1 p1;
|
||||
if(!S.tryGet(2, p1))
|
||||
return S.retVoid();
|
||||
|
||||
static auto functor = std::mem_fn(method);
|
||||
S.clear();
|
||||
functor(obj, p1);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, typename T, typename R, typename P1, typename P2, R(T:: * method)(P1, P2)const>
|
||||
class LuaMethodWrapper <U, R(T:: *)(P1, P2)const, method>
|
||||
@@ -170,150 +328,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//deprecated, should use LuaMethodWrapper instead, once implemented
|
||||
template <typename T>
|
||||
class LuaCallWrapper
|
||||
{
|
||||
public:
|
||||
using Wrapped = typename std::remove_const<T>::type;
|
||||
|
||||
static std::function<int(lua_State *, T *)> createFunctor(void (Wrapped::* method)())
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
functor(object);
|
||||
return S.retVoid();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::function<int(lua_State *, T *)> createFunctor(void (Wrapped::* method)() const)
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
functor(object);
|
||||
return S.retVoid();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
static std::function<int(lua_State *, T *)> createFunctor(R (Wrapped::* method)())
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
S.clear();
|
||||
S.push(functor(object));
|
||||
return S.retPushed();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
static std::function<int(lua_State *, T *)> createFunctor(R (Wrapped::* method)() const)
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
S.clear();
|
||||
S.push(functor(object));
|
||||
return S.retPushed();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename P1>
|
||||
static std::function<int(lua_State *, T *)> createFunctor(void (Wrapped::* method)(P1))
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
P1 p1;
|
||||
if(S.tryGet(1, p1))
|
||||
{
|
||||
functor(object, p1);
|
||||
}
|
||||
|
||||
return S.retVoid();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename P1>
|
||||
static std::function<int(lua_State *, T *)> createFunctor(void (Wrapped::* method)(P1) const)
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
P1 p1;
|
||||
if(S.tryGet(1, p1))
|
||||
{
|
||||
functor(object, p1);
|
||||
}
|
||||
|
||||
return S.retVoid();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename R, typename P1>
|
||||
static std::function<int(lua_State *, T *)> createFunctor(R (Wrapped::* method)(P1))
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
P1 p1;
|
||||
if(S.tryGet(1, p1))
|
||||
{
|
||||
S.push(functor(object, p1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return S.retVoid();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename R, typename P1>
|
||||
static std::function<int(lua_State *, T *)> createFunctor(R (Wrapped::* method)(P1) const)
|
||||
{
|
||||
auto functor = std::mem_fn(method);
|
||||
auto ret = [=](lua_State * L, T * object)->int
|
||||
{
|
||||
LuaStack S(L);
|
||||
P1 p1;
|
||||
if(S.tryGet(1, p1))
|
||||
{
|
||||
S.push(functor(object, p1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return S.retVoid();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user