Browse Source

Add ThreadProxyRenderTimer (#12900)

* Add ThreadProxyRenderTimer

* Forgot IsBackground

* Increase default stack size in ThreadProxyRenderTimer
pull/12915/head
Max Katz 3 years ago
committed by GitHub
parent
commit
3619b80549
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 70
      src/Avalonia.Base/Rendering/ThreadProxyRenderTimer.cs
  2. 2
      src/Avalonia.Native/AvaloniaNativePlatform.cs

70
src/Avalonia.Base/Rendering/ThreadProxyRenderTimer.cs

@ -0,0 +1,70 @@
using System;
using System.Diagnostics;
using System.Threading;
using Avalonia.Metadata;
namespace Avalonia.Rendering;
[PrivateApi]
public sealed class ThreadProxyRenderTimer : IRenderTimer
{
private readonly IRenderTimer _inner;
private readonly Stopwatch _stopwatch;
private readonly Thread _timerThread;
private readonly AutoResetEvent _autoResetEvent;
private Action<TimeSpan>? _tick;
private int _subscriberCount;
private bool _registered;
public ThreadProxyRenderTimer(IRenderTimer inner, int maxStackSize = 1 * 1024 * 1024)
{
_inner = inner;
_stopwatch = new Stopwatch();
_autoResetEvent = new AutoResetEvent(false);
_timerThread = new Thread(RenderTimerThreadFunc, maxStackSize) { Name = "RenderTimerLoop", IsBackground = true };
}
public event Action<TimeSpan> Tick
{
add
{
_tick += value;
if (!_registered)
{
_registered = true;
_timerThread.Start();
}
if (_subscriberCount++ == 0)
{
_inner.Tick += InnerTick;
}
}
remove
{
if (--_subscriberCount == 0)
{
_inner.Tick -= InnerTick;
}
_tick -= value;
}
}
private void RenderTimerThreadFunc()
{
while (_autoResetEvent.WaitOne())
{
_tick?.Invoke(_stopwatch.Elapsed);
}
}
private void InnerTick(TimeSpan obj)
{
_autoResetEvent.Set();
}
public bool RunsInBackground => true;
}

2
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -108,7 +108,7 @@ namespace Avalonia.Native
.Bind<IPlatformSettings>().ToConstant(new NativePlatformSettings(_factory.CreatePlatformSettings()))
.Bind<IWindowingPlatform>().ToConstant(this)
.Bind<IClipboard>().ToConstant(new ClipboardImpl(_factory.CreateClipboard()))
.Bind<IRenderTimer>().ToConstant(new AvaloniaNativeRenderTimer(_factory.CreatePlatformRenderTimer()))
.Bind<IRenderTimer>().ToConstant(new ThreadProxyRenderTimer(new AvaloniaNativeRenderTimer(_factory.CreatePlatformRenderTimer())))
.Bind<IMountedVolumeInfoProvider>().ToConstant(new MacOSMountedVolumeInfoProvider())
.Bind<IPlatformDragSource>().ToConstant(new AvaloniaNativeDragSource(_factory))
.Bind<IPlatformLifetimeEventsImpl>().ToConstant(applicationPlatform)

Loading…
Cancel
Save