diff options
Diffstat (limited to 'plugins/MirLua/src/mlua.cpp')
-rw-r--r-- | plugins/MirLua/src/mlua.cpp | 106 |
1 files changed, 104 insertions, 2 deletions
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<void> CMLua::Hooks(1, PtrKeySortT);
+LIST<void> CMLua::Events(1, PtrKeySortT);
+LIST<void> CMLua::Services(1, PtrKeySortT);
+LIST<void> CMLua::HookRefs(1, HandleKeySortT);
+LIST<void> 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;
|