Browse Source

Stop the loop when there are no subscribers

pull/4424/head
Nikita Tsukanov 6 years ago
parent
commit
90aad3b785
  1. 65
      src/Avalonia.Visuals/Rendering/SleepLoopRenderTimer.cs

65
src/Avalonia.Visuals/Rendering/SleepLoopRenderTimer.cs

@ -6,28 +6,67 @@ namespace Avalonia.Rendering
{
public class SleepLoopRenderTimer : IRenderTimer
{
public event Action<TimeSpan> Tick;
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)
{
var timeBetweenTicks = TimeSpan.FromSeconds(1d / fps);
new Thread(() =>
_timeBetweenTicks = TimeSpan.FromSeconds(1d / fps);
}
public event Action<TimeSpan> Tick
{
add
{
var st = Stopwatch.StartNew();
var now = st.Elapsed;
var lastTick = now;
lock (_lock)
{
_tick += value;
_count++;
if (_running)
return;
_running = true;
new Thread(LoopProc) { IsBackground = true }.Start();
}
while (true)
}
remove
{
lock (_lock)
{
var timeTillNextTick = lastTick + timeBetweenTicks - now;
if (timeTillNextTick.TotalMilliseconds > 1)
Thread.Sleep(timeTillNextTick);
_tick -= value;
_count--;
}
}
}
void LoopProc()
{
var now = _st.Elapsed;
var lastTick = now;
while (true)
{
var timeTillNextTick = lastTick + _timeBetweenTicks - now;
if (timeTillNextTick.TotalMilliseconds > 1) Thread.Sleep(timeTillNextTick);
Tick?.Invoke(now);
now = st.Elapsed;
lock (_lock)
{
if (_count == 0)
{
_running = false;
return;
}
}
}) { IsBackground = true }.Start();
_tick?.Invoke(now);
now = _st.Elapsed;
}
}
}
}

Loading…
Cancel
Save