62 lines
1.6 KiB
C#
62 lines
1.6 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Conjure.Arcade.Overlay
|
|
{
|
|
public class TickEngine
|
|
{
|
|
private readonly Action _tickAction;
|
|
private readonly int _targetFps;
|
|
private readonly CancellationTokenSource _cancellationSource;
|
|
private bool _isRunning;
|
|
|
|
public TickEngine(Action tickAction, int targetFps = 60)
|
|
{
|
|
_tickAction = tickAction;
|
|
_targetFps = targetFps;
|
|
_cancellationSource = new CancellationTokenSource();
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
if (_isRunning) return;
|
|
|
|
_isRunning = true;
|
|
Task.Run(RunTickLoop, _cancellationSource.Token);
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
_isRunning = false;
|
|
_cancellationSource.Cancel();
|
|
}
|
|
|
|
private async Task RunTickLoop()
|
|
{
|
|
var stopwatch = new Stopwatch();
|
|
var targetFrameTime = TimeSpan.FromSeconds(1.0 / _targetFps);
|
|
|
|
while (_isRunning && !_cancellationSource.Token.IsCancellationRequested)
|
|
{
|
|
stopwatch.Restart();
|
|
|
|
try
|
|
{
|
|
_tickAction();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"Error in tick loop: {ex}");
|
|
}
|
|
|
|
var elapsed = stopwatch.Elapsed;
|
|
if (elapsed < targetFrameTime)
|
|
{
|
|
await Task.Delay(targetFrameTime - elapsed);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |