From b97c40a7095474115cdeac7a93183353b203886b Mon Sep 17 00:00:00 2001 From: MikalaiR Date: Sat, 16 Jan 2016 08:43:00 +0000 Subject: MirLua: lambda-based metatables wrapper git-svn-id: http://svn.miranda-ng.org/main/trunk@16096 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirLua/src/m_database.cpp | 15 +++---- plugins/MirLua/src/m_msg_buttonsbar.cpp | 8 ++-- plugins/MirLua/src/mlua_metatable.h | 73 ++++++++++++++++++++++----------- 3 files changed, 62 insertions(+), 34 deletions(-) (limited to 'plugins/MirLua') diff --git a/plugins/MirLua/src/m_database.cpp b/plugins/MirLua/src/m_database.cpp index 57846c99de..d6b7207cfb 100644 --- a/plugins/MirLua/src/m_database.cpp +++ b/plugins/MirLua/src/m_database.cpp @@ -665,16 +665,17 @@ LUAMOD_API int luaopen_m_database(lua_State *L) lua_pop(L, 1); MT(L, MT_DBEVENTINFO) - .Field(&DBEVENTINFO::szModule, "Module", LUA_TSTRINGA) - .Field(&DBEVENTINFO::timestamp, "Timestamp", LUA_TINTEGER) - .Field(&DBEVENTINFO::eventType, "Type", LUA_TINTEGER) - .Field(&DBEVENTINFO::flags, "Flags", LUA_TINTEGER) - .Field(&DBEVENTINFO::cbBlob, "Length", LUA_TINTEGER) - .Field(&DBEVENTINFO::pBlob, "Blob", LUA_TLIGHTUSERDATA); + .Field(std::function([](DBEVENTINFO* p) { return p->szModule; }), "Module", LUA_TSTRINGA) + .Field(std::function([](DBEVENTINFO* p) { return (void*)p->timestamp; }), "Timestamp", LUA_TINTEGER) + .Field(std::function([](DBEVENTINFO* p) { return (void*)p->eventType; }), "Type", LUA_TINTEGER) + .Field(std::function([](DBEVENTINFO* p) { return (void*)p->flags; }), "Flags", LUA_TINTEGER) + .Field(std::function([](DBEVENTINFO* p) { return (void*)p->cbBlob; }), "Length", LUA_TINTEGER) + .Field(std::function([](DBEVENTINFO* p) { return p->pBlob; }), "Blob", LUA_TLIGHTUSERDATA); + lua_pop(L, 1); MT(L, "CONTACTINFO") - .Field(&CONTACTINFO::hContact, "hContact", LUA_TINTEGER) + .Field(std::function([](CONTACTINFO* p) { return (void*)p->hContact; }), "hContact", LUA_TINTEGER) .Method(ci__index, "__index"); lua_pop(L, 1); diff --git a/plugins/MirLua/src/m_msg_buttonsbar.cpp b/plugins/MirLua/src/m_msg_buttonsbar.cpp index 39fff188a1..9ba12aef48 100644 --- a/plugins/MirLua/src/m_msg_buttonsbar.cpp +++ b/plugins/MirLua/src/m_msg_buttonsbar.cpp @@ -133,10 +133,10 @@ LUAMOD_API int luaopen_m_msg_buttonsbar(lua_State *L) luaL_newlib(L, msgbuttinsbarApi); MT(L, "CustomButtonClickData") - .Field(&CustomButtonClickData::pszModule, "Module", LUA_TSTRINGA) - .Field(&CustomButtonClickData::dwButtonId, "ButtonID", LUA_TINTEGER) - .Field(&CustomButtonClickData::hContact, "hContact", LUA_TINTEGER) - .Field(&CustomButtonClickData::flags, "Flags", LUA_TINTEGER); + .Field(LFUNC(CustomButtonClickData, [](CustomButtonClickData *p) { return p->pszModule; }), "Module", LUA_TSTRINGA) + .Field(LFUNC(CustomButtonClickData, [](CustomButtonClickData *p) { return (void*)p->dwButtonId; }), "ButtonID", LUA_TINTEGER) + .Field(LFUNC(CustomButtonClickData, [](CustomButtonClickData *p) { return (void*)p->hContact; }), "hContact", LUA_TINTEGER) + .Field(LFUNC(CustomButtonClickData, [](CustomButtonClickData *p) { return (void*)p->flags; }), "Flags", LUA_TINTEGER); lua_pop(L, 1); return 1; diff --git a/plugins/MirLua/src/mlua_metatable.h b/plugins/MirLua/src/mlua_metatable.h index eb8ee722d2..e0c2f1adb3 100644 --- a/plugins/MirLua/src/mlua_metatable.h +++ b/plugins/MirLua/src/mlua_metatable.h @@ -1,18 +1,47 @@ #ifndef _LUA_METATABLE_H_ #define _LUA_METATABLE_H_ +#include + +#define LFUNC(T, L) std::function(L) + #define LUA_TINTEGER LUA_NUMTAGS + 1 #define LUA_TSTRINGA LUA_NUMTAGS + 2 #define LUA_TSTRINGW LUA_NUMTAGS + 3 -struct MTField +enum MTFieldGetType +{ + MTFGT_LAMBDA = 1, + MTFGT_OFFSET = 2 +}; + +template +struct MTField : public MZeroedObject { size_t offset; size_t size; int type; + int getType; + std::function lambda; MTField(size_t offset, size_t size, int type) - : offset(offset), size(size), type(type) { } + : offset(offset), size(size), type(type), getType(MTFGT_OFFSET) { } + + MTField(std::function f, int type) + : lambda(f), type(type), getType(MTFGT_LAMBDA) { } + + template + R GetValue(T *obj) const + { + if (getType == MTFGT_LAMBDA) return (R)lambda(obj); + else + { + R res = NULL; + memcpy(&res, ((char*)obj) + offset, size); + return res; + } + } + }; template @@ -22,15 +51,7 @@ private: lua_State *L; static const char *name; - static std::map fields; - - template - static R GetValue(const T *obj, size_t offset, size_t size) - { - R res = NULL; - memcpy(&res, ((char*)obj) + offset, size); - return res; - } + static std::map*> fields; static void Init(lua_State *L, T **obj) { @@ -71,32 +92,30 @@ private: return 1; } - MTField *field = it->second; - size_t offset = field->offset; - size_t size = field->size; + MTField *field = it->second; switch (field->type) { case LUA_TBOOLEAN: - lua_pushboolean(L, GetValue(obj, offset, size)); + lua_pushboolean(L, field->GetValue(obj)); break; case LUA_TINTEGER: - lua_pushinteger(L, GetValue(obj, offset, size)); + lua_pushinteger(L, field->GetValue(obj)); break; case LUA_TNUMBER: - lua_pushnumber(L, GetValue(obj, offset, size)); + lua_pushnumber(L, field->GetValue(obj)); break; case LUA_TSTRING: - lua_pushstring(L, GetValue(obj, offset, size)); + lua_pushstring(L, field->GetValue(obj)); break; case LUA_TSTRINGA: - lua_pushstring(L, ptrA(mir_utf8encode(GetValue(obj, offset, size)))); + lua_pushstring(L, ptrA(mir_utf8encode(field->GetValue(obj)))); break; case LUA_TSTRINGW: - lua_pushstring(L, ptrA(mir_utf8encodeW(GetValue(obj, offset, size)))); + lua_pushstring(L, ptrA(mir_utf8encodeW(field->GetValue(obj)))); break; case LUA_TLIGHTUSERDATA: - lua_pushlightuserdata(L, GetValue(obj, offset, size)); + lua_pushlightuserdata(L, field->GetValue(obj)); break; default: lua_pushnil(L); @@ -134,7 +153,15 @@ public: { size_t offset = reinterpret_cast(&(((T*)0)->*M)); if (type != LUA_TNONE) - fields[name] = new MTField(offset, size, type); + fields[name] = new MTField(offset, size, type); + return *this; + } + + template + MT& Field(std::function f, const char *name, int type) + { + if (type != LUA_TNONE) + fields[name] = new MTField(f, type); return *this; } @@ -165,6 +192,6 @@ template const char *MT::name; template -std::map MT::fields; +std::map*> MT::fields; #endif //_LUA_METATABLE_H_ -- cgit v1.2.3