diff options
Diffstat (limited to 'plugins/MirLua/src')
| -rw-r--r-- | plugins/MirLua/src/m_chat.cpp | 1 | ||||
| -rw-r--r-- | plugins/MirLua/src/m_database.cpp | 4 | ||||
| -rw-r--r-- | plugins/MirLua/src/m_options.cpp | 2 | ||||
| -rw-r--r-- | plugins/MirLua/src/m_protocols.cpp | 4 | ||||
| -rw-r--r-- | plugins/MirLua/src/mlua_metatable.h | 155 | ||||
| -rw-r--r-- | plugins/MirLua/src/mlua_utils.cpp | 13 | 
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());
  | 
