From 2beed00a539e20ffe337bff680bff0224dd884f2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 25 Mar 2021 16:54:01 +0300 Subject: [PATCH 01/10] Make rush! replay frames compatible with legacy --- .../Replays/RushReplayFrame.cs | 32 ++++++++++++++++++- osu.Game.Rulesets.Rush/RushRuleset.cs | 4 +++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index 4623780..3416b49 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -2,11 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Replays.Legacy; using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Replays.Types; namespace osu.Game.Rulesets.Rush.Replays { - public class RushReplayFrame : ReplayFrame + public class RushReplayFrame : ReplayFrame, IConvertibleReplayFrame { public List Actions = new List(); @@ -26,5 +29,32 @@ public RushReplayFrame(double time, IEnumerable buttons) { Actions.AddRange(buttons); } + + public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null) + { + if (currentFrame.MouseLeft1) Actions.Add(RushAction.AirPrimary); + if (currentFrame.MouseLeft2) Actions.Add(RushAction.AirSecondary); + if (currentFrame.MouseRight1) Actions.Add(RushAction.GroundPrimary); + if (currentFrame.MouseRight2) Actions.Add(RushAction.GroundSecondary); + } + + public LegacyReplayFrame ToLegacy(IBeatmap beatmap) + { + ReplayButtonState state = ReplayButtonState.None; + + if (Actions.Contains(RushAction.AirPrimary) || Actions.Contains(RushAction.AirTertiary)) + state |= ReplayButtonState.Left1; + + if (Actions.Contains(RushAction.AirSecondary) || Actions.Contains(RushAction.AirQuaternary)) + state |= ReplayButtonState.Left2; + + if (Actions.Contains(RushAction.GroundPrimary) || Actions.Contains(RushAction.GroundSecondary)) + state |= ReplayButtonState.Right1; + + if (Actions.Contains(RushAction.GroundTertiary) || Actions.Contains(RushAction.GroundQuaternary)) + state |= ReplayButtonState.Right2; + + return new LegacyReplayFrame(Time, 0f, 0f, state); + } } } diff --git a/osu.Game.Rulesets.Rush/RushRuleset.cs b/osu.Game.Rulesets.Rush/RushRuleset.cs index 4e8dd1b..f2b7955 100644 --- a/osu.Game.Rulesets.Rush/RushRuleset.cs +++ b/osu.Game.Rulesets.Rush/RushRuleset.cs @@ -10,8 +10,10 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Rush.Beatmaps; using osu.Game.Rulesets.Rush.Mods; +using osu.Game.Rulesets.Rush.Replays; using osu.Game.Rulesets.Rush.Scoring; using osu.Game.Rulesets.Rush.UI; using osu.Game.Rulesets.Scoring; @@ -86,6 +88,8 @@ public override IEnumerable GetDefaultKeyBindings(int variant = 0) = new KeyBinding(InputKey.MouseLeft, RushAction.AirPrimary), }; + public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new RushReplayFrame(); + public override Drawable CreateIcon() => new RushIcon(); public class RushIcon : CompositeDrawable From a707e2561abca6efa96387c03c8de34d11817c5e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 25 Mar 2021 16:54:48 +0300 Subject: [PATCH 02/10] Add replay recorder support --- .../UI/DrawableRushRuleset.cs | 3 +++ .../UI/RushReplayRecorder.cs | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 osu.Game.Rulesets.Rush/UI/RushReplayRecorder.cs diff --git a/osu.Game.Rulesets.Rush/UI/DrawableRushRuleset.cs b/osu.Game.Rulesets.Rush/UI/DrawableRushRuleset.cs index 4589f0f..a66ec23 100644 --- a/osu.Game.Rulesets.Rush/UI/DrawableRushRuleset.cs +++ b/osu.Game.Rulesets.Rush/UI/DrawableRushRuleset.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Rush.Replays; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Scoring; namespace osu.Game.Rulesets.Rush.UI { @@ -39,6 +40,8 @@ public DrawableRushRuleset(RushRuleset ruleset, IBeatmap beatmap, IReadOnlyList< protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new RushFramedReplayInputHandler(replay); + protected override ReplayRecorder CreateReplayRecorder(Score score) => new RushReplayRecorder(score); + public new RushPlayfield Playfield => (RushPlayfield)base.Playfield; public override DrawableHitObject CreateDrawableRepresentation(RushHitObject h) diff --git a/osu.Game.Rulesets.Rush/UI/RushReplayRecorder.cs b/osu.Game.Rulesets.Rush/UI/RushReplayRecorder.cs new file mode 100644 index 0000000..e9c683d --- /dev/null +++ b/osu.Game.Rulesets.Rush/UI/RushReplayRecorder.cs @@ -0,0 +1,23 @@ +// Copyright (c) Shane Woolcock. Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Rush.Replays; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Rulesets.Rush.UI +{ + public class RushReplayRecorder : ReplayRecorder + { + public RushReplayRecorder(Score target) + : base(target) + { + } + + protected override ReplayFrame HandleFrame(Vector2 mousePosition, List actions, ReplayFrame previousFrame) + => new RushReplayFrame(Time.Current, actions); + } +} From 886e2219c1cf630fed37aa136d7eac9af67dff25 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 04:08:50 +0300 Subject: [PATCH 03/10] Pass side action flags via legacy X mouse position --- .../Replays/RushReplayFrame.cs | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index 3416b49..30e1472 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -1,7 +1,10 @@ // Copyright (c) Shane Woolcock. Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.EnumExtensions; using osu.Game.Beatmaps; using osu.Game.Replays.Legacy; using osu.Game.Rulesets.Replays; @@ -36,25 +39,51 @@ public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayF if (currentFrame.MouseLeft2) Actions.Add(RushAction.AirSecondary); if (currentFrame.MouseRight1) Actions.Add(RushAction.GroundPrimary); if (currentFrame.MouseRight2) Actions.Add(RushAction.GroundSecondary); + + if (currentFrame.MouseX != null) + Actions.AddRange(getActionsFromFlags((RushSideActionFlags)currentFrame.MouseX)); } public LegacyReplayFrame ToLegacy(IBeatmap beatmap) { ReplayButtonState state = ReplayButtonState.None; - if (Actions.Contains(RushAction.AirPrimary) || Actions.Contains(RushAction.AirTertiary)) - state |= ReplayButtonState.Left1; + if (Actions.Contains(RushAction.AirPrimary)) state |= ReplayButtonState.Left1; + if (Actions.Contains(RushAction.AirSecondary)) state |= ReplayButtonState.Left2; + if (Actions.Contains(RushAction.GroundPrimary)) state |= ReplayButtonState.Right1; + if (Actions.Contains(RushAction.GroundSecondary)) state |= ReplayButtonState.Right2; - if (Actions.Contains(RushAction.AirSecondary) || Actions.Contains(RushAction.AirQuaternary)) - state |= ReplayButtonState.Left2; + return new LegacyReplayFrame(Time, (float)getFlagsFromActions(Actions), 0f, state); + } - if (Actions.Contains(RushAction.GroundPrimary) || Actions.Contains(RushAction.GroundSecondary)) - state |= ReplayButtonState.Right1; + private static RushSideActionFlags getFlagsFromActions(IEnumerable actions) + { + RushSideActionFlags flags = RushSideActionFlags.None; - if (Actions.Contains(RushAction.GroundTertiary) || Actions.Contains(RushAction.GroundQuaternary)) - state |= ReplayButtonState.Right2; + if (actions.Contains(RushAction.AirTertiary)) flags |= RushSideActionFlags.AirTertiary; + if (actions.Contains(RushAction.AirQuaternary)) flags |= RushSideActionFlags.AirQuaternary; + if (actions.Contains(RushAction.GroundTertiary)) flags |= RushSideActionFlags.GroundTertiary; + if (actions.Contains(RushAction.GroundQuaternary)) flags |= RushSideActionFlags.GroundQuaternary; + + return flags; + } - return new LegacyReplayFrame(Time, 0f, 0f, state); + private static IEnumerable getActionsFromFlags(RushSideActionFlags sideFlags) + { + if (sideFlags.HasFlagFast(RushSideActionFlags.AirTertiary)) yield return RushAction.AirTertiary; + if (sideFlags.HasFlagFast(RushSideActionFlags.AirQuaternary)) yield return RushAction.AirQuaternary; + if (sideFlags.HasFlagFast(RushSideActionFlags.GroundTertiary)) yield return RushAction.GroundTertiary; + if (sideFlags.HasFlagFast(RushSideActionFlags.GroundQuaternary)) yield return RushAction.GroundQuaternary; + } + + [Flags] + private enum RushSideActionFlags + { + None = 0, + AirTertiary = 1, + AirQuaternary = 2, + GroundTertiary = 4, + GroundQuaternary = 8, } } } From 182a6bfb76fb2fc1cf8191aa97e1a28acc20229e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 04:30:57 +0300 Subject: [PATCH 04/10] Use left shifting instead --- osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index 30e1472..8356d68 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -80,10 +80,10 @@ private static IEnumerable getActionsFromFlags(RushSideActionFlags s private enum RushSideActionFlags { None = 0, - AirTertiary = 1, - AirQuaternary = 2, - GroundTertiary = 4, - GroundQuaternary = 8, + AirTertiary = 1 << 2, + AirQuaternary = 1 << 3, + GroundTertiary = 1 << 6, + GroundQuaternary = 1 << 7, } } } From 74d6a6edc4abba985faf40cc3b0649fb5737eeb4 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 04:31:47 +0300 Subject: [PATCH 05/10] Include all rush! actions instead --- .../Replays/RushReplayFrame.cs | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index 8356d68..fc6888b 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -41,47 +41,49 @@ public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayF if (currentFrame.MouseRight2) Actions.Add(RushAction.GroundSecondary); if (currentFrame.MouseX != null) - Actions.AddRange(getActionsFromFlags((RushSideActionFlags)currentFrame.MouseX)); + Actions.AddRange(getActionsFromFlags((RushActionFlags)currentFrame.MouseX)); } - public LegacyReplayFrame ToLegacy(IBeatmap beatmap) - { - ReplayButtonState state = ReplayButtonState.None; - - if (Actions.Contains(RushAction.AirPrimary)) state |= ReplayButtonState.Left1; - if (Actions.Contains(RushAction.AirSecondary)) state |= ReplayButtonState.Left2; - if (Actions.Contains(RushAction.GroundPrimary)) state |= ReplayButtonState.Right1; - if (Actions.Contains(RushAction.GroundSecondary)) state |= ReplayButtonState.Right2; - - return new LegacyReplayFrame(Time, (float)getFlagsFromActions(Actions), 0f, state); - } + public LegacyReplayFrame ToLegacy(IBeatmap beatmap) => new LegacyReplayFrame(Time, (float)getFlagsFromActions(Actions), 0f, ReplayButtonState.None); - private static RushSideActionFlags getFlagsFromActions(IEnumerable actions) + private static RushActionFlags getFlagsFromActions(IEnumerable actions) { - RushSideActionFlags flags = RushSideActionFlags.None; + RushActionFlags flags = RushActionFlags.None; - if (actions.Contains(RushAction.AirTertiary)) flags |= RushSideActionFlags.AirTertiary; - if (actions.Contains(RushAction.AirQuaternary)) flags |= RushSideActionFlags.AirQuaternary; - if (actions.Contains(RushAction.GroundTertiary)) flags |= RushSideActionFlags.GroundTertiary; - if (actions.Contains(RushAction.GroundQuaternary)) flags |= RushSideActionFlags.GroundQuaternary; + if (actions.Contains(RushAction.AirPrimary)) flags |= RushActionFlags.AirPrimary; + if (actions.Contains(RushAction.AirSecondary)) flags |= RushActionFlags.AirSecondary; + if (actions.Contains(RushAction.AirTertiary)) flags |= RushActionFlags.AirTertiary; + if (actions.Contains(RushAction.AirQuaternary)) flags |= RushActionFlags.AirQuaternary; + if (actions.Contains(RushAction.GroundPrimary)) flags |= RushActionFlags.GroundPrimary; + if (actions.Contains(RushAction.GroundSecondary)) flags |= RushActionFlags.GroundSecondary; + if (actions.Contains(RushAction.GroundTertiary)) flags |= RushActionFlags.GroundTertiary; + if (actions.Contains(RushAction.GroundQuaternary)) flags |= RushActionFlags.GroundQuaternary; return flags; } - private static IEnumerable getActionsFromFlags(RushSideActionFlags sideFlags) + private static IEnumerable getActionsFromFlags(RushActionFlags flags) { - if (sideFlags.HasFlagFast(RushSideActionFlags.AirTertiary)) yield return RushAction.AirTertiary; - if (sideFlags.HasFlagFast(RushSideActionFlags.AirQuaternary)) yield return RushAction.AirQuaternary; - if (sideFlags.HasFlagFast(RushSideActionFlags.GroundTertiary)) yield return RushAction.GroundTertiary; - if (sideFlags.HasFlagFast(RushSideActionFlags.GroundQuaternary)) yield return RushAction.GroundQuaternary; + if (flags.HasFlagFast(RushActionFlags.AirPrimary)) yield return RushAction.AirPrimary; + if (flags.HasFlagFast(RushActionFlags.AirSecondary)) yield return RushAction.AirSecondary; + if (flags.HasFlagFast(RushActionFlags.AirTertiary)) yield return RushAction.AirTertiary; + if (flags.HasFlagFast(RushActionFlags.AirQuaternary)) yield return RushAction.AirQuaternary; + if (flags.HasFlagFast(RushActionFlags.GroundPrimary)) yield return RushAction.GroundPrimary; + if (flags.HasFlagFast(RushActionFlags.GroundSecondary)) yield return RushAction.GroundSecondary; + if (flags.HasFlagFast(RushActionFlags.GroundTertiary)) yield return RushAction.GroundTertiary; + if (flags.HasFlagFast(RushActionFlags.GroundQuaternary)) yield return RushAction.GroundQuaternary; } [Flags] - private enum RushSideActionFlags + private enum RushActionFlags { None = 0, + AirPrimary = 1 << 0, + AirSecondary = 1 << 1, AirTertiary = 1 << 2, AirQuaternary = 1 << 3, + GroundPrimary = 1 << 4, + GroundSecondary = 1 << 5, GroundTertiary = 1 << 6, GroundQuaternary = 1 << 7, } From 528ab0f3fe87c09acb63cc324c29aa32ff4b1fbf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 04:36:04 +0300 Subject: [PATCH 06/10] Remove no longer necessary mouse click checks --- osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index fc6888b..5fa0a9c 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osu.Framework.Extensions.EnumExtensions; using osu.Game.Beatmaps; @@ -35,16 +36,14 @@ public RushReplayFrame(double time, IEnumerable buttons) public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null) { - if (currentFrame.MouseLeft1) Actions.Add(RushAction.AirPrimary); - if (currentFrame.MouseLeft2) Actions.Add(RushAction.AirSecondary); - if (currentFrame.MouseRight1) Actions.Add(RushAction.GroundPrimary); - if (currentFrame.MouseRight2) Actions.Add(RushAction.GroundSecondary); - - if (currentFrame.MouseX != null) - Actions.AddRange(getActionsFromFlags((RushActionFlags)currentFrame.MouseX)); + Debug.Assert(currentFrame.MouseX != null); + Actions.AddRange(getActionsFromFlags((RushActionFlags)currentFrame.MouseX)); } - public LegacyReplayFrame ToLegacy(IBeatmap beatmap) => new LegacyReplayFrame(Time, (float)getFlagsFromActions(Actions), 0f, ReplayButtonState.None); + public LegacyReplayFrame ToLegacy(IBeatmap beatmap) + { + return new LegacyReplayFrame(Time, (float)getFlagsFromActions(Actions), 0f, ReplayButtonState.None); + } private static RushActionFlags getFlagsFromActions(IEnumerable actions) { From 63785f46d6b0afbb7af70705c5258f87236f158d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 18:56:51 +0300 Subject: [PATCH 07/10] Add rush! replay frame conversion parity test --- .../Replay/RushReplayFrameTest.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 osu.Game.Rulesets.Rush.Tests/Replay/RushReplayFrameTest.cs diff --git a/osu.Game.Rulesets.Rush.Tests/Replay/RushReplayFrameTest.cs b/osu.Game.Rulesets.Rush.Tests/Replay/RushReplayFrameTest.cs new file mode 100644 index 0000000..ead02cb --- /dev/null +++ b/osu.Game.Rulesets.Rush.Tests/Replay/RushReplayFrameTest.cs @@ -0,0 +1,28 @@ +// Copyright (c) Shane Woolcock. Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Rush.Replays; + +namespace osu.Game.Rulesets.Rush.Tests.Replay +{ + [TestFixture] + public class RushReplayFrameTest + { + [TestCase] + [TestCase(RushAction.AirPrimary, RushAction.GroundPrimary)] + [TestCase(RushAction.AirPrimary, RushAction.AirSecondary, RushAction.GroundQuaternary)] + [TestCase(RushAction.GroundPrimary, RushAction.GroundSecondary)] + [TestCase(RushAction.AirPrimary, RushAction.AirSecondary, RushAction.AirTertiary, RushAction.AirQuaternary, RushAction.GroundPrimary, RushAction.GroundSecondary, RushAction.GroundTertiary, RushAction.GroundTertiary)] + public void TestParity(params RushAction[] actions) + { + var originalFrame = (RushReplayFrame)new RushRuleset().CreateConvertibleReplayFrame(); + var resultFrame = (RushReplayFrame)new RushRuleset().CreateConvertibleReplayFrame(); + + resultFrame.FromLegacy(originalFrame.ToLegacy(new Beatmap()), new Beatmap()); + + Assert.That(resultFrame.Actions, Is.EquivalentTo(originalFrame.Actions)); + } + } +} From acc27883d116089c2d16551aa52d5e93c499c496 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 18:57:37 +0300 Subject: [PATCH 08/10] Assign numbers to rush actions To indicate that the numbers assigned to each action must never change, to avoid breaking old rush! replay frames, or configuration, etc.. --- osu.Game.Rulesets.Rush/RushInputManager.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Rush/RushInputManager.cs b/osu.Game.Rulesets.Rush/RushInputManager.cs index cd9601d..5607d49 100644 --- a/osu.Game.Rulesets.Rush/RushInputManager.cs +++ b/osu.Game.Rulesets.Rush/RushInputManager.cs @@ -25,28 +25,28 @@ public RushInputManager(RulesetInfo ruleset) public enum RushAction { [Description("Ground (Primary)")] - GroundPrimary, + GroundPrimary = 0, [Description("Ground (Secondary)")] - GroundSecondary, + GroundSecondary = 1, [Description("Ground (Tertiary)")] - GroundTertiary, + GroundTertiary = 2, [Description("Ground (Quaternary)")] - GroundQuaternary, + GroundQuaternary = 3, [Description("Air (Primary)")] - AirPrimary, + AirPrimary = 4, [Description("Air (Secondary)")] - AirSecondary, + AirSecondary = 5, [Description("Air (Tertiary)")] - AirTertiary, + AirTertiary = 6, [Description("Air (Quaternary)")] - AirQuaternary + AirQuaternary = 7 } public static class RushActionExtensions From b7e1dd8e4bc4464d682804f82f4d770c141d878f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 10 Apr 2021 18:59:09 +0300 Subject: [PATCH 09/10] Simplify most of rush! replay frame conversion logic --- .../Replays/RushReplayFrame.cs | 57 +++++-------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index 5fa0a9c..d0a627c 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -1,11 +1,8 @@ // Copyright (c) Shane Woolcock. Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using osu.Framework.Extensions.EnumExtensions; using osu.Game.Beatmaps; using osu.Game.Replays.Legacy; using osu.Game.Rulesets.Replays; @@ -37,54 +34,28 @@ public RushReplayFrame(double time, IEnumerable buttons) public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null) { Debug.Assert(currentFrame.MouseX != null); - Actions.AddRange(getActionsFromFlags((RushActionFlags)currentFrame.MouseX)); - } - public LegacyReplayFrame ToLegacy(IBeatmap beatmap) - { - return new LegacyReplayFrame(Time, (float)getFlagsFromActions(Actions), 0f, ReplayButtonState.None); - } + uint flags = (uint)currentFrame.MouseX; - private static RushActionFlags getFlagsFromActions(IEnumerable actions) - { - RushActionFlags flags = RushActionFlags.None; + int currentBit = 0; - if (actions.Contains(RushAction.AirPrimary)) flags |= RushActionFlags.AirPrimary; - if (actions.Contains(RushAction.AirSecondary)) flags |= RushActionFlags.AirSecondary; - if (actions.Contains(RushAction.AirTertiary)) flags |= RushActionFlags.AirTertiary; - if (actions.Contains(RushAction.AirQuaternary)) flags |= RushActionFlags.AirQuaternary; - if (actions.Contains(RushAction.GroundPrimary)) flags |= RushActionFlags.GroundPrimary; - if (actions.Contains(RushAction.GroundSecondary)) flags |= RushActionFlags.GroundSecondary; - if (actions.Contains(RushAction.GroundTertiary)) flags |= RushActionFlags.GroundTertiary; - if (actions.Contains(RushAction.GroundQuaternary)) flags |= RushActionFlags.GroundQuaternary; + while (flags > 0) + { + if ((flags & 1) > 0) + Actions.Add((RushAction)currentBit); - return flags; + ++currentBit; + flags >>= 1; + } } - private static IEnumerable getActionsFromFlags(RushActionFlags flags) + public LegacyReplayFrame ToLegacy(IBeatmap beatmap) { - if (flags.HasFlagFast(RushActionFlags.AirPrimary)) yield return RushAction.AirPrimary; - if (flags.HasFlagFast(RushActionFlags.AirSecondary)) yield return RushAction.AirSecondary; - if (flags.HasFlagFast(RushActionFlags.AirTertiary)) yield return RushAction.AirTertiary; - if (flags.HasFlagFast(RushActionFlags.AirQuaternary)) yield return RushAction.AirQuaternary; - if (flags.HasFlagFast(RushActionFlags.GroundPrimary)) yield return RushAction.GroundPrimary; - if (flags.HasFlagFast(RushActionFlags.GroundSecondary)) yield return RushAction.GroundSecondary; - if (flags.HasFlagFast(RushActionFlags.GroundTertiary)) yield return RushAction.GroundTertiary; - if (flags.HasFlagFast(RushActionFlags.GroundQuaternary)) yield return RushAction.GroundQuaternary; - } + int flags = 0; + foreach (var action in Actions) + flags |= 1 << (int)action; - [Flags] - private enum RushActionFlags - { - None = 0, - AirPrimary = 1 << 0, - AirSecondary = 1 << 1, - AirTertiary = 1 << 2, - AirQuaternary = 1 << 3, - GroundPrimary = 1 << 4, - GroundSecondary = 1 << 5, - GroundTertiary = 1 << 6, - GroundQuaternary = 1 << 7, + return new LegacyReplayFrame(Time, flags, 0f, ReplayButtonState.None); } } } From 7702403fba3dfc88271a77ffdd494e17c33b17d8 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Sat, 10 Apr 2021 18:40:02 +0200 Subject: [PATCH 10/10] Use uint to store flags in ToLegacy --- osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs index d0a627c..fa632a3 100644 --- a/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs +++ b/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs @@ -51,9 +51,9 @@ public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayF public LegacyReplayFrame ToLegacy(IBeatmap beatmap) { - int flags = 0; + uint flags = 0; foreach (var action in Actions) - flags |= 1 << (int)action; + flags |= 1u << (int)action; return new LegacyReplayFrame(Time, flags, 0f, ReplayButtonState.None); }