1
0

Hook adding uses the new API.

Multiple hooks per plugin can be added. The cPluginManager.AddHook() has four available signatures, the recommended one is cPluginManager.AddHook(HOOK_TYPE, CallbackFunction)
This commit is contained in:
madmaxoft 2013-08-21 21:29:30 +02:00
parent e0e8e18ab2
commit f3a0fed724
9 changed files with 753 additions and 192 deletions

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 08/21/13 10:18:57.
** Generated automatically by tolua++-1.0.92 on 08/21/13 19:38:47.
*/
#ifndef __cplusplus
@ -9307,41 +9307,6 @@ static int tolua_AllToLua_cPluginManager_ReloadPlugins00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: AddHook of class cPluginManager */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddHook00
static int tolua_AllToLua_cPluginManager_AddHook00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
!tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) ||
!tolua_isnumber(tolua_S,3,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0));
cPluginManager::PluginHook a_Hook = ((cPluginManager::PluginHook) (int) tolua_tonumber(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddHook'", NULL);
#endif
{
self->AddHook(a_Plugin,a_Hook);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'AddHook'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetNumPlugins of class cPluginManager */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetNumPlugins00
static int tolua_AllToLua_cPluginManager_GetNumPlugins00(lua_State* tolua_S)
@ -28072,11 +28037,12 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED);
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGING",cPluginManager::HOOK_WEATHER_CHANGING);
tolua_constant(tolua_S,"HOOK_WORLD_TICK",cPluginManager::HOOK_WORLD_TICK);
tolua_constant(tolua_S,"HOOK_NUM_HOOKS",cPluginManager::HOOK_NUM_HOOKS);
tolua_constant(tolua_S,"HOOK_MAX",cPluginManager::HOOK_MAX);
tolua_function(tolua_S,"Get",tolua_AllToLua_cPluginManager_Get00);
tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00);
tolua_function(tolua_S,"FindPlugins",tolua_AllToLua_cPluginManager_FindPlugins00);
tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00);
tolua_function(tolua_S,"AddHook",tolua_AllToLua_cPluginManager_AddHook00);
tolua_function(tolua_S,"GetNumPlugins",tolua_AllToLua_cPluginManager_GetNumPlugins00);
tolua_function(tolua_S,"DisablePlugin",tolua_AllToLua_cPluginManager_DisablePlugin00);
tolua_function(tolua_S,"LoadPlugin",tolua_AllToLua_cPluginManager_LoadPlugin00);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 08/21/13 10:18:58.
** Generated automatically by tolua++-1.0.92 on 08/21/13 19:38:48.
*/
/* Exported function */

View File

@ -77,7 +77,7 @@ public:
bool IsValid(void) const {return (m_Ref != LUA_REFNIL); }
/// Allows to use this class wherever an int (i. e. ref) is to be used
operator int(void) { return m_Ref; }
operator int(void) const { return m_Ref; }
protected:
cLuaState & m_LuaState;

View File

