using System; using System.Collections; using System.Collections.Generic; using System.Threading; using UnityEngine; using System.Diagnostics; namespace Unity.Services.Relay.Scheduler { /// /// Provides the means to schedule tasks on a background thread or the /// main thread. Also allows for creation of co-routines from classes that do /// not inherit from MonoBehaviour. /// /// This is thread safe, through it must be constructed on the main thread. /// /// public sealed class TaskSchedulerThreaded : TaskScheduler { private Queue m_mainThreadTaskQueue = new Queue(); private object m_lock = new object(); private Thread m_mainThread = null; /// /// Constructs a new instances of the Task Scheduler. This must be on the main /// thread as a reference to the thread is captured. /// void Start() { m_mainThread = System.Threading.Thread.CurrentThread; } /// /// Determines whether the current thread is the main thread. /// /// /// Whether or not this thread is the main thread. public override bool IsMainThread() { return (m_mainThread == System.Threading.Thread.CurrentThread); } /// /// Schedules a new task on a background thread. /// /// /// The task that should be executed on a background thread. public override void ScheduleBackgroundTask(Action task) { ThreadPool.QueueUserWorkItem((object state) => { task(); }); } /// /// Schedules a new task on the main thread. The task will be executed during the /// next update. /// /// /// The task that should be executed on the main thread. public override void ScheduleMainThreadTask(Action task) { lock (m_lock) { m_mainThreadTaskQueue.Enqueue(task); } } /// /// The update method which is called every frame. This executes any queued main /// thread tasks. /// void Update() { Queue taskQueue = null; lock (m_lock) { taskQueue = new Queue(m_mainThreadTaskQueue); m_mainThreadTaskQueue.Clear(); } foreach (Action action in taskQueue) { action(); } } } }