Browse Source

PR comments

pull/1131/head
Eli Arbel 9 years ago
parent
commit
e069eb8014
  1. 79
      src/Avalonia.Visuals/Rendering/DirtyVisuals.cs

79
src/Avalonia.Visuals/Rendering/DirtyVisuals.cs

@ -17,8 +17,8 @@ namespace Avalonia.Rendering
{
private SortedDictionary<int, List<IVisual>> _inner = new SortedDictionary<int, List<IVisual>>();
private Dictionary<IVisual, int> _index = new Dictionary<IVisual, int>();
private List<(DeferredChange change, IVisual visual)> _deferredChanges = new List<(DeferredChange, IVisual)>();
private bool _deferring;
private List<IVisual> _deferredChanges = new List<IVisual>();
private int _deferring;
/// <summary>
/// Gets the number of dirty visuals.
@ -31,9 +31,9 @@ namespace Avalonia.Rendering
/// <param name="visual">The dirty visual.</param>
public void Add(IVisual visual)
{
if (_deferring)
if (_deferring > 0)
{
_deferredChanges.Add((DeferredChange.Add, visual));
_deferredChanges.Add(visual);
return;
}
@ -65,42 +65,23 @@ namespace Avalonia.Rendering
/// </summary>
public void Clear()
{
if (_deferring)
if (_deferring > 0)
{
_deferredChanges.Add((DeferredChange.Clear, null));
return;
throw new InvalidOperationException("Cannot clear while enumerating");
}
_inner.Clear();
_index.Clear();
}
/// <summary>
/// Removes a visual from the dirty list.
/// </summary>
/// <param name="visual">The visual.</param>
public void Remove(IVisual visual)
{
if (_deferring)
{
_deferredChanges.Add((DeferredChange.Remove, visual));
return;
}
if (_index.TryGetValue(visual, out var distance))
{
_inner[distance].Remove(visual);
_index.Remove(visual);
}
}
/// <summary>
/// Gets the dirty visuals, in ascending order of distance to their root.
/// </summary>
/// <returns>A collection of visuals.</returns>
public IEnumerator<IVisual> GetEnumerator()
{
using (DeferChanges())
BeginDefer();
try
{
foreach (var i in _inner)
{
@ -110,34 +91,24 @@ namespace Avalonia.Rendering
}
}
}
finally
{
EndDefer();
}
}
private DeferDisposer DeferChanges()
private void BeginDefer()
{
_deferring = true;
return new DeferDisposer(this);
++_deferring;
}
private void EndDefer()
{
if (!_deferring) return;
if (--_deferring > 0) return;
_deferring = false;
foreach (var change in _deferredChanges)
foreach (var visual in _deferredChanges)
{
switch (change.change)
{
case DeferredChange.Add:
Add(change.visual);
break;
case DeferredChange.Remove:
Remove(change.visual);
break;
case DeferredChange.Clear:
Clear();
break;
}
Add(visual);
}
_deferredChanges.Clear();
@ -148,21 +119,5 @@ namespace Avalonia.Rendering
/// </summary>
/// <returns>A collection of visuals.</returns>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private struct DeferDisposer : IDisposable
{
private DirtyVisuals _parent;
internal DeferDisposer(DirtyVisuals parent) => _parent = parent;
public void Dispose() => _parent?.EndDefer();
}
private enum DeferredChange
{
Add,
Remove,
Clear
}
}
}

Loading…
Cancel
Save