SOLVED: Error node.setUserData()

Hello,

I would like to save an object reference in the user Data of a Node. Example

Anyclass obj = new Anyclass();		// create Object
Node node = new Node();				// Create Node
node.setUserData("ID", obj);		// save object refence in Node

but I get an error Message

Apr. 22, 2022 11:20:31 VORM. class com.jme3.app.AppTask invoke()
SCHWERWIEGEND: Exception
java.lang.IllegalArgumentException: Unsupported type: Anyclass

Later I want to get back the reference by using

Anyclass obj = (Anyclass)node.getUserData("ID");   // I know it will not work like this, but how?

Is there any possibility to do something like this or a similar way to do it?

1 Like

Hi @Edmund this is because to be placed as user data a class must implement Savable*. (I may have strong opinions about this).

The Savable interface is for if you are saving a node into a .j3o for persistence, but if you are not using that functionality you can just implement Savable on your Anyclass but then just leave the methods of the Savable interface blank.

*Technically must implement Savable or be one of a small number of classes that are supported inherantly, like Maps and lists

2 Likes

And primitive wrappers, String, Long, etc.

Edit: and outside of those classes, I’d argue that a lot of cases are abusing user data. Not all… but a lot of cases that don’t fit the built-in set.

1 Like

A better way of doing this would ( in my opinion) be to store a reference to the Node in your “AnyClass” object, and then keep a a list and/or map of these objects. This way, you aren’t relying on the scene-graph and spatials/nodes to store your data, and can instead do something like anyClass = anyClassMap.get(node); to retrieve the object containing the important data that relates to that node.

1 Like

I think yeah, you are right it’s a database design situation, it depends on your data, if it’s global (not related to particular node such as userScores or userAssets for instance), then yes using a global class might be the best option.

Based on the example, I imagined AnyClass was something like Zay-ES’s EntityId. Which is definitely something that I would store on a Spatial (might be the only thing).

But EntityId is not JME-specific and thus does not implement Savable, so in the two places in the code that I use it, I just wrap/unwrap it.

Thanks for the answer. I implemented savable and it works fine. Before, I used a list with IDs of my objects but it is much faster to have a direct reference than to search the ID in the List.

3 Likes