Add CurrentThreadScheduler

This commit is contained in:
TORISOUP 2018-07-05 23:32:44 +09:00
parent 51e470950e
commit ac8a4dd2cc
9 changed files with 274 additions and 153 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0700fb042f010694782d238049678651
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<TaskChain> queue;
private static Queue<TaskChain> GetQueue()
{
return queue;
}
private static void SetQueue(Queue<TaskChain> newQueue)
{
queue = newQueue;
}
public void Enqueue(TaskChain item)
{
var q = GetQueue();
if (q == null)
{
q = new Queue<TaskChain>(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<TaskChain> queue)
{
while (queue.Count > 0)
{
var chain = queue.Dequeue();
while (true)
{
var status = chain.Next();
if (status != ExecutionStatus.Continue)
{
break;
}
}
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 21979cc7137a17d4ea8b6202381a02d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<TaskChain> m_taskQueue = new LockQueue<TaskChain>();
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<TaskChain> m_taskQueue = new LockQueue<TaskChain>();
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()
{
}
}
}
}

View File

@ -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<TaskChain> m_queue = new MonitorQueue<TaskChain>();
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<TaskChain> queue = (MonitorQueue<TaskChain>)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<TaskChain> m_queue = new MonitorQueue<TaskChain>();
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<TaskChain> queue = (MonitorQueue<TaskChain>)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
}
}
}