Sunday, 12 May 2013

C++ Threading on Windows Phone 8

I have to admit, the whole multi-thread paradigm for Windows 8 and Windows Phone had me a little lost, so I have been fiercely avoiding it until really needing it for loading FBX animations dynamically.

The problem was that all the examples out there seemed to always call WinRT system operations, which made things confusing at first.

But in the end though, it turned out to be super simple.
 // Get a reference to current thread
 auto currentThread = Concurrency::task_continuation_context::use_current();

 Concurrency::create_task([this]  
 {  
      // This part is run on another thread  
      moveVerticesToOrigin();  
 }).then([this]()  
 {  
      // This part runs back on the original thread  
      movedVerticesToOrigin();  
 },  
 // schedules then() part to run in the current thread  
 currentThread );  

The first part of create_task runs moveVerticesToOrigin on another thread.
The then part runs back on the original thread create_task was called.

Simple!


Here's another example showing you how to pass parameters around
 // Get a reference to current thread
 auto currentThread = Concurrency::task_continuation_context::use_current();

 // I will copy the variable textFileData in the lambda below
  CCText textFileData = fileData;  
   
 // This lambda opens up with this and textFileData  
 // Which means that it'll make a copy of both those variables.  
 Concurrency::create_task([this, textFileData]  
 {  
      // Uses the copied version of textFileData to run this->loadData  
      bool loaded = loadData( textFileData.buffer );  
   
      // Returns a boolean  
      return loaded;  
 }).then([this](bool loaded)  
 {  
      // The loaded boolean is picked up from the first function's return  
   
      // This stuff runs on the original thread.  
      if( loaded )  
      {  
           this->loaded();  
      }  
      else  
      {  
           CCText script = "CCPrimitive3D.Loaded( ";  
           script += primitiveID.buffer;  
           script += " );";  
           CCAppManager::WebJSRunJavaScript( script.buffer, false, false );  
      }  
 }, currentThread );  

In our first function we make a copy of the textFileData parameter from outside the function, then use it on another thread.

We then pass the result loaded, into the then function which is run back on the original thread.

So there! It's actually super easy :)