Using Callable to modify scene graph in multithreaded application

Hi monkeys!

I have been silently using the JME for about a year now and I’m pretty new to multi-threaded programming, but now that I’m working on an application involving networking there is no way around this issue.

I encountered some problems in attaching/detaching spatials from an app-state that does some networking tasks, but I think I’m on a path to fix this using the information found here:
http://hub.jmonkeyengine.org/forum/topic/solved-on-illegalstateexception-scene-graph-is-not-properly-updated-for-rendering-and-futurecall/

Now my question is this:

Do I have to enqueue spatial attachement using a Callable on every single child attachment, even if the parent node is not yet attached to the main root node?

Imagine this spatial structure:

rootNode

  • myNode
    • subNodeA
    • subNodeB
      • geometryB

I was wondering if it is sufficient to just enqueue the attaching of myNode to the rootNode in a multi-threaded way and just use .attachChild() as usual for all of the sub spatials? From my understanding this would make sense, because as long as there is no recursive connection of a spatial to the applications rootNode, modifying this spatial would not lead to a modification of the main scene graph.
Furthermore if this is correct, does it apply to other modifications too, like translating spatials, or changing materials of geometries, etc.? Do I have to use Callables for this stuff too?

Thanks in advance!

That is correct.

Only stuff that is being rendered (i.e. is attached directly or indirectly to the root node - although there are other ways too) need enqueing.

The threading tutorial should cover all this for you.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading

2 Likes

Hmmm, someone seems to have changed that tutorial since I last looked at it and it doesn’t cover this.

Odd.

Thanks!

I’ve read that tutorial (as all the others too, great material!) but couldn’t find this particular answer.

So my basic process will now be something like this:

  • create spatial
  • prepare spatial (set all properties, translations, materials, etc.) using non-enqueued methods
  • attach prepared sub-spatials if necessary using .attachChild()
  • finally attach the main spatial using an enqueued Callable

That is correct.

Although most simple stuff isn’t actually very expensive so it’s not worth doing that sort of thing unless you really are doing a lot of processing.