@ -755,6 +755,157 @@ static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S)
static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, cLuaState & S, int a_ParamIdx)
{
// Helper function for cPluginmanager:AddHook() binding
// Takes care of the new case (#121): args are HOOK_TYPE and CallbackFunction
// The arg types have already been checked
// Retrieve the cPlugin from the LuaState:
cPluginLua * Plugin = GetLuaPlugin(S);
if (Plugin == NULL)
{
// An error message has been already printed in GetLuaPlugin()
return 0;
}
// Retrieve and check the hook type
int HookType = (int)tolua_tonumber(S, a_ParamIdx, -1);
if (!a_PluginManager->IsValidHookType(HookType))
{
LOGWARNING("cPluginManager.AddHook(): Invalid HOOK_TYPE parameter: %d", HookType);
S.LogStackTrace();
return 0;
}
// Add the hook to the plugin
if (!Plugin->AddHookRef(HookType, a_ParamIdx + 1))
{
LOGWARNING("cPluginManager.AddHook(): Cannot add hook %d, unknown error.", HookType);
S.LogStackTrace();
return 0;
}
a_PluginManager->AddHook(Plugin, HookType);
// Success
return 0;
}
static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, cLuaState & S, int a_ParamIdx)
{
// Helper function for cPluginmanager:AddHook() binding
// Takes care of the old case (#121): args are cPluginLua and HOOK_TYPE
// The arg types have already been checked
// Retrieve and check the cPlugin parameter
cPluginLua * Plugin = (cPluginLua *)tolua_tousertype(S, a_ParamIdx, NULL);
if (Plugin == NULL)
{
LOGWARNING("cPluginManager.AddHook(): Invalid Plugin parameter, expected a valid cPlugin object. Hook not added");
S.LogStackTrace();
return 0;
}
if (Plugin != GetLuaPlugin(S))
{
// The plugin parameter passed to us is not our stored plugin. Disallow this!
LOGWARNING("cPluginManager.AddHook(): Invalid Plugin parameter, cannot add hook to foreign plugins. Hook not added.");
S.LogStackTrace();
return 0;
}
// Retrieve and check the hook type
int HookType = (int)tolua_tonumber(S, a_ParamIdx + 1, -1);
if (!a_PluginManager->IsValidHookType(HookType))
{
LOGWARNING("cPluginManager.AddHook(): Invalid HOOK_TYPE parameter: %d", HookType);
S.LogStackTrace();
return 0;
}
// Get the standard name for the callback function:
const char * FnName = cPluginLua::GetHookFnName(HookType);
if (FnName == NULL)
{
LOGWARNING("cPluginManager.AddHook(): Unknown hook type (%d). Hook not added.", HookType);
S.LogStackTrace();
return 0;
}
// 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)
{
LOGWARNING("cPluginManager.AddHook(): Function %s not found. Hook not added.", FnName);
S.LogStackTrace();
return 0;
}
a_PluginManager->AddHook(Plugin, HookType);
// Success
return 0;
}
static int tolua_cPluginManager_AddHook(lua_State * tolua_S)
{
/*
Function signatures:
cPluginManager.AddHook(HOOK_TYPE, CallbackFunction) -- (1) recommended
cPluginManager:Get():AddHook(HOOK_TYPE, CallbackFunction) -- (2) accepted silently
cPluginManager:Get():AddHook(Plugin, HOOK_TYPE) -- (3) old style (#121), accepted but complained about
cPluginManager.AddHook(Plugin, HOOK_TYPE) -- (4) old style (#121) mangled, accepted but complained about
*/
cLuaState S(tolua_S);
cPluginManager * PlgMgr = cPluginManager::Get();
// If the first param is a cPluginManager, use it instead of the global one:
int ParamIdx = 1;
tolua_Error err;
if (tolua_isusertype(S, 1, "cPluginManager", 0, &err))
{
// Style 2 or 3, retrieve the PlgMgr instance
PlgMgr = (cPluginManager *)tolua_tousertype(S, 1, NULL);
if (PlgMgr == NULL)
{
LOGWARNING("Malformed plugin, use cPluginManager.AddHook(HOOK_TYPE, CallbackFunction). Fixing the call for you.");
S.LogStackTrace();
PlgMgr = cPluginManager::Get();
}
ParamIdx += 1;
}
if (lua_isnumber(S, ParamIdx) && lua_isfunction(S, ParamIdx + 1))
{
// The next params are a number and a function, assume style 1 or 2
return tolua_cPluginManager_AddHook_FnRef(PlgMgr, S, ParamIdx);
}
else if (tolua_isusertype(S, ParamIdx, "cPlugin", 0, &err) && lua_isnumber(S, ParamIdx + 1))
{
// The next params are a cPlugin and a number, assume style 3 or 4
return tolua_cPluginManager_AddHook_DefFn(PlgMgr, S, ParamIdx);
}
AString ParamDesc;
Printf(ParamDesc, "%s, %s, %s", S.GetTypeText(1).c_str(), S.GetTypeText(2).c_str(), S.GetTypeText(3).c_str());
LOGWARNING("cPluginManager.AddHook(): bad parameters. Expected HOOK_TYPE and CallbackFunction, got %s. Hook not added.", ParamDesc.c_str());
S.LogStackTrace();
return 0;
}
static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S)
{
int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
@ -1699,6 +1850,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand);
tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand);
tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins);
tolua_function(tolua_S, "AddHook", tolua_cPluginManager_AddHook);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlayer");

