mirror of
https://github.com/love2d/love.git
synced 2026-08-14 01:20:56 +02:00
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:
+32
-47
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user