From f9136d4392b4a3d76f373f6d1a609674d8911d81 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sun, 21 Nov 2021 13:12:35 +0100 Subject: [PATCH] Support multiple arguments in Lua callbacks. --- .../lua/test_scriptscontainer.cpp | 20 +++++++++++++++++++ components/lua/scriptscontainer.cpp | 9 --------- components/lua/scriptscontainer.hpp | 12 +++++++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/apps/openmw_test_suite/lua/test_scriptscontainer.cpp b/apps/openmw_test_suite/lua/test_scriptscontainer.cpp index 344fbb3c78..8be02a2f13 100644 --- a/apps/openmw_test_suite/lua/test_scriptscontainer.cpp +++ b/apps/openmw_test_suite/lua/test_scriptscontainer.cpp @@ -440,4 +440,24 @@ return { EXPECT_EQ(counter4, 25); } + TEST_F(LuaScriptsContainerTest, CallbackWrapper) + { + LuaUtil::Callback callback{mLua.sol()["print"], mLua.newTable()}; + callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptDebugNameKey] = "some_script.lua"; + callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptsContainer::ScriptId{nullptr, 0}; + + testing::internal::CaptureStdout(); + callback(1.5); + EXPECT_EQ(internal::GetCapturedStdout(), "1.5\n"); + + testing::internal::CaptureStdout(); + callback(1.5, 2.5); + EXPECT_EQ(internal::GetCapturedStdout(), "1.5\t2.5\n"); + + testing::internal::CaptureStdout(); + callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = sol::nil; + callback(1.5, 2.5); + EXPECT_EQ(internal::GetCapturedStdout(), "Ignored callback to the removed script some_script.lua\n"); + } + } diff --git a/components/lua/scriptscontainer.cpp b/components/lua/scriptscontainer.cpp index 517ad5f788..eb9da7a60b 100644 --- a/components/lua/scriptscontainer.cpp +++ b/components/lua/scriptscontainer.cpp @@ -530,13 +530,4 @@ namespace LuaUtil updateTimerQueue(mHoursTimersQueue, gameHours); } - void Callback::operator()(sol::object arg) const - { - if (mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil) - LuaUtil::call(mFunc, std::move(arg)); - else - Log(Debug::Debug) << "Ignored callback to the removed script " - << mHiddenData.get(ScriptsContainer::sScriptDebugNameKey); - } - } diff --git a/components/lua/scriptscontainer.hpp b/components/lua/scriptscontainer.hpp index e934868d08..1863d04669 100644 --- a/components/lua/scriptscontainer.hpp +++ b/components/lua/scriptscontainer.hpp @@ -242,7 +242,7 @@ namespace LuaUtil int64_t mTemporaryCallbackCounter = 0; }; - // Wrapper for a single-argument Lua function. + // Wrapper for a Lua function. // Holds information about the script the function belongs to. // Needed to prevent callback calls if the script was removed. struct Callback @@ -250,7 +250,15 @@ namespace LuaUtil sol::function mFunc; sol::table mHiddenData; // same object as Script::mHiddenData in ScriptsContainer - void operator()(sol::object arg) const; + template + void operator()(Args&&... args) const + { + if (mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil) + LuaUtil::call(mFunc, std::forward(args)...); + else + Log(Debug::Debug) << "Ignored callback to the removed script " + << mHiddenData.get(ScriptsContainer::sScriptDebugNameKey); + } }; }