The wiki wasn't very clear about this and as far as I've seen it looks like a way to tag love objects with simple types.
Am I right in that you cannot add properties directly to a love object (such as Joint.myval = "hi")?
And as an extension to this question, what would I do if I want to modify data through setUserData? Would I have to get-modify-set every time?
What is setUserData and why do I need it?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: What is setUserData and why do I need it?
TL;DR: just ignore it.
This is physics-specific; yes you will have to get-set the data. This feature is generally pointless, considering that you can simply use a table lookup instead and it'll work faster on account of not having to do the C++ to Lua transition and back.
These non-native Lua objects are "userdata" (Lua terminology) and Lua cannot operate on them, only C++ code can; they can have metatables, so you could fill it up with C++ functions and use these types of objects the same way you use a table, except that you can't actually perform any operation on them from Lua side. This is why you can't write or read any properties from them, but you can execute "class" functions on them. With that in mind, the "set/getUserData" is a confusing name for this function, which basically just attaches Lua value as a payload to it on the C++ side, not actually does anything with userdata. And on top of that, it will actually crash your game if you attempt multithreaded use, because the Lua payload is only valid for whichever Lua thread created it.
This is physics-specific; yes you will have to get-set the data. This feature is generally pointless, considering that you can simply use a table lookup instead and it'll work faster on account of not having to do the C++ to Lua transition and back.
Code: Select all
userdata[physicsobject] = whatever
Re: What is setUserData and why do I need it?
I'm glad I asked this question, a lot of this should be on the wiki >.>
Re: What is setUserData and why do I need it?
When you have some collision callback that only sees two fixtures (to which last I checked you can't assign any attributes as they are not tables), you may want some way to reference the object they came from to e.g. change its health without requiring a global variable. The simplest way is to store a reference to their 'parent' object inside them. That's what I used get/setUserdata for anyway. It was pretty handy in that sense.
Re: What is setUserData and why do I need it?
Yes, setUserData is very useful when associating a body to a Lua object.
But then you have to modify the table every time a body is created or destroyed.
Re: What is setUserData and why do I need it?
It's not useless a all ! You can't directly set values to a body or a fixture (fixture.x = "hello").
I use it in my physics library if you wan't a real usecase :
https://github.com/4v0v/physics
I use it in my physics library if you wan't a real usecase :
https://github.com/4v0v/physics
Re: What is setUserData and why do I need it?
As for creation, in the other method you have to setUserData anyway, so there's no significant advantage - both methods require an action at creation time. As for destruction, weak tables take care of that automatically. The only extra work is a one-time setup of the weak table.
So for example:
Code: Select all
local bodyData = setmetatable({}, {__mode = 'k'})
function createBody(x, y, extradata)
local body = love.physics.newBody(world, x, y)
bodyData[body] = extradata -- instead of body:setUserData(extradata)
return body
end
As another extra bonus, this method is usable with any object, not just physics objects.
Re: What is setUserData and why do I need it?
Looks much cleaner using setUserData and it doesn't require the "bodyData" global.
PS. Also, I tried the weak table technique and it didn't work as expected.
Weak keys are collected almost right away regardless of whether the bodies are destroyed or not.
PS. Also, I tried the weak table technique and it didn't work as expected.
Weak keys are collected almost right away regardless of whether the bodies are destroyed or not.
Re: What is setUserData and why do I need it?
The multithreading thing is a pretty big deal if you need good performance, I just don't like the extra shared state in bodyData, but if you keep the module its used in small and encapsulate it neatly, it should work out smoothly anyway. I'll think about doing that for my own physics library wrapper maybe.pgimeno wrote: ↑Sat Jul 13, 2019 9:41 amAs for creation, in the other method you have to setUserData anyway, so there's no significant advantage - both methods require an action at creation time. As for destruction, weak tables take care of that automatically. The only extra work is a one-time setup of the weak table.
So for example:As an extra bonus, bodyData is not accessible from other threads so you can't get crashes as you do with setUserData if used from another thread. It can also be hidden from user code, so it can be used in libraries transparently.Code: Select all
local bodyData = setmetatable({}, {__mode = 'k'}) function createBody(x, y, extradata) local body = love.physics.newBody(world, x, y) bodyData[body] = extradata -- instead of body:setUserData(extradata) return body end
As another extra bonus, this method is usable with any object, not just physics objects.
Re: What is setUserData and why do I need it?
Make sure your weak keys and weak values have strong references elsewhere. If their only references are weak ones, they're counted as garbage.
Who is online
Users browsing this forum: Bing [Bot] and 2 guests