JMonkey Multithreading

Hello,

If a node is attaching to an other node then this must be happened in same Thread as jmonkey is running. That’s similar to swing.
I think I am right.

My problem is: My jmonkey canvas is running in an eclipse RCP application. So I can not expect that each scene graph manipulations are executed in correct thread. Thereforce I enqueue each manipulation(in general attach and detach of nodes) in SimpleApplication.enqueue.

Now my question: It is possible to figure out whether an enqueue is necesarry? If I am in the correct thread then I want execute the code immediately else I have to enqueue my action.

You can check to see if you are in rendering thread or not then decide to enqueue your action or not.

protected boolean isRenderThread() {
        return Thread.currentThread() == renderThread; //You get renderThread from application thread.
    }

Thx for your reply.
I set the renderThread Attribute in my simpleUpdate Method. Is there a beter way to get the render thread?

The BIG question here is how come you don’t know what thread you’re on? Looks like your code is pretty much messed up.

1 Like

That is right. It was wrote by a mathematician. My job is just to replace the graphic engine and not a refactoring. That’s hard enought for me :slight_smile:

But if I save a reference of the thread in my start method. This must be enough?

@Override
    public void start() {
renderThread = Thread.currentThread();
}

You can also get it in simpleInitApp() or initialize() or start() method.

Note: You might not need that checking, because:
Each Control’s controlUpdate and each AppStates update method are run in the RenderThread whereas your RCP Code might always be the different Thread.

So I guess you could save the checking work by simply enqueing everything coming from RCP and not enqueuing the Controls. That however only works if you don’t call a Control’s Method.

My last note is: Maybe you are even fine by just using enqueue all the time since the overhead might not be that huge, because: Adding/Removing is a bit costly, so you don’t want to do that very frequently (each frame). But that depends on the code ofcourse

As Darkchaos said,enqueuing is probably the easier and most versatile way to be sure that any code runs on render thread and it’s not so weighty.

I have done something similar. What i did is that i use all the old and mulithreaded drawing update and things to write pending updates that are queued for the actual drawing thread via the update method. For this i used on of the concurrent queues that java now has. Was simple and fairly fast. In fact i queued operators that worked on the scene graph poll until time is up or none left. Apply each to scene graph.

For some things however it was simpler. Controllers just viewed some volatile variables. Dirty and hacky. But mostly gets the job done.

I save current reference of the jmonkey thread in the initialze method and check before I call the Callable.call(). The reason is: I have to wait until the process ends.
SimpleApplication.enqueue(new Callable() {…}).get().
That’s my code which I use for scene graph updates.

    public static <T> void enqueue(MySimpleApplication app, Callable<T> callable) {
        if (app.isRenderThread())
            try {
                callable.call();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        else
            try {
                app.enqueue(callable).get();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

In general, that seems like a special case but either way beware of deadlocks. If you routinely do this when calling the JME thread and also routinely do this when calling from JME to the AWT/SWT thread then you pretty easily create deadlock conditions.

So if you do decide to always wait… just make sure to only ever do it in one direction. Though in general there is almost no reason to wait if you aren’t getting the response anyway.

1 Like