From e29fd4d0ead4353ff2e03fcd793400d8e0779481 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sat, 7 Nov 2015 18:42:19 +0000 Subject: MirLua: added metatables wrapper git-svn-id: http://svn.miranda-ng.org/main/trunk@15697 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirLua/src/m_chat.cpp | 2 +- plugins/MirLua/src/m_database.cpp | 16 +-- plugins/MirLua/src/m_genmenu.cpp | 2 +- plugins/MirLua/src/m_message.cpp | 2 +- plugins/MirLua/src/m_msg_buttonsbar.cpp | 19 ++-- plugins/MirLua/src/m_protocols.cpp | 8 +- plugins/MirLua/src/mlua_metatable.h | 155 ++++++++++++++++++++++++++++++ plugins/MirLua/src/mlua_options.cpp | 10 +- plugins/MirLua/src/mlua_script.cpp | 9 +- plugins/MirLua/src/mlua_script.h | 3 +- plugins/MirLua/src/mlua_script_loader.cpp | 11 +-- plugins/MirLua/src/mlua_script_loader.h | 4 +- plugins/MirLua/src/mlua_utils.cpp | 9 +- plugins/MirLua/src/stdafx.h | 3 + 14 files changed, 199 insertions(+), 54 deletions(-) create mode 100644 plugins/MirLua/src/mlua_metatable.h (limited to 'plugins/MirLua/src') diff --git a/plugins/MirLua/src/m_chat.cpp b/plugins/MirLua/src/m_chat.cpp index 57a37ae7bd..5874db12bd 100644 --- a/plugins/MirLua/src/m_chat.cpp +++ b/plugins/MirLua/src/m_chat.cpp @@ -136,7 +136,7 @@ static int gce__index(lua_State *L) static const luaL_Reg gceMeta[] = { - { "__init", gce__init }, + { MT_GCEVENT, gce__init }, { "__index", gce__index }, { NULL, NULL } }; diff --git a/plugins/MirLua/src/m_database.cpp b/plugins/MirLua/src/m_database.cpp index ab9224bb1e..63fb270bfd 100644 --- a/plugins/MirLua/src/m_database.cpp +++ b/plugins/MirLua/src/m_database.cpp @@ -345,8 +345,6 @@ static int lua_SettingIterator(lua_State *L) static int lua_AllSettings(lua_State *L) { MCONTACT hContact = lua_tointeger(L, 1); - int tp = lua_type(L, 2); - const char *type = lua_typename(L, tp); const char* szModule = luaL_checkstring(L, 2); enumDBSettingsParam* param = (enumDBSettingsParam*)mir_alloc(sizeof(enumDBSettingsParam)); @@ -618,15 +616,7 @@ static int dbei__index(lua_State *L) else if (mir_strcmpi(key, "Length") == 0) lua_pushnumber(L, dbei->cbBlob); else if (mir_strcmpi(key, "Blob") == 0) - { - lua_newtable(L); - for (DWORD i = 0; i < dbei->cbBlob; i++) - { - lua_pushinteger(L, i + 1); - lua_pushinteger(L, dbei->pBlob[i]); - lua_settable(L, -3); - } - } + lua_pushlightuserdata(L, dbei->pBlob); else lua_pushnil(L); @@ -644,7 +634,7 @@ static int dbei__gc(lua_State *L) static const luaL_Reg dbeiMeta[] = { - { "__init", dbei__init }, + { "MT_DBEVENTINFO", dbei__init }, { "__index", dbei__index }, { "__gc", dbei__gc }, { NULL, NULL } @@ -712,7 +702,7 @@ static int dbcw__index(lua_State *L) static const luaL_Reg dbcwMeta[] = { - { "__init", dbcw__init }, + { MT_DBCONTACTWRITESETTING, dbcw__init }, { "__index", dbcw__index }, { NULL, NULL } }; diff --git a/plugins/MirLua/src/m_genmenu.cpp b/plugins/MirLua/src/m_genmenu.cpp index 695e9b18cf..f1b9342c3e 100644 --- a/plugins/MirLua/src/m_genmenu.cpp +++ b/plugins/MirLua/src/m_genmenu.cpp @@ -52,7 +52,7 @@ static int lua_CreateRoot(lua_State *L) int position = lua_tointeger(L, 3); HANDLE hIcon = (HANDLE)lua_touserdata(L, 4); - HGENMENU res = Menu_CreateRoot(MO_MAIN, ptrT(Utf8DecodeT(name)), position, hIcon); + HGENMENU res = Menu_CreateRoot(hMenuObject, ptrT(Utf8DecodeT(name)), position, hIcon); lua_pushlightuserdata(L, res); return 1; diff --git a/plugins/MirLua/src/m_message.cpp b/plugins/MirLua/src/m_message.cpp index 4855e18299..6d6959c5e4 100644 --- a/plugins/MirLua/src/m_message.cpp +++ b/plugins/MirLua/src/m_message.cpp @@ -173,7 +173,7 @@ static int mwed__index(lua_State *L) static luaL_Reg mwedMeta[] = { - { "__init", mwed__init }, + { MT_MESSAGEWINDOWEVENTDATA, mwed__init }, { "__index", mwed__index }, { NULL, NULL } }; diff --git a/plugins/MirLua/src/m_msg_buttonsbar.cpp b/plugins/MirLua/src/m_msg_buttonsbar.cpp index a5007f7d46..4082fa0ba0 100644 --- a/plugins/MirLua/src/m_msg_buttonsbar.cpp +++ b/plugins/MirLua/src/m_msg_buttonsbar.cpp @@ -212,7 +212,7 @@ static luaL_Reg msgbuttinsbarApi[] = { NULL, NULL } }; -#define MT_CUSTOMBUTTONCLICKDATA "CustomButtonClickData" +/*#define MT_CUSTOMBUTTONCLICKDATA "CustomButtonClickData" static int bcd__init(lua_State *L) { @@ -252,18 +252,25 @@ static int bcd__index(lua_State *L) static luaL_Reg bcdMeta[] = { - { "__init", bcd__init }, + { MT_CUSTOMBUTTONCLICKDATA, bcd__init }, { "__index", bcd__index }, { NULL, NULL } -}; +};*/ LUAMOD_API int luaopen_m_msg_buttonsbar(lua_State *L) { luaL_newlib(L, msgbuttinsbarApi); - - luaL_newmetatable(L, MT_CUSTOMBUTTONCLICKDATA); - luaL_setfuncs(L, bcdMeta, 0); + + MT(L, "CustomButtonClickData") + .Field(&CustomButtonClickData::pszModule, "Module") + .Field(&CustomButtonClickData::dwButtonId, "ButtonID") + .Field(&CustomButtonClickData::hContact, "hContact") + .Field(&CustomButtonClickData::flags, "Flags"); lua_pop(L, 1); + /*luaL_newmetatable(L, MT_CUSTOMBUTTONCLICKDATA); + luaL_setfuncs(L, bcdMeta, 0); + lua_pop(L, 1);*/ + return 1; } diff --git a/plugins/MirLua/src/m_protocols.cpp b/plugins/MirLua/src/m_protocols.cpp index 911c699e33..dc5fa97839 100644 --- a/plugins/MirLua/src/m_protocols.cpp +++ b/plugins/MirLua/src/m_protocols.cpp @@ -361,7 +361,7 @@ static int pd__index(lua_State *L) static luaL_Reg pdMeta[] = { - { "__init", pd__init }, + { MT_PROTOCOLDESCRIPTOR, pd__init }, { "__index", pd__index }, { NULL, NULL } }; @@ -412,7 +412,7 @@ static int pa__index(lua_State *L) static luaL_Reg paMeta[] = { - { "__init", pa__init }, + { MT_PROTOACCOUNT, pa__init }, { "__index", pa__index }, { NULL, NULL } }; @@ -461,7 +461,7 @@ static int ack__index(lua_State *L) static luaL_Reg ackMeta[] = { - { "__init", ack__init }, + { MT_ACKDATA, ack__init }, { "__index", ack__index }, { NULL, NULL } }; @@ -505,7 +505,7 @@ static int ccs__index(lua_State *L) static luaL_Reg ccsMeta[] = { - { "__init", ccs__init }, + { MT_CCSDATA, ccs__init }, { "__index", ccs__index }, { NULL, NULL } }; diff --git a/plugins/MirLua/src/mlua_metatable.h b/plugins/MirLua/src/mlua_metatable.h new file mode 100644 index 0000000000..ffedc22134 --- /dev/null +++ b/plugins/MirLua/src/mlua_metatable.h @@ -0,0 +1,155 @@ +#ifndef _LUA_METATABLE_H_ +#define _LUA_METATABLE_H_ + +#include +#include + +#define LUA_TINTEGER LUA_NUMTAGS + 1 +#define LUA_TSTRINGA LUA_NUMTAGS + 2 +#define LUA_TSTRINGW LUA_NUMTAGS + 3 + +struct MTField +{ + size_t offset; + size_t size; + int type; + + MTField(size_t offset, size_t size, int type) + : offset(offset), size(size), type(type) { } +}; + +template +class MT +{ +private: + static const char *name; + static std::map fields; + + template static int GetType(R T::*) { return NULL; } + + template<> static int GetType(int T::*) { return LUA_TINTEGER; } + template<> static int GetType(unsigned int T::*) { return LUA_TINTEGER; } + template<> static int GetType(long T::*) { return LUA_TINTEGER; } + template<> static int GetType(unsigned long T::*) { return LUA_TINTEGER; } + template<> static int GetType(long long T::*) { return LUA_TINTEGER; } + template<> static int GetType(unsigned long long T::*) { return LUA_TINTEGER; } + + template<> static int GetType(char* T::*) { return LUA_TSTRINGA; } + template<> static int GetType(wchar_t* T::*) { return LUA_TSTRINGW; } + + template + static R GetValue(const T *obj, size_t offset, size_t size) + { + R res; + memcpy(&res, ((char*)obj) + offset, size); + return res; + } + + static int __new(lua_State *L) + { + T *obj = NULL; + T **udata = NULL; + + int type = lua_type(L, 1); + switch (type) + { + case LUA_TLIGHTUSERDATA: + obj = (T*)MT::Load(L); + if (obj == NULL) break; + //case LUA_TNONE: + udata = (T**)lua_newuserdata(L, sizeof(T*)); + *udata = MT::Init(obj); + //case LUA_TUSERDATA: + // luaL_setmetatable(L, MT::name); + // return 1; + } + lua_pushnil(L); + + return 1; + } + + static int __index(lua_State *L) + { + T *obj = *(T**)luaL_checkudata(L, 1, MT::name); + const char *key = lua_tostring(L, 2); + + auto it = fields.find(key); + if (it == fields.end()) + { + lua_pushnil(L); + return 1; + } + + MTField *field = it->second; + size_t offset = field->offset; + size_t size = field->size; + + switch (field->type) + { + case LUA_TBOOLEAN: + lua_pushboolean(L, GetValue(obj, offset, size)); + break; + case LUA_TINTEGER: + lua_pushinteger(L, GetValue(obj, offset, size)); + break; + case LUA_TNUMBER: + lua_pushnumber(L, GetValue(obj, offset, size)); + break; + case LUA_TSTRING: + lua_pushstring(L, GetValue(obj, offset, size)); + break; + case LUA_TSTRINGA: + lua_pushstring(L, ptrA(mir_utf8encode(GetValue(obj, offset, size)))); + break; + case LUA_TSTRINGW: + lua_pushstring(L, ptrA(mir_utf8encodeW(GetValue(obj, offset, size)))); + break; + default: + lua_pushnil(L); + } + + return 1; + } + + static int __gc(lua_State *L) + { + T** obj = (T**)luaL_checkudata(L, 1, MT::name); + MT::Free(obj); + return 0; + } + + static T* Load(lua_State *L) { return (T*)lua_touserdata(L, 1); } + static T* Init(T *val) { return val; } + static void Free(T *obj) { obj = NULL; } + +public: + MT(lua_State *L, const char *tname) + { + MT::name = tname; + + lua_pushcfunction(L, __new); + lua_setglobal(L, MT::name); + + luaL_newmetatable(L, MT::name); + lua_pushcfunction(L, __index); + lua_setfield(L, -2, "__index"); + } + + template + MT& Field(R T::*M, const char *name, int type = LUA_TNONE, size_t size = sizeof(R)) + { + size_t offset = reinterpret_cast(&(((T*)0)->*M)); + if (type == LUA_TNONE) type = GetType(M); + if (type != LUA_TNONE) + fields[name] = new MTField(offset, size, type); + return *this; + } +}; + +template +const char *MT::name; + +template +std::map MT::fields; + +#endif //_LUA_METATABLE_H_ diff --git a/plugins/MirLua/src/mlua_options.cpp b/plugins/MirLua/src/mlua_options.cpp index 61b3cd7166..7b89599af5 100644 --- a/plugins/MirLua/src/mlua_options.cpp +++ b/plugins/MirLua/src/mlua_options.cpp @@ -55,10 +55,10 @@ void CLuaOptions::LoadScripts() { CMLuaScript* script = g_mLua->Scripts[i]; TCHAR* fileName = NEWTSTR_ALLOCA(script->GetFileName()); - int iItem = m_scripts.AddItem(fileName, -1, (LPARAM)script, script->GetGroup()); + int iItem = m_scripts.AddItem(fileName, -1, (LPARAM)script); if (db_get_b(NULL, MODULE, _T2A(fileName), 1)) m_scripts.SetCheckState(iItem, TRUE); - m_scripts.SetItem(iItem, 1, _T(""), 0); + m_scripts.SetItem(iItem, 1, TranslateT("Open"), 0); //#ifdef DEBUG m_scripts.SetItem(iItem, 2, _T(""), 1); //#endif @@ -79,13 +79,13 @@ void CLuaOptions::OnInitDialog() FoldersGetCustomPathT(g_hCommonScriptFolder, scriptDir, _countof(scriptDir), VARST(COMMON_SCRIPTS_PATHT)); PathToRelativeT(scriptDir, relativeScriptDir, NULL); mir_sntprintf(header, _T("%s (%s)"), TranslateT("Common scripts"), relativeScriptDir); - m_scripts.AddGroup(0, header); - m_scripts.EnableGroupView(TRUE); + //m_scripts.AddGroup(0, header); + //m_scripts.EnableGroupView(TRUE); m_scripts.AddColumn(0, _T("Script"), 420); m_scripts.AddColumn(1, NULL, 32 - GetSystemMetrics(SM_CXVSCROLL)); //#ifdef DEBUG - m_scripts.AddColumn(2, NULL, 32 - GetSystemMetrics(SM_CXVSCROLL)); + //m_scripts.AddColumn(2, NULL, 32 - GetSystemMetrics(SM_CXVSCROLL)); //#endif LoadScripts(); diff --git a/plugins/MirLua/src/mlua_script.cpp b/plugins/MirLua/src/mlua_script.cpp index 7ac927deaf..f2deb2ff27 100644 --- a/plugins/MirLua/src/mlua_script.cpp +++ b/plugins/MirLua/src/mlua_script.cpp @@ -1,12 +1,10 @@ #include "stdafx.h" -CMLuaScript::CMLuaScript(lua_State *L, const TCHAR* path, int iGroup) +CMLuaScript::CMLuaScript(lua_State *L, const TCHAR* path) : L(L), unloadRef(0) { mir_tstrcpy(filePath, path); - group = iGroup; - fileName = _tcsrchr(filePath, '\\') + 1; size_t length = mir_tstrlen(fileName) - 3; @@ -36,11 +34,6 @@ const TCHAR* CMLuaScript::GetFileName() const return fileName; } -const int CMLuaScript::GetGroup() const -{ - return group; -} - bool CMLuaScript::Load() { if (luaL_loadfile(L, T2Utf(filePath))) diff --git a/plugins/MirLua/src/mlua_script.h b/plugins/MirLua/src/mlua_script.h index 0b299112b7..38e207549d 100644 --- a/plugins/MirLua/src/mlua_script.h +++ b/plugins/MirLua/src/mlua_script.h @@ -10,11 +10,10 @@ private: TCHAR* fileName; TCHAR filePath[MAX_PATH]; bool isLoaded; - int group; int unloadRef; public: - CMLuaScript(lua_State *L, const TCHAR* path, int iGroup = 0); + CMLuaScript(lua_State *L, const TCHAR* path); ~CMLuaScript(); const char* GetModuleName() const; diff --git a/plugins/MirLua/src/mlua_script_loader.cpp b/plugins/MirLua/src/mlua_script_loader.cpp index 9f83d6b9cb..b95b907c8a 100644 --- a/plugins/MirLua/src/mlua_script_loader.cpp +++ b/plugins/MirLua/src/mlua_script_loader.cpp @@ -18,13 +18,13 @@ void CLuaScriptLoader::RegisterScriptsFolder(const char *path) lua_pop(L, 1); } -void CLuaScriptLoader::LoadScript(const TCHAR *scriptDir, const TCHAR *file, int iGroup) +void CLuaScriptLoader::LoadScript(const TCHAR *scriptDir, const TCHAR *file) { TCHAR fullPath[MAX_PATH], path[MAX_PATH]; mir_sntprintf(fullPath, _T("%s\\%s"), scriptDir, file); PathToRelativeT(fullPath, path); - CMLuaScript *script = new CMLuaScript(L, path, iGroup); + CMLuaScript *script = new CMLuaScript(L, path); g_mLua->Scripts.insert(script); TCHAR buf[4096]; @@ -38,13 +38,12 @@ void CLuaScriptLoader::LoadScript(const TCHAR *scriptDir, const TCHAR *file, int if (script->Load()) { - TCHAR buf[4096]; mir_sntprintf(buf, _T("%s:OK"), path); CallService(MS_NETLIB_LOGW, (WPARAM)hNetlib, (LPARAM)buf); } } -void CLuaScriptLoader::LoadScripts(const TCHAR *scriptDir, int iGroup) +void CLuaScriptLoader::LoadScripts(const TCHAR *scriptDir) { TCHAR buf[4096]; mir_sntprintf(buf, _T("Loading scripts from %s"), scriptDir); @@ -63,7 +62,7 @@ void CLuaScriptLoader::LoadScripts(const TCHAR *scriptDir, int iGroup) { if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - LoadScript(scriptDir, fd.cFileName, iGroup); + LoadScript(scriptDir, fd.cFileName); } while (FindNextFile(hFind, &fd)); FindClose(hFind); } @@ -75,5 +74,5 @@ void CLuaScriptLoader::Load(lua_State *L) CLuaScriptLoader loader(L); FoldersGetCustomPathT(g_hCommonScriptFolder, scriptDir, _countof(scriptDir), VARST(COMMON_SCRIPTS_PATHT)); - loader.LoadScripts(scriptDir, 0); + loader.LoadScripts(scriptDir); } \ No newline at end of file diff --git a/plugins/MirLua/src/mlua_script_loader.h b/plugins/MirLua/src/mlua_script_loader.h index e7844b6e76..28e2d9332c 100644 --- a/plugins/MirLua/src/mlua_script_loader.h +++ b/plugins/MirLua/src/mlua_script_loader.h @@ -10,8 +10,8 @@ private: void RegisterScriptsFolder(const char *path); - void LoadScript(const TCHAR *scriptDir, const TCHAR *file, int iGroup = 0); - void LoadScripts(const TCHAR *scriptDir, int iGroup = 0); + void LoadScript(const TCHAR *scriptDir, const TCHAR *file); + void LoadScripts(const TCHAR *scriptDir); public: static void Load(lua_State *L); diff --git a/plugins/MirLua/src/mlua_utils.cpp b/plugins/MirLua/src/mlua_utils.cpp index 558652ef35..9bfa298cca 100644 --- a/plugins/MirLua/src/mlua_utils.cpp +++ b/plugins/MirLua/src/mlua_utils.cpp @@ -119,10 +119,11 @@ LPARAM luaM_tolparam(lua_State *L, int idx) int luaM_totable(lua_State *L) { - const char *tname = luaL_checkstring(L, -1); + const char *tname = luaL_checkstring(L, 2); - luaL_getmetatable(L, tname); - lua_getfield(L, -1, "__init"); + //luaL_getmetatable(L, tname); + //lua_getfield(L, -1, "__init"); + lua_getglobal(L, tname); lua_pushvalue(L, 1); if (lua_pcall(L, 1, 1, 0)) CallService(MS_NETLIB_LOG, (WPARAM)hNetlib, (LPARAM)lua_tostring(L, -1)); @@ -133,9 +134,7 @@ int luaM_totable(lua_State *L) void ShowNotification(const char *caption, const char *message, int flags, MCONTACT hContact) { if (Miranda_Terminated()) - { return; - } if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) { diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h index 552ff7b89c..0929db0d56 100644 --- a/plugins/MirLua/src/stdafx.h +++ b/plugins/MirLua/src/stdafx.h @@ -46,6 +46,7 @@ class CMLuaScript; #include "mlua_module_loader.h" #include "mlua_script_loader.h" #include "mlua_options.h" +#include "mlua_metatable.h" #define MODULE "MirLua" @@ -120,4 +121,6 @@ void ShowNotification(const char *caption, const char *message, int flags, MCONT void ObsoleteMethod(lua_State *L, const char *message); +#include + #endif //_COMMON_H_ -- cgit v1.2.3