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/mlua_metatable.h | 73 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'plugins/MirLua/src/mlua_metatable.h') 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