A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

75 lines
1.9 KiB

using System;
using System.Diagnostics;
using System.Threading;
using Avalonia.Metadata;
namespace Avalonia.Rendering
{
[PrivateApi]
public class SleepLoopRenderTimer : IRenderTimer
{
private Action<TimeSpan>? _tick;
private int _count;
private readonly object _lock = new object();
private bool _running;
private readonly Stopwatch _st = Stopwatch.StartNew();
private readonly TimeSpan _timeBetweenTicks;
public SleepLoopRenderTimer(int fps)
{
_timeBetweenTicks = TimeSpan.FromSeconds(1d / fps);
}
public event Action<TimeSpan> Tick
{
add
{
lock (_lock)
{
_tick += value;
_count++;
if (_running)
return;
_running = true;
new Thread(LoopProc) { IsBackground = true }.Start();
}
}
remove
{
lock (_lock)
{
_tick -= value;
_count--;
}
}
}
public bool RunsInBackground => true;
void LoopProc()
{
var lastTick = _st.Elapsed;
while (true)
{
var now = _st.Elapsed;
var timeTillNextTick = lastTick + _timeBetweenTicks - now;
if (timeTillNextTick.TotalMilliseconds > 1) Thread.Sleep(timeTillNextTick);
lastTick = now = _st.Elapsed;
lock (_lock)
{
if (_count == 0)
{
_running = false;
return;
}
}
_tick?.Invoke(now);
}
}
}
}