From b987b7a8e5a78ff3cd63da062917b1c5fce91cc2 Mon Sep 17 00:00:00 2001 From: aunsane Date: Wed, 21 Mar 2018 01:28:14 +0300 Subject: MurLua: various fixes - fixed script reloading - fixed string interpolation - hook and service refs moved to Enviroment - removed RegisterProtocol from m_protocols - code cleanup - version bump --- plugins/MirLua/src/m_core.cpp | 66 ++++++++++++++----------------- plugins/MirLua/src/m_protocols.cpp | 22 +---------- plugins/MirLua/src/mlua.cpp | 59 ++++++--------------------- plugins/MirLua/src/mlua.h | 16 +------- plugins/MirLua/src/mlua_environment.cpp | 42 +++++++++++++++++--- plugins/MirLua/src/mlua_environment.h | 10 ++++- plugins/MirLua/src/mlua_metatable.h | 3 +- plugins/MirLua/src/mlua_module_loader.cpp | 9 +---- plugins/MirLua/src/mlua_options.cpp | 24 +++++------ plugins/MirLua/src/mlua_script.cpp | 2 +- plugins/MirLua/src/mlua_script_loader.cpp | 9 ++--- plugins/MirLua/src/stdafx.h | 2 + plugins/MirLua/src/version.h | 2 +- 13 files changed, 109 insertions(+), 157 deletions(-) (limited to 'plugins/MirLua') diff --git a/plugins/MirLua/src/m_core.cpp b/plugins/MirLua/src/m_core.cpp index c57595ffef..9bcbdd5205 100644 --- a/plugins/MirLua/src/m_core.cpp +++ b/plugins/MirLua/src/m_core.cpp @@ -13,7 +13,7 @@ static int core_CreateHookableEvent(lua_State *L) return 1; } -int HookEventLuaStateParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) +int HookEventLuaParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) { lua_State *L = (lua_State*)obj; @@ -67,20 +67,21 @@ static int core_HookEvent(lua_State *L) HANDLE res = nullptr; CMLuaEnvironment *env = CMLuaEnvironment::GetEnvironment(L); - if (env) + if (env) { res = HookEventObjParam(name, HookEventEnvParam, env, ref); + if (res) + env->AddHookRef(res, ref); + } else - res = HookEventObjParam(name, HookEventLuaStateParam, L, ref); - if (res == nullptr) - { + res = HookEventObjParam(name, HookEventLuaParam, L, ref); + + if (res == nullptr) { luaL_unref(L, LUA_REGISTRYINDEX, ref); lua_pushnil(L); return 1; } - CMLua::HookRefs.insert(new HandleRefParam(L, res, ref)); - lua_pushlightuserdata(L, res); return 1; @@ -96,21 +97,23 @@ static int core_HookTemporaryEvent(lua_State *L) HANDLE res = nullptr; CMLuaEnvironment *env = CMLuaEnvironment::GetEnvironment(L); - if (env) + if (env) { res = HookEventObjParam(name, HookEventEnvParam, env, ref); + if (res) + env->AddHookRef(res, ref); + } else - res = HookEventObjParam(name, HookEventLuaStateParam, L, ref); + res = HookEventObjParam(name, HookEventLuaParam, L, ref); + // event does not exists, call hook immideatelly - if (res == nullptr) - { + if (res == nullptr) { + luaL_unref(L, LUA_REGISTRYINDEX, ref); lua_pushnil(L); lua_pushnil(L); luaM_pcall(L, 2, 1); return lua_tointeger(env->L, -1); } - CMLua::HookRefs.insert(new HandleRefParam(L, res, ref)); - lua_pushlightuserdata(L, res); return 1; @@ -122,15 +125,10 @@ static int core_UnhookEvent(lua_State *L) HANDLE hEvent = lua_touserdata(L, 1); int res = UnhookEvent(hEvent); - if (!res) - { - HandleRefParam *param = (HandleRefParam*)CMLua::HookRefs.find(&hEvent); - if (param != nullptr) - { - luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - CMLua::HookRefs.remove(param); - delete param; - } + if (!res) { + CMLuaEnvironment *env = CMLuaEnvironment::GetEnvironment(L); + if (env) + env->ReleaseHookRef(hEvent); } lua_pushboolean(L, !res); @@ -196,19 +194,20 @@ static int core_CreateServiceFunction(lua_State *L) HANDLE res = nullptr; CMLuaEnvironment *env = CMLuaEnvironment::GetEnvironment(L); - if (env) + if (env) { res = CreateServiceFunctionObjParam(name, CreateServiceFunctionEnvParam, env, ref); + if (res) + env->AddServiceRef(res, ref); + } else res = CreateServiceFunctionObjParam(name, CreateServiceFunctionLuaStateParam, L, ref); - if (!res) - { + + if (!res) { luaL_unref(L, LUA_REGISTRYINDEX, ref); lua_pushnil(L); return 1; } - CMLua::ServiceRefs.insert(new HandleRefParam(L, res, ref)); - lua_pushlightuserdata(L, res); return 1; @@ -241,13 +240,9 @@ static int core_DestroyServiceFunction(lua_State *L) luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); HANDLE hService = lua_touserdata(L, 1); - HandleRefParam *param = (HandleRefParam*)CMLua::ServiceRefs.find(&hService); - if (param != nullptr) - { - luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - CMLua::ServiceRefs.remove(param); - delete param; - } + CMLuaEnvironment *env = CMLuaEnvironment::GetEnvironment(L); + if (env) + env->ReleaseHookRef(hService); DestroyServiceFunction(hService); @@ -364,8 +359,7 @@ static int core_TerminateThread(lua_State *L) HANDLE hThread = (HANDLE)lua_touserdata(L, 1); auto it = lstThreads.find(hThread); - if (it != lstThreads.end()) - { + if (it != lstThreads.end()) { DestroyThread(it->second); lua_pushboolean(L, TerminateThread(hThread, 0)); } diff --git a/plugins/MirLua/src/m_protocols.cpp b/plugins/MirLua/src/m_protocols.cpp index 4ecb5d7b3c..a2e3d7fbc1 100644 --- a/plugins/MirLua/src/m_protocols.cpp +++ b/plugins/MirLua/src/m_protocols.cpp @@ -6,8 +6,7 @@ static int lua_GetProtocol(lua_State *L) { const char *szProto = nullptr; - switch (lua_type(L, 1)) - { + switch (lua_type(L, 1)) { case LUA_TNUMBER: { const char *szModule = GetContactProto(lua_tonumber(L, 1)); @@ -38,8 +37,7 @@ static int lua_ProtocolIterator(lua_State *L) int count = lua_tointeger(L, lua_upvalueindex(2)); PROTOCOLDESCRIPTOR **protos = (PROTOCOLDESCRIPTOR**)lua_touserdata(L, lua_upvalueindex(3)); - if (i < count) - { + if (i < count) { lua_pushinteger(L, (i + 1)); lua_replace(L, lua_upvalueindex(1)); MT::Apply(L, protos[i]); @@ -64,21 +62,6 @@ static int lua_Protocols(lua_State *L) return 1; } -static int lua_RegisterProtocol(lua_State *L) -{ - ptrA name(mir_utf8decodeA(luaL_checkstring(L, 1))); - - PROTOCOLDESCRIPTOR pd = { 0 }; - pd.cbSize = sizeof(pd); - pd.szName = name; - pd.type = PROTOTYPE_PROTOCOL; - int res = Proto_RegisterModule(&pd); - - lua_pushboolean(L, res == 0); - - return 1; -} - static int lua_ChainSend(lua_State *L) { MCONTACT hContact = luaL_checknumber(L, 1); @@ -237,7 +220,6 @@ static luaL_Reg protocolsApi[] = { { "GetProtocol", lua_GetProtocol }, { "Protocols", lua_Protocols }, - { "RegisterProtocol", lua_RegisterProtocol }, { "CallSendChain", lua_ChainSend }, { "CallReceiveChain", lua_ChainRecv }, diff --git a/plugins/MirLua/src/mlua.cpp b/plugins/MirLua/src/mlua.cpp index 4b438122c6..3f1da7760c 100644 --- a/plugins/MirLua/src/mlua.cpp +++ b/plugins/MirLua/src/mlua.cpp @@ -2,15 +2,7 @@ int hMLuaLangpack; -LIST CMLua::HookRefs(1, HandleKeySortT); -LIST CMLua::ServiceRefs(1, HandleKeySortT); - -static int CompareScripts(const CMLuaScript* p1, const CMLuaScript* p2) -{ - return mir_strcmpi(p1->GetModuleName(), p2->GetModuleName()); -} - -CMLua::CMLua() : L(nullptr), Scripts(10, CompareScripts) +CMLua::CMLua() : L(nullptr), Scripts(1) { MUUID muidLast = MIID_LAST; hMLuaLangpack = GetPluginLangId(muidLast, 0); @@ -139,13 +131,13 @@ static int mlua_interpolate(lua_State *L) char pattern[128]; if (lua_istable(L, 2)) { - for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 2)) { + for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 3)) { lua_pushvalue(L, -2); const char *key = lua_tostring(L, -1); const char *val = lua_tostring(L, -2); mir_snprintf(pattern, "{%s}", key); - string = luaL_gsub(L, string, pattern, val); + string = luaL_gsub(L, string, pattern, val ? val : ""); } } else { @@ -154,26 +146,23 @@ static int mlua_interpolate(lua_State *L) const char *val = lua_tostring(L, i); mir_snprintf(pattern, "{%d}", i - 1); - string = luaL_gsub(L, string, pattern, val); + string = luaL_gsub(L, string, pattern, val ? val : ""); lua_pop(L, 1); } } lua_Debug ar; - - size_t level = 1; - + int level = 1; while (lua_getstack(L, level++, &ar)) { - size_t i = 1; + int i = 1; while (const char *name = lua_getlocal(L, &ar, i++)) { const char *val = lua_tostring(L, -1); - if (val) { - mir_snprintf(pattern, "${%s}", name); - string = luaL_gsub(L, string, pattern, val); - lua_pop(L, 1); - } + mir_snprintf(pattern, "{%s}", name); + string = luaL_gsub(L, string, pattern, val ? val : ""); + lua_pop(L, 1); } } + lua_pushstring(L, string); return 1; @@ -241,12 +230,7 @@ void CMLua::Unload() { Log("Unloading lua engine"); - while (int last = Scripts.getCount()) - { - CMLuaScript *script = g_mLua->Scripts[last - 1]; - Scripts.remove(script); - delete script; - } + Scripts.destroy(); KillModuleIcons(hMLuaLangpack); KillModuleSounds(hMLuaLangpack); @@ -259,27 +243,6 @@ void CMLua::Unload() lua_close(L); } -void CMLua::KillLuaRefs() -{ - while (HookRefs.getCount()) { - HandleRefParam *param = (HandleRefParam*)HookRefs[0]; - if (param != nullptr) { - luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - HookRefs.remove(0); - delete param; - } - } - - while (ServiceRefs.getCount()) { - HandleRefParam *param = (HandleRefParam*)ServiceRefs[0]; - if (param != nullptr) { - luaL_unref(param->L, LUA_REGISTRYINDEX, param->ref); - ServiceRefs.remove(0); - delete param; - } - } -} - /***********************************************/ static int mlua_call(lua_State *L) diff --git a/plugins/MirLua/src/mlua.h b/plugins/MirLua/src/mlua.h index 21ace43dc6..44ebd4a40d 100644 --- a/plugins/MirLua/src/mlua.h +++ b/plugins/MirLua/src/mlua.h @@ -1,15 +1,6 @@ #ifndef _LUA_CORE_H_ #define _LUA_CORE_H_ -struct HandleRefParam -{ - HANDLE h; - int ref; - lua_State *L; - HandleRefParam(HANDLE h) : L(nullptr), h(h), ref(0) { } - HandleRefParam(lua_State *L, HANDLE h, int ref = 0) : L(L), h(h), ref(ref) { } -}; - class CMLua { private: @@ -17,13 +8,8 @@ private: void SetPaths(); - static void KillLuaRefs(); - public: - static LIST HookRefs; - static LIST ServiceRefs; - - LIST Scripts; + OBJLIST Scripts; CMLua(); ~CMLua(); diff --git a/plugins/MirLua/src/mlua_environment.cpp b/plugins/MirLua/src/mlua_environment.cpp index 9c28645274..4a82e63231 100644 --- a/plugins/MirLua/src/mlua_environment.cpp +++ b/plugins/MirLua/src/mlua_environment.cpp @@ -6,18 +6,24 @@ CMLuaEnvironment::CMLuaEnvironment(lua_State *L) : L(L) { MUUID muidLast = MIID_LAST; - id = GetPluginLangId(muidLast, 0); + m_id = GetPluginLangId(muidLast, 0); } CMLuaEnvironment::~CMLuaEnvironment() { - KillModuleIcons(id); - KillModuleSounds(id); - KillModuleMenus(id); - KillModuleHotkeys(id); + KillModuleIcons(m_id); + KillModuleSounds(m_id); + KillModuleMenus(m_id); + KillModuleHotkeys(m_id); KillObjectEventHooks(this); KillObjectServices(this); + + for (auto &it : m_hookRefs) + luaL_unref(L, LUA_REGISTRYINDEX, it.second); + + for (auto &it : m_serviceRefs) + luaL_unref(L, LUA_REGISTRYINDEX, it.second); } CMLuaEnvironment* CMLuaEnvironment::GetEnvironment(lua_State *L) @@ -42,7 +48,31 @@ int CMLuaEnvironment::GetEnvironmentId(lua_State *L) int CMLuaEnvironment::GetId() const { - return id; + return m_id; +} + +void CMLuaEnvironment::AddHookRef(HANDLE h, int ref) +{ + m_hookRefs[h] = ref; +} + +void CMLuaEnvironment::ReleaseHookRef(HANDLE h) +{ + auto it = m_hookRefs.find(h); + if (it != m_hookRefs.end()) + luaL_unref(L, LUA_REGISTRYINDEX, it->second); +} + +void CMLuaEnvironment::AddServiceRef(HANDLE h, int ref) +{ + m_serviceRefs[h] = ref; +} + +void CMLuaEnvironment::ReleaseServiceRef(HANDLE h) +{ + auto it = m_serviceRefs.find(h); + if (it != m_serviceRefs.end()) + luaL_unref(L, LUA_REGISTRYINDEX, it->second); } void CMLuaEnvironment::CreateEnvironmentTable() diff --git a/plugins/MirLua/src/mlua_environment.h b/plugins/MirLua/src/mlua_environment.h index eb72bf42b8..aa6ebb103a 100644 --- a/plugins/MirLua/src/mlua_environment.h +++ b/plugins/MirLua/src/mlua_environment.h @@ -4,7 +4,9 @@ class CMLuaEnvironment { private: - int id; + int m_id; + std::map m_hookRefs; + std::map m_serviceRefs; void CreateEnvironmentTable(); @@ -19,6 +21,12 @@ public: int GetId() const; + void AddHookRef(HANDLE h, int ref); + void ReleaseHookRef(HANDLE h); + + void AddServiceRef(HANDLE h, int ref); + void ReleaseServiceRef(HANDLE h); + bool Load(); }; diff --git a/plugins/MirLua/src/mlua_metatable.h b/plugins/MirLua/src/mlua_metatable.h index 6de588edf8..33d3b40e7e 100644 --- a/plugins/MirLua/src/mlua_metatable.h +++ b/plugins/MirLua/src/mlua_metatable.h @@ -126,8 +126,7 @@ private: T **udata = (T**)lua_newuserdata(L, sizeof(T*)); *udata = Init(L); - if (*udata == nullptr) - { + if (*udata == nullptr) { lua_pushnil(L); return 1; } diff --git a/plugins/MirLua/src/mlua_module_loader.cpp b/plugins/MirLua/src/mlua_module_loader.cpp index c28e6edaeb..d914bad120 100644 --- a/plugins/MirLua/src/mlua_module_loader.cpp +++ b/plugins/MirLua/src/mlua_module_loader.cpp @@ -6,17 +6,12 @@ CMLuaModuleLoader::CMLuaModuleLoader(lua_State *L) : L(L) void CMLuaModuleLoader::Load(const char *name, lua_CFunction loader) { - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_pushcfunction(L, loader); - lua_pushstring(L, name); - luaM_pcall(L, 1, 1); - lua_setfield(L, -2, name); - lua_pop(L, 1); + luaL_requiref(L, name, loader, 0); } void CMLuaModuleLoader::Preload(const char *name, lua_CFunction loader) { - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); lua_pushcfunction(L, loader); lua_setfield(L, -2, name); lua_pop(L, 1); diff --git a/plugins/MirLua/src/mlua_options.cpp b/plugins/MirLua/src/mlua_options.cpp index 2a7d141e41..a4afbf33dc 100644 --- a/plugins/MirLua/src/mlua_options.cpp +++ b/plugins/MirLua/src/mlua_options.cpp @@ -16,8 +16,7 @@ CMLuaOptions::CMLuaOptions(int idDialog) void CMLuaOptions::LoadScripts() { - for (auto &it : g_mLua->Scripts) - { + for (auto &it : g_mLua->Scripts) { wchar_t *fileName = NEWWSTR_ALLOCA(it->GetFileName()); int iIcon = it->GetStatus() - 1; int iItem = m_scripts.AddItem(fileName, iIcon, (LPARAM)it); @@ -57,8 +56,7 @@ void CMLuaOptions::OnInitDialog() void CMLuaOptions::OnApply() { int count = m_scripts.GetItemCount(); - for (int iItem = 0; iItem < count; iItem++) - { + for (int iItem = 0; iItem < count; iItem++) { wchar_t fileName[MAX_PATH]; m_scripts.GetItemText(iItem, 0, fileName, _countof(fileName)); if (!m_scripts.GetCheckState(iItem)) @@ -70,16 +68,13 @@ void CMLuaOptions::OnApply() INT_PTR CMLuaOptions::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) { - switch (msg) - { + switch (msg) { case WM_NOTIFY: { LPNMHDR lpnmHdr = (LPNMHDR)lParam; - if (lpnmHdr->idFrom == (UINT_PTR)m_scripts.GetCtrlId() && lpnmHdr->code == LVN_ITEMCHANGED) - { + if (lpnmHdr->idFrom == (UINT_PTR)m_scripts.GetCtrlId() && lpnmHdr->code == LVN_ITEMCHANGED) { LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; - if (pnmv->uChanged & LVIF_STATE && pnmv->uNewState & LVIS_STATEIMAGEMASK) - { + if (pnmv->uChanged & LVIF_STATE && pnmv->uNewState & LVIS_STATEIMAGEMASK) { if (isScriptListInit) NotifyChange(); } @@ -111,13 +106,14 @@ void CMLuaOptions::OnScriptListClick(CCtrlListView::TEventInfo *evt) break; case 2: - lvi.lParam = (LPARAM)new CMLuaScript(*script); - delete script; - script = (CMLuaScript*)lvi.lParam; + CMLuaScript *oldScript = script; + script = new CMLuaScript(*script); + delete oldScript; script->Load(); - lvi.mask = LVIF_IMAGE; + lvi.mask = LVIF_PARAM | LVIF_IMAGE; lvi.iSubItem = 0; + lvi.lParam = (LPARAM)script; lvi.iImage = script->GetStatus() - 1; ListView_SetItem(m_scripts.GetHwnd(), &lvi); m_scripts.Update(evt->nmlvia->iItem); diff --git a/plugins/MirLua/src/mlua_script.cpp b/plugins/MirLua/src/mlua_script.cpp index 79e52b9967..310fecddf9 100644 --- a/plugins/MirLua/src/mlua_script.cpp +++ b/plugins/MirLua/src/mlua_script.cpp @@ -19,7 +19,7 @@ CMLuaScript::CMLuaScript(lua_State *L, const wchar_t *path) } CMLuaScript::CMLuaScript(const CMLuaScript &script) - : CMLuaEnvironment(L), status(None), unloadRef(LUA_NOREF) + : CMLuaEnvironment(script.L), status(None), unloadRef(LUA_NOREF) { mir_wstrcpy(filePath, script.filePath); fileName = mir_wstrdup(script.fileName); diff --git a/plugins/MirLua/src/mlua_script_loader.cpp b/plugins/MirLua/src/mlua_script_loader.cpp index 9f9386a95e..60ceb5cbb5 100644 --- a/plugins/MirLua/src/mlua_script_loader.cpp +++ b/plugins/MirLua/src/mlua_script_loader.cpp @@ -13,8 +13,7 @@ void CMLuaScriptLoader::LoadScript(const wchar_t *scriptDir, const wchar_t *file CMLuaScript *script = new CMLuaScript(L, path); g_mLua->Scripts.insert(script); - if (db_get_b(NULL, MODULE, _T2A(file), 1) == FALSE) - { + if (db_get_b(NULL, MODULE, _T2A(file), 1) == FALSE) { Log(L"%s:PASS", path); return; } @@ -35,10 +34,8 @@ void CMLuaScriptLoader::LoadScripts() WIN32_FIND_DATA fd; HANDLE hFind = FindFirstFile(searchMask, &fd); - if (hFind != INVALID_HANDLE_VALUE) - { - do - { + if (hFind != INVALID_HANDLE_VALUE) { + do { if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; LoadScript(scriptDir, fd.cFileName); diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h index 92ae2a9d46..2939b66922 100644 --- a/plugins/MirLua/src/stdafx.h +++ b/plugins/MirLua/src/stdafx.h @@ -5,6 +5,8 @@ #include #include +#include + #include #include #include diff --git a/plugins/MirLua/src/version.h b/plugins/MirLua/src/version.h index 6507196999..65a0d49d81 100644 --- a/plugins/MirLua/src/version.h +++ b/plugins/MirLua/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 #define __RELEASE_NUM 8 -#define __BUILD_NUM 5 +#define __BUILD_NUM 6 #include -- cgit v1.2.3