Browse Source

Merge branch 'master' into fix-make-MONITORINFO-a-struct

pull/1953/head
ahopper 8 years ago
committed by GitHub
parent
commit
ac5f65e3a3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      src/Avalonia.Visuals/Rendering/RenderLoop.cs
  2. 15
      tests/Avalonia.Visuals.UnitTests/Rendering/RenderLoopTests.cs

34
src/Avalonia.Visuals/Rendering/RenderLoop.cs

@ -19,7 +19,8 @@ namespace Avalonia.Rendering
private readonly IDispatcher _dispatcher; private readonly IDispatcher _dispatcher;
private List<IRenderLoopTask> _items = new List<IRenderLoopTask>(); private List<IRenderLoopTask> _items = new List<IRenderLoopTask>();
private IRenderTimer _timer; private IRenderTimer _timer;
private int inTick; private int _inTick;
private int _inUpdate;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RenderLoop"/> class. /// Initializes a new instance of the <see cref="RenderLoop"/> class.
@ -84,21 +85,36 @@ namespace Avalonia.Rendering
} }
} }
private async void TimerTick(TimeSpan time) private void TimerTick(TimeSpan time)
{ {
if (Interlocked.CompareExchange(ref inTick, 1, 0) == 0) if (Interlocked.CompareExchange(ref _inTick, 1, 0) == 0)
{ {
try try
{ {
if (_items.Any(item => item.NeedsUpdate)) if (_items.Any(item => item.NeedsUpdate) &&
Interlocked.CompareExchange(ref _inUpdate, 1, 0) == 0)
{ {
await _dispatcher.InvokeAsync(() => _dispatcher.Post(() =>
{ {
foreach (var i in _items) for (var i = 0; i < _items.Count; ++i)
{ {
i.Update(time); var item = _items[i];
if (item.NeedsUpdate)
{
try
{
item.Update(time);
}
catch (Exception ex)
{
Logger.Error(LogArea.Visual, this, "Exception in render update: {Error}", ex);
}
}
} }
}, DispatcherPriority.Render).ConfigureAwait(false);
Interlocked.Exchange(ref _inUpdate, 0);
}, DispatcherPriority.Render);
} }
foreach (var i in _items) foreach (var i in _items)
@ -112,7 +128,7 @@ namespace Avalonia.Rendering
} }
finally finally
{ {
Interlocked.Exchange(ref inTick, 0); Interlocked.Exchange(ref _inTick, 0);
} }
} }
} }

15
tests/Avalonia.Visuals.UnitTests/Rendering/RenderLoopTests.cs

@ -19,14 +19,13 @@ namespace Avalonia.Visuals.UnitTests.Rendering
bool inDispatcher = false; bool inDispatcher = false;
dispatcher.Setup( dispatcher.Setup(
d => d.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render)) d => d.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) => .Callback((Action a, DispatcherPriority _) =>
{ {
inDispatcher = true; inDispatcher = true;
a(); a();
inDispatcher = false; inDispatcher = false;
}) });
.Returns(Task.CompletedTask);
var timer = new Mock<IRenderTimer>(); var timer = new Mock<IRenderTimer>();
@ -71,14 +70,13 @@ namespace Avalonia.Visuals.UnitTests.Rendering
var dispatcher = new Mock<IDispatcher>(); var dispatcher = new Mock<IDispatcher>();
bool inDispatcher = false; bool inDispatcher = false;
dispatcher.Setup( dispatcher.Setup(
d => d.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render)) d => d.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) => .Callback((Action a, DispatcherPriority _) =>
{ {
inDispatcher = true; inDispatcher = true;
a(); a();
inDispatcher = false; inDispatcher = false;
}) });
.Returns(Task.CompletedTask);
var timer = new Mock<IRenderTimer>(); var timer = new Mock<IRenderTimer>();
var loop = new RenderLoop(timer.Object, dispatcher.Object); var loop = new RenderLoop(timer.Object, dispatcher.Object);
@ -100,9 +98,8 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{ {
var dispatcher = new Mock<IDispatcher>(); var dispatcher = new Mock<IDispatcher>();
dispatcher.Setup( dispatcher.Setup(
d => d.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render)) d => d.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) => a()) .Callback((Action a, DispatcherPriority _) => a());
.Returns(Task.CompletedTask);
var timer = new Mock<IRenderTimer>(); var timer = new Mock<IRenderTimer>();
var loop = new RenderLoop(timer.Object, dispatcher.Object); var loop = new RenderLoop(timer.Object, dispatcher.Object);

Loading…
Cancel
Save