Multythreading, GameStates and StandardGame

Hello



I have started my adventure through StandardGame, Multythreading and GameStates, and I gone really confused.



I already read everything I can in the wiki, and I explored source code in jME. I am also reading (for the 10000th time) the Sun tutorial about concurrency, to understand the Java 5 new interfaces and classes.



And my questions are…



  • Are GameTasks a way to insert code, in the main OpenGL thread queue, from outside?

  • If, yes! Are not GameTasks a way of creating new Threads?

  • Is lock a way to pause OpenGL thread in a safe way?

  • What about creating other threads, for example to load objects, to load music, to load other data or to communicate with a server? They need to be implemented this way or they can be separated threads? Considering that many of them may not manage data that need to be inserted in the OpenGL main thread.

  • What is the role of GameStates in this scenario?



Thanks.

Even though Darkfrog would be a lot better at this than me, I will try to answer your questions.



  • Yes, GameTasks are going to be executed by the GL thread whenever is safe for it to do so.

  • No, GameTasks are not new threads, just pieces of code that will be executed when their time comes.

  • game.lock() is one way of locking the thread in a safe position, but DF has pointed out that the use of the queue is preferred. Some things can only be accomplished this way.

  • You are free to create as many threads as you want, and have them do what you want, except whenever something needs to go in the GL thread, then you need to use the game queue

  • GameStates are just a neat way to organize your game in such a way that you might have several interchangeable root nodes. Each State has a root note and will be drawn when active.



Hope it helps.

This topic sounds familiar…I think I've seen it somewhere before.  :roll:


Ender said:

Are GameTasks a way to insert code, in the main OpenGL thread queue, from outside?


Yes

Ender said:

If, yes! Are not GameTasks a way of creating new Threads?


No, no new threads are created, but rather the execution of the code in the GameTask is done in the OpenGL thread itself which actually causes that thread to be blocked, which is why you should only do it when necessary to maintain a good multithreading structure in your code.

Ender said:

Is lock a way to pause OpenGL thread in a safe way?


Yes, but even though the OpenGL thread may be locked certain things can still only be done in the OpenGL thread.  However, other things that need not be done in the OpenGL thread, but require thread-safety, can make good use of lock() and unlock().

Ender said:

What about creating other threads, for example to load objects, to load music, to load other data or to communicate with a server? They need to be implemented this way or they can be separated threads? Considering that many of them may not manage data that need to be inserted in the OpenGL main thread.


If they need to inject anything in OpenGL they would need to mimic this methodology (or you could implement your own method if needed).  However, many aspects of games have nothing to do with the on-screen rendering and thus can be in their own threads entirely.  Remember though to use threads where they make sense though rather than just using them as a mystical feature to "make your game go faster".

Ender said:
What is the role of GameStates in this scenario?


GameStates are really a different concept and in many ways are completely abstract of this.  GameStates are always "run" in the OpenGL thread, so it can also be a good way of injecting things into the OpenGL thread without all the hassle, but you then suffer from EVERYTHING being run in the OpenGL thread, so you have to be careful about where you put code.

Hope that helps.
duenez said:

Even though Darkfrog would be a lot better at this than me, I will try to answer your questions.


  • Yes, GameTasks are going to be executed by the GL thread whenever is safe for it to do so.

  • No, GameTasks are not new threads, just pieces of code that will be executed when their time comes.

  • game.lock() is one way of locking the thread in a safe position, but DF has pointed out that the use of the queue is preferred. Some things can only be accomplished this way.

  • You are free to create as many threads as you want, and have them do what you want, except whenever something needs to go in the GL thread, then you need to use the game queue

  • GameStates are just a neat way to organize your game in such a way that you might have several interchangeable root nodes. Each State has a root note and will be drawn when active.



Hope it helps.


We responded at the same time. :)

Actually, game.lock() is the preferred method...when it works, but often only GameTaskQueue will accomplish the task.
darkfrog said:

We responded at the same time. :)


Damn!, yes, I have been swapped, twice in 50 seconds you have agreed with me  :D (well almost perfectly, except for the game.lock() )

Don't let that head of yours swell…consider that many of the people here would consider you being in agreement with me shows your lack of intellect. :wink:

I was actually thinking the other way around… that you were agreeing with me :stuck_out_tongue: since in both places I posted first, that is (it absolutely has nothing to do with the fact that I consider myself to be first in everything  :D)



Now, whether that is good or bad, well I don't know… but it sure is weird.  :smiley:

hehe

Thanks for the very clear answers.



