From 5d8c153c1e21949156a0dbf54b9cf8d71bca4c4d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jan 2021 16:41:03 +0900 Subject: [PATCH] Move schedule logic to buttons rather than section It turns out there's some quite convoluted scheduling / order of execution requirements of ModSelectOverlay and ModSection. Applying scheduling causes a runaway condition ending in zero frames after many mod button changes. I wanted to avoid rewriting the whole component, so have just moved the schedule to guard against the part where drawables are actually changed. --- osu.Game/Overlays/Mods/ModButton.cs | 62 +++++++++++++++------------- osu.Game/Overlays/Mods/ModSection.cs | 8 ++-- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index e574828cd2..51c8bcf9a9 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -64,41 +64,45 @@ namespace osu.Game.Overlays.Mods if (newIndex >= 0 && !Mods[newIndex].HasImplementation) return false; - selectedIndex = newIndex; - Mod modAfter = SelectedMod ?? Mods[0]; - - if (beforeSelected != Selected) + Schedule(() => { - iconsContainer.RotateTo(Selected ? 5f : 0f, 300, Easing.OutElastic); - iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, Easing.OutElastic); - } + selectedIndex = newIndex; + Mod modAfter = SelectedMod ?? Mods[0]; - if (modBefore != modAfter) - { - const float rotate_angle = 16; - - foregroundIcon.RotateTo(rotate_angle * direction, mod_switch_duration, mod_switch_easing); - backgroundIcon.RotateTo(-rotate_angle * direction, mod_switch_duration, mod_switch_easing); - - backgroundIcon.Mod = modAfter; - - using (BeginDelayedSequence(mod_switch_duration, true)) + if (beforeSelected != Selected) { - foregroundIcon - .RotateTo(-rotate_angle * direction) - .RotateTo(0f, mod_switch_duration, mod_switch_easing); - - backgroundIcon - .RotateTo(rotate_angle * direction) - .RotateTo(0f, mod_switch_duration, mod_switch_easing); - - Schedule(() => displayMod(modAfter)); + iconsContainer.RotateTo(Selected ? 5f : 0f, 300, Easing.OutElastic); + iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, Easing.OutElastic); } - } - foregroundIcon.Selected.Value = Selected; + if (modBefore != modAfter) + { + const float rotate_angle = 16; + + foregroundIcon.RotateTo(rotate_angle * direction, mod_switch_duration, mod_switch_easing); + backgroundIcon.RotateTo(-rotate_angle * direction, mod_switch_duration, mod_switch_easing); + + backgroundIcon.Mod = modAfter; + + using (BeginDelayedSequence(mod_switch_duration, true)) + { + foregroundIcon + .RotateTo(-rotate_angle * direction) + .RotateTo(0f, mod_switch_duration, mod_switch_easing); + + backgroundIcon + .RotateTo(rotate_angle * direction) + .RotateTo(0f, mod_switch_duration, mod_switch_easing); + + Schedule(() => displayMod(modAfter)); + } + } + + foregroundIcon.Selected.Value = Selected; + + SelectionChanged?.Invoke(SelectedMod); + }); - SelectionChanged?.Invoke(SelectedMod); return true; } diff --git a/osu.Game/Overlays/Mods/ModSection.cs b/osu.Game/Overlays/Mods/ModSection.cs index 47b101c2b0..0107f94dcf 100644 --- a/osu.Game/Overlays/Mods/ModSection.cs +++ b/osu.Game/Overlays/Mods/ModSection.cs @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Mods /// /// The types of s which should be deselected. /// Set to true to bypass animations and update selections immediately. - public void DeselectTypes(IEnumerable modTypes, bool immediate = false) => Schedule(() => + public void DeselectTypes(IEnumerable modTypes, bool immediate = false) { int delay = 0; @@ -124,13 +124,13 @@ namespace osu.Game.Overlays.Mods } } } - }); + } /// /// Select one or more mods in this section and deselects all other ones. /// /// The types of s which should be selected. - public void SelectTypes(IEnumerable modTypes) => Schedule(() => + public void SelectTypes(IEnumerable modTypes) { foreach (var button in buttons) { @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Mods else button.Deselect(); } - }); + } protected ModSection() {