Advertisement
Guest User

UnityScheduler.cs

a guest
Sep 26th, 2015
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.35 KB | None | 0 0
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using UnityEngine;
  7. using SyncronizationContextQueue = System.Collections.Concurrent.BlockingCollection<System.Collections.Generic.KeyValuePair<System.Threading.SendOrPostCallback, object>>;
  8.  
  9. public class UnityScheduler : MonoBehaviour
  10. {
  11.     public static UnityScheduler Instance { get; private set; }
  12.     public static readonly UnityTaskScheduler MainThread = new UnityTaskScheduler();
  13.  
  14.     private UnitySynchronizationContext synchronizationContext;
  15.  
  16.     private void Awake()
  17.     {
  18.         if (Instance != null)
  19.         {
  20.             throw new NotSupportedException("UnityScheduler already exists.");
  21.         }
  22.         Instance = this;
  23.  
  24.         DontDestroyOnLoad(gameObject);
  25.         synchronizationContext = new UnitySynchronizationContext();
  26.         SynchronizationContext.SetSynchronizationContext(synchronizationContext);
  27.     }
  28.  
  29.     private void Update()
  30.     {
  31.         Task task;
  32.         while (MainThread.mainThreadQueue.TryTake(out task))
  33.         {
  34.             MainThread.ExecuteTask(task);
  35.         }
  36.  
  37.         synchronizationContext?.Run(); // execute continuations
  38.     }
  39.  
  40.     #region Nested classes
  41.     private class UnitySynchronizationContext : SynchronizationContext
  42.     {
  43.         private readonly SyncronizationContextQueue queue = new SyncronizationContextQueue();
  44.  
  45.         public override void Post(SendOrPostCallback d, object state)
  46.         {
  47.             queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
  48.         }
  49.  
  50.         public void Run()
  51.         {
  52.             KeyValuePair<SendOrPostCallback, object> workItem;
  53.             while (queue.TryTake(out workItem))
  54.             {
  55.                 workItem.Key(workItem.Value);
  56.             }
  57.         }
  58.     }
  59.  
  60.     public class UnityTaskScheduler : TaskScheduler
  61.     {
  62.         public readonly BlockingCollection<Task> mainThreadQueue = new BlockingCollection<Task>();
  63.  
  64.         protected override IEnumerable<Task> GetScheduledTasks()
  65.         {
  66.             return mainThreadQueue;
  67.         }
  68.  
  69.         protected override void QueueTask(Task task)
  70.         {
  71.             mainThreadQueue.Add(task);
  72.         }
  73.  
  74.         protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
  75.         {
  76.             if (Thread.CurrentThread.ManagedThreadId != 1)
  77.             {
  78.                 return false;
  79.             }
  80.  
  81.             return TryExecuteTask(task);
  82.         }
  83.  
  84.         public void ExecuteTask(Task task)
  85.         {
  86.             var result = TryExecuteTask(task);
  87.             if (result == false)
  88.             {
  89.                 throw new InvalidOperationException();
  90.             }
  91.         }
  92.     }
  93.     #endregion
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement