For Android, iOS, Windows Phone, Windows, MacOS, Linux and probably a whole set of other platforms that support .Net natively. Try it, it's free!
If you are new to UniParallel, please read the post Using PTaskScheduler - UniParallel Unity package first.
Version 0.6 of the UniParallel package adds a new type of task scheduler called PSyncTaskScheduler which has the same functionalities of the PTaskScheduler adding to it the ability to execute a routine in the main game Thread after a task is finished.
Only 3 of types of tasks are supported, named slightly different:
- Use SyncImmediateTask if you want to schedule a task for immediate execution
- Use SyncTimedTask if you want to schedule a task for delayed execution
- Use SyncRepeatableTask to execute tasks a certain number of times on a interval
Infinite synchronized tasks are supported, obviously, since the purpose of the sync tasks is to execute another routine when finished.
And every starts with and instance of PSyncTaskScheduler
 [...]
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 // schedule your tasks
 [...]
 // check if there's any tasks finished and execute it's post completion routine
 scheduler.Update(); 
The line
scheduler.Update();Let's see an example of a immediate task that will execute a heavy operation in the background and notify the game when completed
 
 [...]
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 SyncImmediateTask task = new SyncImmediateTask(MethodThatCanBlockMyGame, MethodToRunAfterBlockingMethodIsDone);
 scheduler.Enqueue(task);
 [...]
 // The MonoBehaviour update loop
 void Upate()
 {
    scheduler.Update()
 }
 object MethodThatCanBlockMyGame()
 {
    // this is running in the background and allowing your game to continue smoothly
    Boolean isDone = true;
    // Do a few very heavy operations
    ThisIsGoingToTakeALongTime();
    // isDone is the argument passed to MethodToRunAfterBlockingMethodIsDone
    return isDone;
 }
 
 void MethodToRunAfterBlockingMethodIsDone(object result)
 {
   // this is running inside the game's main thread and MUST BE very light-weight code
   Boolean booleanResult = (Boolean) result;  // result is coming from  MethodThatCanBlockMyGame
   if(result)
   {
     Debug.Log("Completed successfully");
   }
   else
   {
     Debug.Log("Ooops");
   }
 }
Note the signatures of the methods MethodThatCanBlockMyGame and MethodToRunAfterBlockingMethodIsDone : they *must* work with only object types, the background method returning and object that will be passed as an argument to the method executed after the background routine is completed.
Let's take a look at the other 2 types of synchronized tasks. They are just as simple to use as immediate tasks. First, timed tasks
 
 [...]
 const int delay = 1000; // 1 second
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 SyncTimedTask timedTask = new SyncTimedTask(MethodToStartAfterDelay, MethodToExecuteAfterComplete, delay); 
 scheduler.Enqueue(timedTask);
 [...]
 // The MonoBehaviour update loop
 void Upate()
 {
    scheduler.Update()
 }
 object MethodToStartAfterDelay()
 {
    // this is running in the background, starting after the specified delay
    Integer calculationResult = DoSomeMath();
    return calculationResult;
 }
 
 void MethodToExecuteAfterComplete(object result)
 {   
   Debug.Log("The calculated number is "+result);   
 }
Then, SyncRepeatableTask tasks. This time of task is not only useful for executing heavy operations in background but also delayed repeatable operations that will result in something to be rendered, like a countdown timer
 
 [...]
 const int delay = 1000;// run every second ...
 const int executionCount = 10; // and 10 times
 
 int mInitialTimerValue = 10;
 PSyncTaskScheduler scheduler = new PSyncTaskScheduler();
 //count down 10 seconds
 SyncRepeatableTask repeatableTask = new SyncRepeatableTask(CountDown, OnEachCountDown, 
                delay, executionCount);
 scheduler.Enqueue(repeatableTask);
 // The MonoBehaviour update loop
 void Upate()
 {
    scheduler.Update()
 }
 
 object CountDown()
 {
    mInitialTimerValue--;
    return mInitialTimerValue;
 }
 
 void OnEachCountDown(object result)
 {   
   Debug.Log("The timer now is at "+result);   
   RenderTimer(mInitialTimerValue);
 }
 
No comments:
Post a Comment