From bda9855521c65b880ea30c9cc7c69274a4e4bcb7 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Mon, 7 Aug 2023 22:07:52 +0800 Subject: [PATCH 1/4] Should add the fill property in the interface. --- .../Workings/HitObjectWorkingPropertyValidatorTest.cs | 4 ++-- .../Objects/Workings/LyricWorkingPropertyValidatorTest.cs | 2 +- .../Objects/Workings/NoteWorkingPropertyValidatorTest.cs | 3 ++- .../Beatmaps/KaraokeBeatmapProcessor.cs | 2 +- .../Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs | 2 +- osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs | 2 +- osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs | 2 +- .../Objects/Types/IHasWorkingProperty.cs | 7 +++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/HitObjectWorkingPropertyValidatorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/HitObjectWorkingPropertyValidatorTest.cs index caac38090..3a57c7ca3 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/HitObjectWorkingPropertyValidatorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/HitObjectWorkingPropertyValidatorTest.cs @@ -9,9 +9,9 @@ namespace osu.Game.Rulesets.Karaoke.Tests.Objects.Workings; -public abstract class HitObjectWorkingPropertyValidatorTest +public abstract class HitObjectWorkingPropertyValidatorTest where TFlag : struct, Enum - where THitObject : KaraokeHitObject, IHasWorkingProperty, new() + where THitObject : KaraokeHitObject, IHasWorkingProperty, new() { [Test] public void CheckInitialState([Values] TFlag flag) diff --git a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs index 03a067031..89cd921e8 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Karaoke.Tests.Objects.Workings; -public class LyricWorkingPropertyValidatorTest : HitObjectWorkingPropertyValidatorTest +public class LyricWorkingPropertyValidatorTest : HitObjectWorkingPropertyValidatorTest { [Test] public void TestStartTime() diff --git a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs index a9992adb4..729b25a50 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs @@ -3,6 +3,7 @@ using System; using NUnit.Framework; +using osu.Game.Rulesets.Karaoke.Beatmaps; using osu.Game.Rulesets.Karaoke.Objects; using osu.Game.Rulesets.Karaoke.Objects.Stages.Classic; using osu.Game.Rulesets.Karaoke.Objects.Workings; @@ -13,7 +14,7 @@ namespace osu.Game.Rulesets.Karaoke.Tests.Objects.Workings; -public class NoteWorkingPropertyValidatorTest : HitObjectWorkingPropertyValidatorTest +public class NoteWorkingPropertyValidatorTest : HitObjectWorkingPropertyValidatorTest { [Test] public void TestPage() diff --git a/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs b/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs index 487a4dfd7..a3395dcbc 100644 --- a/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs @@ -60,7 +60,7 @@ private void applyInvalidProperty(KaraokeBeatmap beatmap) { // should convert to array here because validate the working property might change the start-time and the end time. // which will cause got the wrong item in the array. - foreach (var hitObject in beatmap.HitObjects.OfType().ToArray()) + foreach (var hitObject in beatmap.HitObjects.OfType>().ToArray()) { hitObject.ValidateWorkingProperty(beatmap); } diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs index 740b3a9da..478a747cf 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs @@ -89,7 +89,7 @@ protected void PerformOnSelection(Action action) where T : HitObject protected void InvalidateAllHitObjectWorkingProperty(TWorkingProperty property) where TWorkingProperty : struct, Enum { - foreach (var hitObject in KaraokeBeatmap.HitObjects.OfType>()) + foreach (var hitObject in KaraokeBeatmap.HitObjects.OfType>()) { hitObject.InvalidateWorkingProperty(property); } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs b/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs index 79966e678..728a9a879 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Karaoke.Objects; /// Placing the properties that set by or being calculated. /// Those properties will not be saved into the beatmap. /// -public partial class Lyric : IHasWorkingProperty, IHasEffectApplier +public partial class Lyric : IHasWorkingProperty, IHasEffectApplier { [JsonIgnore] private readonly LyricWorkingPropertyValidator workingPropertyValidator; diff --git a/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs b/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs index 63288ed23..1592085ed 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Karaoke.Objects; /// Placing the properties that set by or being calculated. /// Those properties will not be saved into the beatmap. /// -public partial class Note : IHasWorkingProperty, IHasEffectApplier +public partial class Note : IHasWorkingProperty, IHasEffectApplier { [JsonIgnore] private readonly NoteWorkingPropertyValidator workingPropertyValidator; diff --git a/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs b/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs index 3663de913..55e41c70b 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs @@ -2,11 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; -using osu.Game.Rulesets.Karaoke.Beatmaps; namespace osu.Game.Rulesets.Karaoke.Objects.Types; -public interface IHasWorkingProperty : IHasWorkingProperty +public interface IHasWorkingProperty : IHasWorkingProperty where TWorkingProperty : struct, Enum { bool InvalidateWorkingProperty(TWorkingProperty workingProperty); @@ -14,7 +13,7 @@ public interface IHasWorkingProperty : IHasWorkingProperty TWorkingProperty[] GetAllInvalidWorkingProperties(); } -public interface IHasWorkingProperty +public interface IHasWorkingProperty { - void ValidateWorkingProperty(KaraokeBeatmap beatmap); + void ValidateWorkingProperty(TFillProperty fillProperty); } From c7e762184f5add50b653eb04ef251968b099a58f Mon Sep 17 00:00:00 2001 From: andy840119 Date: Mon, 7 Aug 2023 21:51:42 +0800 Subject: [PATCH 2/4] Implement the validator for the property that is affected by stage. --- .../Workings/LyricStageWorkingProperty.cs | 33 +++++++++++++++++++ .../LyricStageWorkingPropertyValidator.cs | 16 +++++++++ .../Workings/NoteStageWorkingProperty.cs | 18 ++++++++++ .../NoteStageWorkingPropertyValidator.cs | 16 +++++++++ 4 files changed, 83 insertions(+) create mode 100644 osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingProperty.cs create mode 100644 osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingPropertyValidator.cs create mode 100644 osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingProperty.cs create mode 100644 osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingPropertyValidator.cs diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingProperty.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingProperty.cs new file mode 100644 index 000000000..cf700c229 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingProperty.cs @@ -0,0 +1,33 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; + +namespace osu.Game.Rulesets.Karaoke.Objects.Workings; + +/// +/// Specifies which properties in the are being invalidated. +/// +[Flags] +public enum LyricStageWorkingProperty +{ + /// + /// is being invalidated. + /// + StartTime = 1, + + /// + /// is being invalidated. + /// + Duration = 1 << 1, + + /// + /// and is being invalidated. + /// + Timing = StartTime | Duration, + + /// + /// is being invalidated. + /// + EffectApplier = 1 << 2, +} diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingPropertyValidator.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingPropertyValidator.cs new file mode 100644 index 000000000..2e52ea4a6 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricStageWorkingPropertyValidator.cs @@ -0,0 +1,16 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Rulesets.Karaoke.Objects.Workings; + +public class LyricStageWorkingPropertyValidator : HitObjectWorkingPropertyValidator +{ + public LyricStageWorkingPropertyValidator(Lyric hitObject) + : base(hitObject) + { + } + + protected override bool HasDataProperty(LyricStageWorkingProperty flags) => false; + + protected override bool IsWorkingPropertySynced(Lyric hitObject, LyricStageWorkingProperty flags) => true; +} diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingProperty.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingProperty.cs new file mode 100644 index 000000000..107c34a6d --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingProperty.cs @@ -0,0 +1,18 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; + +namespace osu.Game.Rulesets.Karaoke.Objects.Workings; + +/// +/// Specifies which properties in the are being invalidated. +/// +[Flags] +public enum NoteStageWorkingProperty +{ + /// + /// is being invalidated. + /// + EffectApplier = 1, +} diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingPropertyValidator.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingPropertyValidator.cs new file mode 100644 index 000000000..d9284a841 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteStageWorkingPropertyValidator.cs @@ -0,0 +1,16 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Rulesets.Karaoke.Objects.Workings; + +public class NoteStageWorkingPropertyValidator : HitObjectWorkingPropertyValidator +{ + public NoteStageWorkingPropertyValidator(Note hitObject) + : base(hitObject) + { + } + + protected override bool HasDataProperty(NoteStageWorkingProperty flags) => false; + + protected override bool IsWorkingPropertySynced(Note hitObject, NoteStageWorkingProperty flags) => true; +} From 86e1ee329dcf1385d56277455b567731b39dd06d Mon Sep 17 00:00:00 2001 From: andy840119 Date: Mon, 7 Aug 2023 22:13:50 +0800 Subject: [PATCH 3/4] Add the working property interface for the stage info. --- .../ChangeHandlers/BaseChangeHandlerTest.cs | 23 +++++++++++++++++-- osu.Game.Rulesets.Karaoke/Objects/Lyric.cs | 1 + .../Objects/Lyric_Working.cs | 22 +++++++++++++++--- osu.Game.Rulesets.Karaoke/Objects/Note.cs | 1 + .../Objects/Note_Working.cs | 23 ++++++++++++++++--- .../Objects/Types/IHasWorkingProperty.cs | 2 ++ 6 files changed, 64 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseChangeHandlerTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseChangeHandlerTest.cs index 761f9b9dd..e613785c3 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseChangeHandlerTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseChangeHandlerTest.cs @@ -12,6 +12,9 @@ using osu.Game.Rulesets.Karaoke.Configuration; using osu.Game.Rulesets.Karaoke.Edit.Utils; using osu.Game.Rulesets.Karaoke.Objects; +using osu.Game.Rulesets.Karaoke.Objects.Types; +using osu.Game.Rulesets.Karaoke.Objects.Workings; +using osu.Game.Rulesets.Karaoke.Stages; using osu.Game.Rulesets.Karaoke.Stages.Types; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit; @@ -233,13 +236,29 @@ protected void AssertWorkingPropertyInHitObjectValid() return editorBeatmap.HitObjects.OfType().All(hitObject => hitObject switch { - Lyric lyric => lyric.GetAllInvalidWorkingProperties().Length == 0, - Note note => note.GetAllInvalidWorkingProperties().Length == 0, + Lyric lyric => !hasInvalidWorkingProperty(lyric), + Note note => !hasInvalidWorkingProperty(note), _ => throw new NotSupportedException(), }); }); } + private static bool hasInvalidWorkingProperty(Lyric lyric) + { + if (lyric is not (IHasWorkingProperty workingProperty and IHasWorkingProperty stageWorkingProperty)) + throw new NotSupportedException(); + + return workingProperty.HasInvalidWorkingProperty() || stageWorkingProperty.HasInvalidWorkingProperty(); + } + + private static bool hasInvalidWorkingProperty(Note note) + { + if (note is not (IHasWorkingProperty workingProperty and IHasWorkingProperty stageWorkingProperty)) + throw new NotSupportedException(); + + return workingProperty.HasInvalidWorkingProperty() || stageWorkingProperty.HasInvalidWorkingProperty(); + } + private partial class MockEditorChangeHandler : TransactionalCommitComponent, IEditorChangeHandler { public event Action? OnStateChange; diff --git a/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs b/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs index ba9b9d141..dda640db0 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs @@ -188,6 +188,7 @@ public IReferenceLyricPropertyConfig? ReferenceLyricConfig public Lyric() { workingPropertyValidator = new LyricWorkingPropertyValidator(this); + stageWorkingPropertyValidator = new LyricStageWorkingPropertyValidator(this); initInternalBindingEvent(); initReferenceLyricEvent(); diff --git a/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs b/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs index 728a9a879..2fe3be178 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs @@ -21,23 +21,35 @@ namespace osu.Game.Rulesets.Karaoke.Objects; /// Placing the properties that set by or being calculated. /// Those properties will not be saved into the beatmap. /// -public partial class Lyric : IHasWorkingProperty, IHasEffectApplier +public partial class Lyric : IHasWorkingProperty, IHasWorkingProperty, IHasEffectApplier { [JsonIgnore] private readonly LyricWorkingPropertyValidator workingPropertyValidator; + [JsonIgnore] + private readonly LyricStageWorkingPropertyValidator stageWorkingPropertyValidator; + public bool InvalidateWorkingProperty(LyricWorkingProperty workingProperty) => workingPropertyValidator.Invalidate(workingProperty); + public bool InvalidateWorkingProperty(LyricStageWorkingProperty workingProperty) + => stageWorkingPropertyValidator.Invalidate(workingProperty); + private void updateStateByWorkingProperty(LyricWorkingProperty workingProperty) => workingPropertyValidator.UpdateStateByWorkingProperty(workingProperty); - public LyricWorkingProperty[] GetAllInvalidWorkingProperties() + private void updateStateByWorkingProperty(LyricStageWorkingProperty workingProperty) + => stageWorkingPropertyValidator.UpdateStateByWorkingProperty(workingProperty); + + LyricWorkingProperty[] IHasWorkingProperty.GetAllInvalidWorkingProperties() => workingPropertyValidator.GetAllInvalidFlags(); + LyricStageWorkingProperty[] IHasWorkingProperty.GetAllInvalidWorkingProperties() + => stageWorkingPropertyValidator.GetAllInvalidFlags(); + public void ValidateWorkingProperty(KaraokeBeatmap beatmap) { - foreach (var flag in GetAllInvalidWorkingProperties()) + foreach (var flag in workingPropertyValidator.GetAllInvalidFlags()) { switch (flag) { @@ -113,6 +125,10 @@ static IStageEffectApplier getStageEffectApplier(KaraokeBeatmap beatmap, Karaoke } } + public void ValidateWorkingProperty(StageInfo stageInfo) + { + } + [JsonIgnore] public double LyricStartTime { get; private set; } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Note.cs b/osu.Game.Rulesets.Karaoke/Objects/Note.cs index db516c93a..fcacb5765 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Note.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Note.cs @@ -127,6 +127,7 @@ public int ReferenceTimeTagIndex public Note() { workingPropertyValidator = new NoteWorkingPropertyValidator(this); + stageWorkingPropertyValidator = new NoteStageWorkingPropertyValidator(this); initInternalBindingEvent(); initReferenceLyricEvent(); diff --git a/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs b/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs index 1592085ed..273ec1e30 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Karaoke.Objects.Stages; using osu.Game.Rulesets.Karaoke.Objects.Types; using osu.Game.Rulesets.Karaoke.Objects.Workings; +using osu.Game.Rulesets.Karaoke.Stages; namespace osu.Game.Rulesets.Karaoke.Objects; @@ -20,23 +21,35 @@ namespace osu.Game.Rulesets.Karaoke.Objects; /// Placing the properties that set by or being calculated. /// Those properties will not be saved into the beatmap. /// -public partial class Note : IHasWorkingProperty, IHasEffectApplier +public partial class Note : IHasWorkingProperty, IHasWorkingProperty, IHasEffectApplier { [JsonIgnore] private readonly NoteWorkingPropertyValidator workingPropertyValidator; + [JsonIgnore] + private readonly NoteStageWorkingPropertyValidator stageWorkingPropertyValidator; + public bool InvalidateWorkingProperty(NoteWorkingProperty workingProperty) => workingPropertyValidator.Invalidate(workingProperty); + public bool InvalidateWorkingProperty(NoteStageWorkingProperty workingProperty) + => stageWorkingPropertyValidator.Invalidate(workingProperty); + private void updateStateByWorkingProperty(NoteWorkingProperty workingProperty) => workingPropertyValidator.UpdateStateByWorkingProperty(workingProperty); - public NoteWorkingProperty[] GetAllInvalidWorkingProperties() + private void updateStateByWorkingProperty(NoteStageWorkingProperty workingProperty) + => stageWorkingPropertyValidator.UpdateStateByWorkingProperty(workingProperty); + + NoteWorkingProperty[] IHasWorkingProperty.GetAllInvalidWorkingProperties() => workingPropertyValidator.GetAllInvalidFlags(); + NoteStageWorkingProperty[] IHasWorkingProperty.GetAllInvalidWorkingProperties() + => stageWorkingPropertyValidator.GetAllInvalidFlags(); + public void ValidateWorkingProperty(KaraokeBeatmap beatmap) { - foreach (var flag in GetAllInvalidWorkingProperties()) + foreach (var flag in workingPropertyValidator.GetAllInvalidFlags()) { switch (flag) { @@ -73,6 +86,10 @@ static IStageEffectApplier getStageEffectApplier(KaraokeBeatmap beatmap, Note no } } + public void ValidateWorkingProperty(StageInfo stageInfo) + { + } + [JsonIgnore] public readonly Bindable PageIndexBindable = new(); diff --git a/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs b/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs index 55e41c70b..08b69dc58 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Types/IHasWorkingProperty.cs @@ -11,6 +11,8 @@ public interface IHasWorkingProperty : IHasWork bool InvalidateWorkingProperty(TWorkingProperty workingProperty); TWorkingProperty[] GetAllInvalidWorkingProperties(); + + bool HasInvalidWorkingProperty() => GetAllInvalidWorkingProperties().Length > 0; } public interface IHasWorkingProperty From 62a92fb456bf4d43f8b94d3104386b7cb782f053 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Mon, 7 Aug 2023 23:00:07 +0800 Subject: [PATCH 4/4] It's time to separate the invalidate property. --- .../LyricStageWorkingPropertyValidatorTest.cs | 64 ++++++++++++++ .../LyricWorkingPropertyValidatorTest.cs | 47 ---------- .../NoteWorkingPropertyValidatorTest.cs | 14 --- .../Beatmaps/KaraokeBeatmapProcessor.cs | 16 +++- .../Stages/ClassicStageChangeHandler.cs | 2 +- osu.Game.Rulesets.Karaoke/Mods/ModStage.cs | 6 +- .../Objects/Lyric_Working.cs | 85 +++++++++---------- .../Objects/Note_Working.cs | 27 +++--- .../Objects/Workings/LyricWorkingProperty.cs | 26 +----- .../Workings/LyricWorkingPropertyValidator.cs | 8 -- .../Objects/Workings/NoteWorkingProperty.cs | 5 -- .../Workings/NoteWorkingPropertyValidator.cs | 2 - .../Stages/Preview/PreviewStageInfo.cs | 4 +- 13 files changed, 137 insertions(+), 169 deletions(-) create mode 100644 osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricStageWorkingPropertyValidatorTest.cs diff --git a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricStageWorkingPropertyValidatorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricStageWorkingPropertyValidatorTest.cs new file mode 100644 index 000000000..e64b6f499 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricStageWorkingPropertyValidatorTest.cs @@ -0,0 +1,64 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using NUnit.Framework; +using osu.Game.Rulesets.Karaoke.Objects; +using osu.Game.Rulesets.Karaoke.Objects.Stages.Classic; +using osu.Game.Rulesets.Karaoke.Objects.Workings; +using osu.Game.Rulesets.Karaoke.Stages; +using osu.Game.Rulesets.Karaoke.Stages.Classic; + +namespace osu.Game.Rulesets.Karaoke.Tests.Objects.Workings; + +public class LyricStageWorkingPropertyValidatorTest : HitObjectWorkingPropertyValidatorTest +{ + [Test] + public void TestStartTime() + { + var lyric = new Lyric(); + + // state is valid because assign the property. + Assert.DoesNotThrow(() => lyric.StartTime = 1000); + AssetIsValid(lyric, LyricStageWorkingProperty.StartTime, true); + } + + [Test] + public void TestDuration() + { + var lyric = new Lyric(); + + // state is valid because assign the property. + Assert.DoesNotThrow(() => lyric.Duration = 1000); + AssetIsValid(lyric, LyricStageWorkingProperty.Duration, true); + } + + [Test] + public void TestTiming() + { + var lyric = new Lyric(); + + // state is still invalid because duration is not assign. + Assert.DoesNotThrow(() => lyric.StartTime = 1000); + AssetIsValid(lyric, LyricStageWorkingProperty.Timing, false); + + // ok, should be valid now. + Assert.DoesNotThrow(() => lyric.Duration = 1000); + AssetIsValid(lyric, LyricStageWorkingProperty.Timing, true); + } + + [Test] + public void TestEffectApplier() + { + var lyric = new Lyric(); + + // state is valid because assign the property. + Assert.DoesNotThrow(() => lyric.EffectApplier = new LyricClassicStageEffectApplier(Array.Empty(), new ClassicStageDefinition())); + AssetIsValid(lyric, LyricStageWorkingProperty.EffectApplier, true); + } + + protected override bool IsInitialStateValid(LyricStageWorkingProperty flag) + { + return new LyricStageWorkingPropertyValidator(new Lyric()).IsValid(flag); + } +} diff --git a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs index 89cd921e8..8a698bb0c 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs @@ -7,10 +7,7 @@ using osu.Game.Rulesets.Karaoke.Beatmaps; using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas; using osu.Game.Rulesets.Karaoke.Objects; -using osu.Game.Rulesets.Karaoke.Objects.Stages.Classic; using osu.Game.Rulesets.Karaoke.Objects.Workings; -using osu.Game.Rulesets.Karaoke.Stages; -using osu.Game.Rulesets.Karaoke.Stages.Classic; using osu.Game.Rulesets.Karaoke.Tests.Extensions; using osu.Game.Rulesets.Karaoke.Tests.Helper; @@ -18,40 +15,6 @@ namespace osu.Game.Rulesets.Karaoke.Tests.Objects.Workings; public class LyricWorkingPropertyValidatorTest : HitObjectWorkingPropertyValidatorTest { - [Test] - public void TestStartTime() - { - var lyric = new Lyric(); - - // state is valid because assign the property. - Assert.DoesNotThrow(() => lyric.StartTime = 1000); - AssetIsValid(lyric, LyricWorkingProperty.StartTime, true); - } - - [Test] - public void TestDuration() - { - var lyric = new Lyric(); - - // state is valid because assign the property. - Assert.DoesNotThrow(() => lyric.Duration = 1000); - AssetIsValid(lyric, LyricWorkingProperty.Duration, true); - } - - [Test] - public void TestTiming() - { - var lyric = new Lyric(); - - // state is still invalid because duration is not assign. - Assert.DoesNotThrow(() => lyric.StartTime = 1000); - AssetIsValid(lyric, LyricWorkingProperty.Timing, false); - - // ok, should be valid now. - Assert.DoesNotThrow(() => lyric.Duration = 1000); - AssetIsValid(lyric, LyricWorkingProperty.Timing, true); - } - [Test] public void TestSingers() { @@ -189,16 +152,6 @@ public void TestReferenceLyric() Assert.Throws(() => lyric.ReferenceLyric = null); } - [Test] - public void TestEffectApplier() - { - var lyric = new Lyric(); - - // state is valid because assign the property. - Assert.DoesNotThrow(() => lyric.EffectApplier = new LyricClassicStageEffectApplier(Array.Empty(), new ClassicStageDefinition())); - AssetIsValid(lyric, LyricWorkingProperty.EffectApplier, true); - } - protected override bool IsInitialStateValid(LyricWorkingProperty flag) { return new LyricWorkingPropertyValidator(new Lyric()).IsValid(flag); diff --git a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs index 729b25a50..1df723032 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs @@ -1,14 +1,10 @@ // Copyright (c) andy840119 . Licensed under the GPL Licence. // See the LICENCE file in the repository root for full licence text. -using System; using NUnit.Framework; using osu.Game.Rulesets.Karaoke.Beatmaps; using osu.Game.Rulesets.Karaoke.Objects; -using osu.Game.Rulesets.Karaoke.Objects.Stages.Classic; using osu.Game.Rulesets.Karaoke.Objects.Workings; -using osu.Game.Rulesets.Karaoke.Stages; -using osu.Game.Rulesets.Karaoke.Stages.Classic; using osu.Game.Rulesets.Karaoke.Tests.Extensions; using osu.Game.Rulesets.Karaoke.Tests.Helper; @@ -76,16 +72,6 @@ public void TestReferenceLyric() Assert.Throws(() => note.ReferenceLyric = null); } - [Test] - public void TestEffectApplier() - { - var note = new Note(); - - // page state is valid because assign the property. - Assert.DoesNotThrow(() => note.EffectApplier = new NoteClassicStageEffectApplier(Array.Empty(), new ClassicStageDefinition())); - AssetIsValid(note, NoteWorkingProperty.EffectApplier, true); - } - protected override bool IsInitialStateValid(NoteWorkingProperty flag) { return new NoteWorkingPropertyValidator(new Note()).IsValid(flag); diff --git a/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs b/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs index a3395dcbc..e2f3190ec 100644 --- a/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs @@ -1,6 +1,7 @@ // Copyright (c) andy840119 . Licensed under the GPL Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Beatmaps; @@ -41,10 +42,10 @@ private void applyStage(KaraokeBeatmap beatmap) // should invalidate the working property here because the stage info is changed. beatmap.HitObjects.OfType().ForEach(x => { - x.InvalidateWorkingProperty(LyricWorkingProperty.Timing); - x.InvalidateWorkingProperty(LyricWorkingProperty.EffectApplier); + x.InvalidateWorkingProperty(LyricStageWorkingProperty.Timing); + x.InvalidateWorkingProperty(LyricStageWorkingProperty.EffectApplier); }); - beatmap.HitObjects.OfType().ForEach(x => x.InvalidateWorkingProperty(NoteWorkingProperty.EffectApplier)); + beatmap.HitObjects.OfType().ForEach(x => x.InvalidateWorkingProperty(NoteStageWorkingProperty.EffectApplier)); } if (beatmap.CurrentStageInfo is IHasCalculatedProperty calculatedProperty) @@ -64,5 +65,14 @@ private void applyInvalidProperty(KaraokeBeatmap beatmap) { hitObject.ValidateWorkingProperty(beatmap); } + + var stageInfo = beatmap.CurrentStageInfo; + if (stageInfo == null) + throw new InvalidCastException(); + + foreach (var hitObject in beatmap.HitObjects.OfType>().ToArray()) + { + hitObject.ValidateWorkingProperty(stageInfo); + } } } diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/ClassicStageChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/ClassicStageChangeHandler.cs index 277993021..b79b04f6b 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/ClassicStageChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/ClassicStageChangeHandler.cs @@ -119,7 +119,7 @@ private void performTimingInfoChanged(Action action) { action(stageInfo.LyricTimingInfo); - InvalidateAllHitObjectWorkingProperty(LyricWorkingProperty.Timing); + InvalidateAllHitObjectWorkingProperty(LyricStageWorkingProperty.Timing); }); } } diff --git a/osu.Game.Rulesets.Karaoke/Mods/ModStage.cs b/osu.Game.Rulesets.Karaoke/Mods/ModStage.cs index e58c337a4..c4f19bc47 100644 --- a/osu.Game.Rulesets.Karaoke/Mods/ModStage.cs +++ b/osu.Game.Rulesets.Karaoke/Mods/ModStage.cs @@ -38,10 +38,10 @@ public override void ApplyToBeatmap(IBeatmap beatmap) // has the same logic in the beatmap processor. beatmap.HitObjects.OfType().ForEach(x => { - x.InvalidateWorkingProperty(LyricWorkingProperty.Timing); - x.InvalidateWorkingProperty(LyricWorkingProperty.EffectApplier); + x.InvalidateWorkingProperty(LyricStageWorkingProperty.Timing); + x.InvalidateWorkingProperty(LyricStageWorkingProperty.EffectApplier); }); - beatmap.HitObjects.OfType().ForEach(x => x.InvalidateWorkingProperty(NoteWorkingProperty.EffectApplier)); + beatmap.HitObjects.OfType().ForEach(x => x.InvalidateWorkingProperty(NoteStageWorkingProperty.EffectApplier)); } protected abstract void ApplyToCurrentStageInfo(TStageInfo stageInfo); diff --git a/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs b/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs index 2fe3be178..44fcfccfc 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Lyric_Working.cs @@ -53,18 +53,6 @@ public void ValidateWorkingProperty(KaraokeBeatmap beatmap) { switch (flag) { - case LyricWorkingProperty.StartTime: - StartTime = getStartTime(beatmap, this); - break; - - case LyricWorkingProperty.Duration: - Duration = getDuration(beatmap, this); - break; - - case LyricWorkingProperty.Timing: - // start time and duration should be set by other condition. - break; - case LyricWorkingProperty.Singers: Singers = getSingers(beatmap, SingerIds); break; @@ -77,35 +65,11 @@ public void ValidateWorkingProperty(KaraokeBeatmap beatmap) ReferenceLyric = findLyricById(beatmap, ReferenceLyricId); break; - case LyricWorkingProperty.EffectApplier: - EffectApplier = getStageEffectApplier(beatmap, this); - break; - default: throw new ArgumentOutOfRangeException(); } } - static double getStartTime(KaraokeBeatmap beatmap, KaraokeHitObject lyric) - { - var stageInfo = beatmap.CurrentStageInfo; - if (stageInfo == null) - throw new InvalidCastException(); - - (double? startTime, double? _) = stageInfo.GetStartAndEndTime(lyric); - return startTime ?? 0; - } - - static double getDuration(KaraokeBeatmap beatmap, KaraokeHitObject lyric) - { - var stageInfo = beatmap.CurrentStageInfo; - if (stageInfo == null) - throw new InvalidCastException(); - - (double? startTime, double? endTime) = stageInfo.GetStartAndEndTime(lyric); - return endTime - startTime ?? 0; - } - static IDictionary getSingers(KaraokeBeatmap beatmap, IEnumerable singerIds) => beatmap.SingerInfo.GetSingerByIds(singerIds.ToArray()); @@ -114,19 +78,46 @@ static IDictionary getSingers(KaraokeBeatmap beatmap, IEn static Lyric? findLyricById(IBeatmap beatmap, ElementId? id) => id == null ? null : beatmap.HitObjects.OfType().Single(x => x.ID == id); + } - static IStageEffectApplier getStageEffectApplier(KaraokeBeatmap beatmap, KaraokeHitObject lyric) + public void ValidateWorkingProperty(StageInfo stageInfo) + { + foreach (var flag in stageWorkingPropertyValidator.GetAllInvalidFlags()) { - var stageInfo = beatmap.CurrentStageInfo; - if (stageInfo == null) - throw new InvalidCastException(); + switch (flag) + { + case LyricStageWorkingProperty.StartTime: + StartTime = getStartTime(stageInfo, this); + break; + + case LyricStageWorkingProperty.Duration: + Duration = getDuration(stageInfo, this); + break; + + case LyricStageWorkingProperty.Timing: + // start time and duration should be set by other condition. + break; + + case LyricStageWorkingProperty.EffectApplier: + EffectApplier = stageInfo.GetStageAppliers(this); + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } - return stageInfo.GetStageAppliers(lyric); + static double getStartTime(StageInfo stageInfo, KaraokeHitObject lyric) + { + (double? startTime, double? _) = stageInfo.GetStartAndEndTime(lyric); + return startTime ?? 0; } - } - public void ValidateWorkingProperty(StageInfo stageInfo) - { + static double getDuration(StageInfo stageInfo, KaraokeHitObject lyric) + { + (double? startTime, double? endTime) = stageInfo.GetStartAndEndTime(lyric); + return endTime - startTime ?? 0; + } } [JsonIgnore] @@ -148,7 +139,7 @@ public override double StartTime set { base.StartTime = value; - updateStateByWorkingProperty(LyricWorkingProperty.StartTime); + updateStateByWorkingProperty(LyricStageWorkingProperty.StartTime); } } @@ -165,7 +156,7 @@ public double Duration set { DurationBindable.Value = value; - updateStateByWorkingProperty(LyricWorkingProperty.Duration); + updateStateByWorkingProperty(LyricStageWorkingProperty.Duration); } } @@ -244,7 +235,7 @@ public IStageEffectApplier EffectApplier { EffectApplierBindable.Value = value; - updateStateByWorkingProperty(LyricWorkingProperty.EffectApplier); + updateStateByWorkingProperty(LyricStageWorkingProperty.EffectApplier); } } } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs b/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs index 273ec1e30..e9ee25817 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Note_Working.cs @@ -61,10 +61,6 @@ public void ValidateWorkingProperty(KaraokeBeatmap beatmap) ReferenceLyric = findLyricById(beatmap, ReferenceLyricId); break; - case NoteWorkingProperty.EffectApplier: - EffectApplier = getStageEffectApplier(beatmap, this); - break; - default: throw new ArgumentOutOfRangeException(); } @@ -75,19 +71,22 @@ public void ValidateWorkingProperty(KaraokeBeatmap beatmap) static Lyric? findLyricById(IBeatmap beatmap, ElementId? id) => id == null ? null : beatmap.HitObjects.OfType().Single(x => x.ID == id); - - static IStageEffectApplier getStageEffectApplier(KaraokeBeatmap beatmap, Note note) - { - var stageInfo = beatmap.CurrentStageInfo; - if (stageInfo == null) - throw new InvalidCastException(); - - return stageInfo.GetStageAppliers(note); - } } public void ValidateWorkingProperty(StageInfo stageInfo) { + foreach (var flag in stageWorkingPropertyValidator.GetAllInvalidFlags()) + { + switch (flag) + { + case NoteStageWorkingProperty.EffectApplier: + EffectApplier = stageInfo.GetStageAppliers(this); + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } } [JsonIgnore] @@ -190,7 +189,7 @@ public IStageEffectApplier EffectApplier { EffectApplierBindable.Value = value; - updateStateByWorkingProperty(NoteWorkingProperty.EffectApplier); + updateStateByWorkingProperty(NoteStageWorkingProperty.EffectApplier); } } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingProperty.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingProperty.cs index 7f45ff25d..a921200aa 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingProperty.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingProperty.cs @@ -11,38 +11,18 @@ namespace osu.Game.Rulesets.Karaoke.Objects.Workings; [Flags] public enum LyricWorkingProperty { - /// - /// is being invalidated. - /// - StartTime = 1, - - /// - /// is being invalidated. - /// - Duration = 1 << 1, - - /// - /// and is being invalidated. - /// - Timing = StartTime | Duration, - /// /// is being invalidated. /// - Singers = 1 << 2, + Singers = 1, /// /// is being invalidated. /// - Page = 1 << 3, + Page = 1 << 1, /// /// is being invalidated. /// - ReferenceLyric = 1 << 4, - - /// - /// is being invalidated. - /// - EffectApplier = 1 << 5, + ReferenceLyric = 1 << 2, } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingPropertyValidator.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingPropertyValidator.cs index 901f7ce30..06b8954c8 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingPropertyValidator.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/LyricWorkingPropertyValidator.cs @@ -18,26 +18,18 @@ public LyricWorkingPropertyValidator(Lyric hitObject) protected override bool HasDataProperty(LyricWorkingProperty flags) => flags switch { - LyricWorkingProperty.StartTime => false, - LyricWorkingProperty.Duration => false, - LyricWorkingProperty.Timing => false, LyricWorkingProperty.Singers => true, LyricWorkingProperty.Page => false, LyricWorkingProperty.ReferenceLyric => true, - LyricWorkingProperty.EffectApplier => false, _ => throw new ArgumentOutOfRangeException(nameof(flags), flags, null), }; protected override bool IsWorkingPropertySynced(Lyric hitObject, LyricWorkingProperty flags) => flags switch { - LyricWorkingProperty.StartTime => true, - LyricWorkingProperty.Duration => true, - LyricWorkingProperty.Timing => true, LyricWorkingProperty.Singers => isWorkingSingerSynced(hitObject), LyricWorkingProperty.Page => true, LyricWorkingProperty.ReferenceLyric => isReferenceLyricSynced(hitObject), - LyricWorkingProperty.EffectApplier => true, _ => throw new ArgumentOutOfRangeException(nameof(flags), flags, null), }; diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingProperty.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingProperty.cs index bc7daf86b..649413f40 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingProperty.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingProperty.cs @@ -20,9 +20,4 @@ public enum NoteWorkingProperty /// is being invalidated. /// ReferenceLyric = 1 << 1, - - /// - /// is being invalidated. - /// - EffectApplier = 1 << 2, } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingPropertyValidator.cs b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingPropertyValidator.cs index a30a23bf7..5b032e94d 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingPropertyValidator.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Workings/NoteWorkingPropertyValidator.cs @@ -17,7 +17,6 @@ protected override bool HasDataProperty(NoteWorkingProperty flags) => { NoteWorkingProperty.Page => false, NoteWorkingProperty.ReferenceLyric => true, - NoteWorkingProperty.EffectApplier => false, _ => throw new ArgumentOutOfRangeException(nameof(flags), flags, null), }; @@ -26,7 +25,6 @@ protected override bool IsWorkingPropertySynced(Note hitObject, NoteWorkingPrope { NoteWorkingProperty.Page => true, NoteWorkingProperty.ReferenceLyric => hitObject.ReferenceLyric?.ID == hitObject.ReferenceLyricId, - NoteWorkingProperty.EffectApplier => true, _ => throw new ArgumentOutOfRangeException(nameof(flags), flags, null), }; } diff --git a/osu.Game.Rulesets.Karaoke/Stages/Preview/PreviewStageInfo.cs b/osu.Game.Rulesets.Karaoke/Stages/Preview/PreviewStageInfo.cs index 38fa1aa5a..aa0331f41 100644 --- a/osu.Game.Rulesets.Karaoke/Stages/Preview/PreviewStageInfo.cs +++ b/osu.Game.Rulesets.Karaoke/Stages/Preview/PreviewStageInfo.cs @@ -86,8 +86,8 @@ public void ValidateCalculatedProperty(IBeatmap beatmap) layoutCategory.AddToMapping(element, lyric); // Need to invalidate the working property in the lyric to let the property re-fill in the beatmap processor. - lyric.InvalidateWorkingProperty(LyricWorkingProperty.Timing); - lyric.InvalidateWorkingProperty(LyricWorkingProperty.EffectApplier); + lyric.InvalidateWorkingProperty(LyricStageWorkingProperty.Timing); + lyric.InvalidateWorkingProperty(LyricStageWorkingProperty.EffectApplier); } calculatedPropertyIsUpdated = true;