Fix changing Size/Position not invalidating self correctly

This commit is contained in:
smoogipoo
2020-06-04 21:22:48 +09:00
parent d5bad81fce
commit eb3bed07b4
2 changed files with 84 additions and 5 deletions

View File

@@ -5,6 +5,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Layout;
using osu.Framework.Testing;
using osu.Framework.Tests.Visual;
using osu.Framework.Utils;
@@ -84,6 +85,53 @@ namespace osu.Framework.Tests.Layout
});
}
[Test]
public void TestChangePositionInvalidatesMiscGeometryOnSelf()
{
TestBox1 box = null;
AddStep("create test", () =>
{
Child = box = new TestBox1
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
};
});
AddUntilStep("wait for validation", () => box.MiscGeometryLayoutValue.IsValid);
AddAssert("change position and ensure MiscGeometry invalidated on self", () =>
{
box.Position = new Vector2(50);
return !box.MiscGeometryLayoutValue.IsValid;
});
}
[Test]
public void TestChangeSizeInvalidatesDrawSizeOnSelf()
{
TestBox1 box = null;
AddStep("create test", () =>
{
Child = box = new TestBox1
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(50)
};
});
AddUntilStep("wait for validation", () => box.DrawSizeLayoutValue.IsValid);
AddAssert("change size and ensure DrawSize invalidated on self", () =>
{
box.Size = new Vector2(100);
return !box.DrawSizeLayoutValue.IsValid;
});
}
private class TestContainer1 : Container<Drawable>
{
public void AdjustScale(float scale = 1.0f)
@@ -92,5 +140,25 @@ namespace osu.Framework.Tests.Layout
this.ResizeTo(new Vector2(1 / scale));
}
}
private class TestBox1 : Box
{
public readonly LayoutValue MiscGeometryLayoutValue = new LayoutValue(Invalidation.MiscGeometry, InvalidationSource.Self);
public readonly LayoutValue DrawSizeLayoutValue = new LayoutValue(Invalidation.DrawSize, InvalidationSource.Self);
public TestBox1()
{
AddLayout(MiscGeometryLayoutValue);
AddLayout(DrawSizeLayoutValue);
}
protected override void Update()
{
base.Update();
MiscGeometryLayoutValue.Validate();
DrawSizeLayoutValue.Validate();
}
}
}
}

View File

@@ -298,7 +298,8 @@ namespace osu.Framework.Graphics
double allowedDuration = blocking ? 16 : 100;
if (loadDuration > allowedDuration)
Logger.Log($@"{ToString()} took {loadDuration:0.00}ms to load" + (blocking ? " (and blocked the update thread)" : " (async)"), LoggingTarget.Performance, blocking ? LogLevel.Important : LogLevel.Verbose);
Logger.Log($@"{ToString()} took {loadDuration:0.00}ms to load" + (blocking ? " (and blocked the update thread)" : " (async)"), LoggingTarget.Performance,
blocking ? LogLevel.Important : LogLevel.Verbose);
}
}
@@ -1744,7 +1745,17 @@ namespace osu.Framework.Graphics
/// <param name="invalidation">The flags to invalidate with.</param>
/// <param name="source">The source that triggered the invalidation.</param>
/// <returns>If any layout was invalidated.</returns>
public bool Invalidate(Invalidation invalidation = Invalidation.All, InvalidationSource source = InvalidationSource.Self)
public bool Invalidate(Invalidation invalidation = Invalidation.All, InvalidationSource source = InvalidationSource.Self) => invalidate(invalidation, source);
/// <summary>
/// Invalidates the layout of this <see cref="Drawable"/>.
/// </summary>
/// <param name="invalidation">The flags to invalidate with.</param>
/// <param name="source">The source that triggered the invalidation.</param>
/// <param name="propagateToParent">Whether to propagate the invalidation to the parent of this <see cref="Drawable"/>.
/// Only has an effect if <paramref name="source"/> is <see cref="InvalidationSource.Self"/>.</param>
/// <returns>If any layout was invalidated.</returns>
private bool invalidate(Invalidation invalidation = Invalidation.All, InvalidationSource source = InvalidationSource.Self, bool propagateToParent = true)
{
if (source != InvalidationSource.Child && source != InvalidationSource.Parent && source != InvalidationSource.Self)
throw new InvalidOperationException($"A {nameof(Drawable)} can only be invalidated with a singular {nameof(source)} (child, parent, or self).");
@@ -1762,7 +1773,7 @@ namespace osu.Framework.Graphics
// If the invalidation originated locally, propagate to the immediate parent.
// Note: This is done _before_ invalidation is blocked below, since the parent always needs to be aware of changes even if the Drawable's invalidation state hasn't changed.
// This is for only propagating once, otherwise it would propagate all the way to the root Drawable.
if (source == InvalidationSource.Self)
if (propagateToParent && source == InvalidationSource.Self)
Parent?.Invalidate(invalidation, InvalidationSource.Child);
// Perform the invalidation.
@@ -1834,8 +1845,8 @@ namespace osu.Framework.Graphics
/// <param name="changedAxes">The <see cref="Axes"/> that were affected.</param>
private void invalidateParentSizeDependencies(Invalidation invalidation, Axes changedAxes)
{
// A parent source is faked so that the invalidation doesn't propagate upwards unnecessarily.
Invalidate(invalidation, InvalidationSource.Parent);
// We're invalidating the parent manually, so we should not propagate it upwards.
invalidate(invalidation, InvalidationSource.Self, false);
// The fast path, which performs an invalidation on the parent along with optimisations for bypassed sizing axes.
Parent?.InvalidateChildrenSizeDependencies(invalidation, changedAxes, this);