Coherent GT has support for multithreading which can greatly enhance your game's performance at an added complexity cost.
When using the async mode, most calls to Coherent GT are deferred and executed on another thread. We guarantee that your callbacks and event listeners will still be run on the main thread (the thread that they are registered on, that is).
Furthermore, Coherent GT will never deadlock but race conditions are unavoidable and as such the user must protect against them by himself.
Enabling the async mode is as simple as checking the Run Asynchronously option in the CoherentGTSystem component.
Note that some methods are always synchronous and will block your main thread no matter what the current mode is. These methods are:
Coherent.UIGT.View.Destroy
and destroying the view component.Coherent.UIGT.View.GoForward
, Coherent.UIGT.View.LoadURL
, etc.)Coherent.UIGT.View.IMESetComposition
, etc.) Additionaly the initialization and uninitialization of the UI System are also synchronous.Asynchronous mode implies that the JavaScript execution is also deferred on the UI thread. This may require some changes if your existing code depends on the fact that up to now, callbacks were executed in the same stack.
Consider the following communication:
C#:
void Bar() { // Code } // During initialization view.BindCall("Bar", (System.Action)this.Bar); // During your main loop view.TriggerEvent("foo");
JS:
engine.on("foo", function fooHandler() { // Code engine.trigger("bar"); });
Calling view.TriggerEvent("foo")
in the synchronous mode will execute the methods in the following simplified callstack:
Callstack |
---|
Bar |
JavaScript fooHandler |
View TriggerEvent |
GameLoop |
In the async mode you get no such guarantee. fooHandler
will be executed whenever the UI thread gets to it and Bar
will be executed during the first View.Layout
or View.ExecuteJSTimers
after fooHandler
has completed.
Let's look at a more concrete example
C#:
void StartGame() { // Initialize the game } // During initialization view.BindCall("StartGame", (System.Action)this.StartGame);
JS:
startButton.addEventListener("click", function () { engine.trigger("StartGame"); doSomethingAssumingTheGameHasStarted(); });
If you are running in a synchronous mode, this code will work fine. When the button is clicked, the engine will call StartGame
immediately, which will in turn initialize the game. Thus, by the time engine.call("StartGame")
returns you can assume that everything is ready.
This assumption does not hold in asynchronous mode as the execution of StartGame
will be delayed. To cope with this, use another event to notify the JS that everything is ready:
C#:
void StartGame() { // Initialize the game view.TriggerEvent(GameStarted); } // During initialization view.BindCall("StartGame", (System.Action)this.StartGame);
JS:
startButton.addEventListener("click", function () { engine.call("StartGame"); }); engine.on("GameStarted", function () { doSomethingAssumingTheGameHasStarted(); });
Knowing what Coherent GT does under the hood might be useful if you run into any problems.
If you are to call Coherent.UIGT.View.Layout
for example, instead of running the layout immediately, Coherent GT will now post a job task to another thread (the UI thread) via a queue. The UI thread waits for any tasks to be posted and executes them in order. Note that Coherent will wait for the previous call to layout for this view to complete before issuing the next command in the interest of preventing overtasking the UI thread.
The UI thread can communicate to the main thread via another task queue. For example, when the time for execution of your event handlers (registered via Coherent.UIGT.View.RegisterForEvent
or through your custom view listener) comes, the UI thread will ask the main thread to run the callback. This guarantees that your code runs only on the main thread. Most of these events will be triggered during the call to Coherent.UIGT.View.Layout
.
Note that there are no changes to Coherent.UIGT.ViewRenderer
and you can still paint the view on your rendering thread without complications.