From 6010dde86edb4f70a71594f1c771c22bb6683aff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 15:30:29 +0900 Subject: [PATCH 01/17] Move `SkinnableInfo` to better namespace --- .../Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs | 1 - osu.Game/Extensions/DrawableExtensions.cs | 1 - osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs | 2 -- osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs | 1 - osu.Game/Skinning/ISkinnableTarget.cs | 2 +- osu.Game/Skinning/LegacyComboCounter.cs | 1 - osu.Game/{Screens/Play/HUD => Skinning}/SkinnableInfo.cs | 4 ++-- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- 8 files changed, 4 insertions(+), 10 deletions(-) rename osu.Game/{Screens/Play/HUD => Skinning}/SkinnableInfo.cs (98%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 94cb8517e9..615bf609dc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -19,7 +19,6 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Skinning.Legacy; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; -using osu.Game.Screens.Play.HUD; using osu.Game.Skinning; using osu.Game.Storyboards; diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index 375960305c..021745e5e1 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -5,7 +5,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; -using osu.Game.Screens.Play.HUD; using osu.Game.Skinning; using osuTK; diff --git a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs index 28ceaf09fc..3298c267f3 100644 --- a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs +++ b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs @@ -10,9 +10,7 @@ using osu.Framework.Logging; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Localisation; using osu.Game.Screens.Edit.Components; -using osu.Game.Screens.Play.HUD; using osu.Game.Skinning; using osuTK; diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index c8f66f3e56..41b6b24da1 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Extensions; using osu.Game.Screens.Edit; -using osu.Game.Screens.Play.HUD; using osu.Game.Skinning; namespace osu.Game.Overlays.SkinEditor diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 3f116f8f76..6429d116dd 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -6,7 +6,7 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Extensions; -using osu.Game.Screens.Play.HUD; +using osu.Game.Rulesets; namespace osu.Game.Skinning { diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index c132a72001..1de13841fe 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Scoring; -using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Skinning diff --git a/osu.Game/Screens/Play/HUD/SkinnableInfo.cs b/osu.Game/Skinning/SkinnableInfo.cs similarity index 98% rename from osu.Game/Screens/Play/HUD/SkinnableInfo.cs rename to osu.Game/Skinning/SkinnableInfo.cs index 9fdae50615..96aaed667e 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableInfo.cs +++ b/osu.Game/Skinning/SkinnableInfo.cs @@ -13,10 +13,10 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Logging; using osu.Game.Configuration; using osu.Game.Extensions; -using osu.Game.Skinning; +using osu.Game.Rulesets; using osuTK; -namespace osu.Game.Screens.Play.HUD +namespace osu.Game.Skinning { /// /// Serialised information governing custom changes to an . diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index b21e51c0cf..cbc719cef5 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -8,7 +8,7 @@ using System.Threading; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Screens.Play.HUD; +using osu.Game.Skinning.Serialisation; namespace osu.Game.Skinning { From 9e651a7ca26f48eb9a95d770a29fb6bd680173f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 15:36:18 +0900 Subject: [PATCH 02/17] Rename `SkinnableInfo` to `SkinnableDrawableInfo` --- .../Skins/SkinDeserialisationTest.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 16 +++++++-------- osu.Game/Extensions/DrawableExtensions.cs | 20 +++++++++---------- .../SkinEditor/SkinComponentToolbox.cs | 2 +- .../SkinEditor/SkinEditorChangeHandler.cs | 4 ++-- osu.Game/Skinning/ISkinnableTarget.cs | 4 ++-- osu.Game/Skinning/LegacyComboCounter.cs | 2 +- ...nnableInfo.cs => SkinnableDrawableInfo.cs} | 8 ++++---- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- 9 files changed, 30 insertions(+), 30 deletions(-) rename osu.Game/Skinning/{SkinnableInfo.cs => SkinnableDrawableInfo.cs} (93%) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 3bab91bd9c..16cae1d34f 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -74,7 +74,7 @@ namespace osu.Game.Tests.Skins } } - var editableTypes = SkinnableInfo.GetAllAvailableDrawables().Where(t => (Activator.CreateInstance(t) as ISkinnableDrawable)?.IsEditable == true); + var editableTypes = SkinnableDrawableInfo.GetAllAvailableDrawables().Where(t => (Activator.CreateInstance(t) as ISkinnableDrawable)?.IsEditable == true); Assert.That(instantiatedTypes, Is.EquivalentTo(editableTypes)); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 615bf609dc..8318f70e8f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -90,15 +90,15 @@ namespace osu.Game.Tests.Visual.Gameplay return almostEqual(actualInfo, expectedInfo); } - private static bool almostEqual(SkinnableInfo info, SkinnableInfo? other) => + private static bool almostEqual(SkinnableDrawableInfo drawableInfo, SkinnableDrawableInfo? other) => other != null - && info.Type == other.Type - && info.Anchor == other.Anchor - && info.Origin == other.Origin - && Precision.AlmostEquals(info.Position, other.Position, 1) - && Precision.AlmostEquals(info.Scale, other.Scale) - && Precision.AlmostEquals(info.Rotation, other.Rotation) - && info.Children.SequenceEqual(other.Children, new FuncEqualityComparer(almostEqual)); + && drawableInfo.Type == other.Type + && drawableInfo.Anchor == other.Anchor + && drawableInfo.Origin == other.Origin + && Precision.AlmostEquals(drawableInfo.Position, other.Position, 1) + && Precision.AlmostEquals(drawableInfo.Scale, other.Scale) + && Precision.AlmostEquals(drawableInfo.Rotation, other.Rotation) + && drawableInfo.Children.SequenceEqual(other.Children, new FuncEqualityComparer(almostEqual)); protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard? storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, Audio, currentBeatmapSkin); diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index 021745e5e1..c590d4fa31 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -48,26 +48,26 @@ namespace osu.Game.Extensions public static Vector2 ScreenSpaceDeltaToParentSpace(this Drawable drawable, Vector2 delta) => drawable.Parent.ToLocalSpace(drawable.Parent.ToScreenSpace(Vector2.Zero) + delta); - public static SkinnableInfo CreateSkinnableInfo(this Drawable component) => new SkinnableInfo(component); + public static SkinnableDrawableInfo CreateSkinnableInfo(this Drawable component) => new SkinnableDrawableInfo(component); - public static void ApplySkinnableInfo(this Drawable component, SkinnableInfo info) + public static void ApplySkinnableInfo(this Drawable component, SkinnableDrawableInfo drawableInfo) { // todo: can probably make this better via deserialisation directly using a common interface. - component.Position = info.Position; - component.Rotation = info.Rotation; - component.Scale = info.Scale; - component.Anchor = info.Anchor; - component.Origin = info.Origin; + component.Position = drawableInfo.Position; + component.Rotation = drawableInfo.Rotation; + component.Scale = drawableInfo.Scale; + component.Anchor = drawableInfo.Anchor; + component.Origin = drawableInfo.Origin; if (component is ISkinnableDrawable skinnable) { - skinnable.UsesFixedAnchor = info.UsesFixedAnchor; + skinnable.UsesFixedAnchor = drawableInfo.UsesFixedAnchor; foreach (var (_, property) in component.GetSettingsSourceProperties()) { var bindable = ((IBindable)property.GetValue(component)!); - if (!info.Settings.TryGetValue(property.Name.ToSnakeCase(), out object? settingValue)) + if (!drawableInfo.Settings.TryGetValue(property.Name.ToSnakeCase(), out object? settingValue)) { // TODO: We probably want to restore default if not included in serialisation information. // This is not simple to do as SetDefault() is only found in the typed Bindable interface right now. @@ -80,7 +80,7 @@ namespace osu.Game.Extensions if (component is Container container) { - foreach (var child in info.Children) + foreach (var child in drawableInfo.Children) container.Add(child.CreateInstance()); } } diff --git a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs index 3298c267f3..37bc7df4fa 100644 --- a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs +++ b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.SkinEditor { fill.Clear(); - var skinnableTypes = SkinnableInfo.GetAllAvailableDrawables(); + var skinnableTypes = SkinnableDrawableInfo.GetAllAvailableDrawables(target?.Ruleset); foreach (var type in skinnableTypes) attemptAddComponent(type); } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 41b6b24da1..2d519d3489 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -52,12 +52,12 @@ namespace osu.Game.Overlays.SkinEditor if (firstTarget == null) return; - var deserializedContent = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(newState)); + var deserializedContent = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(newState)); if (deserializedContent == null) return; - SkinnableInfo[] skinnableInfo = deserializedContent.ToArray(); + SkinnableDrawableInfo[] skinnableInfo = deserializedContent.ToArray(); Drawable[] targetComponents = firstTarget.Components.OfType().ToArray(); if (!skinnableInfo.Select(s => s.Type).SequenceEqual(targetComponents.Select(d => d.GetType()))) diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 6429d116dd..4610851216 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -29,7 +29,7 @@ namespace osu.Game.Skinning /// Serialise all children as . /// /// The serialised content. - IEnumerable CreateSkinnableInfo() => Components.Select(d => ((Drawable)d).CreateSkinnableInfo()); + IEnumerable CreateSkinnableInfo() => Components.Select(d => ((Drawable)d).CreateSkinnableInfo()); /// /// Reload this target from the current skin. @@ -39,7 +39,7 @@ namespace osu.Game.Skinning /// /// Reload this target from the provided skinnable information. /// - void Reload(SkinnableInfo[] skinnableInfo); + void Reload(SkinnableDrawableInfo[] skinnableInfo); /// /// Add a new skinnable component to this target. diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index 1de13841fe..c03386266b 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -44,7 +44,7 @@ namespace osu.Game.Skinning private readonly Container counterContainer; /// - /// Hides the combo counter internally without affecting its . + /// Hides the combo counter internally without affecting its . /// /// /// This is used for rulesets that provide their own combo counter and don't want this HUD one to be visible, diff --git a/osu.Game/Skinning/SkinnableInfo.cs b/osu.Game/Skinning/SkinnableDrawableInfo.cs similarity index 93% rename from osu.Game/Skinning/SkinnableInfo.cs rename to osu.Game/Skinning/SkinnableDrawableInfo.cs index 96aaed667e..5e30f94ac6 100644 --- a/osu.Game/Skinning/SkinnableInfo.cs +++ b/osu.Game/Skinning/SkinnableDrawableInfo.cs @@ -22,7 +22,7 @@ namespace osu.Game.Skinning /// Serialised information governing custom changes to an . /// [Serializable] - public class SkinnableInfo + public sealed class SkinnableDrawableInfo { public Type Type { get; set; } @@ -41,10 +41,10 @@ namespace osu.Game.Skinning public Dictionary Settings { get; set; } = new Dictionary(); - public List Children { get; } = new List(); + public List Children { get; } = new List(); [JsonConstructor] - public SkinnableInfo() + public SkinnableDrawableInfo() { } @@ -52,7 +52,7 @@ namespace osu.Game.Skinning /// Construct a new instance populating all attributes from the provided drawable. /// /// The drawable which attributes should be sourced from. - public SkinnableInfo(Drawable component) + public SkinnableDrawableInfo(Drawable component) { Type = component.GetType(); diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index cbc719cef5..586462cb8c 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Skinning Target = target; } - public void Reload(SkinnableInfo[] skinnableInfo) + public void Reload(SkinnableDrawableInfo[] skinnableInfo) { var drawables = new List(); From 856efd9fd9d04e312e77030d9740e738e1355b95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 15:47:41 +0900 Subject: [PATCH 03/17] Rename `SkinnableDrawableInfo` to `SerialisedDrawableInfo` --- osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 8 ++++---- osu.Game/Extensions/DrawableExtensions.cs | 4 ++-- .../Overlays/SkinEditor/SkinComponentToolbox.cs | 3 ++- .../Overlays/SkinEditor/SkinEditorChangeHandler.cs | 8 ++++---- osu.Game/Skinning/ISkinnableDrawable.cs | 6 ++++-- osu.Game/Skinning/ISkinnableTarget.cs | 7 +++---- osu.Game/Skinning/LegacyComboCounter.cs | 2 +- ...bleDrawableInfo.cs => SerialisedDrawableInfo.cs} | 13 ++++++------- osu.Game/Skinning/Skin.cs | 9 ++++----- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- 11 files changed, 32 insertions(+), 32 deletions(-) rename osu.Game/Skinning/{SkinnableDrawableInfo.cs => SerialisedDrawableInfo.cs} (89%) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 16cae1d34f..c782fbd084 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -74,7 +74,7 @@ namespace osu.Game.Tests.Skins } } - var editableTypes = SkinnableDrawableInfo.GetAllAvailableDrawables().Where(t => (Activator.CreateInstance(t) as ISkinnableDrawable)?.IsEditable == true); + var editableTypes = SerialisedDrawableInfo.GetAllAvailableDrawables().Where(t => (Activator.CreateInstance(t) as ISkinnableDrawable)?.IsEditable == true); Assert.That(instantiatedTypes, Is.EquivalentTo(editableTypes)); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 8318f70e8f..5005cff265 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Gameplay if (actualComponentsContainer == null) return false; - var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); + var actualInfo = actualComponentsContainer.CreateSerialisedInfo(); var expectedComponentsContainer = expectedSource.GetDrawableComponent(new GlobalSkinComponentLookup(target)) as Container; if (expectedComponentsContainer == null) @@ -84,13 +84,13 @@ namespace osu.Game.Tests.Visual.Gameplay Add(expectedComponentsAdjustmentContainer); expectedComponentsAdjustmentContainer.UpdateSubTree(); - var expectedInfo = expectedComponentsContainer.CreateSkinnableInfo(); + var expectedInfo = expectedComponentsContainer.CreateSerialisedInfo(); Remove(expectedComponentsAdjustmentContainer, true); return almostEqual(actualInfo, expectedInfo); } - private static bool almostEqual(SkinnableDrawableInfo drawableInfo, SkinnableDrawableInfo? other) => + private static bool almostEqual(SerialisedDrawableInfo drawableInfo, SerialisedDrawableInfo? other) => other != null && drawableInfo.Type == other.Type && drawableInfo.Anchor == other.Anchor @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.Gameplay && Precision.AlmostEquals(drawableInfo.Position, other.Position, 1) && Precision.AlmostEquals(drawableInfo.Scale, other.Scale) && Precision.AlmostEquals(drawableInfo.Rotation, other.Rotation) - && drawableInfo.Children.SequenceEqual(other.Children, new FuncEqualityComparer(almostEqual)); + && drawableInfo.Children.SequenceEqual(other.Children, new FuncEqualityComparer(almostEqual)); protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard? storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, Audio, currentBeatmapSkin); diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index c590d4fa31..cc561cebc4 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -48,9 +48,9 @@ namespace osu.Game.Extensions public static Vector2 ScreenSpaceDeltaToParentSpace(this Drawable drawable, Vector2 delta) => drawable.Parent.ToLocalSpace(drawable.Parent.ToScreenSpace(Vector2.Zero) + delta); - public static SkinnableDrawableInfo CreateSkinnableInfo(this Drawable component) => new SkinnableDrawableInfo(component); + public static SerialisedDrawableInfo CreateSerialisedInfo(this Drawable component) => new SerialisedDrawableInfo(component); - public static void ApplySkinnableInfo(this Drawable component, SkinnableDrawableInfo drawableInfo) + public static void ApplySerialisedInfo(this Drawable component, SerialisedDrawableInfo drawableInfo) { // todo: can probably make this better via deserialisation directly using a common interface. component.Position = drawableInfo.Position; diff --git a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs index 37bc7df4fa..2f3fd8b5e5 100644 --- a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs +++ b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs @@ -10,6 +10,7 @@ using osu.Framework.Logging; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Screens.Edit.Components; using osu.Game.Skinning; using osuTK; @@ -48,7 +49,7 @@ namespace osu.Game.Overlays.SkinEditor { fill.Clear(); - var skinnableTypes = SkinnableDrawableInfo.GetAllAvailableDrawables(target?.Ruleset); + var skinnableTypes = SerialisedDrawableInfo.GetAllAvailableDrawables(); foreach (var type in skinnableTypes) attemptAddComponent(type); } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 2d519d3489..77032589a0 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.SkinEditor if (firstTarget == null) return; - var skinnableInfos = firstTarget.CreateSkinnableInfo().ToArray(); + var skinnableInfos = firstTarget.CreateSerialisedInfo().ToArray(); string json = JsonConvert.SerializeObject(skinnableInfos, new JsonSerializerSettings { Formatting = Formatting.Indented }); stream.Write(Encoding.UTF8.GetBytes(json)); } @@ -52,12 +52,12 @@ namespace osu.Game.Overlays.SkinEditor if (firstTarget == null) return; - var deserializedContent = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(newState)); + var deserializedContent = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(newState)); if (deserializedContent == null) return; - SkinnableDrawableInfo[] skinnableInfo = deserializedContent.ToArray(); + SerialisedDrawableInfo[] skinnableInfo = deserializedContent.ToArray(); Drawable[] targetComponents = firstTarget.Components.OfType().ToArray(); if (!skinnableInfo.Select(s => s.Type).SequenceEqual(targetComponents.Select(d => d.GetType()))) @@ -70,7 +70,7 @@ namespace osu.Game.Overlays.SkinEditor int i = 0; foreach (var drawable in targetComponents) - drawable.ApplySkinnableInfo(skinnableInfo[i++]); + drawable.ApplySerialisedInfo(skinnableInfo[i++]); } } } diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISkinnableDrawable.cs index 1ecd6f967e..5ec2fa0f43 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISkinnableDrawable.cs @@ -13,8 +13,10 @@ namespace osu.Game.Skinning /// Denotes a drawable which, as a drawable, can be adjusted via skinning specifications. /// /// - /// Attaching this interface to any will make it serialisable to skin settings. - /// Adding annotated bindables will also serialise these settings alongside each instance. + /// Attaching this interface to any will make it serialisable to user skins (see ). + /// Adding annotated bindables will also allow serialising settings automatically. + /// + /// Serialisation is done via using . /// public interface ISkinnableDrawable : IDrawable { diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 4610851216..e10fc6e069 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Extensions; -using osu.Game.Rulesets; namespace osu.Game.Skinning { @@ -26,10 +25,10 @@ namespace osu.Game.Skinning IBindableList Components { get; } /// - /// Serialise all children as . + /// Serialise all children as . /// /// The serialised content. - IEnumerable CreateSkinnableInfo() => Components.Select(d => ((Drawable)d).CreateSkinnableInfo()); + IEnumerable CreateSerialisedInfo() => Components.Select(d => ((Drawable)d).CreateSerialisedInfo()); /// /// Reload this target from the current skin. @@ -39,7 +38,7 @@ namespace osu.Game.Skinning /// /// Reload this target from the provided skinnable information. /// - void Reload(SkinnableDrawableInfo[] skinnableInfo); + void Reload(SerialisedDrawableInfo[] skinnableInfo); /// /// Add a new skinnable component to this target. diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index c03386266b..f46f5a69f0 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -44,7 +44,7 @@ namespace osu.Game.Skinning private readonly Container counterContainer; /// - /// Hides the combo counter internally without affecting its . + /// Hides the combo counter internally without affecting its . /// /// /// This is used for rulesets that provide their own combo counter and don't want this HUD one to be visible, diff --git a/osu.Game/Skinning/SkinnableDrawableInfo.cs b/osu.Game/Skinning/SerialisedDrawableInfo.cs similarity index 89% rename from osu.Game/Skinning/SkinnableDrawableInfo.cs rename to osu.Game/Skinning/SerialisedDrawableInfo.cs index 5e30f94ac6..8bcfed1dbc 100644 --- a/osu.Game/Skinning/SkinnableDrawableInfo.cs +++ b/osu.Game/Skinning/SerialisedDrawableInfo.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Logging; using osu.Game.Configuration; using osu.Game.Extensions; -using osu.Game.Rulesets; using osuTK; namespace osu.Game.Skinning @@ -22,7 +21,7 @@ namespace osu.Game.Skinning /// Serialised information governing custom changes to an . /// [Serializable] - public sealed class SkinnableDrawableInfo + public sealed class SerialisedDrawableInfo { public Type Type { get; set; } @@ -41,10 +40,10 @@ namespace osu.Game.Skinning public Dictionary Settings { get; set; } = new Dictionary(); - public List Children { get; } = new List(); + public List Children { get; } = new List(); [JsonConstructor] - public SkinnableDrawableInfo() + public SerialisedDrawableInfo() { } @@ -52,7 +51,7 @@ namespace osu.Game.Skinning /// Construct a new instance populating all attributes from the provided drawable. /// /// The drawable which attributes should be sourced from. - public SkinnableDrawableInfo(Drawable component) + public SerialisedDrawableInfo(Drawable component) { Type = component.GetType(); @@ -75,7 +74,7 @@ namespace osu.Game.Skinning if (component is Container container) { foreach (var child in container.OfType().OfType()) - Children.Add(child.CreateSkinnableInfo()); + Children.Add(child.CreateSerialisedInfo()); } } @@ -88,7 +87,7 @@ namespace osu.Game.Skinning try { Drawable d = (Drawable)Activator.CreateInstance(Type)!; - d.ApplySkinnableInfo(this); + d.ApplySerialisedInfo(this); return d; } catch (Exception e) diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index c55b4e789c..44bdcafe4c 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -18,7 +18,6 @@ using osu.Framework.Logging; using osu.Game.Audio; using osu.Game.Database; using osu.Game.IO; -using osu.Game.Screens.Play.HUD; namespace osu.Game.Skinning { @@ -38,9 +37,9 @@ namespace osu.Game.Skinning public SkinConfiguration Configuration { get; set; } - public IDictionary DrawableComponentInfo => drawableComponentInfo; + public IDictionary DrawableComponentInfo => drawableComponentInfo; - private readonly Dictionary drawableComponentInfo = new Dictionary(); + private readonly Dictionary drawableComponentInfo = new Dictionary(); public abstract ISample? GetSample(ISampleInfo sampleInfo); @@ -120,7 +119,7 @@ namespace osu.Game.Skinning jsonContent = jsonContent.Replace(@"osu.Game.Screens.Play.SongProgress", @"osu.Game.Screens.Play.HUD.DefaultSongProgress"); jsonContent = jsonContent.Replace(@"osu.Game.Screens.Play.HUD.LegacyComboCounter", @"osu.Game.Skinning.LegacyComboCounter"); - var deserializedContent = JsonConvert.DeserializeObject>(jsonContent); + var deserializedContent = JsonConvert.DeserializeObject>(jsonContent); if (deserializedContent == null) continue; @@ -155,7 +154,7 @@ namespace osu.Game.Skinning /// The target container to serialise to this skin. public void UpdateDrawableTarget(ISkinnableTarget targetContainer) { - DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSkinnableInfo().ToArray(); + DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSerialisedInfo().ToArray(); } public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 586462cb8c..8b37767113 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Skinning Target = target; } - public void Reload(SkinnableDrawableInfo[] skinnableInfo) + public void Reload(SerialisedDrawableInfo[] skinnableInfo) { var drawables = new List(); From 8cb5a51aa77d6db5cce44273b7722543d38619a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 15:14:38 +0900 Subject: [PATCH 04/17] Add further documentation to skin classes --- osu.Game/Skinning/ISkin.cs | 2 +- osu.Game/Skinning/ISkinComponentLookup.cs | 3 ++- osu.Game/Skinning/ISkinSource.cs | 10 +++++++++- osu.Game/Skinning/ISkinnableDrawable.cs | 4 ++-- osu.Game/Skinning/SerialisedDrawableInfo.cs | 3 ++- osu.Game/Skinning/SkinProvidingContainer.cs | 7 ++++++- osu.Game/Skinning/SkinReloadableDrawable.cs | 3 ++- osu.Game/Skinning/SkinTransformer.cs | 7 +++++++ 8 files changed, 31 insertions(+), 8 deletions(-) diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index 45be5582f6..fa04dda202 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -10,7 +10,7 @@ using osu.Game.Audio; namespace osu.Game.Skinning { /// - /// Provides access to skinnable elements. + /// Provides access to various elements contained by a skin. /// public interface ISkin { diff --git a/osu.Game/Skinning/ISkinComponentLookup.cs b/osu.Game/Skinning/ISkinComponentLookup.cs index be4043d7cf..25ee086707 100644 --- a/osu.Game/Skinning/ISkinComponentLookup.cs +++ b/osu.Game/Skinning/ISkinComponentLookup.cs @@ -4,7 +4,8 @@ namespace osu.Game.Skinning { /// - /// A lookup type which can be used with . + /// The base lookup type to be used with . + /// Should be implemented as necessary to add further criteria to lookups, which are usually consumed by ruleset transformers or legacy lookup cases. /// /// /// Implementations of should match on types implementing this interface diff --git a/osu.Game/Skinning/ISkinSource.cs b/osu.Game/Skinning/ISkinSource.cs index 89f656a12c..b05d52d47c 100644 --- a/osu.Game/Skinning/ISkinSource.cs +++ b/osu.Game/Skinning/ISkinSource.cs @@ -7,8 +7,16 @@ using System.Collections.Generic; namespace osu.Game.Skinning { /// - /// Provides access to skinnable elements. + /// An abstract skin implementation which generally provides access to more than one skins (with fallback logic). /// + /// + /// Common usage is to do an initial lookup via , and use the returned + /// to do further lookups for related components. + /// + /// The initial lookup is used to lock consecutive lookups to the same underlying skin source (as to not get some elements + /// from one skin and others from another, which would be the case if using methods like + /// directly). + /// public interface ISkinSource : ISkin { /// diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISkinnableDrawable.cs index 5ec2fa0f43..48f5b91c29 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISkinnableDrawable.cs @@ -10,13 +10,13 @@ using osu.Game.Configuration; namespace osu.Game.Skinning { /// - /// Denotes a drawable which, as a drawable, can be adjusted via skinning specifications. + /// A drawable which can be serialised to a skin, placed and customised via the skin layout editor. /// /// /// Attaching this interface to any will make it serialisable to user skins (see ). /// Adding annotated bindables will also allow serialising settings automatically. /// - /// Serialisation is done via using . + /// Serialisation is done via using . /// public interface ISkinnableDrawable : IDrawable { diff --git a/osu.Game/Skinning/SerialisedDrawableInfo.cs b/osu.Game/Skinning/SerialisedDrawableInfo.cs index 8bcfed1dbc..90762da011 100644 --- a/osu.Game/Skinning/SerialisedDrawableInfo.cs +++ b/osu.Game/Skinning/SerialisedDrawableInfo.cs @@ -18,7 +18,8 @@ using osuTK; namespace osu.Game.Skinning { /// - /// Serialised information governing custom changes to an . + /// Serialised backing data for s. + /// Used for json serialisation in user skins. /// [Serializable] public sealed class SerialisedDrawableInfo diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index afead7b072..2612e0b47c 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -15,8 +15,13 @@ using osu.Game.Audio; namespace osu.Game.Skinning { /// - /// A container which adds a local to the hierarchy. + /// A container which adds a provided to the DI skin lookup hierarchy. /// + /// + /// This container will expose an to its children. + /// The source will first consider the skin provided via the constructor (if any), then fallback + /// to any providers in the parent DI hierarchy. + /// public partial class SkinProvidingContainer : Container, ISkinSource { public event Action? SourceChanged; diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index 1c947a4a84..cef1db4bc0 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -9,7 +9,8 @@ using osu.Framework.Graphics.Pooling; namespace osu.Game.Skinning { /// - /// A drawable which has a callback when the skin changes. + /// A poolable drawable implementation which has a pre-wired callback (see ) that fires + /// once on load and again on any subsequent skin change. /// public abstract partial class SkinReloadableDrawable : PoolableDrawable { diff --git a/osu.Game/Skinning/SkinTransformer.cs b/osu.Game/Skinning/SkinTransformer.cs index e05961d404..ed5b04da1e 100644 --- a/osu.Game/Skinning/SkinTransformer.cs +++ b/osu.Game/Skinning/SkinTransformer.cs @@ -10,6 +10,13 @@ using osu.Game.Audio; namespace osu.Game.Skinning { + /// + /// A default skin transformer, which falls back to the provided skin by default. + /// + /// + /// Implementations of skin transformers should generally derive this class and override + /// individual lookup methods, modifying the lookup flow as required. + /// public abstract class SkinTransformer : ISkinTransformer { public ISkin Skin { get; } From d159d6b9700d90f6a40cda0f832df59f6086e7ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 16:01:26 +0900 Subject: [PATCH 05/17] Rename `ISkinnableDrawable` to `ISerialisableDrawable` --- .../Skins/SkinDeserialisationTest.cs | 2 +- osu.Game/Extensions/DrawableExtensions.cs | 2 +- osu.Game/Overlays/SkinEditor/SkinBlueprint.cs | 4 ++-- .../SkinEditor/SkinBlueprintContainer.cs | 22 +++++++++---------- .../SkinEditor/SkinComponentToolbox.cs | 2 +- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 10 ++++----- .../SkinEditor/SkinEditorChangeHandler.cs | 4 ++-- .../SkinEditor/SkinSelectionHandler.cs | 10 ++++----- osu.Game/Screens/Play/HUD/BPMCounter.cs | 2 +- .../ClicksPerSecond/ClicksPerSecondCounter.cs | 2 +- osu.Game/Screens/Play/HUD/ComboCounter.cs | 2 +- .../Play/HUD/DefaultAccuracyCounter.cs | 2 +- .../Screens/Play/HUD/DefaultHealthDisplay.cs | 2 +- .../Screens/Play/HUD/DefaultScoreCounter.cs | 2 +- .../Play/HUD/HitErrorMeters/HitErrorMeter.cs | 2 +- .../JudgementCounterDisplay.cs | 2 +- .../Play/HUD/PerformancePointsCounter.cs | 2 +- osu.Game/Screens/Play/HUD/SongProgress.cs | 2 +- .../Screens/Play/HUD/UnstableRateCounter.cs | 2 +- osu.Game/Skinning/Components/BigBlackBox.cs | 2 +- .../Skinning/FontAdjustableSkinComponent.cs | 2 +- ...leDrawable.cs => ISerialisableDrawable.cs} | 6 ++--- osu.Game/Skinning/ISkinnableTarget.cs | 8 +++---- osu.Game/Skinning/LegacyAccuracyCounter.cs | 2 +- osu.Game/Skinning/LegacyComboCounter.cs | 2 +- osu.Game/Skinning/LegacyHealthDisplay.cs | 2 +- osu.Game/Skinning/LegacyScoreCounter.cs | 2 +- osu.Game/Skinning/SerialisedDrawableInfo.cs | 14 +++++++----- osu.Game/Skinning/SkinnableSprite.cs | 2 +- osu.Game/Skinning/SkinnableTargetContainer.cs | 10 ++++----- 30 files changed, 67 insertions(+), 63 deletions(-) rename osu.Game/Skinning/{ISkinnableDrawable.cs => ISerialisableDrawable.cs} (87%) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index c782fbd084..b897523560 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -74,7 +74,7 @@ namespace osu.Game.Tests.Skins } } - var editableTypes = SerialisedDrawableInfo.GetAllAvailableDrawables().Where(t => (Activator.CreateInstance(t) as ISkinnableDrawable)?.IsEditable == true); + var editableTypes = SerialisedDrawableInfo.GetAllAvailableDrawables().Where(t => (Activator.CreateInstance(t) as ISerialisableDrawable)?.IsEditable == true); Assert.That(instantiatedTypes, Is.EquivalentTo(editableTypes)); } diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index cc561cebc4..b6f74f5777 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -59,7 +59,7 @@ namespace osu.Game.Extensions component.Anchor = drawableInfo.Anchor; component.Origin = drawableInfo.Origin; - if (component is ISkinnableDrawable skinnable) + if (component is ISerialisableDrawable skinnable) { skinnable.UsesFixedAnchor = drawableInfo.UsesFixedAnchor; diff --git a/osu.Game/Overlays/SkinEditor/SkinBlueprint.cs b/osu.Game/Overlays/SkinEditor/SkinBlueprint.cs index 893bc4bac2..55ea362873 100644 --- a/osu.Game/Overlays/SkinEditor/SkinBlueprint.cs +++ b/osu.Game/Overlays/SkinEditor/SkinBlueprint.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.SkinEditor { - public partial class SkinBlueprint : SelectionBlueprint + public partial class SkinBlueprint : SelectionBlueprint { private Container box = null!; @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.SkinEditor [Resolved] private OsuColour colours { get; set; } = null!; - public SkinBlueprint(ISkinnableDrawable component) + public SkinBlueprint(ISerialisableDrawable component) : base(component) { } diff --git a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs index a448b3d0c1..1e7bec5417 100644 --- a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs +++ b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs @@ -24,11 +24,11 @@ using osuTK.Input; namespace osu.Game.Overlays.SkinEditor { - public partial class SkinBlueprintContainer : BlueprintContainer + public partial class SkinBlueprintContainer : BlueprintContainer { private readonly Drawable target; - private readonly List> targetComponents = new List>(); + private readonly List> targetComponents = new List>(); [Resolved] private SkinEditor editor { get; set; } = null!; @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.SkinEditor foreach (var targetContainer in targetContainers) { - var bindableList = new BindableList { BindTarget = targetContainer.Components }; + var bindableList = new BindableList { BindTarget = targetContainer.Components }; bindableList.BindCollectionChanged(componentsChanged, true); targetComponents.Add(bindableList); @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.SkinEditor case NotifyCollectionChangedAction.Add: Debug.Assert(e.NewItems != null); - foreach (var item in e.NewItems.Cast()) + foreach (var item in e.NewItems.Cast()) AddBlueprintFor(item); break; @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.SkinEditor case NotifyCollectionChangedAction.Reset: Debug.Assert(e.OldItems != null); - foreach (var item in e.OldItems.Cast()) + foreach (var item in e.OldItems.Cast()) RemoveBlueprintFor(item); break; @@ -85,16 +85,16 @@ namespace osu.Game.Overlays.SkinEditor Debug.Assert(e.NewItems != null); Debug.Assert(e.OldItems != null); - foreach (var item in e.OldItems.Cast()) + foreach (var item in e.OldItems.Cast()) RemoveBlueprintFor(item); - foreach (var item in e.NewItems.Cast()) + foreach (var item in e.NewItems.Cast()) AddBlueprintFor(item); break; } }); - protected override void AddBlueprintFor(ISkinnableDrawable item) + protected override void AddBlueprintFor(ISerialisableDrawable item) { if (!item.IsEditable) return; @@ -145,12 +145,12 @@ namespace osu.Game.Overlays.SkinEditor // convert to game space coordinates delta = firstBlueprint.ToScreenSpace(delta) - firstBlueprint.ToScreenSpace(Vector2.Zero); - SelectionHandler.HandleMovement(new MoveSelectionEvent(firstBlueprint, delta)); + SelectionHandler.HandleMovement(new MoveSelectionEvent(firstBlueprint, delta)); } - protected override SelectionHandler CreateSelectionHandler() => new SkinSelectionHandler(); + protected override SelectionHandler CreateSelectionHandler() => new SkinSelectionHandler(); - protected override SelectionBlueprint CreateBlueprintFor(ISkinnableDrawable component) + protected override SelectionBlueprint CreateBlueprintFor(ISerialisableDrawable component) => new SkinBlueprint(component); protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs index 2f3fd8b5e5..cd9f7cc935 100644 --- a/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs +++ b/osu.Game/Overlays/SkinEditor/SkinComponentToolbox.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.SkinEditor { Drawable instance = (Drawable)Activator.CreateInstance(type)!; - if (!((ISkinnableDrawable)instance).IsEditable) return; + if (!((ISerialisableDrawable)instance).IsEditable) return; fill.Add(new ToolboxComponentButton(instance, target) { diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 866de7e621..aafc97d769 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.SkinEditor public const float MENU_HEIGHT = 40; - public readonly BindableList SelectedComponents = new BindableList(); + public readonly BindableList SelectedComponents = new BindableList(); protected override bool StartHidden => true; @@ -302,13 +302,13 @@ namespace osu.Game.Overlays.SkinEditor private void placeComponent(Type type) { - if (!(Activator.CreateInstance(type) is ISkinnableDrawable component)) - throw new InvalidOperationException($"Attempted to instantiate a component for placement which was not an {typeof(ISkinnableDrawable)}."); + if (!(Activator.CreateInstance(type) is ISerialisableDrawable component)) + throw new InvalidOperationException($"Attempted to instantiate a component for placement which was not an {typeof(ISerialisableDrawable)}."); placeComponent(component); } - private void placeComponent(ISkinnableDrawable component, bool applyDefaults = true) + private void placeComponent(ISerialisableDrawable component, bool applyDefaults = true) { var targetContainer = getFirstTarget(); @@ -400,7 +400,7 @@ namespace osu.Game.Overlays.SkinEditor this.FadeOut(TRANSITION_DURATION, Easing.OutQuint); } - public void DeleteItems(ISkinnableDrawable[] items) + public void DeleteItems(ISerialisableDrawable[] items) { foreach (var item in items) availableTargets.FirstOrDefault(t => t.Components.Contains(item))?.Remove(item); diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 77032589a0..65872920f1 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.SkinEditor private readonly ISkinnableTarget? firstTarget; // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable - private readonly BindableList? components; + private readonly BindableList? components; public SkinEditorChangeHandler(Drawable targetScreen) { @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.SkinEditor if (firstTarget == null) return; - components = new BindableList { BindTarget = firstTarget.Components }; + components = new BindableList { BindTarget = firstTarget.Components }; components.BindCollectionChanged((_, _) => SaveState()); } diff --git a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs index 86fcd35e03..c628ad8480 100644 --- a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays.SkinEditor { - public partial class SkinSelectionHandler : SelectionHandler + public partial class SkinSelectionHandler : SelectionHandler { [Resolved] private SkinEditor skinEditor { get; set; } = null!; @@ -147,7 +147,7 @@ namespace osu.Game.Overlays.SkinEditor return true; } - public override bool HandleMovement(MoveSelectionEvent moveEvent) + public override bool HandleMovement(MoveSelectionEvent moveEvent) { foreach (var c in SelectedBlueprints) { @@ -178,10 +178,10 @@ namespace osu.Game.Overlays.SkinEditor SelectionBox.CanReverse = false; } - protected override void DeleteItems(IEnumerable items) => + protected override void DeleteItems(IEnumerable items) => skinEditor.DeleteItems(items.ToArray()); - protected override IEnumerable GetContextMenuItemsForSelection(IEnumerable> selection) + protected override IEnumerable GetContextMenuItemsForSelection(IEnumerable> selection) { var closestItem = new TernaryStateRadioMenuItem("Closest", MenuItemType.Standard, _ => applyClosestAnchors()) { @@ -209,7 +209,7 @@ namespace osu.Game.Overlays.SkinEditor foreach (var item in base.GetContextMenuItemsForSelection(selection)) yield return item; - IEnumerable createAnchorItems(Func checkFunction, Action applyFunction) + IEnumerable createAnchorItems(Func checkFunction, Action applyFunction) { var displayableAnchors = new[] { diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 500ab0169f..cd24237493 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public partial class BPMCounter : RollingCounter, ISkinnableDrawable + public partial class BPMCounter : RollingCounter, ISerialisableDrawable { protected override double RollingDuration => 750; diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs index cb72bb5f6f..1aa7c5e091 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD.ClicksPerSecond { - public partial class ClicksPerSecondCounter : RollingCounter, ISkinnableDrawable + public partial class ClicksPerSecondCounter : RollingCounter, ISerialisableDrawable { [Resolved] private ClicksPerSecondCalculator calculator { get; set; } = null!; diff --git a/osu.Game/Screens/Play/HUD/ComboCounter.cs b/osu.Game/Screens/Play/HUD/ComboCounter.cs index afccbc4ef0..17531281aa 100644 --- a/osu.Game/Screens/Play/HUD/ComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/ComboCounter.cs @@ -7,7 +7,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public abstract partial class ComboCounter : RollingCounter, ISkinnableDrawable + public abstract partial class ComboCounter : RollingCounter, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs index 1a082e58b7..eb3c71afbb 100644 --- a/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs @@ -9,7 +9,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public partial class DefaultAccuracyCounter : GameplayAccuracyCounter, ISkinnableDrawable + public partial class DefaultAccuracyCounter : GameplayAccuracyCounter, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs index 62d66efb33..2c43905a46 100644 --- a/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs @@ -19,7 +19,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public partial class DefaultHealthDisplay : HealthDisplay, IHasAccentColour, ISkinnableDrawable + public partial class DefaultHealthDisplay : HealthDisplay, IHasAccentColour, ISerialisableDrawable { /// /// The base opacity of the glow. diff --git a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs index f116617271..7cc2dc1751 100644 --- a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs @@ -10,7 +10,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public partial class DefaultScoreCounter : GameplayScoreCounter, ISkinnableDrawable + public partial class DefaultScoreCounter : GameplayScoreCounter, ISerialisableDrawable { public DefaultScoreCounter() { diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs index 191f63e97d..5d65208afe 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { - public abstract partial class HitErrorMeter : CompositeDrawable, ISkinnableDrawable + public abstract partial class HitErrorMeter : CompositeDrawable, ISerialisableDrawable { protected HitWindows HitWindows { get; private set; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 80d2e0863f..a9b59a02b5 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD.JudgementCounter { - public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable + public partial class JudgementCounterDisplay : CompositeDrawable, ISerialisableDrawable { public const int TRANSFORM_DURATION = 250; diff --git a/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs b/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs index 15484f2965..4f37c215e9 100644 --- a/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs +++ b/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs @@ -35,7 +35,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public partial class PerformancePointsCounter : RollingCounter, ISkinnableDrawable + public partial class PerformancePointsCounter : RollingCounter, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index 4647c0352b..ebe2fb83e6 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public abstract partial class SongProgress : OverlayContainer, ISkinnableDrawable + public abstract partial class SongProgress : OverlayContainer, ISerialisableDrawable { // Some implementations of this element allow seeking during gameplay playback. // Set a sane default of never handling input to override the behaviour provided by OverlayContainer. diff --git a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs index f450ae799e..4ceca817e2 100644 --- a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs +++ b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public partial class UnstableRateCounter : RollingCounter, ISkinnableDrawable + public partial class UnstableRateCounter : RollingCounter, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/Components/BigBlackBox.cs b/osu.Game/Skinning/Components/BigBlackBox.cs index 043a276e49..3c63dae8d8 100644 --- a/osu.Game/Skinning/Components/BigBlackBox.cs +++ b/osu.Game/Skinning/Components/BigBlackBox.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning.Components /// Intended to be a test bed for skinning. May be removed at some point in the future. /// [UsedImplicitly] - public partial class BigBlackBox : CompositeDrawable, ISkinnableDrawable + public partial class BigBlackBox : CompositeDrawable, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/FontAdjustableSkinComponent.cs b/osu.Game/Skinning/FontAdjustableSkinComponent.cs index 2e41b35abb..8f3a1d41c6 100644 --- a/osu.Game/Skinning/FontAdjustableSkinComponent.cs +++ b/osu.Game/Skinning/FontAdjustableSkinComponent.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning /// /// A skin component that contains text and allows the user to choose its font. /// - public abstract partial class FontAdjustableSkinComponent : Container, ISkinnableDrawable + public abstract partial class FontAdjustableSkinComponent : Container, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISerialisableDrawable.cs similarity index 87% rename from osu.Game/Skinning/ISkinnableDrawable.cs rename to osu.Game/Skinning/ISerialisableDrawable.cs index 48f5b91c29..23cbda6344 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISerialisableDrawable.cs @@ -18,7 +18,7 @@ namespace osu.Game.Skinning /// /// Serialisation is done via using . /// - public interface ISkinnableDrawable : IDrawable + public interface ISerialisableDrawable : IDrawable { /// /// Whether this component should be editable by an end user. @@ -26,8 +26,8 @@ namespace osu.Game.Skinning bool IsEditable => true; /// - /// In the context of the skin layout editor, whether this has a permanent anchor defined. - /// If , this 's is automatically determined by proximity, + /// In the context of the skin layout editor, whether this has a permanent anchor defined. + /// If , this 's is automatically determined by proximity, /// If , a fixed anchor point has been defined. /// bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index e10fc6e069..5833898d81 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -10,7 +10,7 @@ using osu.Game.Extensions; namespace osu.Game.Skinning { /// - /// Denotes a container which can house s. + /// Denotes a container which can house s. /// public interface ISkinnableTarget : IDrawable { @@ -22,7 +22,7 @@ namespace osu.Game.Skinning /// /// A bindable list of components which are being tracked by this skinnable target. /// - IBindableList Components { get; } + IBindableList Components { get; } /// /// Serialise all children as . @@ -44,12 +44,12 @@ namespace osu.Game.Skinning /// Add a new skinnable component to this target. /// /// The component to add. - void Add(ISkinnableDrawable drawable); + void Add(ISerialisableDrawable drawable); /// /// Remove an existing skinnable component from this target. /// /// The component to remove. - void Remove(ISkinnableDrawable component); + void Remove(ISerialisableDrawable component); } } diff --git a/osu.Game/Skinning/LegacyAccuracyCounter.cs b/osu.Game/Skinning/LegacyAccuracyCounter.cs index e75fb1e7e9..c99cdba91c 100644 --- a/osu.Game/Skinning/LegacyAccuracyCounter.cs +++ b/osu.Game/Skinning/LegacyAccuracyCounter.cs @@ -8,7 +8,7 @@ using osuTK; namespace osu.Game.Skinning { - public partial class LegacyAccuracyCounter : GameplayAccuracyCounter, ISkinnableDrawable + public partial class LegacyAccuracyCounter : GameplayAccuracyCounter, ISerialisableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index f46f5a69f0..cd72055fce 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -14,7 +14,7 @@ namespace osu.Game.Skinning /// /// Uses the 'x' symbol and has a pop-out effect while rolling over. /// - public partial class LegacyComboCounter : CompositeDrawable, ISkinnableDrawable + public partial class LegacyComboCounter : CompositeDrawable, ISerialisableDrawable { public Bindable Current { get; } = new BindableInt { MinValue = 0 }; diff --git a/osu.Game/Skinning/LegacyHealthDisplay.cs b/osu.Game/Skinning/LegacyHealthDisplay.cs index c3cb9770fa..f785022f84 100644 --- a/osu.Game/Skinning/LegacyHealthDisplay.cs +++ b/osu.Game/Skinning/LegacyHealthDisplay.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Skinning { - public partial class LegacyHealthDisplay : HealthDisplay, ISkinnableDrawable + public partial class LegacyHealthDisplay : HealthDisplay, ISerialisableDrawable { private const double epic_cutoff = 0.5; diff --git a/osu.Game/Skinning/LegacyScoreCounter.cs b/osu.Game/Skinning/LegacyScoreCounter.cs index 88e7bbc23a..d8ee6b21de 100644 --- a/osu.Game/Skinning/LegacyScoreCounter.cs +++ b/osu.Game/Skinning/LegacyScoreCounter.cs @@ -8,7 +8,7 @@ using osuTK; namespace osu.Game.Skinning { - public partial class LegacyScoreCounter : GameplayScoreCounter, ISkinnableDrawable + public partial class LegacyScoreCounter : GameplayScoreCounter, ISerialisableDrawable { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; diff --git a/osu.Game/Skinning/SerialisedDrawableInfo.cs b/osu.Game/Skinning/SerialisedDrawableInfo.cs index 90762da011..f571f1a945 100644 --- a/osu.Game/Skinning/SerialisedDrawableInfo.cs +++ b/osu.Game/Skinning/SerialisedDrawableInfo.cs @@ -18,9 +18,13 @@ using osuTK; namespace osu.Game.Skinning { /// - /// Serialised backing data for s. + /// Serialised backing data for s. /// Used for json serialisation in user skins. /// + /// + /// Can be created using . + /// Can also be applied to an existing drawable using . + /// [Serializable] public sealed class SerialisedDrawableInfo { @@ -36,7 +40,7 @@ namespace osu.Game.Skinning public Anchor Origin { get; set; } - /// + /// public bool UsesFixedAnchor { get; set; } public Dictionary Settings { get; set; } = new Dictionary(); @@ -62,7 +66,7 @@ namespace osu.Game.Skinning Anchor = component.Anchor; Origin = component.Origin; - if (component is ISkinnableDrawable skinnable) + if (component is ISerialisableDrawable skinnable) UsesFixedAnchor = skinnable.UsesFixedAnchor; foreach (var (_, property) in component.GetSettingsSourceProperties()) @@ -74,7 +78,7 @@ namespace osu.Game.Skinning if (component is Container container) { - foreach (var child in container.OfType().OfType()) + foreach (var child in container.OfType().OfType()) Children.Add(child.CreateSerialisedInfo()); } } @@ -102,7 +106,7 @@ namespace osu.Game.Skinning { return typeof(OsuGame).Assembly.GetTypes() .Where(t => !t.IsInterface && !t.IsAbstract) - .Where(t => typeof(ISkinnableDrawable).IsAssignableFrom(t)) + .Where(t => typeof(ISerialisableDrawable).IsAssignableFrom(t)) .OrderBy(t => t.Name) .ToArray(); } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index c3449562c3..1d97566470 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -21,7 +21,7 @@ namespace osu.Game.Skinning /// /// A skinnable element which uses a single texture backing. /// - public partial class SkinnableSprite : SkinnableDrawable, ISkinnableDrawable + public partial class SkinnableSprite : SkinnableDrawable, ISerialisableDrawable { protected override bool ApplySizeRestrictionsToDefault => true; diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 8b37767113..7acf83576a 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -18,9 +18,9 @@ namespace osu.Game.Skinning public GlobalSkinComponentLookup.LookupType Target { get; } - public IBindableList Components => components; + public IBindableList Components => components; - private readonly BindableList components = new BindableList(); + private readonly BindableList components = new BindableList(); public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; // ensure that components are loaded even if the target container is hidden (ie. due to user toggle). @@ -68,7 +68,7 @@ namespace osu.Game.Skinning LoadComponentAsync(content, wrapper => { AddInternal(wrapper); - components.AddRange(wrapper.Children.OfType()); + components.AddRange(wrapper.Children.OfType()); ComponentsLoaded = true; }, (cancellationSource = new CancellationTokenSource()).Token); } @@ -79,7 +79,7 @@ namespace osu.Game.Skinning /// /// Thrown when attempting to add an element to a target which is not supported by the current skin. /// Thrown if the provided instance is not a . - public void Add(ISkinnableDrawable component) + public void Add(ISerialisableDrawable component) { if (content == null) throw new NotSupportedException("Attempting to add a new component to a target container which is not supported by the current skin."); @@ -94,7 +94,7 @@ namespace osu.Game.Skinning /// /// Thrown when attempting to add an element to a target which is not supported by the current skin. /// Thrown if the provided instance is not a . - public void Remove(ISkinnableDrawable component) + public void Remove(ISerialisableDrawable component) { if (content == null) throw new NotSupportedException("Attempting to remove a new component from a target container which is not supported by the current skin."); From a7b47f6503e5de4cbaa1674cfa559e7e4e71247d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 16:28:42 +0900 Subject: [PATCH 06/17] Rename `ISkinnableTarget` to `ISerialisableDrawableContainer` --- osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs | 2 +- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 10 +++++----- .../Overlays/SkinEditor/SkinEditorChangeHandler.cs | 4 ++-- ...ableTarget.cs => ISerialisableDrawableContainer.cs} | 5 +++-- osu.Game/Skinning/Skin.cs | 4 ++-- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 +++--- 6 files changed, 16 insertions(+), 15 deletions(-) rename osu.Game/Skinning/{ISkinnableTarget.cs => ISerialisableDrawableContainer.cs} (86%) diff --git a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs index 1e7bec5417..08b4c85e4a 100644 --- a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs +++ b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.SkinEditor SelectedItems.BindTo(editor.SelectedComponents); // track each target container on the current screen. - var targetContainers = target.ChildrenOfType().ToArray(); + var targetContainers = target.ChildrenOfType().ToArray(); if (targetContainers.Length == 0) { diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index aafc97d769..39187d6471 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -339,18 +339,18 @@ namespace osu.Game.Overlays.SkinEditor settingsSidebar.Add(new SkinSettingsToolbox(component)); } - private IEnumerable availableTargets => targetScreen.ChildrenOfType(); + private IEnumerable availableTargets => targetScreen.ChildrenOfType(); - private ISkinnableTarget? getFirstTarget() => availableTargets.FirstOrDefault(); + private ISerialisableDrawableContainer? getFirstTarget() => availableTargets.FirstOrDefault(); - private ISkinnableTarget? getTarget(GlobalSkinComponentLookup.LookupType target) + private ISerialisableDrawableContainer? getTarget(GlobalSkinComponentLookup.LookupType target) { return availableTargets.FirstOrDefault(c => c.Target == target); } private void revert() { - ISkinnableTarget[] targetContainers = availableTargets.ToArray(); + ISerialisableDrawableContainer[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) { @@ -370,7 +370,7 @@ namespace osu.Game.Overlays.SkinEditor if (!hasBegunMutating) return; - ISkinnableTarget[] targetContainers = availableTargets.ToArray(); + ISerialisableDrawableContainer[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) currentSkin.Value.UpdateDrawableTarget(t); diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 65872920f1..6c66714b79 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.SkinEditor { public partial class SkinEditorChangeHandler : EditorChangeHandler { - private readonly ISkinnableTarget? firstTarget; + private readonly ISerialisableDrawableContainer? firstTarget; // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable private readonly BindableList? components; @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.SkinEditor // In the future we'll want this to cover all changes, even to skin's `InstantiationInfo`. // We'll also need to consider cases where multiple targets are on screen at the same time. - firstTarget = targetScreen.ChildrenOfType().FirstOrDefault(); + firstTarget = targetScreen.ChildrenOfType().FirstOrDefault(); if (firstTarget == null) return; diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISerialisableDrawableContainer.cs similarity index 86% rename from osu.Game/Skinning/ISkinnableTarget.cs rename to osu.Game/Skinning/ISerialisableDrawableContainer.cs index 5833898d81..386ebee085 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISerialisableDrawableContainer.cs @@ -10,9 +10,10 @@ using osu.Game.Extensions; namespace osu.Game.Skinning { /// - /// Denotes a container which can house s. + /// A container which can house s. + /// Contains functionality for new drawables to be added, removed, and reloaded from provided . /// - public interface ISkinnableTarget : IDrawable + public interface ISerialisableDrawableContainer : IDrawable { /// /// The definition of this target. diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 44bdcafe4c..ebe9d2bdd3 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -143,7 +143,7 @@ namespace osu.Game.Skinning /// Remove all stored customisations for the provided target. /// /// The target container to reset. - public void ResetDrawableTarget(ISkinnableTarget targetContainer) + public void ResetDrawableTarget(ISerialisableDrawableContainer targetContainer) { DrawableComponentInfo.Remove(targetContainer.Target); } @@ -152,7 +152,7 @@ namespace osu.Game.Skinning /// Update serialised information for the provided target. /// /// The target container to serialise to this skin. - public void UpdateDrawableTarget(ISkinnableTarget targetContainer) + public void UpdateDrawableTarget(ISerialisableDrawableContainer targetContainer) { DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSerialisedInfo().ToArray(); } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 7acf83576a..abed2c09b6 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -12,7 +12,7 @@ using osu.Game.Skinning.Serialisation; namespace osu.Game.Skinning { - public partial class SkinnableTargetContainer : SkinReloadableDrawable, ISkinnableTarget + public partial class SkinnableTargetContainer : SkinReloadableDrawable, ISerialisableDrawableContainer { private Container? content; @@ -76,7 +76,7 @@ namespace osu.Game.Skinning ComponentsLoaded = true; } - /// + /// /// Thrown when attempting to add an element to a target which is not supported by the current skin. /// Thrown if the provided instance is not a . public void Add(ISerialisableDrawable component) @@ -91,7 +91,7 @@ namespace osu.Game.Skinning components.Add(component); } - /// + /// /// Thrown when attempting to add an element to a target which is not supported by the current skin. /// Thrown if the provided instance is not a . public void Remove(ISerialisableDrawable component) From e61d2d571c1b23c6f1e0d4df9f35fdc2f5b93053 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 16:35:23 +0900 Subject: [PATCH 07/17] Move the lookup type out of `ISserialisableDrawableContainer` --- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 6 +++--- osu.Game/Skinning/ISerialisableDrawableContainer.cs | 5 ----- osu.Game/Skinning/Skin.cs | 6 +++--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 39187d6471..25448906b2 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -339,7 +339,7 @@ namespace osu.Game.Overlays.SkinEditor settingsSidebar.Add(new SkinSettingsToolbox(component)); } - private IEnumerable availableTargets => targetScreen.ChildrenOfType(); + private IEnumerable availableTargets => targetScreen.ChildrenOfType(); private ISerialisableDrawableContainer? getFirstTarget() => availableTargets.FirstOrDefault(); @@ -350,7 +350,7 @@ namespace osu.Game.Overlays.SkinEditor private void revert() { - ISerialisableDrawableContainer[] targetContainers = availableTargets.ToArray(); + SkinnableTargetContainer[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) { @@ -370,7 +370,7 @@ namespace osu.Game.Overlays.SkinEditor if (!hasBegunMutating) return; - ISerialisableDrawableContainer[] targetContainers = availableTargets.ToArray(); + SkinnableTargetContainer[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) currentSkin.Value.UpdateDrawableTarget(t); diff --git a/osu.Game/Skinning/ISerialisableDrawableContainer.cs b/osu.Game/Skinning/ISerialisableDrawableContainer.cs index 386ebee085..54d8a68c95 100644 --- a/osu.Game/Skinning/ISerialisableDrawableContainer.cs +++ b/osu.Game/Skinning/ISerialisableDrawableContainer.cs @@ -15,11 +15,6 @@ namespace osu.Game.Skinning /// public interface ISerialisableDrawableContainer : IDrawable { - /// - /// The definition of this target. - /// - GlobalSkinComponentLookup.LookupType Target { get; } - /// /// A bindable list of components which are being tracked by this skinnable target. /// diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index ebe9d2bdd3..b97b167419 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -143,7 +143,7 @@ namespace osu.Game.Skinning /// Remove all stored customisations for the provided target. /// /// The target container to reset. - public void ResetDrawableTarget(ISerialisableDrawableContainer targetContainer) + public void ResetDrawableTarget(SkinnableTargetContainer targetContainer) { DrawableComponentInfo.Remove(targetContainer.Target); } @@ -152,9 +152,9 @@ namespace osu.Game.Skinning /// Update serialised information for the provided target. /// /// The target container to serialise to this skin. - public void UpdateDrawableTarget(ISerialisableDrawableContainer targetContainer) + public void UpdateDrawableTarget(SkinnableTargetContainer targetContainer) { - DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSerialisedInfo().ToArray(); + DrawableComponentInfo[targetContainer.Target] = ((ISerialisableDrawableContainer)targetContainer).CreateSerialisedInfo().ToArray(); } public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) From b1cf6d83d89050686fb1db8dc8df65d28cf0d42b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 17:51:18 +0900 Subject: [PATCH 08/17] Move extension methods closer to serialisation classes --- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 1 - osu.Game/Extensions/DrawableExtensions.cs | 41 --------------- .../SkinEditor/SkinEditorChangeHandler.cs | 1 - osu.Game/Skinning/ISerialisableDrawable.cs | 2 +- .../ISerialisableDrawableContainer.cs | 1 - .../SerialisableDrawableExtensions.cs | 51 +++++++++++++++++++ osu.Game/Skinning/SkinnableTargetContainer.cs | 1 - 7 files changed, 52 insertions(+), 46 deletions(-) create mode 100644 osu.Game/Skinning/SerialisableDrawableExtensions.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 5005cff265..339b38eacd 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -13,7 +13,6 @@ using osu.Framework.Timing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Database; -using osu.Game.Extensions; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Skinning.Legacy; diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index b6f74f5777..915a2292a2 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -1,11 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Configuration; -using osu.Game.Skinning; using osuTK; namespace osu.Game.Extensions @@ -47,42 +43,5 @@ namespace osu.Game.Extensions /// The delta vector in Parent's coordinates. public static Vector2 ScreenSpaceDeltaToParentSpace(this Drawable drawable, Vector2 delta) => drawable.Parent.ToLocalSpace(drawable.Parent.ToScreenSpace(Vector2.Zero) + delta); - - public static SerialisedDrawableInfo CreateSerialisedInfo(this Drawable component) => new SerialisedDrawableInfo(component); - - public static void ApplySerialisedInfo(this Drawable component, SerialisedDrawableInfo drawableInfo) - { - // todo: can probably make this better via deserialisation directly using a common interface. - component.Position = drawableInfo.Position; - component.Rotation = drawableInfo.Rotation; - component.Scale = drawableInfo.Scale; - component.Anchor = drawableInfo.Anchor; - component.Origin = drawableInfo.Origin; - - if (component is ISerialisableDrawable skinnable) - { - skinnable.UsesFixedAnchor = drawableInfo.UsesFixedAnchor; - - foreach (var (_, property) in component.GetSettingsSourceProperties()) - { - var bindable = ((IBindable)property.GetValue(component)!); - - if (!drawableInfo.Settings.TryGetValue(property.Name.ToSnakeCase(), out object? settingValue)) - { - // TODO: We probably want to restore default if not included in serialisation information. - // This is not simple to do as SetDefault() is only found in the typed Bindable interface right now. - continue; - } - - skinnable.CopyAdjustedSetting(bindable, settingValue); - } - } - - if (component is Container container) - { - foreach (var child in drawableInfo.Children) - container.Add(child.CreateInstance()); - } - } } } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 6c66714b79..d1a1850796 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -9,7 +9,6 @@ using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Testing; -using osu.Game.Extensions; using osu.Game.Screens.Edit; using osu.Game.Skinning; diff --git a/osu.Game/Skinning/ISerialisableDrawable.cs b/osu.Game/Skinning/ISerialisableDrawable.cs index 23cbda6344..65ece96a67 100644 --- a/osu.Game/Skinning/ISerialisableDrawable.cs +++ b/osu.Game/Skinning/ISerialisableDrawable.cs @@ -16,7 +16,7 @@ namespace osu.Game.Skinning /// Attaching this interface to any will make it serialisable to user skins (see ). /// Adding annotated bindables will also allow serialising settings automatically. /// - /// Serialisation is done via using . + /// Serialisation is done via using . /// public interface ISerialisableDrawable : IDrawable { diff --git a/osu.Game/Skinning/ISerialisableDrawableContainer.cs b/osu.Game/Skinning/ISerialisableDrawableContainer.cs index 54d8a68c95..9f93d8a2e3 100644 --- a/osu.Game/Skinning/ISerialisableDrawableContainer.cs +++ b/osu.Game/Skinning/ISerialisableDrawableContainer.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Game.Extensions; namespace osu.Game.Skinning { diff --git a/osu.Game/Skinning/SerialisableDrawableExtensions.cs b/osu.Game/Skinning/SerialisableDrawableExtensions.cs new file mode 100644 index 0000000000..5e8c2843a9 --- /dev/null +++ b/osu.Game/Skinning/SerialisableDrawableExtensions.cs @@ -0,0 +1,51 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; +using osu.Game.Extensions; + +namespace osu.Game.Skinning +{ + public static class SerialisableDrawableExtensions + { + public static SerialisedDrawableInfo CreateSerialisedInfo(this Drawable component) => new SerialisedDrawableInfo(component); + + public static void ApplySerialisedInfo(this Drawable component, SerialisedDrawableInfo drawableInfo) + { + // todo: can probably make this better via deserialisation directly using a common interface. + component.Position = drawableInfo.Position; + component.Rotation = drawableInfo.Rotation; + component.Scale = drawableInfo.Scale; + component.Anchor = drawableInfo.Anchor; + component.Origin = drawableInfo.Origin; + + if (component is ISerialisableDrawable skinnable) + { + skinnable.UsesFixedAnchor = drawableInfo.UsesFixedAnchor; + + foreach (var (_, property) in component.GetSettingsSourceProperties()) + { + var bindable = ((IBindable)property.GetValue(component)!); + + if (!drawableInfo.Settings.TryGetValue(property.Name.ToSnakeCase(), out object? settingValue)) + { + // TODO: We probably want to restore default if not included in serialisation information. + // This is not simple to do as SetDefault() is only found in the typed Bindable interface right now. + continue; + } + + skinnable.CopyAdjustedSetting(bindable, settingValue); + } + } + + if (component is Container container) + { + foreach (var child in drawableInfo.Children) + container.Add(child.CreateInstance()); + } + } + } +} diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index abed2c09b6..d29152da6c 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -8,7 +8,6 @@ using System.Threading; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Skinning.Serialisation; namespace osu.Game.Skinning { From a92e42bb842ef318c84cbb10306f05042785e441 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 18:31:55 +0900 Subject: [PATCH 09/17] Rename `SkinnableTargetContainer` to `SkinComponentsContainer` Also use full `SkinComponentsContainerLookup` instead of the sub-type. This will potentially be useful once we bring in per-ruleset targets. --- .../TestSceneCatchPlayerLegacySkin.cs | 2 +- .../Legacy/CatchLegacySkinTransformer.cs | 6 +++--- .../Skins/SkinDeserialisationTest.cs | 16 ++++++++-------- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 10 +++++----- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 10 +++++----- .../Visual/Gameplay/TestSceneSkinEditor.cs | 2 +- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 12 ++++++------ osu.Game/Screens/Play/HUDOverlay.cs | 6 +++--- osu.Game/Screens/Select/SongSelect.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 8 ++++---- osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 +++--- osu.Game/Skinning/LegacySkin.cs | 6 +++--- osu.Game/Skinning/Skin.cs | 18 +++++++++--------- ...ontainer.cs => SkinComponentsContainer.cs} | 19 ++++++++++++++----- ...up.cs => SkinComponentsContainerLookup.cs} | 10 +++++----- osu.Game/Skinning/TrianglesSkin.cs | 8 ++++---- .../Tests/Visual/LegacySkinPlayerTestScene.cs | 4 ++-- 17 files changed, 77 insertions(+), 68 deletions(-) rename osu.Game/Skinning/{SkinnableTargetContainer.cs => SkinComponentsContainer.cs} (83%) rename osu.Game/Skinning/{GlobalSkinComponentLookup.cs => SkinComponentsContainerLookup.cs} (55%) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs index 8f3f39be9b..4c1ba33aa2 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Tests if (withModifiedSkin) { AddStep("change component scale", () => Player.ChildrenOfType().First().Scale = new Vector2(2f)); - AddStep("update target", () => Player.ChildrenOfType().ForEach(LegacySkin.UpdateDrawableTarget)); + AddStep("update target", () => Player.ChildrenOfType().ForEach(LegacySkin.UpdateDrawableTarget)); AddStep("exit player", () => Player.Exit()); CreateTest(); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index a06435583b..6704fd82e9 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -28,11 +28,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GlobalSkinComponentLookup targetComponent) + if (lookup is SkinComponentsContainerLookup componentLookup) { - switch (targetComponent.Lookup) + switch (componentLookup.Target) { - case GlobalSkinComponentLookup.LookupType.MainHUDComponents: + case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: var components = base.GetDrawableComponent(lookup) as Container; if (providesComboCounter && components != null) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index b897523560..5d7cbad46d 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.MainHUDComponents], Has.Length.EqualTo(9)); } } @@ -101,10 +101,10 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.MainHUDComponents], Has.Length.EqualTo(6)); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.SongSelect], Has.Length.EqualTo(1)); - var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect].First(); + var skinnableInfo = skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.SongSelect].First(); Assert.That(skinnableInfo.Type, Is.EqualTo(typeof(SkinnableSprite))); Assert.That(skinnableInfo.Settings.First().Key, Is.EqualTo("sprite_name")); @@ -115,10 +115,10 @@ namespace osu.Game.Tests.Skins using (var storage = new ZipArchiveReader(stream)) { var skin = new TestSkin(new SkinInfo(), null, storage); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); - Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.MainHUDComponents], Has.Length.EqualTo(8)); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); + Assert.That(skin.DrawableComponentInfo[SkinComponentsContainerLookup.TargetArea.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 339b38eacd..514a2d7e84 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -36,8 +36,8 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestEmptyLegacyBeatmapSkinFallsBack() { CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null)); - AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); - AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); + AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); + AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinComponentsContainerLookup.TargetArea.MainHUDComponents, skinManager.CurrentSkin.Value)); } protected void CreateSkinTest(SkinInfo gameCurrentSkin, Func getBeatmapSkin) @@ -52,9 +52,9 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - protected bool AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType target, ISkin expectedSource) + protected bool AssertComponentsFromExpectedSource(SkinComponentsContainerLookup.TargetArea target, ISkin expectedSource) { - var targetContainer = Player.ChildrenOfType().First(s => s.Target == target); + var targetContainer = Player.ChildrenOfType().First(s => s.Lookup.Target == target); var actualComponentsContainer = targetContainer.ChildrenOfType().SingleOrDefault(c => c.Parent == targetContainer); if (actualComponentsContainer == null) @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSerialisedInfo(); - var expectedComponentsContainer = expectedSource.GetDrawableComponent(new GlobalSkinComponentLookup(target)) as Container; + var expectedComponentsContainer = expectedSource.GetDrawableComponent(new SkinComponentsContainerLookup(target)) as Container; if (expectedComponentsContainer == null) return false; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 5e1412d79b..b918c5e64a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -235,8 +235,8 @@ namespace osu.Game.Tests.Visual.Gameplay createNew(); AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded); - AddUntilStep("wait for components to be hidden", () => hudOverlay.ChildrenOfType().Single().Alpha == 0); - AddUntilStep("wait for hud load", () => hudOverlay.ChildrenOfType().All(c => c.ComponentsLoaded)); + AddUntilStep("wait for components to be hidden", () => hudOverlay.ChildrenOfType().Single().Alpha == 0); + AddUntilStep("wait for hud load", () => hudOverlay.ChildrenOfType().All(c => c.ComponentsLoaded)); AddStep("bind on update", () => { @@ -254,10 +254,10 @@ namespace osu.Game.Tests.Visual.Gameplay createNew(); AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded); - AddUntilStep("wait for components to be hidden", () => hudOverlay.ChildrenOfType().Single().Alpha == 0); + AddUntilStep("wait for components to be hidden", () => hudOverlay.ChildrenOfType().Single().Alpha == 0); - AddStep("reload components", () => hudOverlay.ChildrenOfType().Single().Reload()); - AddUntilStep("skinnable components loaded", () => hudOverlay.ChildrenOfType().Single().ComponentsLoaded); + AddStep("reload components", () => hudOverlay.ChildrenOfType().Single().Reload()); + AddUntilStep("skinnable components loaded", () => hudOverlay.ChildrenOfType().Single().ComponentsLoaded); } private void createNew(Action? action = null) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 86d97b4999..62fdb67a30 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Gameplay { base.SetUpSteps(); - AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); + AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); AddStep("reload skin editor", () => { diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 25448906b2..133ec10202 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -339,25 +339,25 @@ namespace osu.Game.Overlays.SkinEditor settingsSidebar.Add(new SkinSettingsToolbox(component)); } - private IEnumerable availableTargets => targetScreen.ChildrenOfType(); + private IEnumerable availableTargets => targetScreen.ChildrenOfType(); private ISerialisableDrawableContainer? getFirstTarget() => availableTargets.FirstOrDefault(); - private ISerialisableDrawableContainer? getTarget(GlobalSkinComponentLookup.LookupType target) + private ISerialisableDrawableContainer? getTarget(SkinComponentsContainerLookup.TargetArea target) { - return availableTargets.FirstOrDefault(c => c.Target == target); + return availableTargets.FirstOrDefault(c => c.Lookup.Target == target); } private void revert() { - SkinnableTargetContainer[] targetContainers = availableTargets.ToArray(); + SkinComponentsContainer[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) { currentSkin.Value.ResetDrawableTarget(t); // add back default components - getTarget(t.Target)?.Reload(); + getTarget(t.Lookup.Target)?.Reload(); } } @@ -370,7 +370,7 @@ namespace osu.Game.Overlays.SkinEditor if (!hasBegunMutating) return; - SkinnableTargetContainer[] targetContainers = availableTargets.ToArray(); + SkinComponentsContainer[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) currentSkin.Value.UpdateDrawableTarget(t); diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 4d1f0b96b6..e41afd7722 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -88,7 +88,7 @@ namespace osu.Game.Screens.Play private readonly BindableBool holdingForHUD = new BindableBool(); - private readonly SkinnableTargetContainer mainComponents; + private readonly SkinComponentsContainer mainComponents; /// /// A flow which sits at the left side of the screen to house leaderboard (and related) components. @@ -390,7 +390,7 @@ namespace osu.Game.Screens.Play } } - private partial class MainComponentsContainer : SkinnableTargetContainer + private partial class MainComponentsContainer : SkinComponentsContainer { private Bindable scoringMode; @@ -398,7 +398,7 @@ namespace osu.Game.Screens.Play private OsuConfigManager config { get; set; } public MainComponentsContainer() - : base(GlobalSkinComponentLookup.LookupType.MainHUDComponents) + : base(new SkinComponentsContainerLookup(SkinComponentsContainerLookup.TargetArea.MainHUDComponents)) { RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8786821c77..2d3d0f88d7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -273,7 +273,7 @@ namespace osu.Game.Screens.Select } } }, - new SkinnableTargetContainer(GlobalSkinComponentLookup.LookupType.SongSelect) + new SkinComponentsContainer(new SkinComponentsContainerLookup(SkinComponentsContainerLookup.TargetArea.SongSelect)) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 71f0888c6f..7b4d51ee83 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -90,10 +90,10 @@ namespace osu.Game.Skinning switch (lookup) { - case GlobalSkinComponentLookup globalLookup: - switch (globalLookup.Lookup) + case SkinComponentsContainerLookup componentLookup: + switch (componentLookup.Target) { - case GlobalSkinComponentLookup.LookupType.SongSelect: + case SkinComponentsContainerLookup.TargetArea.SongSelect: var songSelectComponents = new DefaultSkinComponentsContainer(_ => { // do stuff when we need to. @@ -101,7 +101,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case GlobalSkinComponentLookup.LookupType.MainHUDComponents: + case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: var skinnableTargetWrapper = new DefaultSkinComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 8407b144f8..84ca6ed967 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -45,11 +45,11 @@ namespace osu.Game.Skinning public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GlobalSkinComponentLookup targetComponent) + if (lookup is SkinComponentsContainerLookup targetComponent) { - switch (targetComponent.Lookup) + switch (targetComponent.Target) { - case GlobalSkinComponentLookup.LookupType.MainHUDComponents: + case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: // this should exist in LegacySkin instead, but there isn't a fallback skin for LegacySkins yet. // therefore keep the check here until fallback default legacy skin is supported. if (!this.HasFont(LegacyFont.Score)) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 284a938bce..c581fcdfb6 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -343,10 +343,10 @@ namespace osu.Game.Skinning switch (lookup) { - case GlobalSkinComponentLookup target: - switch (target.Lookup) + case SkinComponentsContainerLookup componentLookup: + switch (componentLookup.Target) { - case GlobalSkinComponentLookup.LookupType.MainHUDComponents: + case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: var skinnableTargetWrapper = new DefaultSkinComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index b97b167419..977fab1b7e 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -37,9 +37,9 @@ namespace osu.Game.Skinning public SkinConfiguration Configuration { get; set; } - public IDictionary DrawableComponentInfo => drawableComponentInfo; + public IDictionary DrawableComponentInfo => drawableComponentInfo; - private readonly Dictionary drawableComponentInfo = new Dictionary(); + private readonly Dictionary drawableComponentInfo = new Dictionary(); public abstract ISample? GetSample(ISampleInfo sampleInfo); @@ -100,7 +100,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); // skininfo files may be null for default skin. - foreach (GlobalSkinComponentLookup.LookupType skinnableTarget in Enum.GetValues()) + foreach (SkinComponentsContainerLookup.TargetArea skinnableTarget in Enum.GetValues()) { string filename = $"{skinnableTarget}.json"; @@ -143,18 +143,18 @@ namespace osu.Game.Skinning /// Remove all stored customisations for the provided target. /// /// The target container to reset. - public void ResetDrawableTarget(SkinnableTargetContainer targetContainer) + public void ResetDrawableTarget(SkinComponentsContainer targetContainer) { - DrawableComponentInfo.Remove(targetContainer.Target); + DrawableComponentInfo.Remove(targetContainer.Lookup.Target); } /// /// Update serialised information for the provided target. /// /// The target container to serialise to this skin. - public void UpdateDrawableTarget(SkinnableTargetContainer targetContainer) + public void UpdateDrawableTarget(SkinComponentsContainer targetContainer) { - DrawableComponentInfo[targetContainer.Target] = ((ISerialisableDrawableContainer)targetContainer).CreateSerialisedInfo().ToArray(); + DrawableComponentInfo[targetContainer.Lookup.Target] = ((ISerialisableDrawableContainer)targetContainer).CreateSerialisedInfo().ToArray(); } public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) @@ -165,8 +165,8 @@ namespace osu.Game.Skinning case SkinnableSprite.SpriteComponentLookup sprite: return this.GetAnimation(sprite.LookupName, false, false); - case GlobalSkinComponentLookup target: - if (!DrawableComponentInfo.TryGetValue(target.Lookup, out var skinnableInfo)) + case SkinComponentsContainerLookup componentLookup: + if (!DrawableComponentInfo.TryGetValue(componentLookup.Target, out var skinnableInfo)) return null; var components = new List(); diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinComponentsContainer.cs similarity index 83% rename from osu.Game/Skinning/SkinnableTargetContainer.cs rename to osu.Game/Skinning/SkinComponentsContainer.cs index d29152da6c..2620b40729 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinComponentsContainer.cs @@ -11,11 +11,20 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Skinning { - public partial class SkinnableTargetContainer : SkinReloadableDrawable, ISerialisableDrawableContainer + /// + /// A container which holds many skinnable components, with functionality to add, remove and reload layouts. + /// Used to allow user customisation of skin layouts. + /// + /// + /// This is currently used as a means of serialising skin layouts to files. + /// Currently, one json file in a skin will represent one , containing + /// the output of . + /// + public partial class SkinComponentsContainer : SkinReloadableDrawable, ISerialisableDrawableContainer { private Container? content; - public GlobalSkinComponentLookup.LookupType Target { get; } + public SkinComponentsContainerLookup Lookup { get; } public IBindableList Components => components; @@ -27,9 +36,9 @@ namespace osu.Game.Skinning private CancellationTokenSource? cancellationSource; - public SkinnableTargetContainer(GlobalSkinComponentLookup.LookupType target) + public SkinComponentsContainer(SkinComponentsContainerLookup lookup) { - Target = target; + Lookup = lookup; } public void Reload(SerialisedDrawableInfo[] skinnableInfo) @@ -46,7 +55,7 @@ namespace osu.Game.Skinning }); } - public void Reload() => Reload(CurrentSkin.GetDrawableComponent(new GlobalSkinComponentLookup(Target)) as Container); + public void Reload() => Reload(CurrentSkin.GetDrawableComponent(Lookup) as Container); public void Reload(Container? componentsContainer) { diff --git a/osu.Game/Skinning/GlobalSkinComponentLookup.cs b/osu.Game/Skinning/SkinComponentsContainerLookup.cs similarity index 55% rename from osu.Game/Skinning/GlobalSkinComponentLookup.cs rename to osu.Game/Skinning/SkinComponentsContainerLookup.cs index 7dcc3c4f14..ac6e98b23a 100644 --- a/osu.Game/Skinning/GlobalSkinComponentLookup.cs +++ b/osu.Game/Skinning/SkinComponentsContainerLookup.cs @@ -3,16 +3,16 @@ namespace osu.Game.Skinning { - public class GlobalSkinComponentLookup : ISkinComponentLookup + public class SkinComponentsContainerLookup : ISkinComponentLookup { - public readonly LookupType Lookup; + public readonly TargetArea Target; - public GlobalSkinComponentLookup(LookupType lookup) + public SkinComponentsContainerLookup(TargetArea target) { - Lookup = lookup; + Target = target; } - public enum LookupType + public enum TargetArea { MainHUDComponents, SongSelect diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 7de2b124e7..5e0712012e 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -68,10 +68,10 @@ namespace osu.Game.Skinning switch (lookup) { - case GlobalSkinComponentLookup target: - switch (target.Lookup) + case SkinComponentsContainerLookup componentLookup: + switch (componentLookup.Target) { - case GlobalSkinComponentLookup.LookupType.SongSelect: + case SkinComponentsContainerLookup.TargetArea.SongSelect: var songSelectComponents = new DefaultSkinComponentsContainer(_ => { // do stuff when we need to. @@ -79,7 +79,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case GlobalSkinComponentLookup.LookupType.MainHUDComponents: + case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: var skinnableTargetWrapper = new DefaultSkinComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs b/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs index c5efdf36b4..2e254f5b95 100644 --- a/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs +++ b/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs @@ -45,13 +45,13 @@ namespace osu.Game.Tests.Visual private void addResetTargetsStep() { - AddStep("reset targets", () => this.ChildrenOfType().ForEach(t => + AddStep("reset targets", () => this.ChildrenOfType().ForEach(t => { LegacySkin.ResetDrawableTarget(t); t.Reload(); })); - AddUntilStep("wait for components to load", () => this.ChildrenOfType().All(t => t.ComponentsLoaded)); + AddUntilStep("wait for components to load", () => this.ChildrenOfType().All(t => t.ComponentsLoaded)); } public partial class SkinProvidingPlayer : TestPlayer From 08ed174f61d3547d8019af4a436309e8b2dc1486 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Feb 2023 18:48:13 +0900 Subject: [PATCH 10/17] Change `GameplaySkinComponentLookup`'s generic to always be an `enum` And document the class better. --- osu.Game/Skinning/GameplaySkinComponentLookup.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/GameplaySkinComponentLookup.cs b/osu.Game/Skinning/GameplaySkinComponentLookup.cs index 9247ca0e4d..984df3f5bc 100644 --- a/osu.Game/Skinning/GameplaySkinComponentLookup.cs +++ b/osu.Game/Skinning/GameplaySkinComponentLookup.cs @@ -1,12 +1,23 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Skinning { + /// + /// A lookup typed intended for use for skinnable gameplay components (not HUD level components). + /// + /// + /// The most common usage of this class is for ruleset-specific skinning implementations, but it can also be used directly + /// (see 's usage for ) where ruleset-agnostic elements are required. + /// + /// An enum lookup type. public class GameplaySkinComponentLookup : ISkinComponentLookup - where T : notnull + where T : Enum { public readonly T Component; @@ -16,7 +27,7 @@ namespace osu.Game.Skinning } protected virtual string RulesetPrefix => string.Empty; - protected virtual string ComponentName => Component.ToString() ?? string.Empty; + protected virtual string ComponentName => Component.ToString(); public string LookupName => string.Join('/', new[] { "Gameplay", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s))); From 0b25f7baeb1e71be25fb7f3db18760493ded2d7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Feb 2023 15:27:30 +0900 Subject: [PATCH 11/17] Reword and fix typos in some new xmldoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Skinning/GameplaySkinComponentLookup.cs | 2 +- osu.Game/Skinning/ISkinSource.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/GameplaySkinComponentLookup.cs b/osu.Game/Skinning/GameplaySkinComponentLookup.cs index 984df3f5bc..a44bf3a43d 100644 --- a/osu.Game/Skinning/GameplaySkinComponentLookup.cs +++ b/osu.Game/Skinning/GameplaySkinComponentLookup.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Skinning { /// - /// A lookup typed intended for use for skinnable gameplay components (not HUD level components). + /// A lookup type intended for use for skinnable gameplay components (not HUD level components). /// /// /// The most common usage of this class is for ruleset-specific skinning implementations, but it can also be used directly diff --git a/osu.Game/Skinning/ISkinSource.cs b/osu.Game/Skinning/ISkinSource.cs index b05d52d47c..0dfc99e3bc 100644 --- a/osu.Game/Skinning/ISkinSource.cs +++ b/osu.Game/Skinning/ISkinSource.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace osu.Game.Skinning { /// - /// An abstract skin implementation which generally provides access to more than one skins (with fallback logic). + /// An abstract skin implementation, whose primary purpose is to properly handle component fallback across multiple layers of skins (e.g.: beatmap skin, user skin, default skin). /// /// /// Common usage is to do an initial lookup via , and use the returned From eea0cd3cf8c29d200cdb685f1c1cd75800165f88 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Feb 2023 15:31:35 +0900 Subject: [PATCH 12/17] Reword xmldoc on `ISerialisableDrawable` to make less skin-centric --- osu.Game/Skinning/ISerialisableDrawable.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/ISerialisableDrawable.cs b/osu.Game/Skinning/ISerialisableDrawable.cs index 65ece96a67..503b44c2dd 100644 --- a/osu.Game/Skinning/ISerialisableDrawable.cs +++ b/osu.Game/Skinning/ISerialisableDrawable.cs @@ -10,13 +10,14 @@ using osu.Game.Configuration; namespace osu.Game.Skinning { /// - /// A drawable which can be serialised to a skin, placed and customised via the skin layout editor. + /// A drawable which is intended to be serialised to . /// /// - /// Attaching this interface to any will make it serialisable to user skins (see ). - /// Adding annotated bindables will also allow serialising settings automatically. + /// This is currently used exclusively for serialisation to a skin, and leaned on heavily to allow placement and customisation in the skin layout editor. + /// That said, it is intended to be flexible enough to potentially be used in other places we want to serialise drawables in the future. /// - /// Serialisation is done via using . + /// Attaching this interface to any will make it serialisable via . + /// Adding annotated bindables will also allow serialising settings automatically. /// public interface ISerialisableDrawable : IDrawable { From 76f7accd1378be9ca051c0cf3e1b2936d9b14eaf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Feb 2023 15:33:56 +0900 Subject: [PATCH 13/17] Standardise all local `SkinComponentsContainerLookup` variables to `containerLookup` --- .../Skinning/Legacy/CatchLegacySkinTransformer.cs | 4 ++-- osu.Game/Skinning/ArgonSkin.cs | 4 ++-- osu.Game/Skinning/LegacyBeatmapSkin.cs | 4 ++-- osu.Game/Skinning/LegacySkin.cs | 4 ++-- osu.Game/Skinning/Skin.cs | 4 ++-- osu.Game/Skinning/TrianglesSkin.cs | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 6704fd82e9..fb8af9bdb6 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is SkinComponentsContainerLookup componentLookup) + if (lookup is SkinComponentsContainerLookup containerLookup) { - switch (componentLookup.Target) + switch (containerLookup.Target) { case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: var components = base.GetDrawableComponent(lookup) as Container; diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 7b4d51ee83..737b222b9d 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -90,8 +90,8 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinComponentsContainerLookup componentLookup: - switch (componentLookup.Target) + case SkinComponentsContainerLookup containerLookup: + switch (containerLookup.Target) { case SkinComponentsContainerLookup.TargetArea.SongSelect: var songSelectComponents = new DefaultSkinComponentsContainer(_ => diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 84ca6ed967..1cbfda16cf 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -45,9 +45,9 @@ namespace osu.Game.Skinning public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is SkinComponentsContainerLookup targetComponent) + if (lookup is SkinComponentsContainerLookup containerLookup) { - switch (targetComponent.Target) + switch (containerLookup.Target) { case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: // this should exist in LegacySkin instead, but there isn't a fallback skin for LegacySkins yet. diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index c581fcdfb6..98d9f1d617 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -343,8 +343,8 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinComponentsContainerLookup componentLookup: - switch (componentLookup.Target) + case SkinComponentsContainerLookup containerLookup: + switch (containerLookup.Target) { case SkinComponentsContainerLookup.TargetArea.MainHUDComponents: var skinnableTargetWrapper = new DefaultSkinComponentsContainer(container => diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 977fab1b7e..f261937012 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -165,8 +165,8 @@ namespace osu.Game.Skinning case SkinnableSprite.SpriteComponentLookup sprite: return this.GetAnimation(sprite.LookupName, false, false); - case SkinComponentsContainerLookup componentLookup: - if (!DrawableComponentInfo.TryGetValue(componentLookup.Target, out var skinnableInfo)) + case SkinComponentsContainerLookup containerLookup: + if (!DrawableComponentInfo.TryGetValue(containerLookup.Target, out var skinnableInfo)) return null; var components = new List(); diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 5e0712012e..12cdb71744 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -68,8 +68,8 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinComponentsContainerLookup componentLookup: - switch (componentLookup.Target) + case SkinComponentsContainerLookup containerLookup: + switch (containerLookup.Target) { case SkinComponentsContainerLookup.TargetArea.SongSelect: var songSelectComponents = new DefaultSkinComponentsContainer(_ => From 81dcc105a96fb72b8cbd066432fc70fef532620a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Feb 2023 15:34:41 +0900 Subject: [PATCH 14/17] Rename left-over `skinnable` naming in `SerialisedDrawableExtensions` --- osu.Game/Skinning/SerialisableDrawableExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Skinning/SerialisableDrawableExtensions.cs b/osu.Game/Skinning/SerialisableDrawableExtensions.cs index 5e8c2843a9..51b57a000d 100644 --- a/osu.Game/Skinning/SerialisableDrawableExtensions.cs +++ b/osu.Game/Skinning/SerialisableDrawableExtensions.cs @@ -22,9 +22,9 @@ namespace osu.Game.Skinning component.Anchor = drawableInfo.Anchor; component.Origin = drawableInfo.Origin; - if (component is ISerialisableDrawable skinnable) + if (component is ISerialisableDrawable serialisableDrawable) { - skinnable.UsesFixedAnchor = drawableInfo.UsesFixedAnchor; + serialisableDrawable.UsesFixedAnchor = drawableInfo.UsesFixedAnchor; foreach (var (_, property) in component.GetSettingsSourceProperties()) { @@ -37,7 +37,7 @@ namespace osu.Game.Skinning continue; } - skinnable.CopyAdjustedSetting(bindable, settingValue); + serialisableDrawable.CopyAdjustedSetting(bindable, settingValue); } } From cb7df7282b78e9fd3abf05aac19d0fedf515416f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Feb 2023 20:01:59 +0900 Subject: [PATCH 15/17] Apply NRT to `SerialisedDrawableInfo` --- osu.Game/Skinning/SerialisedDrawableInfo.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Skinning/SerialisedDrawableInfo.cs b/osu.Game/Skinning/SerialisedDrawableInfo.cs index f571f1a945..12f6d3ac7e 100644 --- a/osu.Game/Skinning/SerialisedDrawableInfo.cs +++ b/osu.Game/Skinning/SerialisedDrawableInfo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -28,7 +26,7 @@ namespace osu.Game.Skinning [Serializable] public sealed class SerialisedDrawableInfo { - public Type Type { get; set; } + public Type Type { get; set; } = null!; public Vector2 Position { get; set; } From 1a63ca9ecedd280d19b6dbdf48a311c5c56c1ce3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Feb 2023 14:18:05 +0900 Subject: [PATCH 16/17] Add xmldoc around `SkinComponentsContainerLookup` --- osu.Game/Skinning/SkinComponentsContainer.cs | 3 +++ osu.Game/Skinning/SkinComponentsContainerLookup.cs | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/osu.Game/Skinning/SkinComponentsContainer.cs b/osu.Game/Skinning/SkinComponentsContainer.cs index 2620b40729..7d7a4965f6 100644 --- a/osu.Game/Skinning/SkinComponentsContainer.cs +++ b/osu.Game/Skinning/SkinComponentsContainer.cs @@ -24,6 +24,9 @@ namespace osu.Game.Skinning { private Container? content; + /// + /// The lookup criteria which will be used to retrieve components from the active skin. + /// public SkinComponentsContainerLookup Lookup { get; } public IBindableList Components => components; diff --git a/osu.Game/Skinning/SkinComponentsContainerLookup.cs b/osu.Game/Skinning/SkinComponentsContainerLookup.cs index ac6e98b23a..b0b87f18b5 100644 --- a/osu.Game/Skinning/SkinComponentsContainerLookup.cs +++ b/osu.Game/Skinning/SkinComponentsContainerLookup.cs @@ -3,8 +3,14 @@ namespace osu.Game.Skinning { + /// + /// Represents a lookup of a collection of elements that make up a particular skinnable of the game. + /// public class SkinComponentsContainerLookup : ISkinComponentLookup { + /// + /// The target area / layer of the game for which skin components will be returned. + /// public readonly TargetArea Target; public SkinComponentsContainerLookup(TargetArea target) @@ -12,6 +18,9 @@ namespace osu.Game.Skinning Target = target; } + /// + /// Represents a particular area or part of a game screen whose layout can be customised using the skin editor. + /// public enum TargetArea { MainHUDComponents, From 449e5fa6f82d10a9006db2ed5d96ffbe9ebd0a26 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 17 Feb 2023 22:09:52 +0300 Subject: [PATCH 17/17] Rename one more left-over `skinnable` naming --- osu.Game/Skinning/SerialisedDrawableInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/SerialisedDrawableInfo.cs b/osu.Game/Skinning/SerialisedDrawableInfo.cs index 12f6d3ac7e..29078f0d74 100644 --- a/osu.Game/Skinning/SerialisedDrawableInfo.cs +++ b/osu.Game/Skinning/SerialisedDrawableInfo.cs @@ -64,8 +64,8 @@ namespace osu.Game.Skinning Anchor = component.Anchor; Origin = component.Origin; - if (component is ISerialisableDrawable skinnable) - UsesFixedAnchor = skinnable.UsesFixedAnchor; + if (component is ISerialisableDrawable serialisableDrawable) + UsesFixedAnchor = serialisableDrawable.UsesFixedAnchor; foreach (var (_, property) in component.GetSettingsSourceProperties()) {