Sic10/SicUI/Controls/Common/AnimationQueue.cs

104 lines
2.0 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace SicUI.Controls.Common
{
public class AnimationQueue
{
private ConcurrentQueue<AnimationParameter> queue;
private AutoResetEvent eventHandler;
public event EventHandler<StatusUpdateArgs> StatusUpdated;
private bool idle;
private ReaderWriterLockSlim idleLocker;
private readonly string name;
public AnimationQueue(string name)
{
idleLocker = new ReaderWriterLockSlim();
eventHandler = new AutoResetEvent(false);
queue = new ConcurrentQueue<AnimationParameter>();
idle = true;
this.name = name;
Task.Run(() => Consume());
}
public void EnqueueStatus(AnimationParameter parameter)
{
queue.Enqueue(parameter);
try
{
idleLocker.EnterReadLock();
if (idle)
{
eventHandler.Set();
idle = false;
}
}
finally
{
idleLocker.ExitReadLock();
}
}
public AnimationParameter LastStatus
{
get;
private set;
}
private void Consume()
{
Thread.CurrentThread.Name = name;
while (true)
{
eventHandler.WaitOne();
AnimationParameter parameter = null;
if (queue.TryDequeue(out parameter))
{
LastStatus = parameter;
if (StatusUpdated != null)
{
try
{
idleLocker.EnterWriteLock();
idle = false;
}
finally
{
idleLocker.ExitWriteLock();
}
StatusUpdated(this, new StatusUpdateArgs() { Event = eventHandler, Parameter = parameter });
}
}
else
{
try
{
idleLocker.EnterWriteLock();
idle = true;
}
finally
{
idleLocker.ExitWriteLock();
}
}
}
}
}
public class StatusUpdateArgs : EventArgs
{
public AutoResetEvent Event { get; set; }
public AnimationParameter Parameter { get; set; }
}
public class AnimationParameter
{
public string Target { get; set; }
public string ArmA { get; set; }
public string ArmB { get; set; }
}
}