|
@@ -26,7 +26,7 @@
|
|
namespace love
|
|
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);
|
|
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
|
|
// We could get rid of the dynamic_cast for more performance, but it would
|
|
// be less safe...
|
|
// be less safe...
|
|
if (dynamic_cast<Object *>(u->object) != nullptr)
|
|
if (dynamic_cast<Object *>(u->object) != nullptr)
|
|
- return u->type;
|
|
|
|
|
|
+ return u;
|
|
|
|
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
@@ -73,25 +73,20 @@ Variant::Variant(const char *string, size_t len)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-Variant::Variant(void *userdata)
|
|
|
|
|
|
+Variant::Variant(void *lightuserdata)
|
|
: type(LUSERDATA)
|
|
: 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.
|
|
// Variant gets ownership of the vector.
|
|
@@ -103,20 +98,18 @@ Variant::Variant(std::vector<std::pair<Variant, Variant>> *table)
|
|
|
|
|
|
Variant::Variant(const Variant &v)
|
|
Variant::Variant(const Variant &v)
|
|
: type(v.type)
|
|
: type(v.type)
|
|
- , udatatype(v.udatatype)
|
|
|
|
, data(v.data)
|
|
, data(v.data)
|
|
{
|
|
{
|
|
if (type == STRING)
|
|
if (type == STRING)
|
|
data.string->retain();
|
|
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)
|
|
else if (type == TABLE)
|
|
data.table->retain();
|
|
data.table->retain();
|
|
}
|
|
}
|
|
|
|
|
|
Variant::Variant(Variant &&v)
|
|
Variant::Variant(Variant &&v)
|
|
: type(std::move(v.type))
|
|
: type(std::move(v.type))
|
|
- , udatatype(std::move(v.udatatype))
|
|
|
|
, data(std::move(v.data))
|
|
, data(std::move(v.data))
|
|
{
|
|
{
|
|
v.type = NIL;
|
|
v.type = NIL;
|
|
@@ -124,42 +117,32 @@ Variant::Variant(Variant &&v)
|
|
|
|
|
|
Variant::~Variant()
|
|
Variant::~Variant()
|
|
{
|
|
{
|
|
- switch (type)
|
|
|
|
- {
|
|
|
|
- case STRING:
|
|
|
|
|
|
+ if (type == STRING)
|
|
data.string->release();
|
|
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();
|
|
data.table->release();
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
Variant &Variant::operator = (const Variant &v)
|
|
Variant &Variant::operator = (const Variant &v)
|
|
{
|
|
{
|
|
if (v.type == STRING)
|
|
if (v.type == STRING)
|
|
v.data.string->retain();
|
|
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)
|
|
else if (v.type == TABLE)
|
|
v.data.table->retain();
|
|
v.data.table->retain();
|
|
|
|
|
|
if (type == STRING)
|
|
if (type == STRING)
|
|
data.string->release();
|
|
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)
|
|
else if (type == TABLE)
|
|
data.table->release();
|
|
data.table->release();
|
|
|
|
|
|
type = v.type;
|
|
type = v.type;
|
|
data = v.data;
|
|
data = v.data;
|
|
- udatatype = v.udatatype;
|
|
|
|
|
|
|
|
return *this;
|
|
return *this;
|
|
}
|
|
}
|
|
@@ -168,6 +151,7 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
|
|
{
|
|
{
|
|
size_t len;
|
|
size_t len;
|
|
const char *str;
|
|
const char *str;
|
|
|
|
+ Proxy *p = nullptr;
|
|
|
|
|
|
if (n < 0) // Fix the stack position, we might modify it later
|
|
if (n < 0) // Fix the stack position, we might modify it later
|
|
n += lua_gettop(L) + 1;
|
|
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:
|
|
case LUA_TLIGHTUSERDATA:
|
|
return Variant(lua_touserdata(L, n));
|
|
return Variant(lua_touserdata(L, n));
|
|
case LUA_TUSERDATA:
|
|
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:
|
|
case LUA_TNIL:
|
|
return Variant();
|
|
return Variant();
|
|
case LUA_TTABLE:
|
|
case LUA_TTABLE:
|
|
@@ -259,14 +250,8 @@ void Variant::toLua(lua_State *L) const
|
|
case LUSERDATA:
|
|
case LUSERDATA:
|
|
lua_pushlightuserdata(L, data.userdata);
|
|
lua_pushlightuserdata(L, data.userdata);
|
|
break;
|
|
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;
|
|
break;
|
|
case TABLE:
|
|
case TABLE:
|
|
{
|
|
{
|