From 64e3325b4140bf89e30cb8cb2e7f9fa90dd64716 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Thu, 5 Nov 2020 18:00:26 +0900
Subject: [PATCH] Abstract out common part of legacy spinner implementations

Some elements going forward will be shared, so it makes sense to have a
common base class to add these shared elements.
---
 .../Skinning/LegacyNewStyleSpinner.cs         | 33 +++-----------
 .../Skinning/LegacyOldStyleSpinner.cs         | 31 +++----------
 .../Skinning/LegacySpinner.cs                 | 44 +++++++++++++++++++
 3 files changed, 57 insertions(+), 51 deletions(-)
 create mode 100644 osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs

diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs
index 31e2ab1239..5b6aac8f08 100644
--- a/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs
@@ -3,7 +3,6 @@
 
 using osu.Framework.Allocation;
 using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
 using osu.Framework.Graphics.Sprites;
 using osu.Framework.Utils;
 using osu.Game.Rulesets.Objects.Drawables;
@@ -19,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
     /// Legacy skinned spinner with two main spinning layers, one fixed overlay and one final spinning overlay.
     /// No background layer.
     /// </summary>
-    public class LegacyNewStyleSpinner : CompositeDrawable
+    public class LegacyNewStyleSpinner : LegacySpinner
     {
         private Sprite glow;
         private Sprite discBottom;
@@ -27,17 +26,13 @@ namespace osu.Game.Rulesets.Osu.Skinning
         private Sprite spinningMiddle;
         private Sprite fixedMiddle;
 
-        private DrawableSpinner drawableSpinner;
-
         private const float final_scale = 0.625f;
 
         private readonly Color4 glowColour = new Color4(3, 151, 255, 255);
 
         [BackgroundDependencyLoader]
-        private void load(ISkinSource source, DrawableHitObject drawableObject)
+        private void load(ISkinSource source)
         {
-            drawableSpinner = (DrawableSpinner)drawableObject;
-
             Scale = new Vector2(final_scale);
 
             InternalChildren = new Drawable[]
@@ -77,16 +72,10 @@ namespace osu.Game.Rulesets.Osu.Skinning
             };
         }
 
-        protected override void LoadComplete()
+        protected override void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
         {
-            base.LoadComplete();
+            base.UpdateStateTransforms(drawableHitObject, state);
 
-            drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
-            updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
-        }
-
-        private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
-        {
             switch (drawableHitObject)
             {
                 case DrawableSpinner d:
@@ -125,20 +114,12 @@ namespace osu.Game.Rulesets.Osu.Skinning
         protected override void Update()
         {
             base.Update();
-            spinningMiddle.Rotation = discTop.Rotation = drawableSpinner.RotationTracker.Rotation;
+            spinningMiddle.Rotation = discTop.Rotation = DrawableSpinner.RotationTracker.Rotation;
             discBottom.Rotation = discTop.Rotation / 3;
 
-            glow.Alpha = drawableSpinner.Progress;
+            glow.Alpha = DrawableSpinner.Progress;
 
-            Scale = new Vector2(final_scale * (0.8f + (float)Interpolation.ApplyEasing(Easing.Out, drawableSpinner.Progress) * 0.2f));
-        }
-
-        protected override void Dispose(bool isDisposing)
-        {
-            base.Dispose(isDisposing);
-
-            if (drawableSpinner != null)
-                drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms;
+            Scale = new Vector2(final_scale * (0.8f + (float)Interpolation.ApplyEasing(Easing.Out, DrawableSpinner.Progress) * 0.2f));
         }
     }
 }
diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs
index 1954ff6e38..56702e6712 100644
--- a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs
@@ -18,9 +18,8 @@ namespace osu.Game.Rulesets.Osu.Skinning
     /// <summary>
     /// Legacy skinned spinner with one main spinning layer and a background layer.
     /// </summary>
-    public class LegacyOldStyleSpinner : CompositeDrawable
+    public class LegacyOldStyleSpinner : LegacySpinner
     {
-        private DrawableSpinner drawableSpinner;
         private Sprite disc;
         private Sprite metreSprite;
         private Container metre;
@@ -31,14 +30,10 @@ namespace osu.Game.Rulesets.Osu.Skinning
         private const float final_metre_height = 692 * sprite_scale;
 
         [BackgroundDependencyLoader]
-        private void load(ISkinSource source, DrawableHitObject drawableObject)
+        private void load(ISkinSource source)
         {
             spinnerBlink = source.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.SpinnerNoBlink)?.Value != true;
 
-            drawableSpinner = (DrawableSpinner)drawableObject;
-
-            RelativeSizeAxes = Axes.Both;
-
             InternalChild = new Container
             {
                 // the old-style spinner relied heavily on absolute screen-space coordinate values.
@@ -85,16 +80,10 @@ namespace osu.Game.Rulesets.Osu.Skinning
             };
         }
 
-        protected override void LoadComplete()
+        protected override void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
         {
-            base.LoadComplete();
+            base.UpdateStateTransforms(drawableHitObject, state);
 
-            drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
-            updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
-        }
-
-        private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
-        {
             if (!(drawableHitObject is DrawableSpinner d))
                 return;
 
@@ -110,11 +99,11 @@ namespace osu.Game.Rulesets.Osu.Skinning
         protected override void Update()
         {
             base.Update();
-            disc.Rotation = drawableSpinner.RotationTracker.Rotation;
+            disc.Rotation = DrawableSpinner.RotationTracker.Rotation;
 
             // careful: need to call this exactly once for all calculations in a frame
             // as the function has a random factor in it
-            var metreHeight = getMetreHeight(drawableSpinner.Progress);
+            var metreHeight = getMetreHeight(DrawableSpinner.Progress);
 
             // hack to make the metre blink up from below than down from above.
             // move down the container to be able to apply masking for the metre,
@@ -140,13 +129,5 @@ namespace osu.Game.Rulesets.Osu.Skinning
 
             return (float)barCount / total_bars * final_metre_height;
         }
-
-        protected override void Dispose(bool isDisposing)
-        {
-            base.Dispose(isDisposing);
-
-            if (drawableSpinner != null)
-                drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms;
-        }
     }
 }
diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs
new file mode 100644
index 0000000000..efbafdc17a
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs
@@ -0,0 +1,44 @@
+// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+
+namespace osu.Game.Rulesets.Osu.Skinning
+{
+    public abstract class LegacySpinner : CompositeDrawable
+    {
+        protected DrawableSpinner DrawableSpinner { get; private set; }
+
+        [BackgroundDependencyLoader]
+        private void load(DrawableHitObject drawableHitObject)
+        {
+            RelativeSizeAxes = Axes.Both;
+
+            DrawableSpinner = (DrawableSpinner)drawableHitObject;
+        }
+
+        protected override void LoadComplete()
+        {
+            base.LoadComplete();
+
+            DrawableSpinner.ApplyCustomUpdateState += UpdateStateTransforms;
+            UpdateStateTransforms(DrawableSpinner, DrawableSpinner.State.Value);
+        }
+
+        protected virtual void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
+        {
+        }
+
+        protected override void Dispose(bool isDisposing)
+        {
+            base.Dispose(isDisposing);
+
+            if (DrawableSpinner != null)
+                DrawableSpinner.ApplyCustomUpdateState -= UpdateStateTransforms;
+        }
+    }
+}