diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index f66fe2b8b2..1199db587a 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -2,9 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; @@ -60,7 +57,9 @@ namespace osu.Game.Extensions component.Scale = info.Scale; component.Anchor = info.Anchor; component.Origin = info.Origin; - component.UsingClosestAnchor().Value = info.UsingClosestAnchor; + + if (component is ISkinnableDrawable skinnable) + skinnable.UsingClosestAnchor = info.UsingClosestAnchor; if (component is Container container) { @@ -68,26 +67,5 @@ namespace osu.Game.Extensions container.Add(child.CreateInstance()); } } - - /// - ///

A ConditionalWeakTable is preferable to a Dictionary because a Dictionary will keep - /// orphaned references to an forever, unless manually pruned.

- ///

is used as a thin wrapper around bool because ConditionalWeakTable requires a reference type as both a key and a value.

- ///

was chosen over because it is a common ancestor between (which is required for logic) - /// and (which is required for serialization via ).

- ///

This collection is thread-safe according to the - /// documentation, - /// but the BindableBools are not unless leased.

- ///
- private static readonly ConditionalWeakTable is_drawable_using_closest_anchor_lookup = new ConditionalWeakTable(); - - /// - /// Gets or creates a representing whether is using the closest anchor point within its - /// parent. - /// - /// A whose is if the is using the closest anchor point, - /// otherwise . - public static BindableBool UsingClosestAnchor(this IDrawable drawable) => - is_drawable_using_closest_anchor_lookup.GetValue(drawable, _ => new BindableBool(true)); } } diff --git a/osu.Game/Screens/Play/HUD/SkinnableInfo.cs b/osu.Game/Screens/Play/HUD/SkinnableInfo.cs index 5c733a9bc1..a76634a1f0 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableInfo.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableInfo.cs @@ -55,7 +55,10 @@ namespace osu.Game.Screens.Play.HUD Scale = component.Scale; Anchor = component.Anchor; Origin = component.Origin; - UsingClosestAnchor = component.UsingClosestAnchor().Value; + + UsingClosestAnchor = + // true if it's not an ISkinnableDrawable + !(component is ISkinnableDrawable skinnable) || skinnable.UsingClosestAnchor; if (component is Container container) { diff --git a/osu.Game/Skinning/Editor/SkinSelectionHandler.cs b/osu.Game/Skinning/Editor/SkinSelectionHandler.cs index 5acc949182..f4476b9de7 100644 --- a/osu.Game/Skinning/Editor/SkinSelectionHandler.cs +++ b/osu.Game/Skinning/Editor/SkinSelectionHandler.cs @@ -241,7 +241,7 @@ namespace osu.Game.Skinning.Editor private void updateDrawableAnchorIfUsingClosest(Drawable drawable) { - if (!drawable.UsingClosestAnchor().Value) return; + if (!(drawable is ISkinnableDrawable { UsingClosestAnchor: true })) return; var closestAnchor = getClosestAnchorForDrawable(drawable); @@ -265,8 +265,8 @@ namespace osu.Game.Skinning.Editor protected override IEnumerable GetContextMenuItemsForSelection(IEnumerable> selection) { - int checkAnchor(Drawable drawable) => - drawable.UsingClosestAnchor().Value + static int checkAnchor(Drawable drawable) => + drawable is ISkinnableDrawable { UsingClosestAnchor: true } ? closest_text_hash : (int)drawable.Anchor; @@ -331,8 +331,12 @@ namespace osu.Game.Skinning.Editor { var drawable = (Drawable)item; - var anchor = mapHashToAnchorSettings(hash, drawable); + var (usingClosest, anchor) = + hash == closest_text_hash + ? (true, getClosestAnchorForDrawable(drawable)) + : (false, (Anchor)hash); + item.UsingClosestAnchor = usingClosest; updateDrawableAnchor(drawable, anchor); } } @@ -344,20 +348,6 @@ namespace osu.Game.Skinning.Editor drawable.Position -= drawable.AnchorPosition - previousAnchor; } - private Anchor mapHashToAnchorSettings(int hash, Drawable drawable) - { - var isUsingClosestAnchor = drawable.UsingClosestAnchor(); - - if (hash == closest_text_hash) - { - isUsingClosestAnchor.Value = true; - return getClosestAnchorForDrawable(drawable); - } - - isUsingClosestAnchor.Value = false; - return (Anchor)hash; - } - private static void adjustScaleFromAnchor(ref Vector2 scale, Anchor reference) { // cancel out scale in axes we don't care about (based on which drag handle was used).