Unfortunatelly I discovered that this answers lead me to new questions. :smiley:


  1. Which are these pieces of code that absolutelly need to be executed in the OpenGL thread?
  2. Does StandardGame resolve this problem form me?
  3. How can I mix separated thread with a StandardGame based game?



    For the 3rd question I want to take in consideration an obvious example. A common case.

    Imagine I want to implement a thread, that separatedly preloads a bunch of models, audio and textures, to show a part of the game, that is getting closer to the player. All these while the game is already running.

    I can guess, in this case, that the file opening, loading and parsing of the file format data can be done in a separate thread. They are all J2SE feasable operations.



    a) Reading a file from the disk.

    b) Parsing its content.

    c) And eventualy managing it someway, if needed, to be usable by the game.



    So I should be able to use the StandardGame way of setting up an application (a simple class with a main method) and also create a thread that, sometime and someway will be started to achieve this task and, then, putted again to sleep when it has completed.



    But, at what point should I pass everything to the OpenGL thread? At the creation of the models (i.e. new Box()), or some steps later at the update calls for the geometries or rendering?



    Thanks.

Doubly unfortunately for you, some of your questions don't have a definite answer!  :oops:


  1. This is a very hard question… The tight answer is whatever uses the lwjgl API to work on OGL. Now, this might not seem like a very useful answer, and you are right… It is not. The reason being that there is not definite way of telling whether a call needs to be done in the GL thread or not. There has been some discussion about making this explicit in jME, but so fat it is not.



      Your best guess is that if it is messing with rendering or context, then it IS a GL call. I would go about not putting it, and when problems happen, putting them in GL. You might be conservative and work your way the other way.


  2. Nope, it does not solve any problem. StandardGame does nothing to ensure you know what you are doing. It is only you who know which parts need to be GL. It only gives you the API for doing so with the GameTaskQueue.


  3. The answer to this is fairly easy… The way you would do it in normal Java… You might need a lock object somewhere to ensure synchronization or something, but in the end, you can fire up a thread pretty much anywhere, the tread would do whatever it needs to do, and communicate its actions in the normal way. The only difference is that, whenever it tries to do a GL call, it will use the Queue.



      In your example, You fire up a Thread with the files to read… In the thread you load the files, create the Spatials you need without attaching them to the scene graph, then send to the Queue all update methods (geometric, texture, light states, etc) and the actual attaching of the objects. And voila!, you have made the other threads aware of the changes (because they will presumably use the Queue and Futures to poll the scene graph).

Thanks a lot for your patience answering these questions.


duenez said:
Doubly unfortunately for you, some of your questions don't have a definite answer!  ://


Oh! This is the reason for I never found a wiki article or a forum thread listing "all calls" that need to be done in OpenGL thread. XD
Reading the forum threads and the wiki, I was, in fact, going to realize that this is the "Big Problem". :D

duenez said:
1) This is a very hard question... [...] There has been some discussion about making this explicit in jME, but so fat it is not.


:D Human beings created it. But now it is living and growing as if it was an living creature. :D

duenez said:
Your best guess is that if it is messing with rendering or context, then it IS a GL call.


Uncomfortable situation for me, because I like predictable behaviours. But, I can live with it.

duenez said:
2) Nope, it does not solve any problem.


So, basically, I could continue to work extending BaseGame or I can use StandardGame, but I have to manage calls to OpenGL thread by my self, in both cases.

duenez said:
3) The answer to this is fairly easy... The way you would do it in normal Java...


Thanks. This was a doubt that was frazzling me.

duenez said:
In your example [...]


Thanks for the explanation. It is exactly what I need to know.

I am going to develop a game (as many others here XD ). At the moment I am almost alone, even if I have 2 IT students that would help me in the spare time. But they are really busy.

I am following a very "project engineering" kind of approach, and currently I am collecting every tech information I can to start creating a schematic rappresentation of the game architecture. I am trying to be more abstract I can in this step. This to optimize the effort spent in the future developing steps. I cannot use a xtreme programming approach because the members live in different places and, moreover, we cannot be sure to be everyday working on it (spare time project). Anyway I found a similar approach that do not consider the Time factor in a such tight way and that is based more on really little tasks to achieve.

Unfortunately, understanding the relations between OpenGL and Threads is something that cannot be postpone easily. :D
Ender said:

Oh! This is the reason for I never found a wiki article or a forum thread listing "all calls" that need to be done in OpenGL thread. XD

There is such a thread actually, but i couldn't find it anymore :)
darkfrog said:

GameStates are really a different concept and in many ways are completely abstract of this.

GameStates can be used for anything, but the update and render methods are always executed in the OpenGL thread, so it's not advisable to do "everything" within GameStates as you are no longer multi-threading at all, but writing everything within a single thread.



GameStates can help in multi-threading in the sense you can add "aspects" to your game on-the-fly after processing something in another thread.  For example, I can load a bunch of information in a background thread and build a GameState to display the content once that is completed and add it to the game itself rather than blocking the game's update process until it is finished loading or doing some hacky "state-changes" within a Game itself.

Ah I see… Then I think I got it right the first time… phew  XD