summaryrefslogtreecommitdiff
path: root/plugins/MirLua
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
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')
-rw-r--r--plugins/MirLua/src/m_chat.cpp1
-rw-r--r--plugins/MirLua/src/m_database.cpp4
-rw-r--r--plugins/MirLua/src/m_options.cpp2
-rw-r--r--plugins/MirLua/src/m_protocols.cpp4
-rw-r--r--plugins/MirLua/src/mlua_metatable.h155
-rw-r--r--plugins/MirLua/src/mlua_utils.cpp13
6 files changed, 127 insertions, 52 deletions
diff --git a/plugins/MirLua/src/m_chat.cpp b/plugins/MirLua/src/m_chat.cpp
index dfe8b3c54d..dbecbc774e 100644
--- a/plugins/MirLua/src/m_chat.cpp
+++ b/plugins/MirLua/src/m_chat.cpp
@@ -5,6 +5,7 @@ static luaL_Reg chatApi[] =
{ NULL, NULL }
};
+template <>
int MT<GCEVENT>::Index(lua_State *L, GCEVENT *gce)
{
const char *key = lua_tostring(L, 2);
diff --git a/plugins/MirLua/src/m_database.cpp b/plugins/MirLua/src/m_database.cpp
index b9318c1047..fab5f86d57 100644
--- a/plugins/MirLua/src/m_database.cpp
+++ b/plugins/MirLua/src/m_database.cpp
@@ -589,6 +589,7 @@ static luaL_Reg databaseApi[] =
#define MT_DBCONTACTWRITESETTING "DBCONTACTWRITESETTING"
+template <>
int MT<DBCONTACTWRITESETTING>::Index(lua_State *L, DBCONTACTWRITESETTING *dbcw)
{
const char *key = luaL_checkstring(L, 2);
@@ -639,6 +640,7 @@ int MT<DBCONTACTWRITESETTING>::Index(lua_State *L, DBCONTACTWRITESETTING *dbcw)
#define MT_DBEVENTINFO "DBEVENTINFO"
+template <>
void MT<DBEVENTINFO>::Init(lua_State *L, DBEVENTINFO **dbei)
{
MEVENT hDbEvent = luaL_checkinteger(L, 1);
@@ -650,6 +652,7 @@ void MT<DBEVENTINFO>::Init(lua_State *L, DBEVENTINFO **dbei)
db_event_get((MEVENT)hDbEvent, (*dbei));
}
+template <>
int MT<DBEVENTINFO>::Index(lua_State *L, DBEVENTINFO *dbei)
{
const char *key = luaL_checkstring(L, 2);
@@ -669,6 +672,7 @@ int MT<DBEVENTINFO>::Index(lua_State *L, DBEVENTINFO *dbei)
return 1;
}
+template <>
void MT<DBEVENTINFO>::Free(lua_State*, DBEVENTINFO **dbei)
{
mir_free((*dbei)->pBlob);
diff --git a/plugins/MirLua/src/m_options.cpp b/plugins/MirLua/src/m_options.cpp
index 37f1d27b22..6d7ec23d2e 100644
--- a/plugins/MirLua/src/m_options.cpp
+++ b/plugins/MirLua/src/m_options.cpp
@@ -34,7 +34,7 @@ public:
}
}
- void OnDestroy()
+ void OnDestroy() override
{
lua_pushnil(L);
lua_rawsetp(L, LUA_REGISTRYINDEX, this);
diff --git a/plugins/MirLua/src/m_protocols.cpp b/plugins/MirLua/src/m_protocols.cpp
index 354a65daf5..423d732c32 100644
--- a/plugins/MirLua/src/m_protocols.cpp
+++ b/plugins/MirLua/src/m_protocols.cpp
@@ -233,8 +233,8 @@ LUAMOD_API int luaopen_m_protocols(lua_State *L)
MT<CCSDATA>(L, "CCSDATA")
.Field(&CCSDATA::hContact, "hContact", LUA_TINTEGER)
.Field(&CCSDATA::szProtoService, "Service", LUA_TSTRINGA)
- .Field([](CCSDATA *ccd) { return (void*)ccd->wParam; }, "wParam", LUA_TLIGHTUSERDATA)
- .Field([](CCSDATA *ccd) { return (void*)ccd->lParam; }, "lParam", LUA_TLIGHTUSERDATA);
+ .Field([](CCSDATA *ccd) -> MTFieldVal { MTFieldVal tmp; tmp.userdata = (void*)ccd->wParam; return tmp; }, "wParam", LUA_TLIGHTUSERDATA)
+ .Field([](CCSDATA *ccd) -> MTFieldVal { MTFieldVal tmp; tmp.userdata = (void*)ccd->lParam; return tmp; }, "lParam", LUA_TLIGHTUSERDATA);
MT<PROTORECVEVENT>(L, "PROTORECVEVENT")
.Field(&PROTORECVEVENT::timestamp, "Timestamp", LUA_TINTEGER)
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_
diff --git a/plugins/MirLua/src/mlua_utils.cpp b/plugins/MirLua/src/mlua_utils.cpp
index 6ee3f44186..ec08831a1d 100644
--- a/plugins/MirLua/src/mlua_utils.cpp
+++ b/plugins/MirLua/src/mlua_utils.cpp
@@ -79,22 +79,23 @@ int luaM_print(lua_State *L)
switch (lua_type(L, i))
{
case LUA_TNIL:
- data.Append("nil ");
+ data.Append("nil");
break;
case LUA_TBOOLEAN:
- data.AppendFormat("%s ", lua_toboolean(L, i) ? "true" : "false");
+ data.AppendFormat("%s", lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER:
case LUA_TSTRING:
- data.AppendFormat("%s ", lua_tostring(L, i));
+ data.AppendFormat("%s", lua_tostring(L, i));
break;
default:
- data.AppendFormat("%s(0x%p) ", luaL_typename(L, i), lua_topointer(L, i));
+ data.AppendFormat("%s(0x%p)", luaL_typename(L, i), lua_topointer(L, i));
break;
}
+ data += '\t';
}
- if (data.GetLength() >= 3)
- data.Delete(data.GetLength() - 3, 3);
+ if (data.GetLength() >= 1)
+ data.Delete(data.GetLength() - 1, 1);
Log(data.GetBuffer());