Browse Source

Merge pull request #8455 from ltetak/effectiveViewportChangedListeners

EffectiveViewportChangedListeners thread safety improved
pull/8483/head
Steven Kirk 4 years ago
committed by GitHub
parent
commit
da801b28ca
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/Avalonia.Base/Layout/LayoutManager.cs
  2. 24
      tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs

8
src/Avalonia.Base/Layout/LayoutManager.cs

@ -350,7 +350,7 @@ namespace Avalonia.Layout
{
for (var i = 0; i < count; ++i)
{
var l = _effectiveViewportChangedListeners[i];
var l = listeners[i];
if (!l.Listener.IsAttachedToVisualTree)
{
@ -362,7 +362,7 @@ namespace Avalonia.Layout
if (viewport != l.Viewport)
{
l.Listener.EffectiveViewportChanged(new EffectiveViewportChangedEventArgs(viewport));
_effectiveViewportChangedListeners[i] = new EffectiveViewportChangedListener(l.Listener, viewport);
l.Viewport = viewport;
}
}
}
@ -414,7 +414,7 @@ namespace Avalonia.Layout
}
}
private readonly struct EffectiveViewportChangedListener
private class EffectiveViewportChangedListener
{
public EffectiveViewportChangedListener(ILayoutable listener, Rect viewport)
{
@ -423,7 +423,7 @@ namespace Avalonia.Layout
}
public ILayoutable Listener { get; }
public Rect Viewport { get; }
public Rect Viewport { get; set; }
}
}
}

24
tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs

@ -312,6 +312,30 @@ namespace Avalonia.Base.UnitTests.Layout
});
}
[Fact]
public async Task Event_Unsubscribed_While_Inside_Callback()
{
await RunOnUIThread.Execute(async () =>
{
var root = CreateRoot();
var target = new Canvas();
var raised = 0;
void OnTargetOnEffectiveViewportChanged(object s, EffectiveViewportChangedEventArgs e)
{
target.EffectiveViewportChanged -= OnTargetOnEffectiveViewportChanged;
++raised;
}
target.EffectiveViewportChanged += OnTargetOnEffectiveViewportChanged;
root.Child = target;
await ExecuteInitialLayoutPass(root);
Assert.Equal(1, raised);
});
}
private TestRoot CreateRoot() => new TestRoot { Width = 1200, Height = 900 };
private Task ExecuteInitialLayoutPass(TestRoot root)

Loading…
Cancel
Save