Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix slider tails sometimes not dimming correctly #27401

Merged
merged 2 commits into from
Feb 28, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ protected override void UpdateInitialTransforms()
base.UpdateInitialTransforms();

foreach (var piece in DimmablePieces)
{
// if the specified dimmable piece is a DHO, it is generally not safe to tack transforms onto it directly
// as they may be cleared via the `updateState()` DHO flow,
// so use `ApplyCustomUpdateState` instead. which does not have this pitfall.
if (piece is DrawableHitObject drawableObjectPiece)
drawableObjectPiece.ApplyCustomUpdateState += (dho, _) => applyDim(dho);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, my concern is that UpdateInitialTransforms seems like it can be called more than once, which would bind this each time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good spot but I don't necessarily know what the best option forward is here.

It's either this atrocity:

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index 35cab6459b..2e2831f9ae 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -85,11 +85,16 @@ protected override void UpdateInitialTransforms()
                 // as they may be cleared via the `updateState()` DHO flow,
                 // so use `ApplyCustomUpdateState` instead. which does not have this pitfall.
                 if (piece is DrawableHitObject drawableObjectPiece)
-                    drawableObjectPiece.ApplyCustomUpdateState += (dho, _) => applyDim(dho);
+                {
+                    drawableObjectPiece.ApplyCustomUpdateState -= applyDimToDrawableObject;
+                    drawableObjectPiece.ApplyCustomUpdateState += applyDimToDrawableObject;
+                }
                 else
                     applyDim(piece);
             }
 
+            void applyDimToDrawableObject(DrawableHitObject drawableHitObject, ArmedState _) => applyDim(drawableHitObject);
+
             void applyDim(Drawable piece)
             {
                 piece.FadeColour(new Color4(195, 195, 195, 255));

or splitting the application in two for DHOs and non-DHOs? which also feels pretty crap...

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index 35cab6459b..6bdf7ca82b 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -75,29 +75,43 @@ protected override void OnFree()
 
         protected virtual IEnumerable<Drawable> DimmablePieces => Enumerable.Empty<Drawable>();
 
-        protected override void UpdateInitialTransforms()
+        protected override void LoadComplete()
         {
-            base.UpdateInitialTransforms();
+            base.LoadComplete();
 
             foreach (var piece in DimmablePieces)
             {
                 // if the specified dimmable piece is a DHO, it is generally not safe to tack transforms onto it directly
                 // as they may be cleared via the `updateState()` DHO flow,
                 // so use `ApplyCustomUpdateState` instead. which does not have this pitfall.
-                if (piece is DrawableHitObject drawableObjectPiece)
-                    drawableObjectPiece.ApplyCustomUpdateState += (dho, _) => applyDim(dho);
-                else
-                    applyDim(piece);
+                if (piece is not DrawableHitObject drawableObjectPiece)
+                    continue;
+
+                drawableObjectPiece.ApplyCustomUpdateState += (dho, _) => applyDim(dho);
             }
+        }
 
-            void applyDim(Drawable piece)
+        protected override void UpdateInitialTransforms()
+        {
+            base.UpdateInitialTransforms();
+
+            foreach (var piece in DimmablePieces)
             {
-                piece.FadeColour(new Color4(195, 195, 195, 255));
-                using (piece.BeginDelayedSequence(InitialLifetimeOffset - OsuHitWindows.MISS_WINDOW))
-                    piece.FadeColour(Color4.White, 100);
+                // see `LoadComplete()`.
+                if (piece is DrawableHitObject)
+                    continue;
+
+                applyDim(piece);
             }
         }
 
+        private void applyDim(Drawable piece)
+        {
+            piece.FadeColour(new Color4(195, 195, 195, 255));
+            using (piece.BeginDelayedSequence(InitialLifetimeOffset - OsuHitWindows.MISS_WINDOW))
+                piece.FadeColour(Color4.White, 100);
+        }
+
         protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt;
 
         private OsuInputManager osuActionInputManager;

Copy link
Member

@frenzibyte frenzibyte Feb 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the former diff works it makes most sense to me, I would go with that to keep the ball rolling.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have applied it. I tend to agree it's the less bad option.

else
applyDim(piece);
}

void applyDim(Drawable piece)
{
piece.FadeColour(new Color4(195, 195, 195, 255));
using (piece.BeginDelayedSequence(InitialLifetimeOffset - OsuHitWindows.MISS_WINDOW))
Expand Down
Loading