1
0
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:
AlexVinS
2021-02-16 17:07:30 +03:00
parent ec6f7b88fe
commit 6d245a7821
59 changed files with 693 additions and 827 deletions

View File

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