Last active
December 15, 2015 14:58
-
-
Save NTaylorMullen/5278040 to your computer and use it in GitHub Desktop.
Simplified High Output timer
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
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