View File

@ -118,7 +118,7 @@ public:
Returns true if the hook can be added (handler exists)
Descendants should also log the specific error message as a warning if they return false.
*/
virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) = 0;
virtual bool CanAddHook(int a_Hook) = 0;
// tolua_begin
const AString & GetName(void) const { return m_Name; }

File diff suppressed because it is too large Load Diff

View File

@ -100,7 +100,7 @@ public:
virtual void ClearConsoleCommands(void) override;
virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) override;
virtual bool CanAddHook(int a_Hook) override;
// cWebPlugin override
virtual const AString GetWebTitle(void) const {return GetName(); }
@ -128,18 +128,35 @@ public:
/// Calls the plugin-specified "cLuaWindow slot changed" callback.
void CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum);
protected:
cCriticalSection m_CriticalSection;
cLuaState m_LuaState;
/// Returns the name of Lua function that should handle the specified hook type in the older (#121) API
static const char * GetHookFnName(int a_HookType);
/** Adds a Lua function to be called for the specified hook.
The function has to be on the Lua stack at the specified index a_FnRefIdx
Returns true if the hook was added successfully.
*/
bool AddHookRef(int a_HookType, int a_FnRefIdx);
protected:
/// Maps command name into Lua function reference
typedef std::map<AString, int> CommandMap;
/// Provides an array of Lua function references
typedef std::vector<cLuaState::cRef *> cLuaRefs;
/// Maps hook types into arrays of Lua function references to call for each hook type
typedef std::map<int, cLuaRefs> cHookMap;
cCriticalSection m_CriticalSection;
cLuaState m_LuaState;
CommandMap m_Commands;
CommandMap m_ConsoleCommands;
/// Returns the name of Lua function that should handle the specified hook
const char * GetHookFnName(cPluginManager::PluginHook a_Hook);
cHookMap m_HookMap;
/// Releases all Lua references and closes the LuaState
void Close(void);
} ; // tolua_export

View File

@ -1585,6 +1585,15 @@ void cPluginManager::TabCompleteCommand(const AString & a_Text, AStringVector &
bool cPluginManager::IsValidHookType(int a_HookType)
{
return ((a_HookType >= 0) && (a_HookType <= HOOK_MAX));
}
bool cPluginManager::AddPlugin(cPlugin * a_Plugin)
{
m_Plugins[a_Plugin->GetDirectory()] = a_Plugin;
@ -1603,7 +1612,7 @@ bool cPluginManager::AddPlugin(cPlugin * a_Plugin)
void cPluginManager::AddHook(cPlugin * a_Plugin, PluginHook a_Hook)
void cPluginManager::AddHook(cPlugin * a_Plugin, int a_Hook)
{
if (!a_Plugin)
{

View File

@ -110,6 +110,10 @@ public: // tolua_export
// Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants,
// and it definitely needs adding in cPluginLua::GetHookFnName() !
// Keep these two as the last items, they are used for validity checking and get their values automagically
HOOK_NUM_HOOKS,
HOOK_MAX = HOOK_NUM_HOOKS - 1,
} ;
// tolua_end
@ -133,7 +137,9 @@ public: // tolua_export
void FindPlugins(); // tolua_export
void ReloadPlugins(); // tolua_export
void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); // tolua_export
/// Adds the plugin to the list of plugins called for the specified hook type. Handles multiple adds as a single add
void AddHook(cPlugin * a_Plugin, int a_HookType);
unsigned int GetNumPlugins() const; // tolua_export
@ -237,6 +243,9 @@ public: // tolua_export
*/
void TabCompleteCommand(const AString & a_Text, AStringVector & a_Results, cPlayer * a_Player);
/// Returns true if the specified hook type is within the allowed range
static bool IsValidHookType(int a_HookType);
private:
friend class cRoot;
@ -248,7 +257,7 @@ private:
AString m_HelpString;
} ;
typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap;
typedef std::map<int, cPluginManager::PluginList> HookMap;
typedef std::map<AString, cCommandReg> CommandMap;
PluginList m_DisablePluginList;