## What is setUserData and why do I need it?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Jugbot
Prole
Posts: 14
Joined: Mon Jun 24, 2019 9:54 pm

### What is setUserData and why do I need it?

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?

raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

### 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.

Code: Select all

userdata[physicsobject] = whatever
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.

Jugbot
Prole
Posts: 14
Joined: Mon Jun 24, 2019 9:54 pm

### 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 >.>

TheHUG
Citizen
Posts: 55
Joined: Sun Apr 01, 2018 4:21 pm

### 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.

ivan
Party member
Posts: 1554
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: What is setUserData and why do I need it?

Yes, setUserData is very useful when associating a body to a Lua object.
raidho36 wrote:
Thu Jul 11, 2019 6:52 pm
This feature is generally pointless, considering that you can simply use a table lookup instead
But then you have to modify the table every time a body is created or destroyed.

4vZEROv
Citizen
Posts: 87
Joined: Wed Jan 02, 2019 8:44 pm

### 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

pgimeno
Party member
Posts: 2132
Joined: Sun Oct 18, 2015 2:58 pm

### Re: What is setUserData and why do I need it?

ivan wrote:
Sat Jul 13, 2019 3:32 am
But then you have to modify the table every time a body is created or destroyed.
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'})

local body = love.physics.newBody(world, x, y)
return body
end

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.

As another extra bonus, this method is usable with any object, not just physics objects.

ivan
Party member
Posts: 1554
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### 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.

TheHUG
Citizen
Posts: 55
Joined: Sun Apr 01, 2018 4:21 pm

### Re: What is setUserData and why do I need it?

pgimeno wrote:
Sat Jul 13, 2019 9:41 am
ivan wrote:
Sat Jul 13, 2019 3:32 am
But then you have to modify the table every time a body is created or destroyed.
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'})

local body = love.physics.newBody(world, x, y)
return body
end

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.

As another extra bonus, this method is usable with any object, not just physics objects.
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.

raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

### Re: What is setUserData and why do I need it?

ivan wrote:
Sat Jul 13, 2019 11:09 am
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.
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: No registered users and 17 guests