diff --git a/apps/openmw/mwlua/asyncbindings.cpp b/apps/openmw/mwlua/asyncbindings.cpp index 0ffb2aad8f..d70e9bfea5 100644 --- a/apps/openmw/mwlua/asyncbindings.cpp +++ b/apps/openmw/mwlua/asyncbindings.cpp @@ -6,6 +6,9 @@ namespace sol { template <> struct is_automagical : std::false_type {}; + + template <> + struct is_automagical : std::false_type {}; } namespace MWLua @@ -50,11 +53,15 @@ namespace MWLua asyncId.mContainer->setupUnsavableTimer( TimerType::GAME_TIME, world->getGameTime() + delay, asyncId.mScriptId, std::move(callback)); }; - api["callback"] = [](const AsyncPackageId& asyncId, sol::function fn) + api["callback"] = [](const AsyncPackageId& asyncId, sol::function fn) -> LuaUtil::Callback { return LuaUtil::Callback{std::move(fn), asyncId.mHiddenData}; }; + sol::usertype callbackType = context.mLua->sol().new_usertype("Callback"); + callbackType[sol::meta_function::call] = + [](const LuaUtil::Callback& callback, sol::variadic_args va) { return callback.call(sol::as_args(va)); }; + auto initializer = [](sol::table hiddenData) { LuaUtil::ScriptsContainer::ScriptId id = hiddenData[LuaUtil::ScriptsContainer::sScriptIdKey]; diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 3c458bd7b8..c747d69ab4 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -169,7 +169,7 @@ namespace MWLua // Run queued callbacks for (CallbackWithData& c : mQueuedCallbacks) - c.mCallback(c.mArg); + c.mCallback.call(c.mArg); mQueuedCallbacks.clear(); // Engine handlers in local scripts diff --git a/apps/openmw_test_suite/lua/test_scriptscontainer.cpp b/apps/openmw_test_suite/lua/test_scriptscontainer.cpp index 779debb4e6..900888929d 100644 --- a/apps/openmw_test_suite/lua/test_scriptscontainer.cpp +++ b/apps/openmw_test_suite/lua/test_scriptscontainer.cpp @@ -447,16 +447,16 @@ return { callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptsContainer::ScriptId{nullptr, 0}; testing::internal::CaptureStdout(); - callback(1.5); + callback.call(1.5); EXPECT_EQ(internal::GetCapturedStdout(), "1.5\n"); testing::internal::CaptureStdout(); - callback(1.5, 2.5); + callback.call(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); + callback.call(1.5, 2.5); EXPECT_EQ(internal::GetCapturedStdout(), "Ignored callback to the removed script some_script.lua\n"); } diff --git a/components/lua/scriptscontainer.hpp b/components/lua/scriptscontainer.hpp index e065c487c4..f64ec97722 100644 --- a/components/lua/scriptscontainer.hpp +++ b/components/lua/scriptscontainer.hpp @@ -252,7 +252,7 @@ namespace LuaUtil bool isValid() const { return mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil; } template - sol::object operator()(Args&&... args) const + sol::object call(Args&&... args) const { if (isValid()) return LuaUtil::call(mFunc, std::forward(args)...); @@ -265,7 +265,7 @@ namespace LuaUtil template void tryCall(Args&&... args) const { - try { (*this)(std::forward(args)...); } + try { this->call(std::forward(args)...); } catch (std::exception& e) { Log(Debug::Error) << "Error in callback: " << e.what(); diff --git a/components/lua_ui/widget.cpp b/components/lua_ui/widget.cpp index 49d69f8fd1..c98b7ad38f 100644 --- a/components/lua_ui/widget.cpp +++ b/components/lua_ui/widget.cpp @@ -340,7 +340,7 @@ namespace LuaUi { auto it = mCallbacks.find(name); if (it != mCallbacks.end()) - it->second(argument, mLayout); + it->second.call(argument, mLayout); } void WidgetExtension::keyPress(MyGUI::Widget*, MyGUI::KeyCode code, MyGUI::Char ch) diff --git a/components/lua_ui/widget.hpp b/components/lua_ui/widget.hpp index b6bef55235..3285f629ac 100644 --- a/components/lua_ui/widget.hpp +++ b/components/lua_ui/widget.hpp @@ -111,7 +111,7 @@ namespace LuaUi auto it = w->mCallbacks.find(name); if (it != w->mCallbacks.end()) { - sol::object res = it->second(argumentFactory(w), w->mLayout); + sol::object res = it->second.call(argumentFactory(w), w->mLayout); shouldPropagate = res.is() && res.as(); } if (w->mParent && w->mPropagateEvents && shouldPropagate)