Skip to content

Instantly share code, notes, and snippets.

@NTaylorMullen
Last active December 15, 2015 14:58
Show Gist options
  • Save NTaylorMullen/5278040 to your computer and use it in GitHub Desktop.
Save NTaylorMullen/5278040 to your computer and use it in GitHub Desktop.
Simplified High Output timer
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace EndGate.Core.Utilities
{
internal class Looper : IDisposable
{
private object _updateLock;
private int _fps;
private int _running;
private List<LooperCallback> _callbacks;
public Looper()
{
// Default values
_updateLock = new object();
_running = 0;
_callbacks = new List<LooperCallback>();
}
public void AddCallback(LooperCallback callback)
{
lock (_updateLock)
{
_callbacks.Add(callback);
}
}
public void RemoveCallback(LooperCallback callback)
{
lock (_updateLock)
{
_callbacks.Remove(callback);
}
}
public void Start()
{
ThreadPool.QueueUserWorkItem(Run);
}
private void Run(object state)
{
var timer = Stopwatch.StartNew();
long elapsedTime;
if (Interlocked.Exchange(ref _running, 1) == 0)
{
while (true)
{
// This will never have contention unless the user is setting the fps, callback or stopping the looper
lock (_updateLock)
{
// Verify we're still running
if (_running == 0)
{
break;
}
foreach (LooperCallback callback in _callbacks)
{
elapsedTime = timer.ElapsedMilliseconds - callback.LastTriggered;
if (elapsedTime >= callback.TriggerFrequency)
{
callback.LastTriggered = timer.ElapsedMilliseconds;
callback.Callback();
}
}
Thread.Yield();
}
}
}
timer.Stop();
}
public void Dispose()
{
lock (_updateLock)
{
_callbacks.Clear();
_callbacks = null;
Interlocked.Exchange(ref _running, 0);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EndGate.Core.Utilities
{
internal class LooperCallback
{
private int _fps;
public LooperCallback()
{
}
public LooperCallback(int fps, Action callback)
{
Fps = fps;
Callback = callback;
}
public int TriggerFrequency { get; private set; }
public long LastTriggered { get; set; }
public Action Callback { get; set; }
public int Fps
{
get
{
return _fps;
}
set
{
_fps = value;
TriggerFrequency = 1000 / _fps;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment