Get the original filename of a userdata object? Possible?

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
mode7
Prole
Posts: 35
Joined: Tue Aug 21, 2012 5:45 pm
Contact:

Get the original filename of a userdata object? Possible?

Post by mode7 » Sun Sep 02, 2012 8:52 am

Hello everyone, this is my first post even though i've been lurking for a while now.
I have the following problem:
I'm working on an xml encoder/ decoder that easily allows me to read and write my tables (which contain everything from custom classes to userdata) to and from xml.
Everything works fine so far except when it comes to love userdata. As there are not that many types i decided to manually get the needed data and encode it. The problem is: To create e.g an image object you need a filename. But to reload it I would need to get the filename from the image object (if it was even stored) Is it possible to do this in love?

Thanks in advance?
Alex

User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Get the original filename of a userdata object? Possible

Post by bartbes » Sun Sep 02, 2012 10:20 am

No, it does not know about any original filename, it's hard to, isn't it? love.graphics.newImage(filename) actually turns into something along the lines of love.graphics.newImage(love.image.newImageData(love.filesystem.read(filename))) internally. You could store it with the userdata, with relative ease.

How about this:

Code: Select all

registry = setmetatable({}, {__mode = "k"})
registry[image] = "path/to/image.png"
If you write some wrappers around often-used functions, something like that should work fine.

mode7
Prole
Posts: 35
Joined: Tue Aug 21, 2012 5:45 pm
Contact:

Re: Get the original filename of a userdata object? Possible

Post by mode7 » Sun Sep 02, 2012 10:49 am

Thanks for ther quick answer. I already thought a wrapper would be needed.
Thanks for the code example. I'm pretty new to lua though and I dont know exactly what you are trying to do here. could you give me a hint ;)

User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Get the original filename of a userdata object? Possible

Post by bartbes » Sun Sep 02, 2012 10:56 am

Right, well, I'm using the userdata as keys in my table, because it then becomes easy to look up. I'm assuming you got this far.

What I did to the table, is quite a useful feature in lua, I'm using weak tables. Weak tables allow you to tell lua that the keys (in this case) and/or the values in the table should not be counter for its garbage collection.
The terminology here is a "weak reference", with "k" I've indicated that the keys are weak references.
What this actually does, is that when there's only weak references left to something, the garbage collection treats it as if there were none. This means that if you have an image in your register, that gets unloaded somewhere else (it gets inaccessible), the registry won't be keeping it around, allowing the memory to be released. Not just that, it's handled gracefully as well, in the sense that that index in the table also disappears, along with its associated value.

Santos
Party member
Posts: 384
Joined: Sat Oct 22, 2011 7:37 am

Re: Get the original filename of a userdata object? Possible

Post by Santos » Sun Sep 02, 2012 4:59 pm

Hmm...

Without weak keys:

Code: Select all

function love.load()
	t = {}

	t[function() return true end] = 'Test!'
	t[{1, 2, 3}] = true
	t[love.graphics.newImage('test.png')] = 123

	collectgarbage()

	for key, _ in pairs(t) do
		print(type(key))
	end
end
Output:
function
table
userdata
As expected!

However, with weak keys...

Code: Select all

function love.load()
	t = setmetatable({}, {__mode = "k"})

	t[function() return true end] = 'Test!'
	t[{1, 2, 3}] = true
	t[love.graphics.newImage('test.png')] = 123

	collectgarbage()

	for key, _ in pairs(t) do
		print(type(key))
	end
end
Output:
userdata
:o Why isn't the image collected?

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Get the original filename of a userdata object? Possible

Post by Robin » Wed Sep 05, 2012 6:36 pm

I guess because LÖVE kept an internal reference around for some reason? (Or maybe for no reason, in which case it would be a bug.)
Help us help you: attach a .love.

User avatar
qaisjp
Party member
Posts: 491
Joined: Tue Sep 04, 2012 10:49 am
Location: United Kingdom
Contact:

Re: Get the original filename of a userdata object? Possible

Post by qaisjp » Thu Sep 06, 2012 5:59 pm

Robin wrote:I guess because LÖVE kept an internal reference around for some reason? (Or maybe for no reason, in which case it would be a bug.)
I do think LOVE keeps internal references ..
Last edited by qaisjp on Thu Sep 06, 2012 6:11 pm, edited 1 time in total.
Lua is not an acronym.

User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Get the original filename of a userdata object? Possible

Post by Boolsheet » Thu Sep 06, 2012 6:09 pm

This is actually explained in the Lua manual.
At the end of each garbage-collection cycle, the finalizers for userdata are called in reverse order of their creation, among those collected in that cycle. That is, the first finalizer to be called is the one associated with the userdata created last in the program. The userdata itself is freed only in the next garbage-collection cycle.
collect twice and it's gone.
Shallow indentations.

Santos
Party member
Posts: 384
Joined: Sat Oct 22, 2011 7:37 am

Re: Get the original filename of a userdata object? Possible

Post by Santos » Thu Sep 06, 2012 8:14 pm

Aaah, cool. Thanks! :)

Post Reply

Who is online

Users browsing this forum: No registered users and 55 guests