mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-07-06 02:51:35 +00:00
Merge pull request #662 from HotaruBlaze/cleanup-lua-templates
Cleanup(server): Refactor code for Lua function dispatch
This commit is contained in:
commit
00997fa732
2 changed files with 67 additions and 53 deletions
|
@ -53,53 +53,67 @@ LangLua::~LangLua()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned int I, unsigned int F>
|
// LuaFunctionDispatcher template struct for Lua function dispatch
|
||||||
struct Lua_dispatch_ {
|
template <unsigned int ArgIndex, unsigned int FunctionIndex>
|
||||||
template<typename R, typename... Args>
|
struct LuaFunctionDispatcher {
|
||||||
inline static R Lua_dispatch(lua_State*&& lua, Args&&... args) noexcept {
|
// Dispatch Lua function with the given arguments
|
||||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
template <typename ReturnType, typename... Args>
|
||||||
auto arg = luabridge::Stack<typename CharType<F_.func.types[I - 1]>::type>::get(lua, I);
|
inline static ReturnType Dispatch(lua_State*&& lua, Args&&... args) noexcept {
|
||||||
return Lua_dispatch_<I - 1, F>::template Lua_dispatch<R>(
|
// Retrieve function data
|
||||||
std::forward<lua_State*>(lua),
|
constexpr ScriptFunctionData const& functionData = ScriptFunctions::functions[FunctionIndex];
|
||||||
arg,
|
// Retrieve argument from the Lua stack
|
||||||
std::forward<Args>(args)...);
|
auto argument = luabridge::Stack<typename CharType<functionData.func.types[ArgIndex - 1]>::type>::get(lua, ArgIndex);
|
||||||
|
// Recursively dispatch the Lua function
|
||||||
|
return LuaFunctionDispatcher<ArgIndex - 1, FunctionIndex>::template Dispatch<ReturnType>(
|
||||||
|
std::forward<lua_State*>(lua), argument, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<unsigned int F>
|
// Specialization for LuaFunctionDispatcher when ArgIndex is 0
|
||||||
struct Lua_dispatch_<0, F> {
|
template <unsigned int FunctionIndex>
|
||||||
template<typename R, typename... Args>
|
struct LuaFunctionDispatcher<0, FunctionIndex> {
|
||||||
inline static R Lua_dispatch(lua_State*&&, Args&&... args) noexcept {
|
// Dispatch Lua function with the given arguments
|
||||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
template <typename ReturnType, typename... Args>
|
||||||
return reinterpret_cast<FunctionEllipsis<R>>(F_.func.addr)(std::forward<Args>(args)...);
|
inline static ReturnType Dispatch(lua_State*&&, Args&&... args) noexcept {
|
||||||
|
// Retrieve function data
|
||||||
|
constexpr ScriptFunctionData const& functionData = ScriptFunctions::functions[FunctionIndex];
|
||||||
|
// Call the C++ function using reinterpret_cast
|
||||||
|
return reinterpret_cast<FunctionEllipsis<ReturnType>>(functionData.func.addr)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<unsigned int I>
|
// Lua function wrapper for functions returning 'void'
|
||||||
static typename std::enable_if<ScriptFunctions::functions[I].func.ret == 'v', int>::type wrapper(lua_State* lua) noexcept {
|
template <unsigned int FunctionIndex>
|
||||||
Lua_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template Lua_dispatch<void>(std::forward<lua_State*>(lua));
|
static typename std::enable_if<ScriptFunctions::functions[FunctionIndex].func.ret == 'v', int>::type LuaFunctionWrapper(lua_State* lua) noexcept {
|
||||||
|
// Dispatch the Lua function
|
||||||
|
LuaFunctionDispatcher<ScriptFunctions::functions[FunctionIndex].func.numargs, FunctionIndex>::template Dispatch<void>(std::forward<lua_State*>(lua));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned int I>
|
// Lua function wrapper for functions with non-void return types
|
||||||
static typename std::enable_if<ScriptFunctions::functions[I].func.ret != 'v', int>::type wrapper(lua_State* lua) noexcept {
|
template <unsigned int FunctionIndex>
|
||||||
auto ret = Lua_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template Lua_dispatch<
|
static typename std::enable_if<ScriptFunctions::functions[FunctionIndex].func.ret != 'v', int>::type LuaFunctionWrapper(lua_State* lua) noexcept {
|
||||||
typename CharType<ScriptFunctions::functions[I].func.ret>::type>(std::forward<lua_State*>(lua));
|
// Dispatch the Lua function
|
||||||
luabridge::Stack <typename CharType<ScriptFunctions::functions[I].func.ret>::type>::push (lua, ret);
|
auto result = LuaFunctionDispatcher<ScriptFunctions::functions[FunctionIndex].func.numargs, FunctionIndex>::template Dispatch<
|
||||||
|
typename CharType<ScriptFunctions::functions[FunctionIndex].func.ret>::type>(std::forward<lua_State*>(lua));
|
||||||
|
// Push the result onto the Lua stack
|
||||||
|
luabridge::Stack<typename CharType<ScriptFunctions::functions[FunctionIndex].func.ret>::type>::push(lua, result);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned int I>
|
// Struct for defining Lua functions with names and wrappers
|
||||||
struct F_
|
template <unsigned int FunctionIndex>
|
||||||
{
|
struct LuaFunctionDefinition {
|
||||||
static constexpr LuaFuctionData F{ScriptFunctions::functions[I].name, wrapper<I>};
|
static constexpr LuaFunctionData FunctionInfo{
|
||||||
|
ScriptFunctions::functions[FunctionIndex].name, LuaFunctionWrapper<FunctionIndex>
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<> struct LuaFunctionDefinition<0> { static constexpr LuaFunctionData FunctionInfo{"CreateTimer", LangLua::CreateTimer}; };
|
||||||
|
template<> struct LuaFunctionDefinition<1> { static constexpr LuaFunctionData FunctionInfo{"CreateTimerEx", LangLua::CreateTimerEx}; };
|
||||||
|
template<> struct LuaFunctionDefinition<2> { static constexpr LuaFunctionData FunctionInfo{"MakePublic", LangLua::MakePublic}; };
|
||||||
|
template<> struct LuaFunctionDefinition<3> { static constexpr LuaFunctionData FunctionInfo{"CallPublic", LangLua::CallPublic}; };
|
||||||
|
|
||||||
template<> struct F_<0> { static constexpr LuaFuctionData F{"CreateTimer", LangLua::CreateTimer}; };
|
|
||||||
template<> struct F_<1> { static constexpr LuaFuctionData F{"CreateTimerEx", LangLua::CreateTimerEx}; };
|
|
||||||
template<> struct F_<2> { static constexpr LuaFuctionData F{"MakePublic", LangLua::MakePublic}; };
|
|
||||||
template<> struct F_<3> { static constexpr LuaFuctionData F{"CallPublic", LangLua::CallPublic}; };
|
|
||||||
|
|
||||||
#ifdef __arm__
|
#ifdef __arm__
|
||||||
template<std::size_t... Is>
|
template<std::size_t... Is>
|
||||||
|
@ -128,30 +142,29 @@ LuaFuctionData *functions(indices<Indices...>)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template<unsigned int I>
|
template<unsigned int I>
|
||||||
struct C
|
struct LuaFunctionInitializer
|
||||||
{
|
{
|
||||||
constexpr static void Fn(LuaFuctionData *functions_)
|
constexpr static void Initialize(LuaFunctionData *functions_)
|
||||||
{
|
{
|
||||||
functions_[I] = F_<I>::F;
|
functions_[I] = LuaFunctionDefinition<I>::FunctionInfo;
|
||||||
C<I - 1>::Fn(functions_);
|
LuaFunctionInitializer<I - 1>::Initialize(functions_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct C<0>
|
struct LuaFunctionInitializer<0>
|
||||||
{
|
{
|
||||||
constexpr static void Fn(LuaFuctionData *functions_)
|
constexpr static void Initialize(LuaFunctionData *functions_)
|
||||||
{
|
{
|
||||||
functions_[0] = F_<0>::F;
|
functions_[0] = LuaFunctionDefinition<0>::FunctionInfo;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t LastI>
|
template<size_t LastI>
|
||||||
LuaFuctionData *functions()
|
LuaFunctionData *GetLuaFunctions()
|
||||||
{
|
{
|
||||||
|
static LuaFunctionData functions_[LastI];
|
||||||
static LuaFuctionData functions_[LastI];
|
LuaFunctionInitializer<LastI - 1>::Initialize(functions_);
|
||||||
C<LastI - 1>::Fn(functions_);
|
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof(functions_) / sizeof(functions_[0]) ==
|
sizeof(functions_) / sizeof(functions_[0]) ==
|
||||||
|
@ -173,20 +186,21 @@ void LangLua::LoadProgram(const char *filename)
|
||||||
constexpr auto functions_n = sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]);
|
constexpr auto functions_n = sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]);
|
||||||
|
|
||||||
#ifdef __arm__
|
#ifdef __arm__
|
||||||
LuaFuctionData *functions_ = functions(IndicesFor<functions_n>{});
|
LuaFunctionData *functions_ = GetLuaFunctions(IndicesFor<functions_n>{});
|
||||||
#else
|
#else
|
||||||
LuaFuctionData *functions_ = functions<sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0])>();
|
LuaFunctionData *functions_ = GetLuaFunctions<sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0])>();
|
||||||
#endif
|
#endif
|
||||||
luabridge::Namespace tes3mp = luabridge::getGlobalNamespace(lua).beginNamespace("tes3mp");
|
luabridge::Namespace tes3mp = luabridge::getGlobalNamespace(lua).beginNamespace("tes3mp");
|
||||||
|
|
||||||
for (unsigned i = 0; i < functions_n; i++)
|
for (unsigned i = 0; i < functions_n; i++)
|
||||||
tes3mp.addCFunction(functions_[i].name, functions_[i].func);
|
tes3mp.addCFunction(functions_[i].name, functions_[i].func);
|
||||||
|
|
||||||
tes3mp.endNamespace();
|
tes3mp.endNamespace();
|
||||||
|
|
||||||
|
if ((err = lua_pcall(lua, 0, 0, 0)) != 0) // Run once script for load in memory.
|
||||||
|
throw std::runtime_error("Lua script " + std::string(filename) + " error (" + std::to_string(err) + "): \"" +
|
||||||
|
std::string(lua_tostring(lua, -1)) + "\"");
|
||||||
|
|
||||||
if ((err = lua_pcall(lua, 0, 0, 0)) != 0) // Run once script for load in memory.
|
|
||||||
throw std::runtime_error("Lua script " + std::string(filename) + " error (" + std::to_string(err) + "): \"" +
|
|
||||||
std::string(lua_tostring(lua, -1)) + "\"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LangLua::FreeProgram()
|
int LangLua::FreeProgram()
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "../ScriptFunction.hpp"
|
#include "../ScriptFunction.hpp"
|
||||||
#include "../Language.hpp"
|
#include "../Language.hpp"
|
||||||
|
|
||||||
struct LuaFuctionData
|
struct LuaFunctionData
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
lua_CFunction func;
|
lua_CFunction func;
|
||||||
|
|
Loading…
Reference in a new issue