diff --git a/include/TLuaEngine.h b/include/TLuaEngine.h index e21bfb1..6653492 100644 --- a/include/TLuaEngine.h +++ b/include/TLuaEngine.h @@ -19,6 +19,11 @@ using TLuaStateId = std::string; namespace fs = std::filesystem; +using TLuaArgTypes = std::variant; +static constexpr size_t TLuaArgTypes_String = 0; +static constexpr size_t TLuaArgTypes_Int = 1; +static constexpr size_t TLuaArgTypes_VariadicArgs = 2; +static constexpr size_t TLuaArgTypes_Bool = 3; class TLuaPlugin; @@ -62,7 +67,7 @@ public: static void WaitForAll(std::vector>& Results); [[nodiscard]] std::shared_ptr EnqueueScript(TLuaStateId StateID, const TLuaChunk& Script); - [[nodiscard]] std::shared_ptr EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::initializer_list& Args); + [[nodiscard]] std::shared_ptr EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::vector& Args); void EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit = false); void RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName); template @@ -77,7 +82,7 @@ public: for (const auto& Function : Event.second) { beammp_debug("TriggerEvent: triggering \"" + Function + "\" on \"" + Event.first + "\""); if (Event.first != IgnoreId) { - Results.push_back(EnqueueFunctionCall(Event.first, Function, { std::forward(Args)... })); + Results.push_back(EnqueueFunctionCall(Event.first, Function, { TLuaArgTypes { std::forward(Args) }... })); } } } @@ -98,7 +103,7 @@ private: StateThreadData(const StateThreadData&) = delete; ~StateThreadData() noexcept { beammp_debug("\"" + mStateId + "\" destroyed"); } [[nodiscard]] std::shared_ptr EnqueueScript(const TLuaChunk& Script); - [[nodiscard]] std::shared_ptr EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list& Args); + [[nodiscard]] std::shared_ptr EnqueueFunctionCall(const std::string& FunctionName, const std::vector& Args); void RegisterEvent(const std::string& EventName, const std::string& FunctionName); void AddPath(const fs::path& Path); // to be added to path and cpath void operator()() override; @@ -118,7 +123,7 @@ private: std::thread mThread; std::queue>> mStateExecuteQueue; std::recursive_mutex mStateExecuteQueueMutex; - std::queue, std::initializer_list>> mStateFunctionQueue; + std::queue, std::vector>> mStateFunctionQueue; std::recursive_mutex mStateFunctionQueueMutex; TLuaEngine* mEngine; sol::state_view mStateView { mState }; diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index 54cac6a..c198de0 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -62,7 +62,7 @@ std::shared_ptr TLuaEngine::EnqueueScript(TLuaStateId StateID, const return mLuaStates.at(StateID)->EnqueueScript(Script); } -std::shared_ptr TLuaEngine::EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::initializer_list& Args) { +std::shared_ptr TLuaEngine::EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::vector& Args) { std::unique_lock Lock(mLuaStatesMutex); beammp_debug("calling \"" + FunctionName + "\" in \"" + StateID + "\""); return mLuaStates.at(StateID)->EnqueueFunctionCall(FunctionName, Args); @@ -346,7 +346,8 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi FSTable.set_function("CreateDirectory", [&](const std::string& Path) -> std::pair { std::error_code errc; std::pair Result; - Result.first = fs::create_directories(Path, errc); + fs::create_directories(Path, errc); + Result.first = errc == std::error_code {}; if (!Result.first) { Result.second = errc.message(); } @@ -363,7 +364,7 @@ std::shared_ptr TLuaEngine::StateThreadData::EnqueueScript(const TLu return Result; } -std::shared_ptr TLuaEngine::StateThreadData::EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list& Args) { +std::shared_ptr TLuaEngine::StateThreadData::EnqueueFunctionCall(const std::string& FunctionName, const std::vector& Args) { beammp_debug("calling \"" + FunctionName + "\" in \"" + mName + "\""); auto Result = std::make_shared(); Result->StateId = mStateId; @@ -430,19 +431,42 @@ void TLuaEngine::StateThreadData::operator()() { { // StateFunctionQueue Scope std::unique_lock Lock(mStateFunctionQueueMutex); if (!mStateFunctionQueue.empty()) { - auto FnNameResultPair = mStateFunctionQueue.front(); + auto FnNameResultPair = std::move(mStateFunctionQueue.front()); mStateFunctionQueue.pop(); Lock.unlock(); auto& StateId = std::get<0>(FnNameResultPair); auto& Result = std::get<1>(FnNameResultPair); - auto& Args = std::get<1>(FnNameResultPair); + auto Args = std::get<2>(FnNameResultPair); Result->StateId = mStateId; beammp_debug("Running function \"" + std::get<0>(FnNameResultPair) + "\""); sol::state_view StateView(mState); auto Fn = StateView[StateId]; beammp_debug("Done running function \"" + StateId + "\""); if (Fn.valid() && Fn.get_type() == sol::type::function) { - auto Res = Fn(Args); + std::vector LuaArgs; + for (const auto& Arg : Args) { + if (Arg.valueless_by_exception()) { + continue; + } + switch (Arg.index()) { + case TLuaArgTypes_String: + LuaArgs.push_back(sol::make_object(StateView, std::get(Arg))); + break; + case TLuaArgTypes_Int: + LuaArgs.push_back(sol::make_object(StateView, std::get(Arg))); + break; + case TLuaArgTypes_VariadicArgs: + LuaArgs.push_back(sol::make_object(StateView, std::get(Arg))); + break; + case TLuaArgTypes_Bool: + LuaArgs.push_back(sol::make_object(StateView, std::get(Arg))); + break; + default: + beammp_error("Unknown argument type, passed as nil"); + break; + } + } + auto Res = Fn(sol::as_args(LuaArgs)); if (Res.valid()) { Result->Error = false; Result->Result = std::move(Res);