Removing/Deleting Metatables!

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
CosmicFloppyDisk
Prole
Posts: 8
Joined: Sat Sep 12, 2015 12:34 am

Removing/Deleting Metatables!

Post by CosmicFloppyDisk »

I might just be retarded or something but I can't do it. Well you see I have these metatables used to create as many window objects as I want, it's quite nice. Accept when you press the "X out" button I don't know how to delete the window, the closest I've come is setting a variable "hide" to true so it's no longer drawn, but it's still there in memory. How would I go about this with a simple function such as

Code: Select all

function Window:Remove()
	-- removing stuffs here
end
Thanks for any help you can give :)
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Removing/Deleting Metatables!

Post by raidho36 »

Unless they have specific function to destroy the window, you should hide it and remove all references to it, thereby making it garbage-collectible. The garbage collector, seeing as the table is no longer used, will collect it and remove from memory. Note that while technically still around, the moment you remove last reference it for all intents and purposes ceases to exist. And since rendering requires that you'd access it, implying that there's a reference to it, if you remove that reference it will not be rendered, too.
CosmicFloppyDisk
Prole
Posts: 8
Joined: Sat Sep 12, 2015 12:34 am

Re: Removing/Deleting Metatables!

Post by CosmicFloppyDisk »

raidho36 wrote:Unless they have specific function to destroy the window, you should hide it and remove all references to it, thereby making it garbage-collectible. The garbage collector, seeing as the table is no longer used, will collect it and remove from memory. Note that while technically still around, the moment you remove last reference it for all intents and purposes ceases to exist. And since rendering requires that you'd access it, implying that there's a reference to it, if you remove that reference it will not be rendered, too.
and removing all references to it would be done how? just setting it to self = nil?
User avatar
s-ol
Party member
Posts: 1080
Joined: Mon Sep 15, 2014 7:41 pm
Location: Milan, Italy
Contact:

Re: Removing/Deleting Metatables!

Post by s-ol »

CosmicFloppyDisk wrote:
raidho36 wrote:Unless they have specific function to destroy the window, you should hide it and remove all references to it, thereby making it garbage-collectible. The garbage collector, seeing as the table is no longer used, will collect it and remove from memory. Note that while technically still around, the moment you remove last reference it for all intents and purposes ceases to exist. And since rendering requires that you'd access it, implying that there's a reference to it, if you remove that reference it will not be rendered, too.
and removing all references to it would be done how? just setting it to self = nil?
No, you must have the window(s) stored somewhere else. For example you might have a list of Windows called 'windows', each of which you call :Draw() on every Frame. In that case you would remove the window from the list/table. Setting the entry to nil would work but you need to make sure you don't leave holes in list-tables of course.

s-ol.nu

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
ivan
Party member
Posts: 1939
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Removing/Deleting Metatables!

Post by ivan »

One of the features of Lua (and most interpreted languages) is that memory is managed automatically.
This is safer than having to "free" the memory by hand because it means that you can't have references that point to a "destroyed" table.
So if you want to really destroy an object, remove all references pointing to it and use "collectgarbage":

Code: Select all

-- create table
mytable = {}
-- remove reference
mytable = nil
-- collect
collectgarbage("collect")
just setting it to self = nil?
No, you have to remove every single reference to the "object" so that there is no way to access it from Lua.

You can use collectgarbage("count") to monitor the amount of memory that is currently allocated.
Good luck.
Last edited by ivan on Mon Sep 12, 2016 5:26 am, edited 1 time in total.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Removing/Deleting Metatables!

Post by raidho36 »

It is safer in that regard, but on the other hand, if you don't want memory to be managed automatically for whatever reason, you'll have to go an extra mile in order to prevent that.
User avatar
ivan
Party member
Posts: 1939
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Removing/Deleting Metatables!

Post by ivan »

I should also mention that a lot of people forget about garbage collection when testing the performance of functions - assuming that performance is "better" when allocating a lot of intermediate tables, for example:

Code: Select all

function myfunc(...)
  local arg = {...}
  for i = 1, #arg do
    local a = arg[i]
    -- do stuff
  end
end
Versus:

Code: Select all

function myfunc2(...)
  for i = 1, select('#', ...) do
    local a = select(i, ...)
    -- do stuff
  end
end
The second function is slower during execution because it calls "select" for each item, but the first creates more garbage.
It's a trade-off, so to "really" compare the performance of both functions you have to use "collectgarbage".
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Removing/Deleting Metatables!

Post by airstruck »

ivan wrote: The second function is slower during execution because it calls "select" for each item, but the first creates more garbage.
It's a trade-off, so to "really" compare the performance of both functions you have to use "collectgarbage".
Specifically, the second one is probably slower because of calling select with a dynamic index value. LuaJIT can't compile that, but it can compile literal index values like '#' or 2 (as of last time I checked anyway).

There are some things you can do to speed up cases like this. You can use code generation to build helper functions for each arity you need, and store those somewhere so you only have the code gen overhead once. Here's an example of that, I don't remember the specifics but I got a good performance boost out of it there.

There might also be simpler ways to do it with recursion, like this:

Code: Select all

function doStuffA (...)
  for i = 1, select('#', ...) do
    local a = select(i, ...)
    print(a)
  end
end

function doStuffB (a, ...)
  if a ~= nil then
    print(a)
    return doStuffB(...)
  end
end
I haven't tested these, but doStuffB might benefit from not calling select(i, ...). Both functions should do the same thing as long as no nils are passed. If anyone does perf this, try it with and without the tail call elimination, I think I remember TCE adversely affecting LuaJIT somehow.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Removing/Deleting Metatables!

Post by raidho36 »

There's a thread on luausers in which they say tail recursion call is eliminated, but it can't be compiled and has to be interpreted. That post dated back to 2010 citing LuaJIT status page, particularly that recursive calls were not traced.
CosmicFloppyDisk
Prole
Posts: 8
Joined: Sat Sep 12, 2015 12:34 am

Re: Removing/Deleting Metatables!

Post by CosmicFloppyDisk »

Thanks guys, I sure this will help :)
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot], Semrush [Bot] and 5 guests