summaryrefslogtreecommitdiff
path: root/plugins/MirLua/src/mlua_metatable.h
diff options
context:
space:
mode:
authorMikalaiR <nikolay.romanovich@narod.ru>2016-07-01 07:43:28 +0000
committerMikalaiR <nikolay.romanovich@narod.ru>2016-07-01 07:43:28 +0000
commitdba6ba812fadfef61e7adf61ff2a65e03ed36789 (patch)
tree25c126b497d9964d1c43a2f06030f5d4612b351b /plugins/MirLua/src/mlua_metatable.h
parentad5f64dcd8dc7944e85208d6ef32eb5adbb4ffe6 (diff)
MirLua: mlua_metatable rewritted
git-svn-id: http://svn.miranda-ng.org/main/trunk@17055 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirLua/src/mlua_metatable.h')
-rw-r--r--plugins/MirLua/src/mlua_metatable.h155
1 files changed, 112 insertions, 43 deletions
diff --git a/plugins/MirLua/src/mlua_metatable.h b/plugins/MirLua/src/mlua_metatable.h
index 1b28285e96..103c8b95d1 100644
--- a/plugins/MirLua/src/mlua_metatable.h
+++ b/plugins/MirLua/src/mlua_metatable.h
@@ -1,51 +1,73 @@
#ifndef _LUA_METATABLE_H_
#define _LUA_METATABLE_H_
+#include <cstddef>
#include <functional>
#define LUA_TINTEGER LUA_NUMTAGS + 1
#define LUA_TSTRINGA LUA_NUMTAGS + 2
#define LUA_TSTRINGW LUA_NUMTAGS + 3
-template<typename T>
-class MTField : public MZeroedObject
+union MTFieldVal
{
-private:
- enum MTFieldGetter
- {
- MTFG_LAMBDA = 1,
- MTFG_OFFSET = 2
- };
+ void *userdata;
+ int boolean;
+ lua_Integer integer;
+ lua_Number number;
+ const char *string;
+ const char *stringA;
+ const wchar_t *stringW;
+};
+
+struct MTField
+{
+ int lua_type;
+ MTFieldVal val;
+};
- size_t offset;
- size_t size;
- int type;
- int getterType;
- std::function<void*(T*)> lambda;
+class CMTField
+{
+public:
+ virtual MTField GetValue(void *obj) = 0;
+ virtual ~CMTField(){};
+};
+template <typename Obj, typename Ret>
+class CMTFieldOffset : public CMTField
+{
+ int lua_type;
+ ptrdiff_t offset;
+ size_t size;
public:
- MTField(size_t offset, size_t size, int type)
- : offset(offset), size(size), type(type), getterType(MTFG_OFFSET) { }
+ CMTFieldOffset(ptrdiff_t off, size_t s, int type) : offset(off), lua_type(type), size(s) {}
+ virtual MTField GetValue(void *obj)
+ {
+ MTField fd = { lua_type };
+ //fd.val = *(Ret*)((char*)obj + offset);
+ memcpy(&fd.val, ((char*)obj + offset), sizeof(Ret));
+ return fd;
+ }
+};
- MTField(std::function<void*(T*)> f, int type)
- : lambda(f), type(type), getterType(MTFG_LAMBDA) { }
+template <typename Obj>
+class CMTFieldLambda : public CMTField
+{
+ int lua_type;
+ std::function<MTFieldVal(Obj*)> lambda;
+public:
- int GetType() const { return type; }
+ CMTFieldLambda(decltype(lambda) f, int type) : lambda(f), lua_type(type) {}
- template<typename R>
- R GetValue(T *obj) const
+ virtual MTField GetValue(void *obj)
{
- if (getterType == MTFG_LAMBDA) return (R)lambda(obj);
- else
- {
- R res = NULL;
- memcpy(&res, ((char*)obj) + offset, size);
- return res;
- }
+ MTField tmp = { lua_type };
+ tmp.val = lambda((Obj*)obj);
+ return tmp;
}
};
+
template<typename T>
class MT
{
@@ -53,7 +75,7 @@ private:
lua_State *L;
static const char *name;
- static std::map<std::string, MTField<T>*> fields;
+ static std::map<std::string, CMTField*> fields;
static void Init(lua_State *L, T **obj)
{
@@ -116,30 +138,30 @@ private:
return Index(L, obj);
}
- MTField<T> *field = it->second;
+ MTField fieldVal = it->second->GetValue(obj);
- switch (field->GetType())
+ switch (fieldVal.lua_type)
{
case LUA_TBOOLEAN:
- lua_pushboolean(L, field->GetValue<int>(obj));
+ lua_pushboolean(L, fieldVal.val.boolean);
break;
case LUA_TINTEGER:
- lua_pushinteger(L, field->GetValue<long long>(obj));
+ lua_pushinteger(L, fieldVal.val.integer);
break;
case LUA_TNUMBER:
- lua_pushnumber(L, field->GetValue<intptr_t>(obj));
+ lua_pushnumber(L, fieldVal.val.number);
break;
case LUA_TSTRING:
- lua_pushstring(L, field->GetValue<char*>(obj));
+ lua_pushstring(L, fieldVal.val.string);
break;
case LUA_TSTRINGA:
- lua_pushstring(L, ptrA(mir_utf8encode(field->GetValue<char*>(obj))));
+ lua_pushstring(L, ptrA(mir_utf8encode(fieldVal.val.stringA)));
break;
case LUA_TSTRINGW:
- lua_pushstring(L, T2Utf(field->GetValue<wchar_t*>(obj)));
+ lua_pushstring(L, T2Utf(fieldVal.val.stringW));
break;
case LUA_TLIGHTUSERDATA:
- lua_pushlightuserdata(L, field->GetValue<void*>(obj));
+ lua_pushlightuserdata(L, fieldVal.val.userdata);
break;
default:
lua_pushnil(L);
@@ -147,7 +169,6 @@ private:
return 1;
}
-
static int lua__gc(lua_State *L)
{
T **obj = (T**)luaL_checkudata(L, 1, MT::name);
@@ -156,6 +177,52 @@ private:
return 0;
}
+ static int lua__tostring(lua_State *L)
+ {
+ T *obj = *(T**)luaL_checkudata(L, 1, MT::name);
+ CMStringA data(MT::name);
+ data += "(";
+
+
+ for (auto it = fields.begin(); it != fields.end(); ++it)
+ {
+ data += it->first.c_str();
+ data += "=";
+ MTField fieldVal = it->second->GetValue(obj);
+
+ switch (fieldVal.lua_type)
+ {
+ case LUA_TBOOLEAN:
+ data.Append(fieldVal.val.boolean == 0 ? "false" : "true");
+ break;
+ case LUA_TINTEGER:
+ data.AppendFormat("%d", fieldVal.val.integer);
+ break;
+ case LUA_TNUMBER:
+ data.AppendFormat("%f", fieldVal.val.number);
+ break;
+ case LUA_TSTRING:
+ data.Append(fieldVal.val.string);
+ break;
+ case LUA_TSTRINGA:
+ data.Append(ptrA(mir_utf8encode(fieldVal.val.stringA)));
+ break;
+ case LUA_TSTRINGW:
+ data.Append(T2Utf(fieldVal.val.stringW));
+ break;
+ case LUA_TLIGHTUSERDATA:
+ data.AppendFormat("(0x%p)", fieldVal.val.userdata);
+ break;
+ default:
+ data.Append("nil");
+ }
+ data += ", ";
+ }
+ data += ")";
+ lua_pushstring(L, data.c_str());
+ return 1;
+ }
+
public:
MT(lua_State *L, const char *tname) : L(L)
{
@@ -170,6 +237,8 @@ public:
lua_setfield(L, -2, "__bnot");
lua_pushcfunction(L, lua__gc);
lua_setfield(L, -2, "__gc");
+ lua_pushcfunction(L, lua__tostring);
+ lua_setfield(L, -2, "__tostring");
lua_pop(L, 1);
lua_createtable(L, 0, 1);
@@ -182,13 +251,13 @@ public:
}
template<typename R>
- MT& Field(R T::*M, const char *name, int type, size_t size = 0)
+ MT& Field(R T:: *M, const char *name, int type, size_t size = 0)
{
if (size == 0)
size = sizeof(M);
- size_t offset = offsetof(T, *M);
+ size_t offset = (size_t)(&(((T*)0)->*M));
if (type != LUA_TNONE)
- fields[name] = new MTField<T>(offset, size, type);
+ fields[name] = new CMTFieldOffset<T, R>(offset, size, type);
return *this;
}
@@ -196,7 +265,7 @@ public:
MT& Field(const L &f, const char *name, int type)
{
if (type != LUA_TNONE)
- fields[name] = new MTField<T>(f, type);
+ fields[name] = new CMTFieldLambda<T>(f, type);
return *this;
}
@@ -218,6 +287,6 @@ template<typename T>
const char *MT<T>::name;
template<typename T>
-std::map<std::string, MTField<T>*> MT<T>::fields;
+std::map<std::string, CMTField*> MT<T>::fields;
#endif //_LUA_METATABLE_H_