From af8c96026d458481543ead176bd15651857826bd Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 2 Mar 2016 10:05:10 +0100 Subject: Removed cWebPlugin, WebAdmin uses cLuaState::cCallback. --- src/Bindings/ManualBindings.cpp | 282 +++++++++++++++++++++++++++++++--------- 1 file changed, 222 insertions(+), 60 deletions(-) (limited to 'src/Bindings/ManualBindings.cpp') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9945929d0..bd781f766 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1702,47 +1702,71 @@ static int tolua_SetObjectCallback(lua_State * tolua_S) -static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S) +// Callback class used for the WebTab: +class cWebTabCallback: + public cWebAdmin::cWebTabCallback { - cLuaState LuaState(tolua_S); - cPluginLua * self = nullptr; +public: + /** The Lua callback to call to generate the page contents. */ + cLuaState::cCallback m_Callback; - if (!LuaState.GetStackValue(1, self)) + virtual bool Call( + const HTTPRequest & a_Request, + const AString & a_UrlPath, + AString & a_Content, + AString & a_ContentType + ) override { - LOGWARNING("cPluginLua:AddWebTab: invalid self as first argument"); - return 0; + AString content, contentType; + return m_Callback.Call(&a_Request, a_UrlPath, cLuaState::Return, a_Content, a_ContentType); } +}; - tolua_Error tolua_err; - tolua_err.array = 0; - tolua_err.index = 3; - tolua_err.type = "function"; - std::string Title; - int Reference = LUA_REFNIL; - if (LuaState.CheckParamString(2) && LuaState.CheckParamFunction(3)) + + +static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S) +{ + // OBSOLETE, use cWebAdmin:AddWebTab() instead! + // Function signature: + // cPluginLua:AddWebTab(Title, CallbackFn, [UrlPath]) + + // TODO: Warn about obsolete API usage + // Only implement after merging the new API change and letting some time for changes in the plugins + + // Check params: + cLuaState LuaState(tolua_S); + cPluginLua * self = cManualBindings::GetLuaPlugin(tolua_S); + if (self == nullptr) { - Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - LuaState.GetStackValue(2, Title); + return 0; } - else + if ( + !LuaState.CheckParamString(2) || + !LuaState.CheckParamFunction(3) || + // Optional string as param 4 + !LuaState.CheckParamEnd(5) + ) { - return cManualBindings::tolua_do_error(tolua_S, "#ferror calling function '#funcname#'", &tolua_err); + return 0; } - if (Reference != LUA_REFNIL) + // Read the params: + AString title, urlPath; + auto callback = std::make_shared(); + if (!LuaState.GetStackValues(2, title, callback->m_Callback)) { - if (!self->AddWebTab(Title.c_str(), tolua_S, Reference)) - { - luaL_unref(tolua_S, LUA_REGISTRYINDEX, Reference); - } + LOGWARNING("cPlugin:AddWebTab(): Cannot read required parameters"); + return 0; } - else + if (!LuaState.GetStackValue(4, urlPath)) { - LOGWARNING("cPluginLua:AddWebTab: invalid function reference in 2nd argument (Title: \"%s\")", Title.c_str()); + urlPath = cWebAdmin::GetURLEncodedString(title); } + cRoot::Get()->GetWebAdmin()->AddWebTab(title, urlPath, self->GetName(), callback); + return 0; } @@ -2107,22 +2131,68 @@ static int tolua_cUrlParser_ParseAuthorityPart(lua_State * a_LuaState) -static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S) +static int tolua_cWebAdmin_AddWebTab(lua_State * tolua_S) +{ + // Function signatures: + // cWebAdmin:AddWebTab(Title, UrlPath, CallbackFn) + + // Check params: + cLuaState LuaState(tolua_S); + cPluginLua * self = cManualBindings::GetLuaPlugin(tolua_S); + if (self == nullptr) + { + return 0; + } + if ( + // Don't care whether the first param is a cWebAdmin instance or class + !LuaState.CheckParamString(2, 3) || + !LuaState.CheckParamFunction(4) || + !LuaState.CheckParamEnd(5) + ) + { + return 0; + } + + // Read the params: + AString title, urlPath; + auto callback = std::make_shared(); + if (!LuaState.GetStackValues(2, title, urlPath, callback->m_Callback)) + { + LOGWARNING("cWebAdmin:AddWebTab(): Cannot read required parameters"); + return 0; + } + + cRoot::Get()->GetWebAdmin()->AddWebTab(title, urlPath, self->GetName(), callback); + + return 0; +} + + + + + +static int tolua_cWebAdmin_GetAllWebTabs(lua_State * tolua_S) { - cWebAdmin * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); + // Function signature: + // cWebAdmin:GetAllWebTabs() -> { {"PluginName", "UrlPath", "Title"}, {"PluginName", "UrlPath", "Title"}, ...} - const cWebAdmin::PluginList & AllPlugins = self->GetPlugins(); + // Don't care about params at all - lua_createtable(tolua_S, static_cast(AllPlugins.size()), 0); + auto webTabs = cRoot::Get()->GetWebAdmin()->GetAllWebTabs(); + lua_createtable(tolua_S, static_cast(webTabs.size()), 0); int newTable = lua_gettop(tolua_S); int index = 1; - cWebAdmin::PluginList::const_iterator iter = AllPlugins.begin(); - while (iter != AllPlugins.end()) - { - const cWebPlugin * Plugin = *iter; - tolua_pushusertype(tolua_S, reinterpret_cast(const_cast(Plugin)), "const cWebPlugin"); + cLuaState L(tolua_S); + for (const auto & wt: webTabs) + { + lua_createtable(tolua_S, 0, 3); + L.Push(wt->m_PluginName); + lua_setfield(tolua_S, -2, "PluginName"); + L.Push(wt->m_UrlPath); + lua_setfield(tolua_S, -2, "UrlPath"); + L.Push(wt->m_Title); + lua_setfield(tolua_S, -2, "Title"); lua_rawseti(tolua_S, newTable, index); - ++iter; ++index; } return 1; @@ -2132,14 +2202,14 @@ static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S) -/** Binding for cWebAdmin::GetHTMLEscapedString. +/** Binding for cWebAdmin::GetBaseURL. Manual code required because ToLua generates an extra return value */ -static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) +static int tolua_cWebAdmin_GetBaseURL(lua_State * tolua_S) { // Check the param types: cLuaState S(tolua_S); if ( - !S.CheckParamUserTable(1, "cWebAdmin") || + // Don't care whether the first param is a cWebAdmin instance or class !S.CheckParamString(2) || !S.CheckParamEnd(3) ) @@ -2152,7 +2222,7 @@ static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) S.GetStackValue(2, Input); // Convert and return: - S.Push(cWebAdmin::GetHTMLEscapedString(Input)); + S.Push(cWebAdmin::GetBaseURL(Input)); return 1; } @@ -2160,14 +2230,14 @@ static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) -/** Binding for cWebAdmin::GetURLEncodedString. +/** Binding for cWebAdmin::GetContentTypeFromFileExt. Manual code required because ToLua generates an extra return value */ -static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) +static int tolua_cWebAdmin_GetContentTypeFromFileExt(lua_State * tolua_S) { // Check the param types: cLuaState S(tolua_S); if ( - !S.CheckParamUserTable(1, "cWebAdmin") || + // Don't care whether the first param is a cWebAdmin instance or class !S.CheckParamString(2) || !S.CheckParamEnd(3) ) @@ -2180,7 +2250,7 @@ static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) S.GetStackValue(2, Input); // Convert and return: - S.Push(cWebAdmin::GetURLEncodedString(Input)); + S.Push(cWebAdmin::GetContentTypeFromFileExt(Input)); return 1; } @@ -2188,20 +2258,112 @@ static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) -static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S) +/** Binding for cWebAdmin::GetHTMLEscapedString. +Manual code required because ToLua generates an extra return value */ +static int tolua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) { - // Returns a map of (SafeTitle -> Title) for the plugin's web tabs. - auto self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); - auto TabNames = self->GetTabNames(); - lua_newtable(tolua_S); - int index = 1; - for (auto itr = TabNames.cbegin(), end = TabNames.cend(); itr != end; ++itr) + // Check the param types: + cLuaState S(tolua_S); + if ( + // Don't care whether the first param is a cWebAdmin instance or class + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) { - tolua_pushstring(tolua_S, itr->second.c_str()); // Because the SafeTitle is supposed to be unique, use it as key - tolua_pushstring(tolua_S, itr->first.c_str()); - lua_rawset(tolua_S, -3); - ++index; + return 0; } + + // Get the parameters: + AString Input; + S.GetStackValue(2, Input); + + // Convert and return: + S.Push(cWebAdmin::GetHTMLEscapedString(Input)); + return 1; +} + + + + + +/** Binding for cWebAdmin::GetPage. */ +static int tolua_cWebAdmin_GetPage(lua_State * tolua_S) +{ + /* + Function signature: + cWebAdmin:GetPage(a_HTTPRequest) -> + { + Content = "", // Content generated by the plugin + ContentType = "", // Content type generated by the plugin (default: "text/html") + UrlPath = "", // URL path of the tab + TabTitle = "", // Tab's title, as register via cWebAdmin:AddWebTab() + PluginName = "", // Plugin's API name + PluginFolder = "", // Plugin's folder name (display name) + } + */ + + // Check the param types: + cLuaState S(tolua_S); + if ( + // Don't care about first param, whether it's cWebAdmin instance or class + !S.CheckParamUserType(2, "HTTPRequest") || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the parameters: + HTTPRequest * request = nullptr; + if (!S.GetStackValue(2, request)) + { + LOGWARNING("cWebAdmin:GetPage(): Cannot read the HTTPRequest parameter."); + return 0; + } + + // Generate the page and push the results as a dictionary-table: + auto page = cRoot::Get()->GetWebAdmin()->GetPage(*request); + lua_createtable(S, 0, 6); + S.Push(page.Content); + lua_setfield(S, -2, "Content"); + S.Push(page.ContentType); + lua_setfield(S, -2, "ContentType"); + S.Push(page.TabUrlPath); + lua_setfield(S, -2, "UrlPath"); + S.Push(page.TabTitle); + lua_setfield(S, -2, "TabTitle"); + S.Push(page.PluginName); + lua_setfield(S, -2, "PluginName"); + S.Push(cPluginManager::Get()->GetPluginFolderName(page.PluginName)); + lua_setfield(S, -2, "PluginFolder"); + return 1; +} + + + + + +/** Binding for cWebAdmin::GetURLEncodedString. +Manual code required because ToLua generates an extra return value */ +static int tolua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) +{ + // Check the param types: + cLuaState S(tolua_S); + if ( + // Don't care whether the first param is a cWebAdmin instance or class + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the parameters: + AString Input; + S.GetStackValue(2, Input); + + // Convert and return: + S.Push(cWebAdmin::GetURLEncodedString(Input)); return 1; } @@ -3655,13 +3817,13 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWebAdmin"); - tolua_function(tolua_S, "GetHTMLEscapedString", tolua_AllToLua_cWebAdmin_GetHTMLEscapedString); - tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins); - tolua_function(tolua_S, "GetURLEncodedString", tolua_AllToLua_cWebAdmin_GetURLEncodedString); - tolua_endmodule(tolua_S); - - tolua_beginmodule(tolua_S, "cWebPlugin"); - tolua_function(tolua_S, "GetTabNames", tolua_cWebPlugin_GetTabNames); + tolua_function(tolua_S, "AddWebTab", tolua_cWebAdmin_AddWebTab); + tolua_function(tolua_S, "GetAllWebTabs", tolua_cWebAdmin_GetAllWebTabs); + tolua_function(tolua_S, "GetBaseURL", tolua_cWebAdmin_GetBaseURL); + tolua_function(tolua_S, "GetContentTypeFromFileExt", tolua_cWebAdmin_GetContentTypeFromFileExt); + tolua_function(tolua_S, "GetHTMLEscapedString", tolua_cWebAdmin_GetHTMLEscapedString); + tolua_function(tolua_S, "GetPage", tolua_cWebAdmin_GetPage); + tolua_function(tolua_S, "GetURLEncodedString", tolua_cWebAdmin_GetURLEncodedString); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "HTTPRequest"); -- cgit v1.2.3 From 4489a89fdec9f4a507400150af34623899b64f46 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 2 Mar 2016 10:12:43 +0100 Subject: Changed plugin hook registrations to use cLuaState::cCallback. --- src/Bindings/ManualBindings.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/Bindings/ManualBindings.cpp') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index bd781f766..7cf79d5da 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -993,7 +993,13 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, } // Retrieve and check the hook type - int HookType = static_cast(tolua_tonumber(S, a_ParamIdx, -1)); + int HookType; + if (!S.GetStackValue(a_ParamIdx, HookType)) + { + LOGWARNING("cPluginManager.AddHook(): Cannot read the hook type."); + S.LogStackTrace(); + return 0; + } if (!a_PluginManager->IsValidHookType(HookType)) { LOGWARNING("cPluginManager.AddHook(): Invalid HOOK_TYPE parameter: %d", HookType); @@ -1002,7 +1008,14 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, } // Add the hook to the plugin - if (!Plugin->AddHookRef(HookType, a_ParamIdx + 1)) + auto callback = std::make_shared(); + if (!S.GetStackValue(a_ParamIdx + 1, callback)) + { + LOGWARNING("cPluginManager.AddHook(): Cannot read the callback parameter"); + S.LogStackTrace(); + return 0; + } + if (!Plugin->AddHookCallback(HookType, callback)) { LOGWARNING("cPluginManager.AddHook(): Cannot add hook %d, unknown error.", HookType); S.LogStackTrace(); @@ -1059,10 +1072,11 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, } // Retrieve the function to call and add it to the plugin: - lua_pushstring(S, FnName); - bool res = Plugin->AddHookRef(HookType, 1); - lua_pop(S, 1); // Pop the function off the stack - if (!res) + auto callback = std::make_shared(); + lua_getglobal(S, FnName); + bool res = S.GetStackValue(-1, callback); + lua_pop(S, 1); + if (!res || !callback->IsValid()) { LOGWARNING("cPluginManager.AddHook(): Function %s not found. Hook not added.", FnName); S.LogStackTrace(); -- cgit v1.2.3 From fb4c3fc4d9325c28b8640f0e717e5e320334a7c6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 10 Jun 2016 21:30:07 +0200 Subject: Changed cLuaWindow callbacks to use cLuaState::cCallback. --- src/Bindings/ManualBindings.cpp | 157 ++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 71 deletions(-) (limited to 'src/Bindings/ManualBindings.cpp') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 7cf79d5da..28120fdc5 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1600,55 +1600,6 @@ static int tolua_cPlayer_GetRestrictions(lua_State * tolua_S) -static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) -{ - // Function signature: cPlayer:OpenWindow(Window) - - // Retrieve the plugin instance from the Lua state - cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S); - if (Plugin == nullptr) - { - return 0; - } - - // Get the parameters: - cPlayer * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); - cWindow * wnd = reinterpret_cast(tolua_tousertype(tolua_S, 2, nullptr)); - if ((self == nullptr) || (wnd == nullptr)) - { - LOGWARNING("%s: invalid self (%p) or wnd (%p)", __FUNCTION__, static_cast(self), static_cast(wnd)); - return 0; - } - - // If cLuaWindow, add a reference, so that Lua won't delete the cLuaWindow object mid-processing - tolua_Error err; - if (tolua_isusertype(tolua_S, 2, "cLuaWindow", 0, &err)) - { - cLuaWindow * LuaWnd = reinterpret_cast(wnd); - // Only if not already referenced - if (!LuaWnd->IsLuaReferenced()) - { - int LuaRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (LuaRef == LUA_REFNIL) - { - LOGWARNING("%s: Cannot create a window reference. Cannot open window \"%s\".", - __FUNCTION__, wnd->GetWindowTitle().c_str() - ); - return 0; - } - LuaWnd->SetLuaRef(Plugin, LuaRef); - } - } - - // Open the window - self->OpenWindow(wnd); - return 0; -} - - - - - static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) { // Function signature: cPlayer:PermissionMatches(PermissionStr, TemplateStr) -> bool @@ -1679,36 +1630,25 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) template < class OBJTYPE, - void (OBJTYPE::*SetCallback)(cPluginLua * a_Plugin, int a_FnRef) + void (OBJTYPE::*SetCallback)(cLuaState::cCallbackPtr a_CallbackFn) > static int tolua_SetObjectCallback(lua_State * tolua_S) { // Function signature: OBJTYPE:SetWhateverCallback(CallbackFunction) - // Retrieve the plugin instance from the Lua state - cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S); - if (Plugin == nullptr) - { - // Warning message has already been printed by GetLuaPlugin(), bail out silently - return 0; - } - // Get the parameters - self and the function reference: - OBJTYPE * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); - if (self == nullptr) - { - LOGWARNING("%s: invalid self (%p)", __FUNCTION__, static_cast(self)); - return 0; - } - int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); // Store function reference for later retrieval - if (FnRef == LUA_REFNIL) + cLuaState L(tolua_S); + OBJTYPE * self; + cLuaState::cCallbackPtr callback; + if (!L.GetStackValues(1, self, callback)) { - LOGERROR("%s: Cannot create a function reference. Callback not set.", __FUNCTION__); + LOGWARNING("%s: Cannot get parameters", __FUNCTION__); + L.LogStackTrace(); return 0; } // Set the callback - (self->*SetCallback)(Plugin, FnRef); + (self->*SetCallback)(callback); return 0; } @@ -2800,6 +2740,79 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S) +static int tolua_cLuaWindow_new(lua_State * tolua_S) +{ + // Function signature: + // cLuaWindow:new(type, slotsX, slotsY, title) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cLuaWindow") || + !L.CheckParamNumber(2, 4) || + !L.CheckParamString(5) || + !L.CheckParamEnd(6) + ) + { + return 0; + } + + // Read params: + int windowType, slotsX, slotsY; + AString title; + if (!L.GetStackValues(2, windowType, slotsX, slotsY, title)) + { + LOGWARNING("%s: Cannot read Lua parameters", __FUNCTION__); + L.LogStackValues(); + L.LogStackTrace(); + } + + // Create the window and return it: + L.Push(new cLuaWindow(L, static_cast(windowType), slotsX, slotsY, title)); + return 1; +} + + + + + +static int tolua_cLuaWindow_new_local(lua_State * tolua_S) +{ + // Function signature: + // cLuaWindow:new(type, slotsX, slotsY, title) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cLuaWindow") || + !L.CheckParamNumber(2, 4) || + !L.CheckParamString(5) || + !L.CheckParamEnd(6) + ) + { + return 0; + } + + // Read params: + int windowType, slotsX, slotsY; + AString title; + if (!L.GetStackValues(2, windowType, slotsX, slotsY, title)) + { + LOGWARNING("%s: Cannot read Lua parameters", __FUNCTION__); + L.LogStackValues(); + L.LogStackTrace(); + } + + // Create the window, register it for GC and return it: + L.Push(new cLuaWindow(L, static_cast(windowType), slotsX, slotsY, title)); + tolua_register_gc(tolua_S, lua_gettop(tolua_S)); + return 1; +} + + + + + static int tolua_cRoot_GetBuildCommitID(lua_State * tolua_S) { cLuaState L(tolua_S); @@ -3343,7 +3356,7 @@ static int tolua_cBoundingBox_CalcLineIntersection(lua_State * a_LuaState) const cBoundingBox * bbox; if (!L.GetStackValues(1, bbox, pt1, pt2)) // Try the regular signature { - L.LogStack(); + L.LogStackValues(); tolua_error(a_LuaState, "Invalid function params. Expected either bbox:CalcLineIntersection(pt1, pt2) or cBoundingBox:CalcLineIntersection(min, max, pt1, pt2).", nullptr); return 0; } @@ -3373,7 +3386,7 @@ static int tolua_cBoundingBox_Intersect(lua_State * a_LuaState) const cBoundingBox * other; if (!L.GetStackValues(1, self, other)) { - L.LogStack(); + L.LogStackValues(); tolua_error(a_LuaState, "Invalid function params. Expected bbox:Intersect(otherBbox).", nullptr); return 0; } @@ -3746,6 +3759,9 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cLuaWindow"); + tolua_function(tolua_S, "new", tolua_cLuaWindow_new); + tolua_function(tolua_S, "new_local", tolua_cLuaWindow_new_local); + tolua_function(tolua_S, ".call", tolua_cLuaWindow_new_local); tolua_function(tolua_S, "SetOnClosing", tolua_SetObjectCallback); tolua_function(tolua_S, "SetOnSlotChanged", tolua_SetObjectCallback); tolua_endmodule(tolua_S); @@ -3766,7 +3782,6 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cPlayer"); tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions); tolua_function(tolua_S, "GetRestrictions", tolua_cPlayer_GetRestrictions); - tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow); tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches); tolua_endmodule(tolua_S); -- cgit v1.2.3 From 257c5a1a54396a3610f63bf469d6cf50ec76aef5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 12 Jun 2016 18:11:40 +0200 Subject: cPluginManager: Use a callback for command handler registration. --- src/Bindings/ManualBindings.cpp | 94 ++++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 29 deletions(-) (limited to 'src/Bindings/ManualBindings.cpp') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 28120fdc5..12cdd3d71 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -43,6 +43,50 @@ +//////////////////////////////////////////////////////////////////////////////// +// LuaCommandHandler: + +/** Defines a bridge between cPluginManager::cCommandHandler and cLuaState::cCallback. */ +class LuaCommandHandler: + public cPluginManager::cCommandHandler +{ +public: + LuaCommandHandler(cLuaState::cCallbackPtr a_Callback): + m_Callback(a_Callback) + { + } + + virtual bool ExecuteCommand( + const AStringVector & a_Split, + cPlayer * a_Player, + const AString & a_Command, + cCommandOutputCallback * a_Output + ) override + { + bool res = false; + AString s; + if (!m_Callback->Call(a_Split, a_Player, a_Command, cLuaState::Return, res, s)) + { + return false; + } + if (res && (a_Output != nullptr) && !s.empty()) + { + a_Output->Out(s); + } + return res; + } + +protected: + cLuaState::cCallbackPtr m_Callback; +}; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cManualBindings: + // Better error reporting for Lua int cManualBindings::tolua_do_error(lua_State * L, const char * a_pMsg, tolua_Error * a_pToLuaError) { @@ -1268,12 +1312,13 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) -static int tolua_cPluginManager_BindCommand(lua_State * L) +static int tolua_cPluginManager_BindCommand(lua_State * a_LuaState) { /* Function signatures: cPluginManager:BindCommand(Command, Permission, Function, HelpString) cPluginManager.BindCommand(Command, Permission, Function, HelpString) -- without the "self" param */ + cLuaState L(a_LuaState); cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) { @@ -1306,29 +1351,24 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) return 0; } cPluginManager * self = cPluginManager::Get(); - AString Command (tolua_tocppstring(L, idx, "")); - AString Permission(tolua_tocppstring(L, idx + 1, "")); - AString HelpString(tolua_tocppstring(L, idx + 3, "")); - - // Store the function reference: - lua_pop(L, 1); // Pop the help string off the stack - int FnRef = luaL_ref(L, LUA_REGISTRYINDEX); // Store function reference - if (FnRef == LUA_REFNIL) + AString Command, Permission, HelpString; + cLuaState::cCallbackPtr Handler; + L.GetStackValues(idx, Command, Permission, Handler, HelpString); + if (!Handler->IsValid()) { LOGERROR("\"BindCommand\": Cannot create a function reference. Command \"%s\" not bound.", Command.c_str()); return 0; } - if (!self->BindCommand(Command, Plugin, Permission, HelpString)) + auto CommandHandler = std::make_shared(Handler); + if (!self->BindCommand(Command, Plugin, CommandHandler, Permission, HelpString)) { // Refused. Possibly already bound. Error message has been given, display the callstack: - cLuaState LS(L); - LS.LogStackTrace(); + L.LogStackTrace(); return 0; } - Plugin->BindCommand(Command, FnRef); - lua_pushboolean(L, true); + L.Push(true); return 1; } @@ -1336,7 +1376,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) -static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) +static int tolua_cPluginManager_BindConsoleCommand(lua_State * a_LuaState) { /* Function signatures: cPluginManager:BindConsoleCommand(Command, Function, HelpString) @@ -1344,6 +1384,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) */ // Get the plugin identification out of LuaState: + cLuaState L(a_LuaState); cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) { @@ -1375,28 +1416,23 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) return 0; } cPluginManager * self = cPluginManager::Get(); - AString Command (tolua_tocppstring(L, idx, "")); - AString HelpString(tolua_tocppstring(L, idx + 2, "")); - - // Store the function reference: - lua_pop(L, 1); // Pop the help string off the stack - int FnRef = luaL_ref(L, LUA_REGISTRYINDEX); // Store function reference - if (FnRef == LUA_REFNIL) + AString Command, HelpString; + cLuaState::cCallbackPtr Handler; + L.GetStackValues(idx, Command, Handler, HelpString); + if (!Handler->IsValid()) { - LOGERROR("\"BindConsoleCommand\": Cannot create a function reference. Console Command \"%s\" not bound.", Command.c_str()); + LOGERROR("\"BindConsoleCommand\": Cannot create a function reference. Console command \"%s\" not bound.", Command.c_str()); return 0; } - if (!self->BindConsoleCommand(Command, Plugin, HelpString)) + auto CommandHandler = std::make_shared(Handler); + if (!self->BindConsoleCommand(Command, Plugin, CommandHandler, HelpString)) { // Refused. Possibly already bound. Error message has been given, display the callstack: - cLuaState LS(L); - LS.LogStackTrace(); + L.LogStackTrace(); return 0; } - - Plugin->BindConsoleCommand(Command, FnRef); - lua_pushboolean(L, true); + L.Push(true); return 1; } -- cgit v1.2.3 From bf88312a1664311968736b4ba7ce1458c8b0954e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 27 Jun 2016 20:49:59 +0200 Subject: Converted cLuaState::cCallbackPtr into a UniquePtr. --- src/Bindings/ManualBindings.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/Bindings/ManualBindings.cpp') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 12cdd3d71..1d735ac83 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -51,8 +51,8 @@ class LuaCommandHandler: public cPluginManager::cCommandHandler { public: - LuaCommandHandler(cLuaState::cCallbackPtr a_Callback): - m_Callback(a_Callback) + LuaCommandHandler(cLuaState::cCallbackPtr && a_Callback): + m_Callback(std::move(a_Callback)) { } @@ -1052,14 +1052,14 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, } // Add the hook to the plugin - auto callback = std::make_shared(); + cLuaState::cCallbackPtr callback; if (!S.GetStackValue(a_ParamIdx + 1, callback)) { LOGWARNING("cPluginManager.AddHook(): Cannot read the callback parameter"); S.LogStackTrace(); return 0; } - if (!Plugin->AddHookCallback(HookType, callback)) + if (!Plugin->AddHookCallback(HookType, std::move(callback))) { LOGWARNING("cPluginManager.AddHook(): Cannot add hook %d, unknown error.", HookType); S.LogStackTrace(); @@ -1116,7 +1116,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, } // Retrieve the function to call and add it to the plugin: - auto callback = std::make_shared(); + cLuaState::cCallbackPtr callback; lua_getglobal(S, FnName); bool res = S.GetStackValue(-1, callback); lua_pop(S, 1); @@ -1360,7 +1360,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * a_LuaState) return 0; } - auto CommandHandler = std::make_shared(Handler); + auto CommandHandler = std::make_shared(std::move(Handler)); if (!self->BindCommand(Command, Plugin, CommandHandler, Permission, HelpString)) { // Refused. Possibly already bound. Error message has been given, display the callstack: @@ -1425,7 +1425,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * a_LuaState) return 0; } - auto CommandHandler = std::make_shared(Handler); + auto CommandHandler = std::make_shared(std::move(Handler)); if (!self->BindConsoleCommand(Command, Plugin, CommandHandler, HelpString)) { // Refused. Possibly already bound. Error message has been given, display the callstack: @@ -1666,7 +1666,7 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) template < class OBJTYPE, - void (OBJTYPE::*SetCallback)(cLuaState::cCallbackPtr a_CallbackFn) + void (OBJTYPE::*SetCallback)(cLuaState::cCallbackPtr && a_CallbackFn) > static int tolua_SetObjectCallback(lua_State * tolua_S) { @@ -1684,7 +1684,7 @@ static int tolua_SetObjectCallback(lua_State * tolua_S) } // Set the callback - (self->*SetCallback)(callback); + (self->*SetCallback)(std::move(callback)); return 0; } -- cgit v1.2.3