Added Object:release. Calling it is the equivalent of removing all Lua-side references to an object and doing a full garbage collection cycle (thus deleting the object from memory if nothing else in LÖVE's code is referencing it).

Any attempt to call a method on the object after it has been released will result in an error. Object:release() returns true if it was successful, or false if not (if it has already been released previously).

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2016-10-06 21:59:01 -03:00
parent bfb00239fd
commit 37520bd18b
7 changed files with 69 additions and 9 deletions
+38 -2
View File
@@ -42,7 +42,11 @@ namespace love
static int w__gc(lua_State *L)
{
Proxy *p = (Proxy *) lua_touserdata(L, 1);
p->object->release();
if (p->object != nullptr)
{
p->object->release();
p->object = nullptr;
}
return 0;
}
@@ -72,7 +76,35 @@ static int w__eq(lua_State *L)
{
Proxy *p1 = (Proxy *)lua_touserdata(L, 1);
Proxy *p2 = (Proxy *)lua_touserdata(L, 2);
luax_pushboolean(L, p1->object == p2->object);
luax_pushboolean(L, p1->object == p2->object && p1->object != nullptr);
return 1;
}
static int w__release(lua_State *L)
{
Proxy *p = (Proxy *) lua_touserdata(L, 1);
Object *object = p->object;
if (object != nullptr)
{
p->object = nullptr;
object->release();
// Fetch the registry table of instantiated objects.
luax_getregistry(L, REGISTRY_OBJECTS);
if (lua_istable(L, -1))
{
// loveobjects[object] = nil
lua_pushlightuserdata(L, object);
lua_pushnil(L);
lua_settable(L, -3);
}
lua_pop(L, 1);
}
luax_pushboolean(L, object != nullptr);
return 1;
}
@@ -329,6 +361,10 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
lua_pushcfunction(L, w__typeOf);
lua_setfield(L, -2, "typeOf");
// Add release
lua_pushcfunction(L, w__release);
lua_setfield(L, -2, "release");
va_list fs;
va_start(fs, name);
for (const luaL_Reg *f = va_arg(fs, const luaL_Reg *); f; f = va_arg(fs, const luaL_Reg *))