Random problems when stand-alone Swing GUI calls BaseGame.start()?

Sirs,



I need help ASAP!



Let's imagine the following:


  1. I create a very simple external and stand-alone Swing GUI that runs JME Game start() and calls a doSomething() method I have implemented inside my JME Game:



public static void main(String arg[]) {
    JFrame frame = new JFrame("MyJMEGame client GUI");
    JButton button = new JButton("doSomething");
    frame.getContentPane().add(button);
    final MyJMEGame game = MyJMEGameImpl();
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            OneCustomObject object = OneCustomObjet();
            game.doSomething(object);
        }
    }
    frame.setVisible(true);
    game.start();
}



2) I run this main, then two windows become opened: the stand-alone Swing GUI and the JME game window.

3) Then I call a few times my doSomething(object) method to do something, whatever, inside my JME Game, like, for instance, updating state. Let's imagine that OneCustomObject it's just like that, a simple POJO transporting state.

4) Suddenly I get "strange" behaviors inside my JME Game, during rendering processes, etc. things like IndexOutOfBoundException or NullPointerException in ArrayList that internally JME Game uses (inside JME API, not mine) to process rendering meshes, vertex, whatever.  And all these breaks are random! They do not happen always at the same time.

I guess there is some problem here with the AWT thread in which I launch my stand-alone Swing GUI and the JME Game I do instance and start outside it, but I call it inside my GUI. Is it right?

Any incoming help with this topic is very welcome!

Thanks!

Sounds like a threading problem.

Before modifying the jme Scenegraph you need to either lock it at a save place, or use the GameTaskQueue, so that the stuff happens inside the main thread.



if you can post a simple test case to reproduce the problem, it would be easier to explain what exactly happens.


Thanks for your answer Core-Dump.



Yes, I think it has to be with threads.



I guess I should do something like this, instead of using the GameTaskQueue:



OneCustomObject object = OneCustomObjet();
game.lock();
game.doSomething(object);
game.unlock();



I havent tried it yet. But what do you think, should it be the right way to threat with the JME Game thread?

Umm, you are locking the OpenGL thread itself.  I believe this could lead to horrible FPS performance.  Maybe using GameTaskQueue would be a better idea.



But I could be ALL sorts of wrong here…

Both ways are possible, as described here:



http://jmonkeyengine.com/wiki/doku.php?id=simplegame_to_standardgame&s=standardgame#creating_our_standardgame



But it’s right that using GameTaskQueue leads to a better performance, as it doesn’t block the GL thread.



Anyway both solutions do not apply to BaseGame (the old way), but for StandardGame. So must I migrate my game, no other choice, but better as StandardGame is the recommended way for production impls.

You can easily use GameTask's with BaseGame.

All you have to do is call its update and render methods when overriding BaseGames methods…



Locking is only useful to ensure thread safety, so you don't get IndexOutOfBounds exceptions and stuff.



But you need to use GameTasks to ensure that certain things get executed inside the OpenGL thread, (all calls to GL11 Methods,like SkyBox.preloadTextures() for example) else you will get NullpointerExceptions.

Hi, Core-Dump,



Why thread-locking (StandardGame lock / unlock) is not safety as GameTaskQueue?



According to that wiki I mentioned before, both solutions are applicable.



In thread-locking the matter is that you block the GL-thread and then your game gets paused until you unlock it.



But in terms of security, isn't it safe as in cases like you mentioned (calls to GL11)?

i dont know all the details, but some OpenGL methods need access to the OpenGL context, which only exists in one thread because OpenGL is not designed for Multithrediness.

Thats what GameTasks are for, to inject methods who need access to the OpenGL thread into the correct Thread.



lock() only makes sure that the update/render loop is stopped, so you can safely attach new elements to the scene graph.



But thats only how i think it works :slight_smile:



Maybe someone else with a deeper knowledge of the system can shed some more light on it.



edit:

more information about jme’s multithreading

Core-Dump, I was registering a problem with GL11 when initializing Font3D. I posted it here: http://www.jmonkeyengine.com/jmeforum/index.php?topic=7389.0



I will use GameTaksQueue as described there and following your recommandation. I hope it will solve the problem :wink: