Browse Source

Merge branch 'master' into issues/1954

pull/1955/head
Andrey Kunchev 8 years ago
committed by GitHub
parent
commit
73245fa960
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 List<IRenderLoopTask> _items = new List<IRenderLoopTask>();
private IRenderTimer _timer;
private int inTick;
private int _inTick;
private int _inUpdate;
/// <summary>
/// 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
{
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)
@ -112,7 +128,7 @@ namespace Avalonia.Rendering
}
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;
dispatcher.Setup(
d => d.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render))
d => d.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) =>
{
inDispatcher = true;
a();
inDispatcher = false;
})
.Returns(Task.CompletedTask);
});
var timer = new Mock<IRenderTimer>();
@ -71,14 +70,13 @@ namespace Avalonia.Visuals.UnitTests.Rendering
var dispatcher = new Mock<IDispatcher>();
bool inDispatcher = false;
dispatcher.Setup(
d => d.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render))
d => d.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) =>
{
inDispatcher = true;
a();
inDispatcher = false;
})
.Returns(Task.CompletedTask);
});
var timer = new Mock<IRenderTimer>();
var loop = new RenderLoop(timer.Object, dispatcher.Object);
@ -100,9 +98,8 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
var dispatcher = new Mock<IDispatcher>();
dispatcher.Setup(
d => d.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) => a())
.Returns(Task.CompletedTask);
d => d.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback((Action a, DispatcherPriority _) => a());
var timer = new Mock<IRenderTimer>();
var loop = new RenderLoop(timer.Object, dispatcher.Object);

Loading…
Cancel
Save