diff --git a/Scripts/UniTask/Scheduler.meta b/Scripts/UniTask/Scheduler.meta new file mode 100644 index 000000000..efdb87bad --- /dev/null +++ b/Scripts/UniTask/Scheduler.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0700fb042f010694782d238049678651 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/UniTask/Scheduler/CurrentThreadScheduler.cs b/Scripts/UniTask/Scheduler/CurrentThreadScheduler.cs new file mode 100644 index 000000000..2d6c00161 --- /dev/null +++ b/Scripts/UniTask/Scheduler/CurrentThreadScheduler.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace UniTask +{ + public static partial class Scheduler + { + private static IScheduler currentThread; + + public static IScheduler CurrentThread + { + get { return currentThread ?? (currentThread = new CurrentThreadScheduler()); } + } + + public class CurrentThreadScheduler : IScheduler + { + [ThreadStatic] + private static Queue queue; + + private static Queue GetQueue() + { + return queue; + } + + private static void SetQueue(Queue newQueue) + { + queue = newQueue; + } + + public void Enqueue(TaskChain item) + { + var q = GetQueue(); + + if (q == null) + { + q = new Queue(5); + q.Enqueue(item); + SetQueue(q); + + try + { + Trampoline.Run(q); + } + finally + { + SetQueue(null); + } + } + else + { + q.Enqueue(item); + } + } + + #region IDisposable Support + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + var queue = GetQueue(); + if (queue != null) queue.Clear(); + SetQueue(null); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + } + + #endregion + } + + static class Trampoline + { + public static void Run(Queue queue) + { + while (queue.Count > 0) + { + var chain = queue.Dequeue(); + + while (true) + { + var status = chain.Next(); + if (status != ExecutionStatus.Continue) + { + break; + } + } + } + } + } + } +} diff --git a/Scripts/UniTask/Scheduler/CurrentThreadScheduler.cs.meta b/Scripts/UniTask/Scheduler/CurrentThreadScheduler.cs.meta new file mode 100644 index 000000000..57b7907fd --- /dev/null +++ b/Scripts/UniTask/Scheduler/CurrentThreadScheduler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21979cc7137a17d4ea8b6202381a02d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/UniTask/StepScheduler.cs b/Scripts/UniTask/Scheduler/StepScheduler.cs similarity index 96% rename from Scripts/UniTask/StepScheduler.cs rename to Scripts/UniTask/Scheduler/StepScheduler.cs index a394763e9..76248017c 100644 --- a/Scripts/UniTask/StepScheduler.cs +++ b/Scripts/UniTask/Scheduler/StepScheduler.cs @@ -1,52 +1,52 @@ -namespace UniTask -{ - public static partial class Scheduler - { - private static StepScheduler mainThread; - - public static StepScheduler MainThread - { - get - { - if (mainThread != null) return mainThread; - mainThread = new StepScheduler(); - MainThreadDispatcher.Initialize(); - return mainThread; - } - } - - public class StepScheduler : IScheduler - { - LockQueue m_taskQueue = new LockQueue(); - - public void Enqueue(TaskChain item) - { - m_taskQueue.Enqueue(item); - } - - TaskChain m_chain; - - public int UpdateAndGetTaskCount() - { - if (m_chain != null) - { - var status = m_chain.Next(); - if (status == ExecutionStatus.Continue) - { - // m_item継続中 - return m_taskQueue.Count; - } - m_chain = null; - } - - int count; - m_chain = m_taskQueue.Dequeue(out count); - return count; - } - - public void Dispose() - { - } - } - } -} +namespace UniTask +{ + public static partial class Scheduler + { + private static StepScheduler mainThread; + + public static StepScheduler MainThread + { + get + { + if (mainThread != null) return mainThread; + mainThread = new StepScheduler(); + MainThreadDispatcher.Initialize(); + return mainThread; + } + } + + public class StepScheduler : IScheduler + { + LockQueue m_taskQueue = new LockQueue(); + + public void Enqueue(TaskChain item) + { + m_taskQueue.Enqueue(item); + } + + TaskChain m_chain; + + public int UpdateAndGetTaskCount() + { + if (m_chain != null) + { + var status = m_chain.Next(); + if (status == ExecutionStatus.Continue) + { + // m_item継続中 + return m_taskQueue.Count; + } + m_chain = null; + } + + int count; + m_chain = m_taskQueue.Dequeue(out count); + return count; + } + + public void Dispose() + { + } + } + } +} diff --git a/Scripts/UniTask/StepScheduler.cs.meta b/Scripts/UniTask/Scheduler/StepScheduler.cs.meta similarity index 100% rename from Scripts/UniTask/StepScheduler.cs.meta rename to Scripts/UniTask/Scheduler/StepScheduler.cs.meta diff --git a/Scripts/UniTask/ThreadPoolScheduler.cs b/Scripts/UniTask/Scheduler/ThreadPoolScheduler.cs similarity index 100% rename from Scripts/UniTask/ThreadPoolScheduler.cs rename to Scripts/UniTask/Scheduler/ThreadPoolScheduler.cs diff --git a/Scripts/UniTask/ThreadPoolScheduler.cs.meta b/Scripts/UniTask/Scheduler/ThreadPoolScheduler.cs.meta similarity index 100% rename from Scripts/UniTask/ThreadPoolScheduler.cs.meta rename to Scripts/UniTask/Scheduler/ThreadPoolScheduler.cs.meta diff --git a/Scripts/UniTask/ThreadScheduler.cs b/Scripts/UniTask/Scheduler/ThreadScheduler.cs similarity index 97% rename from Scripts/UniTask/ThreadScheduler.cs rename to Scripts/UniTask/Scheduler/ThreadScheduler.cs index 8695b3efb..60c425bba 100644 --- a/Scripts/UniTask/ThreadScheduler.cs +++ b/Scripts/UniTask/Scheduler/ThreadScheduler.cs @@ -1,101 +1,101 @@ -using System; -using System.Threading; - -namespace UniTask -{ - public static partial class Scheduler - { - private static IScheduler singleWorkerThread; - - public static IScheduler SingleWorkerThread - { - get { return singleWorkerThread ?? (singleWorkerThread = new ThreadScheduler()); } - } - - public class ThreadScheduler : IScheduler - { - MonitorQueue m_queue = new MonitorQueue(); - - Thread m_thread; - - public ThreadScheduler() - { - // start worker thread - m_thread = new Thread(new ParameterizedThreadStart(Worker)); - m_thread.Start(m_queue); - } - - static void Worker(Object arg) - { - MonitorQueue queue = (MonitorQueue)arg; - while (true) - { - var chain = queue.Dequeue(); - if (chain == null) - { - break; - } - - while (true) - { - var status = chain.Next(); - if (status != ExecutionStatus.Continue) - { - break; - } - } - } - - // end - } - - public void Enqueue(TaskChain item) - { - m_queue.Enqueue(item); - } - - #region IDisposable Support - - private bool disposedValue = false; // 重複する呼び出しを検出するには - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: マネージ状態を破棄します (マネージ オブジェクト)。 - if (m_thread != null) - { - m_queue.Enqueue(null); - m_thread.Join(); - m_thread = null; - } - } - - // TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。 - // TODO: 大きなフィールドを null に設定します。 - - disposedValue = true; - } - } - - // TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。 - // ~ThreadScheduler() { - // // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 - // Dispose(false); - // } - - // このコードは、破棄可能なパターンを正しく実装できるように追加されました。 - public void Dispose() - { - // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 - Dispose(true); - // TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。 - // GC.SuppressFinalize(this); - } - - #endregion - } - } -} +using System; +using System.Threading; + +namespace UniTask +{ + public static partial class Scheduler + { + private static IScheduler singleWorkerThread; + + public static IScheduler SingleWorkerThread + { + get { return singleWorkerThread ?? (singleWorkerThread = new ThreadScheduler()); } + } + + public class ThreadScheduler : IScheduler + { + MonitorQueue m_queue = new MonitorQueue(); + + Thread m_thread; + + public ThreadScheduler() + { + // start worker thread + m_thread = new Thread(new ParameterizedThreadStart(Worker)); + m_thread.Start(m_queue); + } + + static void Worker(Object arg) + { + MonitorQueue queue = (MonitorQueue)arg; + while (true) + { + var chain = queue.Dequeue(); + if (chain == null) + { + break; + } + + while (true) + { + var status = chain.Next(); + if (status != ExecutionStatus.Continue) + { + break; + } + } + } + + // end + } + + public void Enqueue(TaskChain item) + { + m_queue.Enqueue(item); + } + + #region IDisposable Support + + private bool disposedValue = false; // 重複する呼び出しを検出するには + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: マネージ状態を破棄します (マネージ オブジェクト)。 + if (m_thread != null) + { + m_queue.Enqueue(null); + m_thread.Join(); + m_thread = null; + } + } + + // TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。 + // TODO: 大きなフィールドを null に設定します。 + + disposedValue = true; + } + } + + // TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。 + // ~ThreadScheduler() { + // // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 + // Dispose(false); + // } + + // このコードは、破棄可能なパターンを正しく実装できるように追加されました。 + public void Dispose() + { + // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 + Dispose(true); + // TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。 + // GC.SuppressFinalize(this); + } + + #endregion + } + } +} diff --git a/Scripts/UniTask/ThreadScheduler.cs.meta b/Scripts/UniTask/Scheduler/ThreadScheduler.cs.meta similarity index 100% rename from Scripts/UniTask/ThreadScheduler.cs.meta rename to Scripts/UniTask/Scheduler/ThreadScheduler.cs.meta