summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikalaiR <nikolay.romanovich@narod.ru>2016-01-16 08:43:00 +0000
committerMikalaiR <nikolay.romanovich@narod.ru>2016-01-16 08:43:00 +0000
commitb97c40a7095474115cdeac7a93183353b203886b (patch)
treecd645b8b1cf0b2495f17173cace167b820798706
parent405496db2755c557583f4ad95d0279e4a55c4523 (diff)
MirLua: lambda-based metatables wrapper
git-svn-id: http://svn.miranda-ng.org/main/trunk@16096 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--plugins/MirLua/src/m_database.cpp15
-rw-r--r--plugins/MirLua/src/m_msg_buttonsbar.cpp8
-rw-r--r--plugins/MirLua/src/mlua_metatable.h73
3 files changed, 62 insertions, 34 deletions
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<DBEVENTINFO>(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<void*(DBEVENTINFO*)>([](DBEVENTINFO* p) { return p->szModule; }), "Module", LUA_TSTRINGA)
+ .Field(std::function<void*(DBEVENTINFO*)>([](DBEVENTINFO* p) { return (void*)p->timestamp; }), "Timestamp", LUA_TINTEGER)
+ .Field(std::function<void*(DBEVENTINFO*)>([](DBEVENTINFO* p) { return (void*)p->eventType; }), "Type", LUA_TINTEGER)
+ .Field(std::function<void*(DBEVENTINFO*)>([](DBEVENTINFO* p) { return (void*)p->flags; }), "Flags", LUA_TINTEGER)
+ .Field(std::function<void*(DBEVENTINFO*)>([](DBEVENTINFO* p) { return (void*)p->cbBlob; }), "Length", LUA_TINTEGER)
+ .Field(std::function<void*(DBEVENTINFO*)>([](DBEVENTINFO* p) { return p->pBlob; }), "Blob", LUA_TLIGHTUSERDATA);
+
lua_pop(L, 1);
MT<CONTACTINFO>(L, "CONTACTINFO")
- .Field(&CONTACTINFO::hContact, "hContact", LUA_TINTEGER)
+ .Field(std::function<void*(CONTACTINFO*)>([](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<CustomButtonClickData>(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 <functional>
+
+#define LFUNC(T, L) std::function<void*(T*)>(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<typename T>
+struct MTField : public MZeroedObject
{
size_t offset;
size_t size;
int type;
+ int getType;
+ std::function<void*(T*)> 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<void*(T*)> f, int type)
+ : lambda(f), type(type), getType(MTFGT_LAMBDA) { }
+
+ template<typename R = void*>
+ 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<typename T>
@@ -22,15 +51,7 @@ private:
lua_State *L;
static const char *name;
- static std::map<std::string, MTField*> fields;
-
- template<typename R>
- 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<std::string, MTField<T>*> 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<T> *field = it->second;
switch (field->type)
{
case LUA_TBOOLEAN:
- lua_pushboolean(L, GetValue<bool>(obj, offset, size));
+ lua_pushboolean(L, field->GetValue<BOOL>(obj));
break;
case LUA_TINTEGER:
- lua_pushinteger(L, GetValue<long long>(obj, offset, size));
+ lua_pushinteger(L, field->GetValue<long>(obj));
break;
case LUA_TNUMBER:
- lua_pushnumber(L, GetValue<double>(obj, offset, size));
+ lua_pushnumber(L, field->GetValue<intptr_t>(obj));
break;
case LUA_TSTRING:
- lua_pushstring(L, GetValue<char*>(obj, offset, size));
+ lua_pushstring(L, field->GetValue<char*>(obj));
break;
case LUA_TSTRINGA:
- lua_pushstring(L, ptrA(mir_utf8encode(GetValue<char*>(obj, offset, size))));
+ lua_pushstring(L, ptrA(mir_utf8encode(field->GetValue<char*>(obj))));
break;
case LUA_TSTRINGW:
- lua_pushstring(L, ptrA(mir_utf8encodeW(GetValue<wchar_t*>(obj, offset, size))));
+ lua_pushstring(L, ptrA(mir_utf8encodeW(field->GetValue<wchar_t*>(obj))));
break;
case LUA_TLIGHTUSERDATA:
- lua_pushlightuserdata(L, GetValue<void*>(obj, offset, size));
+ lua_pushlightuserdata(L, field->GetValue(obj));
break;
default:
lua_pushnil(L);
@@ -134,7 +153,15 @@ public:
{
size_t offset = reinterpret_cast<size_t>(&(((T*)0)->*M));
if (type != LUA_TNONE)
- fields[name] = new MTField(offset, size, type);
+ fields[name] = new MTField<T>(offset, size, type);
+ return *this;
+ }
+
+ template<typename R>
+ MT& Field(std::function<R(T*)> f, const char *name, int type)
+ {
+ if (type != LUA_TNONE)
+ fields[name] = new MTField<T>(f, type);
return *this;
}
@@ -165,6 +192,6 @@ template<typename T>
const char *MT<T>::name;
template<typename T>
-std::map<std::string, MTField*> MT<T>::fields;
+std::map<std::string, MTField<T>*> MT<T>::fields;
#endif //_LUA_METATABLE_H_