Created
August 19, 2016 13:56
-
-
Save RevenantX/6982836e63b778d18bae2994d171918c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IGameTask | |
{ | |
void Execute(); | |
} | |
class GameTaskManager : IDisposable | |
{ | |
class TaskThread : IDisposable | |
{ | |
private bool _isRunning; | |
private readonly AutoResetEvent _autoResetEvent; | |
private readonly Thread _thread; | |
private readonly Queue<IGameTask> _pendingTasks; | |
private readonly object _taskLock = new object(); | |
public int TasksCount | |
{ | |
get { return _pendingTasks.Count; } | |
} | |
public TaskThread() | |
{ | |
_pendingTasks = new Queue<IGameTask>(); | |
_autoResetEvent = new AutoResetEvent(true); | |
_isRunning = true; | |
_thread = new Thread(ThreadMethod) {IsBackground = true}; | |
_thread.Start(); | |
} | |
private void ThreadMethod() | |
{ | |
while (_isRunning) | |
{ | |
IGameTask task = null; | |
lock (_pendingTasks) | |
{ | |
if (_pendingTasks.Count > 0) | |
{ | |
task = _pendingTasks.Dequeue(); | |
} | |
} | |
if (task != null) | |
{ | |
lock(_taskLock) | |
task.Execute(); | |
} | |
else | |
{ | |
_autoResetEvent.WaitOne(); | |
} | |
} | |
} | |
public void Dispose() | |
{ | |
_isRunning = false; | |
Clear(true); | |
_autoResetEvent.Set(); | |
_thread.Join(); | |
} | |
public void Clear(bool wait) | |
{ | |
lock (_pendingTasks) | |
{ | |
_pendingTasks.Clear(); | |
} | |
if (wait) | |
{ | |
lock (_taskLock) | |
{ | |
} | |
} | |
} | |
public void Enqueue(IGameTask task) | |
{ | |
lock (_pendingTasks) | |
{ | |
_pendingTasks.Enqueue(task); | |
} | |
_autoResetEvent.Set(); | |
} | |
} | |
private readonly Dictionary<Type, TaskThread> _taskThreads = new Dictionary<Type, TaskThread>(); | |
public int GetActiveTasks<T>() where T : IGameTask | |
{ | |
TaskThread t; | |
if (!_taskThreads.TryGetValue(typeof(T), out t)) | |
{ | |
return 0; | |
} | |
return t.TasksCount; | |
} | |
public void Dispose() | |
{ | |
foreach (var taskThread in _taskThreads) | |
{ | |
taskThread.Value.Dispose(); | |
} | |
_taskThreads.Clear(); | |
} | |
public void RunTask<T>(T task) where T : IGameTask | |
{ | |
TaskThread t; | |
Type taskType = typeof(T); | |
if (!_taskThreads.TryGetValue(taskType, out t)) | |
{ | |
t = new TaskThread(); | |
_taskThreads.Add(taskType, t); | |
} | |
t.Enqueue(task); | |
} | |
public void ClearAllTasks<T>(bool wait) where T : IGameTask | |
{ | |
Type t = typeof(T); | |
foreach (var taskThread in _taskThreads) | |
{ | |
if(taskThread.Key == t) | |
taskThread.Value.Clear(wait); | |
} | |
} | |
public void ClearAllTasks(bool wait) | |
{ | |
foreach (var taskThread in _taskThreads) | |
{ | |
taskThread.Value.Clear(wait); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment