views:

222

answers:

3

If you make a game architecture that splits up system components (IE, rendering, physics, logic, input, scripting, etc) into different threads, how do you handle cases where real-time communication is necessary?

For example, if a script wants to draw a box on the screen, it would ideally do this when the rendering component issues a "FrameDrawn" event so that the box would be drawn on top of the screen, at the end of each frame draw. How is this possible if the scripting component and the rendering component are on different threads from each other?

A: 

What you're asking for isn't really possible, which is why the general rule is to only have one UI thread. If another thread wants to show something on the screen, it should send a message to the UI thread which will show the message when it is rendering.

Tal Pressman
+1  A: 

Typically the rendering thread is the only one to ever draw things to the screen. However, since threads can communicate, it's possible for say the scripting thread to tell the rendering thread "Hey, I want to draw a box next frame."

The way our project handles thread communication is in one of two ways. For something that is dynamically edited - lists of objects, moving vehicles, et cetera, we create a mutex that locks the data when it is being changed. If the renderer wants to draw it, but the update thread is deleting that object, the renderer will have to wait. For other things, like the ui, we just have global flags that are written by the ui thread, and read by the renderer, so no mutex is required.

Andrei Krotkov
+1  A: 

What most games will have is a massive pile of data and several threads referring to some subset of that data as needed. Communication between threads is rarely explicit and more commonly is implicit, done through a change in the data caused by one thread and noticed later by a second thread. The changes are protected by mutexes, semaphores, or other low-level synchronisation primitives.

For your drawing example, the scripting thread would change some data in the GUI component and the rendering thread, next time it renders the GUI, would see that new data and draw the box accordingly.

Bear in mind however that most game developers don't thread things quite so much as is in your example, partly because it's difficult to do that effectively with a model that shares so much data and relies on low level locking for correctness. Ideally more game developers would move towards a model that shares less data but that is difficult due to the soft-real-time presentation response requirements.

Kylotan