/* * LuaCallWrapper.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #pragma once #include "api/Registry.h" #include "LuaStack.h" #include VCMI_LIB_NAMESPACE_BEGIN namespace scripting { namespace detail { template struct Seq {}; template struct Gens : Gens {}; template struct Gens<0, S...> { using type = Seq; }; template class LuaArgumentsTuple { public: using TupleData = std::tuple; 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::type()); } private: template int callFunc(lua_State * L, Seq) { LuaStack S(L); bool ok[sizeof...(Args)] = {(S.tryGet(N+1, std::get(args)))...}; if(std::count(std::begin(ok), std::end(ok), false) > 0) return S.retVoid(); R ret = f(std::get(args) ...); S.clear(); S.push(ret); return 1; } }; class LuaFunctionInvoker { public: template static STRONG_INLINE int invoke(lua_State * L, R(*f)(Args ...)) { LuaArgumentsTuple args(f); return args.invoke(L); } }; } template 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 class LuaMethodWrapper { }; template class LuaMethodWrapper { public: static int invoke(lua_State * L) { LuaStack S(L); const 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 class LuaMethodWrapper { 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 class LuaMethodWrapper { public: static int invoke(lua_State * L) { LuaStack S(L); const 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 class LuaMethodWrapper { 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 class LuaMethodWrapper { using PM1 = std::remove_cv_t>; public: static int invoke(lua_State * L) { LuaStack S(L); const U * obj = nullptr; if(!S.tryGet(1,obj)) return S.retVoid(); PM1 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 class LuaMethodWrapper { using PM1 = std::remove_cv_t>; public: static int invoke(lua_State * L) { LuaStack S(L); U * obj = nullptr; if(!S.tryGet(1,obj)) return S.retVoid(); PM1 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 class LuaMethodWrapper { using PM1 = std::remove_cv_t>; public: static int invoke(lua_State * L) { LuaStack S(L); const U * obj = nullptr; if(!S.tryGet(1,obj)) return S.retVoid(); PM1 p1; if(!S.tryGet(2, p1)) return S.retVoid(); static auto functor = std::mem_fn(method); S.clear(); functor(obj, p1); return 0; } }; template class LuaMethodWrapper { using PM1 = std::remove_cv_t>; public: static int invoke(lua_State * L) { LuaStack S(L); U * obj = nullptr; if(!S.tryGet(1,obj)) return S.retVoid(); PM1 p1; if(!S.tryGet(2, p1)) return S.retVoid(); static auto functor = std::mem_fn(method); S.clear(); functor(obj, p1); return 0; } }; template class LuaMethodWrapper { using PM1 = std::remove_cv_t>; using PM2 = std::remove_cv_t>; public: static int invoke(lua_State * L) { LuaStack S(L); const U * obj = nullptr; if(!S.tryGet(1, obj)) return S.retVoid(); PM1 p1; if(!S.tryGet(2, p1)) return S.retVoid(); PM2 p2; if(!S.tryGet(3, p2)) return S.retVoid(); static auto functor = std::mem_fn(method); S.clear(); S.push(functor(obj, p1, p2)); return S.retPushed(); } }; template class LuaMethodWrapper { using PM1 = std::remove_cv_t>; using PM2 = std::remove_cv_t>; public: static int invoke(lua_State * L) { LuaStack S(L); const U * obj = nullptr; if(!S.tryGet(1, obj)) return S.retVoid(); PM1 p1; if(!S.tryGet(2, p1)) return S.retVoid(); PM2 p2; if(!S.tryGet(3, p2)) return S.retVoid(); static auto functor = std::mem_fn(method); S.clear(); functor(obj, p1, p2); return 0; } }; } VCMI_LIB_NAMESPACE_END