diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index e7b4d90d1..240e0f083 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -21,7 +21,6 @@ function check_cache_age(key, max_age) end function core.on_before_close() - -- called before the menu is closed, either exit or to join a game cache_settings:write() end diff --git a/doc/menu_lua_api.md b/doc/menu_lua_api.md index 38940a7ed..c0dcc9068 100644 --- a/doc/menu_lua_api.md +++ b/doc/menu_lua_api.md @@ -25,6 +25,8 @@ Callbacks * `core.event_handler(event)` * `event`: `"MenuQuit"`, `"KeyEnter"`, `"ExitButton"`, `"EditBoxEnter"` or `"FullscreenChange"` +* `core.on_before_close()`: called before the menu is closed, either to exit or + to join a game Gamedata diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp index 04ca4b6b2..964ed84d4 100644 --- a/src/script/cpp_api/s_mainmenu.cpp +++ b/src/script/cpp_api/s_mainmenu.cpp @@ -34,7 +34,7 @@ void ScriptApiMainMenu::handleMainMenuEvent(const std::string &text) lua_getfield(L, -1, "event_handler"); lua_remove(L, -2); // Remove core if (lua_isnil(L, -1)) { - lua_pop(L, 1); // Pop event_handler + lua_pop(L, 2); // Pop event_handler, error handler return; } luaL_checktype(L, -1, LUA_TFUNCTION); @@ -56,7 +56,7 @@ void ScriptApiMainMenu::handleMainMenuButtons(const StringMap &fields) lua_getfield(L, -1, "button_handler"); lua_remove(L, -2); // Remove core if (lua_isnil(L, -1)) { - lua_pop(L, 1); // Pop button handler + lua_pop(L, 2); // Pop button handler, error handler return; } luaL_checktype(L, -1, LUA_TFUNCTION); @@ -76,3 +76,25 @@ void ScriptApiMainMenu::handleMainMenuButtons(const StringMap &fields) PCALL_RES(lua_pcall(L, 1, 0, error_handler)); lua_pop(L, 1); // Pop error handler } + +void ScriptApiMainMenu::beforeClose() +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get handler function + lua_getglobal(L, "core"); + lua_getfield(L, -1, "on_before_close"); + lua_remove(L, -2); // Remove core + if (lua_isnil(L, -1)) { + lua_pop(L, 2); // Pop callback, error handler + return; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + + // Call it + PCALL_RES(lua_pcall(L, 0, 0, error_handler)); + + lua_pop(L, 1); // Pop error handler +} diff --git a/src/script/cpp_api/s_mainmenu.h b/src/script/cpp_api/s_mainmenu.h index 394e4e25b..ec243f65c 100644 --- a/src/script/cpp_api/s_mainmenu.h +++ b/src/script/cpp_api/s_mainmenu.h @@ -27,4 +27,9 @@ public: * @param fields data in field format */ void handleMainMenuButtons(const StringMap &fields); + + /** + * Called before the menu is closed, either to exit or to join a game + */ + void beforeClose(); }; diff --git a/src/script/scripting_mainmenu.cpp b/src/script/scripting_mainmenu.cpp index d0ab5d374..862c3d519 100644 --- a/src/script/scripting_mainmenu.cpp +++ b/src/script/scripting_mainmenu.cpp @@ -114,20 +114,6 @@ bool MainMenuScripting::checkPathAccess(const std::string &abs_path, bool write_ return !write_required; } -void MainMenuScripting::beforeClose() -{ - SCRIPTAPI_PRECHECKHEADER - - int error_handler = PUSH_ERROR_HANDLER(L); - - lua_getglobal(L, "core"); - lua_getfield(L, -1, "on_before_close"); - - PCALL_RES(lua_pcall(L, 0, 0, error_handler)); - - lua_pop(L, 2); // Pop core, error handler -} - void MainMenuScripting::step() { asyncEngine.step(getStack()); diff --git a/src/script/scripting_mainmenu.h b/src/script/scripting_mainmenu.h index f56c67727..d6338786e 100644 --- a/src/script/scripting_mainmenu.h +++ b/src/script/scripting_mainmenu.h @@ -24,9 +24,6 @@ public: // Global step handler to pass back async events void step(); - // Calls core.on_before_close() - void beforeClose(); - // Pass async events from engine to async threads u32 queueAsync(std::string &&serialized_func, std::string &&serialized_param);