From 044f684c197b7dc71556b2c26415cdc694ba51a3 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Mon, 6 Jul 2015 12:38:11 +0000 Subject: MirLua: - fixed correct hooks/services cleanup on reload - added functions OnScriptLoaded and OnScriptUnload to m git-svn-id: http://svn.miranda-ng.org/main/trunk@14498 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirLua/src/m_core.cpp | 76 +++++------------------ plugins/MirLua/src/m_core.h | 26 -------- plugins/MirLua/src/m_msg_buttonsbar.cpp | 4 +- plugins/MirLua/src/mlua.cpp | 106 +++++++++++++++++++++++++++++++- plugins/MirLua/src/mlua.h | 23 +++++++ plugins/MirLua/src/stdafx.h | 3 +- 6 files changed, 146 insertions(+), 92 deletions(-) delete mode 100644 plugins/MirLua/src/m_core.h diff --git a/plugins/MirLua/src/m_core.cpp b/plugins/MirLua/src/m_core.cpp index af33825e13..c9eec524c7 100644 --- a/plugins/MirLua/src/m_core.cpp +++ b/plugins/MirLua/src/m_core.cpp @@ -1,54 +1,5 @@ #include "stdafx.h" -void KillModuleEventHooks() -{ - while (Hooks.getCount()) - { - HANDLE hHook = Hooks[0]; - Hooks.remove(0); - UnhookEvent(hHook); - } - - while (Events.getCount()) - { - HANDLE hEvent = Events[0]; - Events.remove(hEvent); - DestroyHookableEvent(hEvent); - } - - while (HookRefs.getCount()) - { - HandleRefParam *param = (HandleRefParam*)HookRefs[0]; - if (param != NULL) - { - luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - HookRefs.remove(0); - delete param; - } - } -} - -void KillModuleServices() -{ - while (Services.getCount()) - { - HANDLE hService = Services[0]; - Services.remove(0); - DestroyServiceFunction(hService); - } - - while (ServiceRefs.getCount()) - { - HandleRefParam *param = (HandleRefParam*)ServiceRefs[0]; - if (param != NULL) - { - luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - ServiceRefs.remove(0); - delete param; - } - } -} - static int lua_CreateHookableEvent(lua_State *L) { const char *name = luaL_checkstring(L, 1); @@ -56,7 +7,7 @@ static int lua_CreateHookableEvent(lua_State *L) HANDLE res = ::CreateHookableEvent(name); lua_pushlightuserdata(L, res); - Events.insert(res); + CMLua::Events.insert(res); return 1; } @@ -65,7 +16,7 @@ static int lua_DestroyHookableEvent(lua_State *L) { HANDLE hEvent = (HANDLE)lua_touserdata(L, 1); - Events.remove(hEvent); + CMLua::Events.remove(hEvent); int res = ::DestroyHookableEvent(hEvent); lua_pushinteger(L, res); @@ -101,8 +52,8 @@ static int lua_HookEvent(lua_State *L) HANDLE res = ::HookEventObjParam(name, CMLua::HookEventObjParam, L, ref); lua_pushlightuserdata(L, res); - Hooks.insert(res); - HookRefs.insert(new HandleRefParam(L, res, ref)); + CMLua::Hooks.insert(res); + CMLua::HookRefs.insert(new HandleRefParam(L, res, ref)); return 1; } @@ -111,13 +62,13 @@ static int lua_UnhookEvent(lua_State *L) { HANDLE hEvent = (HANDLE)lua_touserdata(L, 1); - Hooks.remove(hEvent); + CMLua::Hooks.remove(hEvent); - HandleRefParam *param = (HandleRefParam*)HookRefs.find(hEvent); + HandleRefParam *param = (HandleRefParam*)CMLua::HookRefs.find(hEvent); if (param != NULL) { luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - HookRefs.remove(param); + CMLua::HookRefs.remove(param); delete param; } @@ -161,8 +112,8 @@ static int lua_CreateServiceFunction(lua_State *L) HANDLE res = ::CreateServiceFunctionObjParam(name, ServiceFunctionObjParam, L, ref); lua_pushlightuserdata(L, res); - Services.insert(res); - ServiceRefs.insert(new HandleRefParam(L, res, ref)); + CMLua::Services.insert(res); + CMLua::ServiceRefs.insert(new HandleRefParam(L, res, ref)); return 1; } @@ -171,13 +122,13 @@ static int lua_DestroyServiceFunction(lua_State *L) { HANDLE hService = (HANDLE)lua_touserdata(L, 1); - Services.remove(hService); + CMLua::Services.remove(hService); - HandleRefParam *param = (HandleRefParam*)ServiceRefs.find(hService); + HandleRefParam *param = (HandleRefParam*)CMLua::ServiceRefs.find(hService); if (param != NULL) { luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - ServiceRefs.remove(param); + CMLua::ServiceRefs.remove(param); delete param; } @@ -248,6 +199,9 @@ luaL_Reg coreApi[] = { "Translate", lua_Translate }, { "ReplaceVariables", lua_ReplaceVariables }, + { "OnScriptLoaded", CMLua::OnScriptLoaded }, + { "OnScriptUnload", CMLua::OnScriptUnload }, + { "NULL", NULL }, { "INVALID_HANDLE_VALUE", NULL }, diff --git a/plugins/MirLua/src/m_core.h b/plugins/MirLua/src/m_core.h deleted file mode 100644 index 8313c3383d..0000000000 --- a/plugins/MirLua/src/m_core.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _LUA_M_CORE_H_ -#define _LUA_M_CORE_H_ - -#define MLUA_CORE "m" -LUAMOD_API int (luaopen_m)(lua_State *L); - -static LIST Hooks(1, PtrKeySortT); -static LIST Events(1, PtrKeySortT); -static LIST Services(1, PtrKeySortT); - -struct HandleRefParam -{ - HANDLE h; - int ref; - lua_State *L; - HandleRefParam(HANDLE h) : L(NULL), h(h), ref(0) { } - HandleRefParam(lua_State *L, HANDLE h, int ref = 0) : L(L), h(h), ref(ref) { } -}; - -static LIST HookRefs(1, HandleKeySortT); -static LIST ServiceRefs(1, HandleKeySortT); - -void KillModuleEventHooks(); -void KillModuleServices(); - -#endif //_LUA_M_CORE_H_ \ No newline at end of file diff --git a/plugins/MirLua/src/m_msg_buttonsbar.cpp b/plugins/MirLua/src/m_msg_buttonsbar.cpp index 1789c5bca1..d150d81d79 100644 --- a/plugins/MirLua/src/m_msg_buttonsbar.cpp +++ b/plugins/MirLua/src/m_msg_buttonsbar.cpp @@ -131,8 +131,8 @@ static int lua_OnMsgToolBarButtonPressed(lua_State *L) HANDLE res = ::HookEventObjParam(ME_MSG_BUTTONPRESSED, ButtonPressedHookEventObjParam, L, ref); lua_pushlightuserdata(L, res); - Hooks.insert(res); - HookRefs.insert(new HandleRefParam(L, res, ref)); + CMLua::Hooks.insert(res); + CMLua::HookRefs.insert(new HandleRefParam(L, res, ref)); return 1; } diff --git a/plugins/MirLua/src/mlua.cpp b/plugins/MirLua/src/mlua.cpp index 0e78810fba..57fa08c7d5 100644 --- a/plugins/MirLua/src/mlua.cpp +++ b/plugins/MirLua/src/mlua.cpp @@ -1,7 +1,16 @@ #include "stdafx.h" +LIST CMLua::Hooks(1, PtrKeySortT); +LIST CMLua::Events(1, PtrKeySortT); +LIST CMLua::Services(1, PtrKeySortT); +LIST CMLua::HookRefs(1, HandleKeySortT); +LIST CMLua::ServiceRefs(1, HandleKeySortT); + CMLua::CMLua() : L(NULL) { + hLoadedEvent = CreateHookableEvent("Lua/Script/Loaded"); + hUnloadEvent = CreateHookableEvent("Lua/Script/Unload"); + Load(); } @@ -37,15 +46,19 @@ void CMLua::Load() CallService(MS_NETLIB_LOG, (WPARAM)hNetlib, (LPARAM)"Loading miranda modules"); CLuaModuleLoader::Load(L); CLuaScriptLoader::Load(L); + + NotifyEventHooks(hLoadedEvent); } void CMLua::Unload() { CallService(MS_NETLIB_LOG, (WPARAM)hNetlib, (LPARAM)"Unloading lua engine"); + NotifyEventHooks(hUnloadEvent); + ::KillModuleMenus(hScriptsLangpack); - ::KillModuleServices(); - ::KillModuleEventHooks(); + CMLua::KillModuleServices(); + CMLua::KillModuleEventHooks(); //KillModuleSubclassing if (L) @@ -58,6 +71,95 @@ void CMLua::Reload() Load(); } +void CMLua::KillModuleEventHooks() +{ + while (Hooks.getCount()) + { + HANDLE hHook = Hooks[0]; + Hooks.remove(0); + UnhookEvent(hHook); + } + + while (Events.getCount()) + { + HANDLE hEvent = Events[0]; + Events.remove(hEvent); + DestroyHookableEvent(hEvent); + } + + while (HookRefs.getCount()) + { + HandleRefParam *param = (HandleRefParam*)HookRefs[0]; + if (param != NULL) + { + luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); + HookRefs.remove(0); + delete param; + } + } +} + +void CMLua::KillModuleServices() +{ + while (Services.getCount()) + { + HANDLE hService = Services[0]; + Services.remove(0); + DestroyServiceFunction(hService); + } + + while (ServiceRefs.getCount()) + { + HandleRefParam *param = (HandleRefParam*)ServiceRefs[0]; + if (param != NULL) + { + luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); + ServiceRefs.remove(0); + delete param; + } + } +} + +int CMLua::OnScriptLoaded(lua_State *L) +{ + if (!lua_isfunction(L, 1)) + { + lua_pushlightuserdata(L, NULL); + return 1; + } + + lua_pushvalue(L, 1); + int ref = luaL_ref(L, LUA_REGISTRYINDEX); + + HANDLE res = ::HookEventObjParam("Lua/Script/Loaded", CMLua::HookEventObjParam, L, ref); + lua_pushlightuserdata(L, res); + + Hooks.insert(res); + HookRefs.insert(new HandleRefParam(L, res, ref)); + + return 1; +} + +int CMLua::OnScriptUnload(lua_State *L) +{ + if (!lua_isfunction(L, 1)) + { + lua_pushlightuserdata(L, NULL); + return 1; + } + + lua_pushvalue(L, 1); + int ref = luaL_ref(L, LUA_REGISTRYINDEX); + + HANDLE res = ::HookEventObjParam("Lua/Script/Unload", CMLua::HookEventObjParam, L, ref); + lua_pushlightuserdata(L, res); + + Hooks.insert(res); + HookRefs.insert(new HandleRefParam(L, res, ref)); + + return 1; +} + int CMLua::HookEventObjParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) { lua_State *L = (lua_State*)obj; diff --git a/plugins/MirLua/src/mlua.h b/plugins/MirLua/src/mlua.h index c792c32780..5d771d8ea9 100644 --- a/plugins/MirLua/src/mlua.h +++ b/plugins/MirLua/src/mlua.h @@ -1,20 +1,43 @@ #ifndef _LUA_CORE_H_ #define _LUA_CORE_H_ +struct HandleRefParam +{ + HANDLE h; + int ref; + lua_State *L; + HandleRefParam(HANDLE h) : L(NULL), h(h), ref(0) { } + HandleRefParam(lua_State *L, HANDLE h, int ref = 0) : L(L), h(h), ref(ref) { } +}; + class CMLua { private: lua_State *L; + HANDLE hLoadedEvent; + HANDLE hUnloadEvent; + + static void KillModuleEventHooks(); + static void KillModuleServices(); void Load(); void Unload(); public: + static LIST Hooks; + static LIST Events; + static LIST Services; + static LIST HookRefs; + static LIST ServiceRefs; + CMLua(); ~CMLua(); void Reload(); + static int OnScriptLoaded(lua_State *L); + static int OnScriptUnload(lua_State *L); + static int HookEventObjParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param); }; diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h index 2a292f03c6..2fbbc83429 100644 --- a/plugins/MirLua/src/stdafx.h +++ b/plugins/MirLua/src/stdafx.h @@ -60,7 +60,8 @@ extern HANDLE hNetlib; #define CUSTOM_SCRIPTS_PATHT MIRANDA_USERDATA "\\Scripts" #endif -#include "m_core.h" +#define MLUA_CORE "m" +LUAMOD_API int (luaopen_m)(lua_State *L); #define MLUA_CLIST "m_clist" LUAMOD_API int (luaopen_m_clist)(lua_State *L); -- cgit v1.2.3