Fix Channel:push and other functions that accept love objects and store them in Variants internally. Cleaned up Variant code a bit.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-09-30 11:11:14 -03:00
parent b838d0de54
commit bc980b0f20
3 changed files with 38 additions and 52 deletions
+32 -47
View File
@@ -26,7 +26,7 @@
namespace love
{
static love::Type *extractudatatype(lua_State *L, int idx)
static Proxy *tryextractproxy(lua_State *L, int idx)
{
Proxy *u = (Proxy *)lua_touserdata(L, idx);
@@ -36,7 +36,7 @@ static love::Type *extractudatatype(lua_State *L, int idx)
// We could get rid of the dynamic_cast for more performance, but it would
// be less safe...
if (dynamic_cast<Object *>(u->object) != nullptr)
return u->type;
return u;
return nullptr;
}
@@ -73,25 +73,20 @@ Variant::Variant(const char *string, size_t len)
}
}
Variant::Variant(void *userdata)
Variant::Variant(void *lightuserdata)
: type(LUSERDATA)
{
data.userdata = userdata;
data.userdata = lightuserdata;
}
Variant::Variant(love::Type *udatatype, void *userdata)
: type(FUSERDATA)
, udatatype(udatatype)
Variant::Variant(love::Type *lovetype, love::Object *object)
: type(LOVEOBJECT)
{
if (udatatype != nullptr)
{
love::Object *o = (love::Object *) userdata;
data.userdata = o;
if (o != nullptr)
o->retain();
}
else
data.userdata = userdata;
data.objectproxy.type = lovetype;
data.objectproxy.object = object;
if (data.objectproxy.object != nullptr)
data.objectproxy.object->retain();
}
// Variant gets ownership of the vector.
@@ -103,20 +98,18 @@ Variant::Variant(std::vector<std::pair<Variant, Variant>> *table)
Variant::Variant(const Variant &v)
: type(v.type)
, udatatype(v.udatatype)
, data(v.data)
{
if (type == STRING)
data.string->retain();
else if (type == FUSERDATA && udatatype != nullptr && data.userdata != nullptr)
((love::Object *) data.userdata)->retain();
else if (type == LOVEOBJECT && data.objectproxy.object != nullptr)
data.objectproxy.object->retain();
else if (type == TABLE)
data.table->retain();
}
Variant::Variant(Variant &&v)
: type(std::move(v.type))
, udatatype(std::move(v.udatatype))
, data(std::move(v.data))
{
v.type = NIL;
@@ -124,42 +117,32 @@ Variant::Variant(Variant &&v)
Variant::~Variant()
{
switch (type)
{
case STRING:
if (type == STRING)
data.string->release();
break;
case FUSERDATA:
if (udatatype != nullptr && data.userdata != nullptr)
((love::Object *) data.userdata)->release();
break;
case TABLE:
else if (type == LOVEOBJECT && data.objectproxy.object != nullptr)
data.objectproxy.object->release();
else if (type == TABLE)
data.table->release();
break;
default:
break;
}
}
Variant &Variant::operator = (const Variant &v)
{
if (v.type == STRING)
v.data.string->retain();
else if (v.type == FUSERDATA && v.udatatype != nullptr && v.data.userdata != nullptr)
((love::Object *) v.data.userdata)->retain();
else if (v.type == LOVEOBJECT && v.data.objectproxy.object != nullptr)
v.data.objectproxy.object->retain();
else if (v.type == TABLE)
v.data.table->retain();
if (type == STRING)
data.string->release();
else if (type == FUSERDATA && udatatype != nullptr && data.userdata != nullptr)
((love::Object *) data.userdata)->release();
else if (type == LOVEOBJECT && data.objectproxy.object != nullptr)
data.objectproxy.object->release();
else if (type == TABLE)
data.table->release();
type = v.type;
data = v.data;
udatatype = v.udatatype;
return *this;
}
@@ -168,6 +151,7 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
{
size_t len;
const char *str;
Proxy *p = nullptr;
if (n < 0) // Fix the stack position, we might modify it later
n += lua_gettop(L) + 1;
@@ -184,7 +168,14 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
case LUA_TLIGHTUSERDATA:
return Variant(lua_touserdata(L, n));
case LUA_TUSERDATA:
return Variant(extractudatatype(L, n), lua_touserdata(L, n));
p = tryextractproxy(L, n);
if (p != nullptr)
return Variant(p->type, p->object);
else
{
luax_typerror(L, n, "love type");
return Variant();
}
case LUA_TNIL:
return Variant();
case LUA_TTABLE:
@@ -259,14 +250,8 @@ void Variant::toLua(lua_State *L) const
case LUSERDATA:
lua_pushlightuserdata(L, data.userdata);
break;
case FUSERDATA:
if (udatatype != nullptr)
luax_pushtype(L, *udatatype, (love::Object *) data.userdata);
else
lua_pushlightuserdata(L, data.userdata);
// I know this is not the same
// sadly, however, it's the most
// I can do (at the moment).
case LOVEOBJECT:
luax_pushtype(L, *data.objectproxy.type, data.objectproxy.object);
break;
case TABLE:
{
+4 -4
View File
@@ -44,7 +44,7 @@ public:
STRING,
SMALLSTRING,
LUSERDATA,
FUSERDATA,
LOVEOBJECT,
NIL,
TABLE
};
@@ -53,8 +53,8 @@ public:
Variant(bool boolean);
Variant(double number);
Variant(const char *string, size_t len);
Variant(void *userdata);
Variant(love::Type *udatatype, void *userdata);
Variant(void *lightuserdata);
Variant(love::Type *type, love::Object *object);
Variant(std::vector<std::pair<Variant, Variant>> *table);
Variant(const Variant &v);
Variant(Variant &&v);
@@ -102,7 +102,6 @@ private:
static const int MAX_SMALL_STRING_LENGTH = 15;
Type type;
love::Type *udatatype;
union Data
{
@@ -110,6 +109,7 @@ private:
double number;
SharedString *string;
void *userdata;
Proxy objectproxy;
SharedTable *table;
struct
{
+2 -1
View File
@@ -74,7 +74,8 @@ int w_wait(lua_State *L)
int w_push(lua_State *L)
{
StrongRef<Message> m(Message::fromLua(L, 1), Acquire::NORETAIN);
StrongRef<Message> m;
luax_catchexcept(L, [&]() { m.set(Message::fromLua(L, 1), Acquire::NORETAIN); });
luax_pushboolean(L, m.get() != nullptr);