From 23af22967ac679d10ea565b69e6374443f01324e Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sun, 28 Jun 2015 20:05:11 +0000 Subject: MirLua: added removing hooks/services on reloading git-svn-id: http://svn.miranda-ng.org/main/trunk@14433 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirLua/src/m_core.cpp | 103 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) (limited to 'plugins/MirLua/src/m_core.cpp') diff --git a/plugins/MirLua/src/m_core.cpp b/plugins/MirLua/src/m_core.cpp index ed30486aad..90dffe5f7c 100644 --- a/plugins/MirLua/src/m_core.cpp +++ b/plugins/MirLua/src/m_core.cpp @@ -1,5 +1,69 @@ #include "stdafx.h" +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 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; + } + } +} + static int lua_CreateHookableEvent(lua_State *L) { const char *name = luaL_checkstring(L, 1); @@ -7,6 +71,8 @@ static int lua_CreateHookableEvent(lua_State *L) HANDLE res = ::CreateHookableEvent(name); lua_pushlightuserdata(L, res); + Events.insert(res); + return 1; } @@ -14,6 +80,8 @@ static int lua_DestroyHookableEvent(lua_State *L) { HANDLE hEvent = (HANDLE)lua_touserdata(L, 1); + Events.remove(hEvent); + int res = ::DestroyHookableEvent(hEvent); lua_pushinteger(L, res); @@ -48,6 +116,9 @@ 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)); + return 1; } @@ -55,6 +126,16 @@ static int lua_UnhookEvent(lua_State *L) { HANDLE hEvent = (HANDLE)lua_touserdata(L, 1); + Hooks.remove(hEvent); + + HandleRefParam *param = (HandleRefParam*)HookRefs.find(hEvent); + if (param != NULL) + { + luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); + HookRefs.remove(param); + delete param; + } + int res = ::UnhookEvent(hEvent); lua_pushinteger(L, res); @@ -75,6 +156,9 @@ static int lua_OnModulesLoaded(lua_State *L) HANDLE res = ::HookEventObjParam(ME_SYSTEM_MODULESLOADED, CMLua::HookEventObjParam, L, ref); lua_pushlightuserdata(L, res); + Hooks.insert(res); + HookRefs.insert(new HandleRefParam(L, res, ref)); + return 1; } @@ -92,6 +176,9 @@ static int lua_OnPreShutdown(lua_State *L) HANDLE res = ::HookEventObjParam(ME_SYSTEM_PRESHUTDOWN, CMLua::HookEventObjParam, L, ref); lua_pushlightuserdata(L, res); + Hooks.insert(res); + HookRefs.insert(new HandleRefParam(L, res, ref)); + return 1; } @@ -108,8 +195,7 @@ static INT_PTR ServiceFunctionObjParam(void *obj, WPARAM wParam, LPARAM lParam, printf("%s\n", lua_tostring(L, -1)); INT_PTR res = (INT_PTR)lua_tointeger(L, 1); - - //luaL_unref(L, LUA_REGISTRYINDEX, ref); + lua_pushinteger(L, res); return res; } @@ -130,6 +216,9 @@ 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)); + return 1; } @@ -137,6 +226,16 @@ static int lua_DestroyServiceFunction(lua_State *L) { HANDLE hService = (HANDLE)lua_touserdata(L, 1); + Services.remove(hService); + + HandleRefParam *param = (HandleRefParam*)ServiceRefs.find(hService); + if (param != NULL) + { + luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); + ServiceRefs.remove(param); + delete param; + } + int res = ::DestroyServiceFunction(hService); lua_pushinteger(L, res); -- cgit v1.2.3