From 87384db8729401b7b6824880cd5cc95eeefa9126 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Sep 2022 00:51:02 +0900 Subject: [PATCH 1/3] Fix slider rotation causing thousands of new drawables to be created --- .../Sliders/Components/PathControlPointPiece.cs | 7 +++++-- osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs | 9 ++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index ab4b492767..59edbe8dc6 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -66,11 +66,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components cachePoints(slider); sliderVersion = slider.Path.Version.GetBoundCopy(); - sliderVersion.BindValueChanged(_ => + + // schedule ensure that updates are only applied after all operations from a single frame are applied. + // this avoids inadvertently changing the slider path type for bach operations. + sliderVersion.BindValueChanged(_ => Scheduler.AddOnce(() => { cachePoints(slider); updatePathType(); - }); + })); controlPoint.Changed += updateMarkerDisplay; diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 57d67acad5..280a35500a 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -186,13 +186,8 @@ namespace osu.Game.Rulesets.Osu.Edit if (h is IHasPath path) { - var controlPoints = path.Path.ControlPoints.Select(p => - new PathControlPoint(RotatePointAroundOrigin(p.Position, Vector2.Zero, delta), p.Type)).ToArray(); - - // Importantly, update as a single operation so automatic adjustment of control points to different - // curve types does not unexpectedly trigger and change the slider's shape. - path.Path.ControlPoints.Clear(); - path.Path.ControlPoints.AddRange(controlPoints); + foreach (PathControlPoint t in path.Path.ControlPoints) + t.Position = RotatePointAroundOrigin(t.Position, Vector2.Zero, delta); } } From c203a030c1bdec9b40168b1ca8844c802436b4d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Sep 2022 04:28:07 +0900 Subject: [PATCH 2/3] Update osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs Co-authored-by: apollo <83023433+apollo-dw@users.noreply.github.com> --- .../Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 59edbe8dc6..5dec5d1cb0 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components sliderVersion = slider.Path.Version.GetBoundCopy(); // schedule ensure that updates are only applied after all operations from a single frame are applied. - // this avoids inadvertently changing the slider path type for bach operations. + // this avoids inadvertently changing the slider path type for batch operations. sliderVersion.BindValueChanged(_ => Scheduler.AddOnce(() => { cachePoints(slider); From 4af76b9f48fd1d4602319af4552bee120b89f2ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Sep 2022 19:55:18 +0900 Subject: [PATCH 3/3] Apply the same change to `HandleFlip` --- .../Edit/OsuSelectionHandler.cs | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 280a35500a..eddc1390f0 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -127,16 +127,13 @@ namespace osu.Game.Rulesets.Osu.Edit { didFlip = true; - var controlPoints = slider.Path.ControlPoints.Select(p => - new PathControlPoint(new Vector2( - (direction == Direction.Horizontal ? -1 : 1) * p.Position.X, - (direction == Direction.Vertical ? -1 : 1) * p.Position.Y - ), p.Type)).ToArray(); - - // Importantly, update as a single operation so automatic adjustment of control points to different - // curve types does not unexpectedly trigger and change the slider's shape. - slider.Path.ControlPoints.Clear(); - slider.Path.ControlPoints.AddRange(controlPoints); + foreach (var cp in slider.Path.ControlPoints) + { + cp.Position = new Vector2( + (direction == Direction.Horizontal ? -1 : 1) * cp.Position.X, + (direction == Direction.Vertical ? -1 : 1) * cp.Position.Y + ); + } } } @@ -186,8 +183,8 @@ namespace osu.Game.Rulesets.Osu.Edit if (h is IHasPath path) { - foreach (PathControlPoint t in path.Path.ControlPoints) - t.Position = RotatePointAroundOrigin(t.Position, Vector2.Zero, delta); + foreach (PathControlPoint cp in path.Path.ControlPoints) + cp.Position = RotatePointAroundOrigin(cp.Position, Vector2.Zero, delta); } }