csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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.
86 lines
2.6 KiB
86 lines
2.6 KiB
using System;
|
|
using System.Reactive.Disposables;
|
|
using System.Threading;
|
|
using Avalonia.Platform;
|
|
using Avalonia.Threading;
|
|
|
|
namespace Avalonia.Headless
|
|
{
|
|
class HeadlessPlatformThreadingInterface : IPlatformThreadingInterface
|
|
{
|
|
public HeadlessPlatformThreadingInterface()
|
|
{
|
|
_thread = Thread.CurrentThread;
|
|
}
|
|
|
|
private AutoResetEvent _event = new AutoResetEvent(false);
|
|
private Thread _thread;
|
|
private object _lock = new object();
|
|
private DispatcherPriority? _signaledPriority;
|
|
|
|
public void RunLoop(CancellationToken cancellationToken)
|
|
{
|
|
while (!cancellationToken.IsCancellationRequested)
|
|
{
|
|
DispatcherPriority? signaled = null;
|
|
lock (_lock)
|
|
{
|
|
signaled = _signaledPriority;
|
|
_signaledPriority = null;
|
|
}
|
|
if(signaled.HasValue)
|
|
Signaled?.Invoke(signaled);
|
|
WaitHandle.WaitAny(new[] {cancellationToken.WaitHandle, _event}, TimeSpan.FromMilliseconds(20));
|
|
}
|
|
}
|
|
|
|
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
|
|
{
|
|
var cancelled = false;
|
|
var enqueued = false;
|
|
var l = new object();
|
|
var timer = new Timer(_ =>
|
|
{
|
|
lock (l)
|
|
{
|
|
if (cancelled || enqueued)
|
|
return;
|
|
enqueued = true;
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
lock (l)
|
|
{
|
|
enqueued = false;
|
|
if (cancelled)
|
|
return;
|
|
tick();
|
|
}
|
|
}, priority);
|
|
}
|
|
}, null, interval, interval);
|
|
return Disposable.Create(() =>
|
|
{
|
|
lock (l)
|
|
{
|
|
timer.Dispose();
|
|
cancelled = true;
|
|
}
|
|
});
|
|
}
|
|
|
|
public void Signal(DispatcherPriority priority)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_signaledPriority == null || _signaledPriority.Value > priority)
|
|
{
|
|
_signaledPriority = priority;
|
|
}
|
|
_event.Set();
|
|
}
|
|
}
|
|
|
|
public bool CurrentThreadIsLoopThread => _thread == Thread.CurrentThread;
|
|
public event Action<DispatcherPriority?> Signaled;
|
|
}
|
|
}
|
|
|