From dc75d55f72af11bdf81b081dad8f5e84be3ed2e2 Mon Sep 17 00:00:00 2001
From: Gabe Livengood <47010459+ggliv@users.noreply.github.com>
Date: Wed, 8 Jun 2022 14:02:15 -0400
Subject: [PATCH 001/317] allow modfailcondition to arbitrarily trigger fail
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 19 +++++++++++++++++++
osu.Game/Rulesets/Scoring/HealthProcessor.cs | 14 ++++++++++----
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 4425ece513..1aab0ab880 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -19,12 +19,31 @@ namespace osu.Game.Rulesets.Mods
public virtual bool PerformFail() => true;
public virtual bool RestartOnFail => Restart.Value;
+ private HealthProcessor healthProcessorInternal;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
+ healthProcessorInternal = healthProcessor;
healthProcessor.FailConditions += FailCondition;
}
+ ///
+ /// Immediately triggers a failure on the loaded .
+ ///
+ protected void TriggerArbitraryFailure() => healthProcessorInternal.TriggerFailure();
+
+ ///
+ /// Determines whether should trigger a failure. Called every time a
+ /// judgement is applied to .
+ ///
+ /// The loaded .
+ /// The latest .
+ /// Whether the fail condition has been met.
+ ///
+ /// This method should only be used to trigger failures based on .
+ /// Using outside values to evaluate failure may introduce event ordering discrepancies, use
+ /// an with instead.
+ ///
protected abstract bool FailCondition(HealthProcessor healthProcessor, JudgementResult result);
}
}
diff --git a/osu.Game/Rulesets/Scoring/HealthProcessor.cs b/osu.Game/Rulesets/Scoring/HealthProcessor.cs
index 0f51560476..4f5ff95477 100644
--- a/osu.Game/Rulesets/Scoring/HealthProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/HealthProcessor.cs
@@ -33,6 +33,15 @@ namespace osu.Game.Rulesets.Scoring
///
public bool HasFailed { get; private set; }
+ ///
+ /// Immediately triggers a failure for this HealthProcessor.
+ ///
+ public void TriggerFailure()
+ {
+ if (Failed?.Invoke() != false)
+ HasFailed = true;
+ }
+
protected override void ApplyResultInternal(JudgementResult result)
{
result.HealthAtJudgement = Health.Value;
@@ -44,10 +53,7 @@ namespace osu.Game.Rulesets.Scoring
Health.Value += GetHealthIncreaseFor(result);
if (meetsAnyFailCondition(result))
- {
- if (Failed?.Invoke() != false)
- HasFailed = true;
- }
+ TriggerFailure();
}
protected override void RevertResultInternal(JudgementResult result)
From 21c5499da16eb88f12d6f5bee8d28b1557559b2f Mon Sep 17 00:00:00 2001
From: Gabe Livengood <47010459+ggliv@users.noreply.github.com>
Date: Fri, 10 Jun 2022 13:11:17 -0400
Subject: [PATCH 002/317] remove arbitrary from method name
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 1aab0ab880..9500734408 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mods
///
/// Immediately triggers a failure on the loaded .
///
- protected void TriggerArbitraryFailure() => healthProcessorInternal.TriggerFailure();
+ protected void TriggerFailure() => healthProcessorInternal.TriggerFailure();
///
/// Determines whether should trigger a failure. Called every time a
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods
///
/// This method should only be used to trigger failures based on .
/// Using outside values to evaluate failure may introduce event ordering discrepancies, use
- /// an with instead.
+ /// an with instead.
///
protected abstract bool FailCondition(HealthProcessor healthProcessor, JudgementResult result);
}
From 6e64a8f55ef5838a5d58625668138fb3c85e34db Mon Sep 17 00:00:00 2001
From: Gabe Livengood <47010459+ggliv@users.noreply.github.com>
Date: Fri, 10 Jun 2022 13:13:35 -0400
Subject: [PATCH 003/317] use event to trigger failure
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 9500734408..63cebc9747 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -19,18 +19,18 @@ namespace osu.Game.Rulesets.Mods
public virtual bool PerformFail() => true;
public virtual bool RestartOnFail => Restart.Value;
- private HealthProcessor healthProcessorInternal;
+ private event Action failureTriggered;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
- healthProcessorInternal = healthProcessor;
+ failureTriggered = healthProcessor.TriggerFailure;
healthProcessor.FailConditions += FailCondition;
}
///
/// Immediately triggers a failure on the loaded .
///
- protected void TriggerFailure() => healthProcessorInternal.TriggerFailure();
+ protected void TriggerFailure() => failureTriggered?.Invoke();
///
/// Determines whether should trigger a failure. Called every time a
From 45981125860b331d5f5dbaa59966e6d354f2fd4c Mon Sep 17 00:00:00 2001
From: Cootz
Date: Sun, 5 Feb 2023 21:46:38 +0300
Subject: [PATCH 004/317] Add OriginalBeatmapHash to ScoreInfo. Update db
schema_version, migration
---
osu.Game/Beatmaps/BeatmapManager.cs | 8 ++++++++
osu.Game/Database/RealmAccess.cs | 15 +++++++++++++++
osu.Game/Scoring/ScoreInfo.cs | 2 ++
3 files changed, 25 insertions(+)
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index ad56bbbc3a..e972f067ca 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
+using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Framework.Testing;
@@ -25,6 +26,7 @@ using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
+using osu.Game.Scoring;
using osu.Game.Skinning;
using osu.Game.Utils;
@@ -454,6 +456,12 @@ namespace osu.Game.Beatmaps
if (transferCollections)
beatmapInfo.TransferCollectionReferences(r, oldMd5Hash);
+ //Unlinking all scores from this beatmap
+ r.All().Where(s => s.BeatmapInfoID == beatmapInfo.ID).ForEach(s => s.BeatmapInfo = new BeatmapInfo());
+
+ //Linking all the previos scores
+ r.All().Where(s => s.OriginalBeatmapHash == beatmapInfo.Hash).ForEach(s => s.BeatmapInfo = beatmapInfo);
+
ProcessBeatmap?.Invoke((liveBeatmapSet, false));
});
}
diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs
index 177c671bca..422ceb8af3 100644
--- a/osu.Game/Database/RealmAccess.cs
+++ b/osu.Game/Database/RealmAccess.cs
@@ -70,6 +70,7 @@ namespace osu.Game.Database
/// 23 2022-08-01 Added LastLocalUpdate to BeatmapInfo.
/// 24 2022-08-22 Added MaximumStatistics to ScoreInfo.
/// 25 2022-09-18 Remove skins to add with new naming.
+ /// 26 2023-02-05 Added OriginalBeatmapHash to ScoreInfo.
///
private const int schema_version = 25;
@@ -865,6 +866,20 @@ namespace osu.Game.Database
case 25:
// Remove the default skins so they can be added back by SkinManager with updated naming.
migration.NewRealm.RemoveRange(migration.NewRealm.All().Where(s => s.Protected));
+ break;
+ case 26:
+ // Adding origin beatmap hash property to ensure the score corresponds to the version of beatmap it should
+ // See: https://github.com/ppy/osu/issues/22062
+ string ScoreInfoName = getMappedOrOriginalName(typeof(ScoreInfo));
+
+ var oldScoreInfos = migration.OldRealm.DynamicApi.All(ScoreInfoName);
+ var newScoreInfos = migration.NewRealm.All();
+
+ for (int i = 0; i < newScoreInfos.Count(); i++)
+ {
+ newScoreInfos.ElementAt(i).OriginalBeatmapHash = oldScoreInfos.ElementAt(i).BeatmapInfo.Hash;
+ }
+
break;
}
}
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 1009474d89..2c029bbe68 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -66,6 +66,8 @@ namespace osu.Game.Scoring
[MapTo("MaximumStatistics")]
public string MaximumStatisticsJson { get; set; } = string.Empty;
+ public string OriginalBeatmapHash { get; set; } = string.Empty;
+
public ScoreInfo(BeatmapInfo? beatmap = null, RulesetInfo? ruleset = null, RealmUser? realmUser = null)
{
Ruleset = ruleset ?? new RulesetInfo();
From d23e787bc1f341ae41c3fa5a21467d0c9f320973 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Sun, 5 Feb 2023 21:55:50 +0300
Subject: [PATCH 005/317] Update `schema_version`
---
osu.Game/Database/RealmAccess.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs
index 422ceb8af3..6f85b3f1be 100644
--- a/osu.Game/Database/RealmAccess.cs
+++ b/osu.Game/Database/RealmAccess.cs
@@ -72,7 +72,7 @@ namespace osu.Game.Database
/// 25 2022-09-18 Remove skins to add with new naming.
/// 26 2023-02-05 Added OriginalBeatmapHash to ScoreInfo.
///
- private const int schema_version = 25;
+ private const int schema_version = 26;
///
/// Lock object which is held during sections, blocking realm retrieval during blocking periods.
From b00848e742d48ef08849d5115690909109c88de9 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Mon, 6 Feb 2023 13:58:41 +0300
Subject: [PATCH 006/317] Fix realm error. Apply `OriginalBeatmapHash` on
import
---
osu.Game/Beatmaps/BeatmapManager.cs | 6 ------
osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 1 +
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index e972f067ca..b46859cc59 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -456,12 +456,6 @@ namespace osu.Game.Beatmaps
if (transferCollections)
beatmapInfo.TransferCollectionReferences(r, oldMd5Hash);
- //Unlinking all scores from this beatmap
- r.All().Where(s => s.BeatmapInfoID == beatmapInfo.ID).ForEach(s => s.BeatmapInfo = new BeatmapInfo());
-
- //Linking all the previos scores
- r.All().Where(s => s.OriginalBeatmapHash == beatmapInfo.Hash).ForEach(s => s.BeatmapInfo = beatmapInfo);
-
ProcessBeatmap?.Invoke((liveBeatmapSet, false));
});
}
diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
index 6f0b0c62f8..4bd068ca0f 100644
--- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
+++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
@@ -123,6 +123,7 @@ namespace osu.Game.Scoring.Legacy
// before returning for database import, we must restore the database-sourced BeatmapInfo.
// if not, the clone operation in GetPlayableBeatmap will cause a dereference and subsequent database exception.
score.ScoreInfo.BeatmapInfo = workingBeatmap.BeatmapInfo;
+ score.ScoreInfo.OriginalBeatmapHash = workingBeatmap.BeatmapInfo.Hash;
return score;
}
From 2c7386db39d894cfa8ef335e7c58659399ed2e19 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Mon, 6 Feb 2023 15:14:14 +0300
Subject: [PATCH 007/317] FIx score appearing on `BeatmapLeaderboard` and
`TopLocalRank`
---
osu.Game/Screens/Play/Player.cs | 1 +
osu.Game/Screens/Select/Carousel/TopLocalRank.cs | 1 +
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 1 +
3 files changed, 3 insertions(+)
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 0d208e6d9b..7bd020db93 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -248,6 +248,7 @@ namespace osu.Game.Screens.Play
// ensure the score is in a consistent state with the current player.
Score.ScoreInfo.BeatmapInfo = Beatmap.Value.BeatmapInfo;
+ Score.ScoreInfo.OriginalBeatmapHash = Beatmap.Value.BeatmapInfo.Hash;
Score.ScoreInfo.Ruleset = ruleset.RulesetInfo;
Score.ScoreInfo.Mods = gameplayMods;
diff --git a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs
index f1b773c831..3df72f7d3b 100644
--- a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs
+++ b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs
@@ -65,6 +65,7 @@ namespace osu.Game.Screens.Select.Carousel
r.All()
.Filter($"{nameof(ScoreInfo.User)}.{nameof(RealmUser.OnlineID)} == $0"
+ $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $1"
+ + $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.OriginalBeatmapHash)}"
+ $" && {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $2"
+ $" && {nameof(ScoreInfo.DeletePending)} == false", api.LocalUser.Value.Id, beatmapInfo.ID, ruleset.Value.ShortName),
localScoresChanged);
diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
index 5c720c8491..3e90d2465b 100644
--- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
+++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
@@ -191,6 +191,7 @@ namespace osu.Game.Screens.Select.Leaderboards
scoreSubscription = realm.RegisterForNotifications(r =>
r.All().Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $0"
+ + $" AND {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.OriginalBeatmapHash)}"
+ $" AND {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $1"
+ $" AND {nameof(ScoreInfo.DeletePending)} == false"
, beatmapInfo.ID, ruleset.Value.ShortName), localScoresChanged);
From cb26601cb4be90a62d898d230a14ac9cb667ecc3 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Tue, 7 Feb 2023 02:29:28 +0300
Subject: [PATCH 008/317] Fix test's score generation
---
osu.Game.Tests/Resources/TestResources.cs | 1 +
.../Visual/SongSelect/TestSceneBeatmapLeaderboard.cs | 10 ++++++++++
.../Visual/UserInterface/TestSceneDeleteLocalScore.cs | 1 +
3 files changed, 12 insertions(+)
diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs
index adf28afc8e..f65d427649 100644
--- a/osu.Game.Tests/Resources/TestResources.cs
+++ b/osu.Game.Tests/Resources/TestResources.cs
@@ -176,6 +176,7 @@ namespace osu.Game.Tests.Resources
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
},
BeatmapInfo = beatmap,
+ OriginalBeatmapHash = beatmap.Hash,
Ruleset = beatmap.Ruleset,
Mods = new Mod[] { new TestModHardRock(), new TestModDoubleTime() },
TotalScore = 2845370,
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index ef0ad6c25c..7a578230d9 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -210,6 +210,7 @@ namespace osu.Game.Tests.Visual.SongSelect
},
Ruleset = new OsuRuleset().RulesetInfo,
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
User = new APIUser
{
Id = 6602580,
@@ -226,6 +227,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddSeconds(-30),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
{
@@ -243,6 +245,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddSeconds(-70),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -261,6 +264,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddMinutes(-40),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -279,6 +283,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-2),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -297,6 +302,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-25),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -315,6 +321,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-50),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -333,6 +340,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-72),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -351,6 +359,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddMonths(-3),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -369,6 +378,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddYears(-2),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
index 7635c61867..14193b1ac8 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
@@ -94,6 +94,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
OnlineID = i,
BeatmapInfo = beatmapInfo,
+ OriginalBeatmapHash = beatmapInfo.Hash,
Accuracy = RNG.NextDouble(),
TotalScore = RNG.Next(1, 1000000),
MaxCombo = RNG.Next(1, 1000),
From 723f13af259da2e022a5c25b61d84b67c8ad75a9 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Tue, 7 Feb 2023 02:43:27 +0300
Subject: [PATCH 009/317] Add summary for `OriginalBeatmapHash`
---
osu.Game/Scoring/ScoreInfo.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 2c029bbe68..7ad2d9203a 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -66,6 +66,9 @@ namespace osu.Game.Scoring
[MapTo("MaximumStatistics")]
public string MaximumStatisticsJson { get; set; } = string.Empty;
+ ///
+ /// Hash of the beatmap where it scored
+ ///
public string OriginalBeatmapHash { get; set; } = string.Empty;
public ScoreInfo(BeatmapInfo? beatmap = null, RulesetInfo? ruleset = null, RealmUser? realmUser = null)
From 1470ea0a311bec07ba3ba6525025939e51322a68 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Tue, 7 Feb 2023 03:07:53 +0300
Subject: [PATCH 010/317] Remove unnecessary using directives
---
osu.Game/Beatmaps/BeatmapManager.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index b46859cc59..ad56bbbc3a 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -13,7 +13,6 @@ using System.Threading.Tasks;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
-using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Framework.Testing;
@@ -26,7 +25,6 @@ using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
-using osu.Game.Scoring;
using osu.Game.Skinning;
using osu.Game.Utils;
From a1ee3df453f46a271d7ba7450f791340119cc539 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Tue, 7 Feb 2023 03:16:25 +0300
Subject: [PATCH 011/317] Improve local variable naming
---
osu.Game/Database/RealmAccess.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs
index 6f85b3f1be..1ef904fbc3 100644
--- a/osu.Game/Database/RealmAccess.cs
+++ b/osu.Game/Database/RealmAccess.cs
@@ -867,12 +867,13 @@ namespace osu.Game.Database
// Remove the default skins so they can be added back by SkinManager with updated naming.
migration.NewRealm.RemoveRange(migration.NewRealm.All().Where(s => s.Protected));
break;
+
case 26:
// Adding origin beatmap hash property to ensure the score corresponds to the version of beatmap it should
// See: https://github.com/ppy/osu/issues/22062
- string ScoreInfoName = getMappedOrOriginalName(typeof(ScoreInfo));
+ string scoreInfoName = getMappedOrOriginalName(typeof(ScoreInfo));
- var oldScoreInfos = migration.OldRealm.DynamicApi.All(ScoreInfoName);
+ var oldScoreInfos = migration.OldRealm.DynamicApi.All(scoreInfoName);
var newScoreInfos = migration.NewRealm.All();
for (int i = 0; i < newScoreInfos.Count(); i++)
From 957c9e7e276037c9c0db101f5e77cbaf3ceda5da Mon Sep 17 00:00:00 2001
From: Cootz <50776304+Cootz@users.noreply.github.com>
Date: Tue, 7 Feb 2023 11:23:39 +0300
Subject: [PATCH 012/317] Update osu.Game/Scoring/ScoreInfo.cs
Co-authored-by: Dean Herbert
---
osu.Game/Scoring/ScoreInfo.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 7ad2d9203a..2ea40df44d 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -67,9 +67,9 @@ namespace osu.Game.Scoring
public string MaximumStatisticsJson { get; set; } = string.Empty;
///
- /// Hash of the beatmap where it scored
+ /// The beatmap's at the point in time when the score was set.
///
- public string OriginalBeatmapHash { get; set; } = string.Empty;
+ public string BeatmapHash { get; set; } = string.Empty;
public ScoreInfo(BeatmapInfo? beatmap = null, RulesetInfo? ruleset = null, RealmUser? realmUser = null)
{
From 7e127dafe21a89f5059f59de5cff7904f34e9783 Mon Sep 17 00:00:00 2001
From: PC
Date: Tue, 7 Feb 2023 11:52:47 +0300
Subject: [PATCH 013/317] Update reference
---
osu.Game.Tests/Resources/TestResources.cs | 2 +-
.../SongSelect/TestSceneBeatmapLeaderboard.cs | 20 +++++++++----------
.../TestSceneDeleteLocalScore.cs | 2 +-
osu.Game/Database/RealmAccess.cs | 4 ++--
osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 2 +-
osu.Game/Scoring/ScoreInfo.cs | 2 +-
osu.Game/Screens/Play/Player.cs | 2 +-
.../Screens/Select/Carousel/TopLocalRank.cs | 2 +-
.../Select/Leaderboards/BeatmapLeaderboard.cs | 2 +-
9 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs
index f65d427649..a2d81c0a75 100644
--- a/osu.Game.Tests/Resources/TestResources.cs
+++ b/osu.Game.Tests/Resources/TestResources.cs
@@ -176,7 +176,7 @@ namespace osu.Game.Tests.Resources
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
},
BeatmapInfo = beatmap,
- OriginalBeatmapHash = beatmap.Hash,
+ BeatmapHash = beatmap.Hash,
Ruleset = beatmap.Ruleset,
Mods = new Mod[] { new TestModHardRock(), new TestModDoubleTime() },
TotalScore = 2845370,
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 7a578230d9..c4bca79480 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -210,7 +210,7 @@ namespace osu.Game.Tests.Visual.SongSelect
},
Ruleset = new OsuRuleset().RulesetInfo,
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
User = new APIUser
{
Id = 6602580,
@@ -227,7 +227,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddSeconds(-30),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
{
@@ -245,7 +245,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddSeconds(-70),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -264,7 +264,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddMinutes(-40),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -283,7 +283,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-2),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -302,7 +302,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-25),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -321,7 +321,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-50),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -340,7 +340,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddHours(-72),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -359,7 +359,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddMonths(-3),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
@@ -378,7 +378,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Date = DateTime.Now.AddYears(-2),
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
index 14193b1ac8..529874b71e 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
@@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
OnlineID = i,
BeatmapInfo = beatmapInfo,
- OriginalBeatmapHash = beatmapInfo.Hash,
+ BeatmapHash = beatmapInfo.Hash,
Accuracy = RNG.NextDouble(),
TotalScore = RNG.Next(1, 1000000),
MaxCombo = RNG.Next(1, 1000),
diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs
index 1ef904fbc3..b151fc6474 100644
--- a/osu.Game/Database/RealmAccess.cs
+++ b/osu.Game/Database/RealmAccess.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Database
/// 23 2022-08-01 Added LastLocalUpdate to BeatmapInfo.
/// 24 2022-08-22 Added MaximumStatistics to ScoreInfo.
/// 25 2022-09-18 Remove skins to add with new naming.
- /// 26 2023-02-05 Added OriginalBeatmapHash to ScoreInfo.
+ /// 26 2023-02-05 Added BeatmapHash to ScoreInfo.
///
private const int schema_version = 26;
@@ -878,7 +878,7 @@ namespace osu.Game.Database
for (int i = 0; i < newScoreInfos.Count(); i++)
{
- newScoreInfos.ElementAt(i).OriginalBeatmapHash = oldScoreInfos.ElementAt(i).BeatmapInfo.Hash;
+ newScoreInfos.ElementAt(i).BeatmapHash = oldScoreInfos.ElementAt(i).BeatmapInfo.Hash;
}
break;
diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
index 4bd068ca0f..9b145ad56e 100644
--- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
+++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs
@@ -123,7 +123,7 @@ namespace osu.Game.Scoring.Legacy
// before returning for database import, we must restore the database-sourced BeatmapInfo.
// if not, the clone operation in GetPlayableBeatmap will cause a dereference and subsequent database exception.
score.ScoreInfo.BeatmapInfo = workingBeatmap.BeatmapInfo;
- score.ScoreInfo.OriginalBeatmapHash = workingBeatmap.BeatmapInfo.Hash;
+ score.ScoreInfo.BeatmapHash = workingBeatmap.BeatmapInfo.Hash;
return score;
}
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 2ea40df44d..62adcb9f94 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Scoring
public string MaximumStatisticsJson { get; set; } = string.Empty;
///
- /// The beatmap's at the point in time when the score was set.
+ /// The at the point in time when the score was set.
///
public string BeatmapHash { get; set; } = string.Empty;
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 7bd020db93..a3d8d3237c 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -248,7 +248,7 @@ namespace osu.Game.Screens.Play
// ensure the score is in a consistent state with the current player.
Score.ScoreInfo.BeatmapInfo = Beatmap.Value.BeatmapInfo;
- Score.ScoreInfo.OriginalBeatmapHash = Beatmap.Value.BeatmapInfo.Hash;
+ Score.ScoreInfo.BeatmapHash = Beatmap.Value.BeatmapInfo.Hash;
Score.ScoreInfo.Ruleset = ruleset.RulesetInfo;
Score.ScoreInfo.Mods = gameplayMods;
diff --git a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs
index 3df72f7d3b..a57a8b0f27 100644
--- a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs
+++ b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs
@@ -65,7 +65,7 @@ namespace osu.Game.Screens.Select.Carousel
r.All()
.Filter($"{nameof(ScoreInfo.User)}.{nameof(RealmUser.OnlineID)} == $0"
+ $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $1"
- + $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.OriginalBeatmapHash)}"
+ + $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.BeatmapHash)}"
+ $" && {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $2"
+ $" && {nameof(ScoreInfo.DeletePending)} == false", api.LocalUser.Value.Id, beatmapInfo.ID, ruleset.Value.ShortName),
localScoresChanged);
diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
index 3e90d2465b..2b40b9faf8 100644
--- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
+++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
@@ -191,7 +191,7 @@ namespace osu.Game.Screens.Select.Leaderboards
scoreSubscription = realm.RegisterForNotifications(r =>
r.All().Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $0"
- + $" AND {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.OriginalBeatmapHash)}"
+ + $" AND {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.BeatmapHash)}"
+ $" AND {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $1"
+ $" AND {nameof(ScoreInfo.DeletePending)} == false"
, beatmapInfo.ID, ruleset.Value.ShortName), localScoresChanged);
From 338d96534a2ad7b27d82eeeafb2c778fb67d0b67 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Wed, 8 Feb 2023 05:01:54 +0300
Subject: [PATCH 014/317] Add leaderboard test on beatmap update
---
.../SongSelect/TestSceneBeatmapLeaderboard.cs | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index c4bca79480..13a24cd490 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -96,6 +96,37 @@ namespace osu.Game.Tests.Visual.SongSelect
checkCount(0);
}
+ [Test]
+ public void TestLocalScoresDisplayOnBeatmapEdit()
+ {
+ BeatmapInfo beatmapInfo = null!;
+
+ AddStep(@"Set scope", () => leaderboard.Scope = BeatmapLeaderboardScope.Local);
+
+ AddStep(@"Set beatmap", () =>
+ {
+ beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
+ beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
+
+ leaderboard.BeatmapInfo = beatmapInfo;
+ });
+
+ clearScores();
+ checkCount(0);
+
+ loadMoreScores(() => beatmapInfo);
+ checkCount(10);
+
+ beatmapEdit(() => beatmapInfo);
+ checkCount(0);
+
+ loadMoreScores(() => beatmapInfo);
+ checkCount(10);
+
+ clearScores();
+ checkCount(0);
+ }
+
[Test]
public void TestGlobalScoresDisplay()
{
@@ -123,6 +154,21 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"None selected", () => leaderboard.SetErrorState(LeaderboardState.NoneSelected));
}
+ private void beatmapEdit(Func beatmapInfo)
+ {
+ AddStep(@"Update beatmap via BeatmapManager", () =>
+ {
+ BeatmapInfo info = beatmapInfo();
+ IBeatmap beatmap = beatmapManager.GetWorkingBeatmap(info).Beatmap;
+
+ beatmap.Difficulty.ApproachRate = 11;
+ beatmap.Difficulty.DrainRate = 11;
+ beatmap.Difficulty.OverallDifficulty = 11;
+
+ beatmapManager.Save(info, beatmap);
+ });
+ }
+
private void showPersonalBestWithNullPosition()
{
leaderboard.SetScores(leaderboard.Scores, new ScoreInfo
From 391af2791b875a9928bba1d92dbcbae2128c0dd0 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Wed, 8 Feb 2023 05:23:42 +0300
Subject: [PATCH 015/317] Fix CSharpWarnings::CS1574,CS1584,CS1581,CS1580
---
osu.Game/Scoring/ScoreInfo.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 62adcb9f94..8c912ef32a 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Scoring
public string MaximumStatisticsJson { get; set; } = string.Empty;
///
- /// The at the point in time when the score was set.
+ /// The .Hash at the point in time when the score was set.
///
public string BeatmapHash { get; set; } = string.Empty;
From 6bf56aff73e07b7cd92241b251ae0ea0d9787b99 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Wed, 8 Feb 2023 05:40:20 +0300
Subject: [PATCH 016/317] Add warning for `ScoreInfo`
---
osu.Game/Scoring/ScoreInfo.cs | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 8c912ef32a..c57e06bee5 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -22,6 +22,13 @@ using Realms;
namespace osu.Game.Scoring
{
+
+ ///
+ /// Store information about the score
+ ///
+ ///
+ /// If you work on inporting/adding score please ensure you provide both BeatmapInfo and BeatmapHash
+ ///
[ExcludeFromDynamicCompile]
[MapTo("Score")]
public class ScoreInfo : RealmObject, IHasGuidPrimaryKey, IHasRealmFiles, ISoftDelete, IEquatable, IScoreInfo
From ab7c9a200bdcc7804927ca68b9c59da58d22d49f Mon Sep 17 00:00:00 2001
From: Cootz
Date: Wed, 8 Feb 2023 05:42:06 +0300
Subject: [PATCH 017/317] Fix a typo
---
osu.Game/Scoring/ScoreInfo.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index c57e06bee5..85452ede17 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Scoring
/// Store information about the score
///
///
- /// If you work on inporting/adding score please ensure you provide both BeatmapInfo and BeatmapHash
+ /// Warning: If you work on importing/adding score please ensure you provide both BeatmapInfo and BeatmapHash
///
[ExcludeFromDynamicCompile]
[MapTo("Score")]
From 4ba915268c5e0a34824d2a03cb501a12574707a4 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Wed, 8 Feb 2023 05:46:47 +0300
Subject: [PATCH 018/317] Change a comment into `RealmAccess`
---
osu.Game/Database/RealmAccess.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs
index b151fc6474..861a74e163 100644
--- a/osu.Game/Database/RealmAccess.cs
+++ b/osu.Game/Database/RealmAccess.cs
@@ -869,7 +869,7 @@ namespace osu.Game.Database
break;
case 26:
- // Adding origin beatmap hash property to ensure the score corresponds to the version of beatmap it should
+ // Add ScoreInfo.BeatmapHash property to ensure the score corresponds to the version of beatmap it should
// See: https://github.com/ppy/osu/issues/22062
string scoreInfoName = getMappedOrOriginalName(typeof(ScoreInfo));
From 086b3eb542348048da062fde8234239e8d7d3ef6 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Wed, 8 Feb 2023 05:50:52 +0300
Subject: [PATCH 019/317] Fix minor formating issues
---
osu.Game/Scoring/ScoreInfo.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 85452ede17..d2ec4ebd5f 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -22,10 +22,9 @@ using Realms;
namespace osu.Game.Scoring
{
-
///
/// Store information about the score
- ///
+ ///
///
/// Warning: If you work on importing/adding score please ensure you provide both BeatmapInfo and BeatmapHash
///
From 5c113ddb030445c5099fdd2334d6b2608f5851ef Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 8 Feb 2023 14:20:58 +0900
Subject: [PATCH 020/317] Reword xmldoc to read better
---
osu.Game/Scoring/ScoreInfo.cs | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index d2ec4ebd5f..6213c65c75 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -23,11 +23,8 @@ using Realms;
namespace osu.Game.Scoring
{
///
- /// Store information about the score
+ /// A realm model containing metadata for a single score.
///
- ///
- /// Warning: If you work on importing/adding score please ensure you provide both BeatmapInfo and BeatmapHash
- ///
[ExcludeFromDynamicCompile]
[MapTo("Score")]
public class ScoreInfo : RealmObject, IHasGuidPrimaryKey, IHasRealmFiles, ISoftDelete, IEquatable, IScoreInfo
@@ -35,8 +32,19 @@ namespace osu.Game.Scoring
[PrimaryKey]
public Guid ID { get; set; }
+ ///
+ /// The this score was made against.
+ ///
+ ///
+ /// When setting this, make sure to also set to allow relational consistency when a beatmap is potentially changed.
+ ///
public BeatmapInfo BeatmapInfo { get; set; } = null!;
+ ///
+ /// The at the point in time when the score was set.
+ ///
+ public string BeatmapHash { get; set; } = string.Empty;
+
public RulesetInfo Ruleset { get; set; } = null!;
public IList Files { get; } = null!;
@@ -72,11 +80,6 @@ namespace osu.Game.Scoring
[MapTo("MaximumStatistics")]
public string MaximumStatisticsJson { get; set; } = string.Empty;
- ///
- /// The .Hash at the point in time when the score was set.
- ///
- public string BeatmapHash { get; set; } = string.Empty;
-
public ScoreInfo(BeatmapInfo? beatmap = null, RulesetInfo? ruleset = null, RealmUser? realmUser = null)
{
Ruleset = ruleset ?? new RulesetInfo();
From c50ea89bc99f3dc142e85ecec3bf2504d3fd5f32 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 8 Feb 2023 14:24:06 +0900
Subject: [PATCH 021/317] Simplify migration to not rely on old/dynamic schema
---
osu.Game/Database/RealmAccess.cs | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs
index 861a74e163..831e328439 100644
--- a/osu.Game/Database/RealmAccess.cs
+++ b/osu.Game/Database/RealmAccess.cs
@@ -869,17 +869,11 @@ namespace osu.Game.Database
break;
case 26:
- // Add ScoreInfo.BeatmapHash property to ensure the score corresponds to the version of beatmap it should
- // See: https://github.com/ppy/osu/issues/22062
- string scoreInfoName = getMappedOrOriginalName(typeof(ScoreInfo));
+ // Add ScoreInfo.BeatmapHash property to ensure scores correspond to the correct version of beatmap.
+ var scores = migration.NewRealm.All();
- var oldScoreInfos = migration.OldRealm.DynamicApi.All(scoreInfoName);
- var newScoreInfos = migration.NewRealm.All();
-
- for (int i = 0; i < newScoreInfos.Count(); i++)
- {
- newScoreInfos.ElementAt(i).BeatmapHash = oldScoreInfos.ElementAt(i).BeatmapInfo.Hash;
- }
+ foreach (var score in scores)
+ score.BeatmapHash = score.BeatmapInfo.Hash;
break;
}
From c7eec371f52dd403a0bfaeea6f645d4a56dd3857 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 8 Feb 2023 15:22:17 +0900
Subject: [PATCH 022/317] Clean up tests somewhat
---
.../SongSelect/TestSceneBeatmapLeaderboard.cs | 41 ++++++++-----------
1 file changed, 18 insertions(+), 23 deletions(-)
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 13a24cd490..83bb58804d 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -86,10 +86,10 @@ namespace osu.Game.Tests.Visual.SongSelect
clearScores();
checkCount(0);
- loadMoreScores(() => beatmapInfo);
+ importMoreScores(() => beatmapInfo);
checkCount(10);
- loadMoreScores(() => beatmapInfo);
+ importMoreScores(() => beatmapInfo);
checkCount(20);
clearScores();
@@ -114,13 +114,23 @@ namespace osu.Game.Tests.Visual.SongSelect
clearScores();
checkCount(0);
- loadMoreScores(() => beatmapInfo);
+ importMoreScores(() => beatmapInfo);
checkCount(10);
- beatmapEdit(() => beatmapInfo);
+ AddStep(@"Save beatmap with changes", () =>
+ {
+ IBeatmap beatmap = beatmapManager.GetWorkingBeatmap(beatmapInfo).Beatmap;
+
+ beatmap.Difficulty.ApproachRate = 11;
+ beatmap.Difficulty.DrainRate = 11;
+ beatmap.Difficulty.OverallDifficulty = 11;
+
+ beatmapManager.Save(beatmapInfo, beatmap);
+ });
+
checkCount(0);
- loadMoreScores(() => beatmapInfo);
+ importMoreScores(() => beatmapInfo);
checkCount(10);
clearScores();
@@ -154,21 +164,6 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"None selected", () => leaderboard.SetErrorState(LeaderboardState.NoneSelected));
}
- private void beatmapEdit(Func beatmapInfo)
- {
- AddStep(@"Update beatmap via BeatmapManager", () =>
- {
- BeatmapInfo info = beatmapInfo();
- IBeatmap beatmap = beatmapManager.GetWorkingBeatmap(info).Beatmap;
-
- beatmap.Difficulty.ApproachRate = 11;
- beatmap.Difficulty.DrainRate = 11;
- beatmap.Difficulty.OverallDifficulty = 11;
-
- beatmapManager.Save(info, beatmap);
- });
- }
-
private void showPersonalBestWithNullPosition()
{
leaderboard.SetScores(leaderboard.Scores, new ScoreInfo
@@ -208,9 +203,9 @@ namespace osu.Game.Tests.Visual.SongSelect
});
}
- private void loadMoreScores(Func beatmapInfo)
+ private void importMoreScores(Func beatmapInfo)
{
- AddStep(@"Load new scores via manager", () =>
+ AddStep(@"Import new scores", () =>
{
foreach (var score in generateSampleScores(beatmapInfo()))
scoreManager.Import(score);
@@ -223,7 +218,7 @@ namespace osu.Game.Tests.Visual.SongSelect
}
private void checkCount(int expected) =>
- AddUntilStep("Correct count displayed", () => leaderboard.ChildrenOfType().Count() == expected);
+ AddUntilStep($"{expected} scores displayed", () => leaderboard.ChildrenOfType().Count(), () => Is.EqualTo(expected));
private static ScoreInfo[] generateSampleScores(BeatmapInfo beatmapInfo)
{
From d4d985ba0f0378d3c93a71b17e5cfcb793a7b41b Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 8 Feb 2023 15:34:46 +0900
Subject: [PATCH 023/317] Improve test to also check that reverting hash
restores old scores
---
.../SongSelect/TestSceneBeatmapLeaderboard.cs | 31 ++++++++++++++-----
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 83bb58804d..01397563fd 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -100,10 +100,11 @@ namespace osu.Game.Tests.Visual.SongSelect
public void TestLocalScoresDisplayOnBeatmapEdit()
{
BeatmapInfo beatmapInfo = null!;
+ string originalHash = string.Empty;
AddStep(@"Set scope", () => leaderboard.Scope = BeatmapLeaderboardScope.Local);
- AddStep(@"Set beatmap", () =>
+ AddStep(@"Import beatmap", () =>
{
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
@@ -114,23 +115,39 @@ namespace osu.Game.Tests.Visual.SongSelect
clearScores();
checkCount(0);
+ AddStep(@"Perform initial save to guarantee stable hash", () =>
+ {
+ IBeatmap beatmap = beatmapManager.GetWorkingBeatmap(beatmapInfo).Beatmap;
+ beatmapManager.Save(beatmapInfo, beatmap);
+
+ originalHash = beatmapInfo.Hash;
+ });
+
importMoreScores(() => beatmapInfo);
checkCount(10);
- AddStep(@"Save beatmap with changes", () =>
+ AddStep(@"Save with changes", () =>
{
IBeatmap beatmap = beatmapManager.GetWorkingBeatmap(beatmapInfo).Beatmap;
-
- beatmap.Difficulty.ApproachRate = 11;
- beatmap.Difficulty.DrainRate = 11;
- beatmap.Difficulty.OverallDifficulty = 11;
-
+ beatmap.Difficulty.ApproachRate = 12;
beatmapManager.Save(beatmapInfo, beatmap);
});
+ AddAssert("Hash changed", () => beatmapInfo.Hash, () => Is.Not.EqualTo(originalHash));
checkCount(0);
importMoreScores(() => beatmapInfo);
+ importMoreScores(() => beatmapInfo);
+ checkCount(20);
+
+ AddStep(@"Revert changes", () =>
+ {
+ IBeatmap beatmap = beatmapManager.GetWorkingBeatmap(beatmapInfo).Beatmap;
+ beatmap.Difficulty.ApproachRate = 8;
+ beatmapManager.Save(beatmapInfo, beatmap);
+ });
+
+ AddAssert("Hash restored", () => beatmapInfo.Hash, () => Is.EqualTo(originalHash));
checkCount(10);
clearScores();
From 38031fdf2327cb50705cd14fa55c4cb1cb058a9d Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 8 Feb 2023 15:38:07 +0900
Subject: [PATCH 024/317] Add test coverage of stores stored in database as
well
---
.../SongSelect/TestSceneBeatmapLeaderboard.cs | 31 ++++++++++++-------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 01397563fd..c234cc8a9c 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -84,16 +84,16 @@ namespace osu.Game.Tests.Visual.SongSelect
});
clearScores();
- checkCount(0);
+ checkDisplayedCount(0);
importMoreScores(() => beatmapInfo);
- checkCount(10);
+ checkDisplayedCount(10);
importMoreScores(() => beatmapInfo);
- checkCount(20);
+ checkDisplayedCount(20);
clearScores();
- checkCount(0);
+ checkDisplayedCount(0);
}
[Test]
@@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual.SongSelect
});
clearScores();
- checkCount(0);
+ checkDisplayedCount(0);
AddStep(@"Perform initial save to guarantee stable hash", () =>
{
@@ -124,7 +124,9 @@ namespace osu.Game.Tests.Visual.SongSelect
});
importMoreScores(() => beatmapInfo);
- checkCount(10);
+
+ checkDisplayedCount(10);
+ checkStoredCount(10);
AddStep(@"Save with changes", () =>
{
@@ -134,11 +136,13 @@ namespace osu.Game.Tests.Visual.SongSelect
});
AddAssert("Hash changed", () => beatmapInfo.Hash, () => Is.Not.EqualTo(originalHash));
- checkCount(0);
+ checkDisplayedCount(0);
+ checkStoredCount(10);
importMoreScores(() => beatmapInfo);
importMoreScores(() => beatmapInfo);
- checkCount(20);
+ checkDisplayedCount(20);
+ checkStoredCount(30);
AddStep(@"Revert changes", () =>
{
@@ -148,10 +152,12 @@ namespace osu.Game.Tests.Visual.SongSelect
});
AddAssert("Hash restored", () => beatmapInfo.Hash, () => Is.EqualTo(originalHash));
- checkCount(10);
+ checkDisplayedCount(10);
+ checkStoredCount(30);
clearScores();
- checkCount(0);
+ checkDisplayedCount(0);
+ checkStoredCount(0);
}
[Test]
@@ -234,9 +240,12 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("Clear all scores", () => scoreManager.Delete());
}
- private void checkCount(int expected) =>
+ private void checkDisplayedCount(int expected) =>
AddUntilStep($"{expected} scores displayed", () => leaderboard.ChildrenOfType().Count(), () => Is.EqualTo(expected));
+ private void checkStoredCount(int expected) =>
+ AddUntilStep($"Total scores stored is {expected}", () => Realm.Run(r => r.All().Count(s => !s.DeletePending)), () => Is.EqualTo(expected));
+
private static ScoreInfo[] generateSampleScores(BeatmapInfo beatmapInfo)
{
return new[]
From 4fdba880b1efc2dcb49a2f3c64585f2e896a64ba Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 8 Feb 2023 15:39:18 +0900
Subject: [PATCH 025/317] Fix xmldoc reference fail at CI
---
osu.Game/Scoring/ScoreInfo.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 6213c65c75..02c7acf350 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -41,7 +41,7 @@ namespace osu.Game.Scoring
public BeatmapInfo BeatmapInfo { get; set; } = null!;
///
- /// The at the point in time when the score was set.
+ /// The at the point in time when the score was set.
///
public string BeatmapHash { get; set; } = string.Empty;
From 74a58fb674945a5ec82f20ca2bffff91b6de776c Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 01:24:27 +0000
Subject: [PATCH 026/317] refactor: separate things in KeyCounter
To implement different different sources of input for KeyCounter, it
is now possible to create a Trigger class (to inherit) instead of
inheriting KeyCounter. This eases the creation of more input sources
(like for tests) while allowing to implement different UI variants.
That way, if another variant of the key counter needs to implemented
(for whathever reason), this can be done by only inheriting KeyCounter
and changing how things are arranged visually.
---
osu.Game/Rulesets/UI/RulesetInputManager.cs | 9 +-
osu.Game/Screens/Play/DefaultKeyCounter.cs | 105 +++++++++++++
osu.Game/Screens/Play/KeyCounter.cs | 157 +++++++-------------
osu.Game/Screens/Play/KeyCounterAction.cs | 10 +-
osu.Game/Screens/Play/KeyCounterKeyboard.cs | 11 +-
osu.Game/Screens/Play/KeyCounterMouse.cs | 11 +-
6 files changed, 177 insertions(+), 126 deletions(-)
create mode 100644 osu.Game/Screens/Play/DefaultKeyCounter.cs
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index a5e442b7de..0fa1f0b332 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -166,7 +166,7 @@ namespace osu.Game.Rulesets.UI
.Select(b => b.GetAction())
.Distinct()
.OrderBy(action => action)
- .Select(action => new KeyCounterAction(action)));
+ .Select(action => keyCounter.CreateKeyCounter(new KeyCounterAction(action))));
}
private partial class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler
@@ -176,11 +176,14 @@ namespace osu.Game.Rulesets.UI
{
}
- public bool OnPressed(KeyBindingPressEvent e) => Target.Children.OfType>().Any(c => c.OnPressed(e.Action, Clock.Rate >= 0));
+ public bool OnPressed(KeyBindingPressEvent e) => Target.Children.Where(c => c.CounterTrigger is KeyCounterAction)
+ .Select(c => (KeyCounterAction)c.CounterTrigger)
+ .Any(c => c.OnPressed(e.Action, Clock.Rate >= 0));
public void OnReleased(KeyBindingReleaseEvent e)
{
- foreach (var c in Target.Children.OfType>())
+ foreach (var c
+ in Target.Children.Where(c => c.CounterTrigger is KeyCounterAction).Select(c => (KeyCounterAction)c.CounterTrigger))
c.OnReleased(e.Action, Clock.Rate >= 0);
}
}
diff --git a/osu.Game/Screens/Play/DefaultKeyCounter.cs b/osu.Game/Screens/Play/DefaultKeyCounter.cs
new file mode 100644
index 0000000000..dcb425ae1d
--- /dev/null
+++ b/osu.Game/Screens/Play/DefaultKeyCounter.cs
@@ -0,0 +1,105 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.Textures;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+using osuTK.Graphics;
+
+namespace osu.Game.Screens.Play
+{
+ public partial class DefaultKeyCounter : KeyCounter
+ {
+ private Sprite buttonSprite = null!;
+ private Sprite glowSprite = null!;
+ private Container textLayer = null!;
+ private SpriteText countSpriteText = null!;
+
+ //further: change default values here and in KeyCounterCollection if needed, instead of passing them in every constructor
+ public Color4 KeyDownTextColor { get; set; } = Color4.DarkGray;
+ public Color4 KeyUpTextColor { get; set; } = Color4.White;
+ public double FadeTime { get; set; }
+
+ public DefaultKeyCounter(Trigger trigger)
+ : base(trigger)
+ {
+ }
+
+ [BackgroundDependencyLoader(true)]
+ private void load(TextureStore textures)
+ {
+ Children = new Drawable[]
+ {
+ buttonSprite = new Sprite
+ {
+ Texture = textures.Get(@"KeyCounter/key-up"),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ },
+ glowSprite = new Sprite
+ {
+ Texture = textures.Get(@"KeyCounter/key-glow"),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Alpha = 0
+ },
+ textLayer = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Text = Name,
+ Font = OsuFont.Numeric.With(size: 12),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativePositionAxes = Axes.Both,
+ Position = new Vector2(0, -0.25f),
+ Colour = KeyUpTextColor
+ },
+ countSpriteText = new OsuSpriteText
+ {
+ Text = CountPresses.ToString(@"#,0"),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativePositionAxes = Axes.Both,
+ Position = new Vector2(0, 0.25f),
+ Colour = KeyUpTextColor
+ }
+ }
+ }
+ };
+ // Set this manually because an element with Alpha=0 won't take it size to AutoSizeContainer,
+ // so the size can be changing between buttonSprite and glowSprite.
+ Height = buttonSprite.DrawHeight;
+ Width = buttonSprite.DrawWidth;
+
+ IsLit.BindValueChanged(e => updateGlowSprite(e.NewValue), true);
+ PressesCount.BindValueChanged(e => countSpriteText.Text = e.NewValue.ToString(@"#,0"), true);
+ }
+
+ private void updateGlowSprite(bool show)
+ {
+ if (show)
+ {
+ double remainingFadeTime = FadeTime * (1 - glowSprite.Alpha);
+ glowSprite.FadeIn(remainingFadeTime, Easing.OutQuint);
+ textLayer.FadeColour(KeyDownTextColor, remainingFadeTime, Easing.OutQuint);
+ }
+ else
+ {
+ double remainingFadeTime = 8 * FadeTime * glowSprite.Alpha;
+ glowSprite.FadeOut(remainingFadeTime, Easing.OutQuint);
+ textLayer.FadeColour(KeyUpTextColor, remainingFadeTime, Easing.OutQuint);
+ }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 4405542b3b..a612edbace 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -1,57 +1,37 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
-using osu.Game.Graphics;
-using osu.Game.Graphics.Sprites;
-using osuTK;
-using osuTK.Graphics;
+using osu.Framework.Input.Events;
namespace osu.Game.Screens.Play
{
public abstract partial class KeyCounter : Container
{
- private Sprite buttonSprite;
- private Sprite glowSprite;
- private Container textLayer;
- private SpriteText countSpriteText;
+ public readonly Trigger CounterTrigger;
- public bool IsCounting { get; set; } = true;
- private int countPresses;
+ protected Bindable IsCountingBindable = new BindableBool(true);
+
+ protected Bindable PressesCount = new BindableInt
+ {
+ MinValue = 0
+ };
+
+ public bool IsCounting
+ {
+ get => IsCountingBindable.Value;
+ set => IsCountingBindable.Value = value;
+ }
public int CountPresses
{
- get => countPresses;
- private set
- {
- if (countPresses != value)
- {
- countPresses = value;
- countSpriteText.Text = value.ToString(@"#,0");
- }
- }
+ get => PressesCount.Value;
+ private set => PressesCount.Value = value;
}
- private bool isLit;
-
- public bool IsLit
- {
- get => isLit;
- protected set
- {
- if (isLit != value)
- {
- isLit = value;
- updateGlowSprite(value);
- }
- }
- }
+ protected Bindable IsLit = new BindableBool();
public void Increment()
{
@@ -69,82 +49,51 @@ namespace osu.Game.Screens.Play
CountPresses--;
}
- //further: change default values here and in KeyCounterCollection if needed, instead of passing them in every constructor
- public Color4 KeyDownTextColor { get; set; } = Color4.DarkGray;
- public Color4 KeyUpTextColor { get; set; } = Color4.White;
- public double FadeTime { get; set; }
-
- protected KeyCounter(string name)
+ protected override void LoadComplete()
{
- Name = name;
+ Add(CounterTrigger);
+ base.LoadComplete();
}
- [BackgroundDependencyLoader(true)]
- private void load(TextureStore textures)
+ protected override bool Handle(UIEvent e) => CounterTrigger.TriggerEvent(e);
+
+ protected KeyCounter(Trigger trigger)
{
- Children = new Drawable[]
- {
- buttonSprite = new Sprite
- {
- Texture = textures.Get(@"KeyCounter/key-up"),
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- },
- glowSprite = new Sprite
- {
- Texture = textures.Get(@"KeyCounter/key-glow"),
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Alpha = 0
- },
- textLayer = new Container
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- new OsuSpriteText
- {
- Text = Name,
- Font = OsuFont.Numeric.With(size: 12),
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativePositionAxes = Axes.Both,
- Position = new Vector2(0, -0.25f),
- Colour = KeyUpTextColor
- },
- countSpriteText = new OsuSpriteText
- {
- Text = CountPresses.ToString(@"#,0"),
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativePositionAxes = Axes.Both,
- Position = new Vector2(0, 0.25f),
- Colour = KeyUpTextColor
- }
- }
- }
- };
- // Set this manually because an element with Alpha=0 won't take it size to AutoSizeContainer,
- // so the size can be changing between buttonSprite and glowSprite.
- Height = buttonSprite.DrawHeight;
- Width = buttonSprite.DrawWidth;
+ CounterTrigger = trigger;
+ trigger.Target = this;
+ Name = trigger.Name;
}
- private void updateGlowSprite(bool show)
+ public abstract partial class Trigger : Component
{
- if (show)
+ private KeyCounter? target;
+
+ public KeyCounter Target
{
- double remainingFadeTime = FadeTime * (1 - glowSprite.Alpha);
- glowSprite.FadeIn(remainingFadeTime, Easing.OutQuint);
- textLayer.FadeColour(KeyDownTextColor, remainingFadeTime, Easing.OutQuint);
+ set => target = value;
}
- else
+
+ protected Trigger(string name)
{
- double remainingFadeTime = 8 * FadeTime * glowSprite.Alpha;
- glowSprite.FadeOut(remainingFadeTime, Easing.OutQuint);
- textLayer.FadeColour(KeyUpTextColor, remainingFadeTime, Easing.OutQuint);
+ Name = name;
+ }
+
+ protected void Lit(bool increment = true)
+ {
+ if (target == null) return;
+
+ target.IsLit.Value = true;
+ if (increment)
+ target.Increment();
+ }
+
+ protected void Unlit(bool preserve = true)
+ {
+ if (target == null) return;
+
+ target.IsLit.Value = false;
+ if (!preserve)
+ target.Decrement();
}
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterAction.cs
index 900d9bcd0e..058dbb1480 100644
--- a/osu.Game/Screens/Play/KeyCounterAction.cs
+++ b/osu.Game/Screens/Play/KeyCounterAction.cs
@@ -7,7 +7,7 @@ using System.Collections.Generic;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterAction : KeyCounter
+ public partial class KeyCounterAction : KeyCounter.Trigger
where T : struct
{
public T Action { get; }
@@ -23,9 +23,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return false;
- IsLit = true;
- if (forwards)
- Increment();
+ Lit(forwards);
return false;
}
@@ -34,9 +32,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return;
- IsLit = false;
- if (!forwards)
- Decrement();
+ Unlit(forwards);
}
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboard.cs
index c5c8b7eeae..4306efd360 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboard.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboard.cs
@@ -8,7 +8,7 @@ using osuTK.Input;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterKeyboard : KeyCounter
+ public partial class KeyCounterKeyboard : KeyCounter.Trigger
{
public Key Key { get; }
@@ -21,17 +21,16 @@ namespace osu.Game.Screens.Play
protected override bool OnKeyDown(KeyDownEvent e)
{
if (e.Key == Key)
- {
- IsLit = true;
- Increment();
- }
+ Lit();
return base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyUpEvent e)
{
- if (e.Key == Key) IsLit = false;
+ if (e.Key == Key)
+ Unlit();
+
base.OnKeyUp(e);
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouse.cs
index cf9c7c029f..00fca47ba2 100644
--- a/osu.Game/Screens/Play/KeyCounterMouse.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouse.cs
@@ -9,7 +9,7 @@ using osuTK;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterMouse : KeyCounter
+ public partial class KeyCounterMouse : KeyCounter.Trigger
{
public MouseButton Button { get; }
@@ -39,17 +39,16 @@ namespace osu.Game.Screens.Play
protected override bool OnMouseDown(MouseDownEvent e)
{
if (e.Button == Button)
- {
- IsLit = true;
- Increment();
- }
+ Lit();
return base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseUpEvent e)
{
- if (e.Button == Button) IsLit = false;
+ if (e.Button == Button)
+ Unlit();
+
base.OnMouseUp(e);
}
}
From 11d0e185b8188d0986f4520131a14ba95ab2322f Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 01:33:09 +0000
Subject: [PATCH 027/317] refactor: separate impl of KeyCounterDisplay
This allows for different layouts of display. Idk, maybe someone would
want to mix both variants? (don't do this please). This commit is mostly
prep for further changes.
---
.../TestSceneOsuTouchInput.cs | 16 ++--
.../Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +-
.../Visual/Gameplay/TestSceneKeyCounter.cs | 18 ++--
.../TestSceneSkinEditorMultipleSkins.cs | 2 +-
.../Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +-
.../Screens/Play/DefaultKeyCounterDisplay.cs | 91 +++++++++++++++++++
osu.Game/Screens/Play/HUDOverlay.cs | 2 +-
osu.Game/Screens/Play/KeyCounterDisplay.cs | 76 ++--------------
8 files changed, 121 insertions(+), 88 deletions(-)
create mode 100644 osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 72bcec6045..cd30d8df83 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -34,9 +34,9 @@ namespace osu.Game.Rulesets.Osu.Tests
[Resolved]
private OsuConfigManager config { get; set; } = null!;
- private TestActionKeyCounter leftKeyCounter = null!;
+ private DefaultKeyCounter leftKeyCounter = null!;
- private TestActionKeyCounter rightKeyCounter = null!;
+ private DefaultKeyCounter rightKeyCounter = null!;
private OsuInputManager osuInputManager = null!;
@@ -59,14 +59,14 @@ namespace osu.Game.Rulesets.Osu.Tests
Origin = Anchor.Centre,
Children = new Drawable[]
{
- leftKeyCounter = new TestActionKeyCounter(OsuAction.LeftButton)
+ leftKeyCounter = new DefaultKeyCounter(new TestActionKeyCounter(OsuAction.LeftButton))
{
Anchor = Anchor.Centre,
Origin = Anchor.CentreRight,
Depth = float.MinValue,
X = -100,
},
- rightKeyCounter = new TestActionKeyCounter(OsuAction.RightButton)
+ rightKeyCounter = new DefaultKeyCounter(new TestActionKeyCounter(OsuAction.RightButton))
{
Anchor = Anchor.Centre,
Origin = Anchor.CentreLeft,
@@ -579,7 +579,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private void checkNotPressed(OsuAction action) => AddAssert($"Not pressing {action}", () => !osuInputManager.PressedActions.Contains(action));
private void checkPressed(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action));
- public partial class TestActionKeyCounter : KeyCounter, IKeyBindingHandler
+ public partial class TestActionKeyCounter : KeyCounter.Trigger, IKeyBindingHandler
{
public OsuAction Action { get; }
@@ -593,8 +593,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
if (e.Action == Action)
{
- IsLit = true;
- Increment();
+ Lit();
}
return false;
@@ -602,7 +601,8 @@ namespace osu.Game.Rulesets.Osu.Tests
public void OnReleased(KeyBindingReleaseEvent e)
{
- if (e.Action == Action) IsLit = false;
+ if (e.Action == Action)
+ Unlit();
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
index 5e1412d79b..4055ef9d3a 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
@@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.Gameplay
hudOverlay = new HUDOverlay(null, Array.Empty());
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
+ hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboard(Key.Space)));
scoreProcessor.Combo.Value = 1;
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 890ac21b40..60ebce4f52 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -17,28 +17,28 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public TestSceneKeyCounter()
{
- KeyCounterKeyboard testCounter;
+ DefaultKeyCounter testCounter;
- KeyCounterDisplay kc = new KeyCounterDisplay
+ KeyCounterDisplay kc = new DefaultKeyCounterDisplay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
- Children = new KeyCounter[]
+ Children = new[]
{
- testCounter = new KeyCounterKeyboard(Key.X),
- new KeyCounterKeyboard(Key.X),
- new KeyCounterMouse(MouseButton.Left),
- new KeyCounterMouse(MouseButton.Right),
+ testCounter = new DefaultKeyCounter(new KeyCounterKeyboard(Key.X)),
+ new DefaultKeyCounter(new KeyCounterKeyboard(Key.X)),
+ new DefaultKeyCounter(new KeyCounterMouse(MouseButton.Left)),
+ new DefaultKeyCounter(new KeyCounterMouse(MouseButton.Right)),
},
};
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
- kc.Add(new KeyCounterKeyboard(key));
+ kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboard(key)));
});
- Key testKey = ((KeyCounterKeyboard)kc.Children.First()).Key;
+ Key testKey = ((KeyCounterKeyboard)kc.Children.First().CounterTrigger).Key;
void addPressKeyStep()
{
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
index d5b6ac38cb..56cf56efd9 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay
};
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
+ hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboard(Key.Space)));
scoreProcessor.Combo.Value = 1;
return new Container
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
index 1f2329af4a..f713bca081 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
@@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay
hudOverlay = new HUDOverlay(null, Array.Empty());
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
+ hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboard(Key.Space)));
action?.Invoke(hudOverlay);
diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
new file mode 100644
index 0000000000..d643070e06
--- /dev/null
+++ b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
@@ -0,0 +1,91 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osuTK.Graphics;
+
+namespace osu.Game.Screens.Play
+{
+ public partial class DefaultKeyCounterDisplay : KeyCounterDisplay
+ {
+ private const int duration = 100;
+ private const double key_fade_time = 80;
+
+ protected override Container Content => KeyFlow;
+
+ public new IReadOnlyList Children
+ {
+ get => (IReadOnlyList)base.Children;
+ set => base.Children = value;
+ }
+
+ public DefaultKeyCounterDisplay()
+ {
+ InternalChild = KeyFlow = new FillFlowContainer
+ {
+ Direction = FillDirection.Horizontal,
+ AutoSizeAxes = Axes.Both,
+ Alpha = 0,
+ };
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ // Don't use autosize as it will shrink to zero when KeyFlow is hidden.
+ // In turn this can cause the display to be masked off screen and never become visible again.
+ Size = KeyFlow.Size;
+ }
+
+ public override void Add(KeyCounter key)
+ {
+ base.Add(key);
+ if (key is not DefaultKeyCounter defaultKey)
+ throw new ArgumentException($"{key.GetType()} is not a supported {nameof(KeyCounter)}.", nameof(key));
+
+ defaultKey.FadeTime = key_fade_time;
+ defaultKey.KeyDownTextColor = KeyDownTextColor;
+ defaultKey.KeyUpTextColor = KeyUpTextColor;
+ }
+
+ protected override void UpdateVisibility() =>
+ // Isolate changing visibility of the key counters from fading this component.
+ KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
+
+ private Color4 keyDownTextColor = Color4.DarkGray;
+
+ public Color4 KeyDownTextColor
+ {
+ get => keyDownTextColor;
+ set
+ {
+ if (value != keyDownTextColor)
+ {
+ keyDownTextColor = value;
+ foreach (var child in Children)
+ child.KeyDownTextColor = value;
+ }
+ }
+ }
+
+ private Color4 keyUpTextColor = Color4.White;
+
+ public Color4 KeyUpTextColor
+ {
+ get => keyUpTextColor;
+ set
+ {
+ if (value != keyUpTextColor)
+ {
+ keyUpTextColor = value;
+ foreach (var child in Children)
+ child.KeyUpTextColor = value;
+ }
+ }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs
index 4d1f0b96b6..a09da14132 100644
--- a/osu.Game/Screens/Play/HUDOverlay.cs
+++ b/osu.Game/Screens/Play/HUDOverlay.cs
@@ -327,7 +327,7 @@ namespace osu.Game.Screens.Play
ShowHealth = { BindTarget = ShowHealthBar }
};
- protected KeyCounterDisplay CreateKeyCounter() => new KeyCounterDisplay
+ protected KeyCounterDisplay CreateKeyCounter() => new DefaultKeyCounterDisplay
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index bb50d4a539..b06d1adfa0 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -12,18 +12,14 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osuTK;
-using osuTK.Graphics;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterDisplay : Container
+ public abstract partial class KeyCounterDisplay : Container
{
- private const int duration = 100;
- private const double key_fade_time = 80;
+ protected readonly Bindable ConfigVisibility = new Bindable();
- private readonly Bindable configVisibility = new Bindable();
-
- protected readonly FillFlowContainer KeyFlow;
+ protected FillFlowContainer KeyFlow;
protected override Container Content => KeyFlow;
@@ -33,48 +29,26 @@ namespace osu.Game.Screens.Play
///
public readonly Bindable AlwaysVisible = new Bindable(true);
- public KeyCounterDisplay()
- {
- InternalChild = KeyFlow = new FillFlowContainer
- {
- Direction = FillDirection.Horizontal,
- AutoSizeAxes = Axes.Both,
- Alpha = 0,
- };
- }
-
- protected override void Update()
- {
- base.Update();
-
- // Don't use autosize as it will shrink to zero when KeyFlow is hidden.
- // In turn this can cause the display to be masked off screen and never become visible again.
- Size = KeyFlow.Size;
- }
-
public override void Add(KeyCounter key)
{
ArgumentNullException.ThrowIfNull(key);
base.Add(key);
key.IsCounting = IsCounting;
- key.FadeTime = key_fade_time;
- key.KeyDownTextColor = KeyDownTextColor;
- key.KeyUpTextColor = KeyUpTextColor;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
- config.BindWith(OsuSetting.KeyOverlay, configVisibility);
+ config.BindWith(OsuSetting.KeyOverlay, ConfigVisibility);
}
protected override void LoadComplete()
{
base.LoadComplete();
- AlwaysVisible.BindValueChanged(_ => updateVisibility());
- configVisibility.BindValueChanged(_ => updateVisibility(), true);
+ AlwaysVisible.BindValueChanged(_ => UpdateVisibility());
+ ConfigVisibility.BindValueChanged(_ => UpdateVisibility(), true);
}
private bool isCounting = true;
@@ -92,41 +66,7 @@ namespace osu.Game.Screens.Play
}
}
- private Color4 keyDownTextColor = Color4.DarkGray;
-
- public Color4 KeyDownTextColor
- {
- get => keyDownTextColor;
- set
- {
- if (value != keyDownTextColor)
- {
- keyDownTextColor = value;
- foreach (var child in Children)
- child.KeyDownTextColor = value;
- }
- }
- }
-
- private Color4 keyUpTextColor = Color4.White;
-
- public Color4 KeyUpTextColor
- {
- get => keyUpTextColor;
- set
- {
- if (value != keyUpTextColor)
- {
- keyUpTextColor = value;
- foreach (var child in Children)
- child.KeyUpTextColor = value;
- }
- }
- }
-
- private void updateVisibility() =>
- // Isolate changing visibility of the key counters from fading this component.
- KeyFlow.FadeTo(AlwaysVisible.Value || configVisibility.Value ? 1 : 0, duration);
+ protected abstract void UpdateVisibility();
public override bool HandleNonPositionalInput => receptor == null;
public override bool HandlePositionalInput => receptor == null;
@@ -141,6 +81,8 @@ namespace osu.Game.Screens.Play
this.receptor = receptor;
}
+ public virtual KeyCounter CreateKeyCounter(KeyCounter.Trigger trigger) => new DefaultKeyCounter(trigger);
+
public partial class Receptor : Drawable
{
protected readonly KeyCounterDisplay Target;
From aa2e0028ab3c20cb4e0afe412e12670e3b14f96f Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 10:59:10 +0000
Subject: [PATCH 028/317] refactor: hide trigger presence from content
---
osu.Game/Screens/Play/KeyCounter.cs | 32 +++++++++++++++++------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index a612edbace..b111305b22 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -14,6 +14,10 @@ namespace osu.Game.Screens.Play
protected Bindable IsCountingBindable = new BindableBool(true);
+ private readonly Container content;
+
+ protected override Container Content => content;
+
protected Bindable PressesCount = new BindableInt
{
MinValue = 0
@@ -31,6 +35,21 @@ namespace osu.Game.Screens.Play
private set => PressesCount.Value = value;
}
+ protected KeyCounter(Trigger trigger)
+ {
+ InternalChildren = new Drawable[]
+ {
+ content = new Container
+ {
+ RelativeSizeAxes = Axes.Both
+ },
+ CounterTrigger = trigger,
+ };
+
+ CounterTrigger.Target = this;
+ Name = trigger.Name;
+ }
+
protected Bindable IsLit = new BindableBool();
public void Increment()
@@ -49,21 +68,8 @@ namespace osu.Game.Screens.Play
CountPresses--;
}
- protected override void LoadComplete()
- {
- Add(CounterTrigger);
- base.LoadComplete();
- }
-
protected override bool Handle(UIEvent e) => CounterTrigger.TriggerEvent(e);
- protected KeyCounter(Trigger trigger)
- {
- CounterTrigger = trigger;
- trigger.Target = this;
- Name = trigger.Name;
- }
-
public abstract partial class Trigger : Component
{
private KeyCounter? target;
From 157bba78305b3474fecc5a529b95c954b994e9e9 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 21:59:17 +0000
Subject: [PATCH 029/317] refactor: rename `Trigger` class to `InputTrigger`
---
.../TestSceneOsuTouchInput.cs | 2 +-
.../Visual/Gameplay/TestSceneKeyCounter.cs | 2 +-
osu.Game/Rulesets/UI/RulesetInputManager.cs | 6 +++---
osu.Game/Screens/Play/DefaultKeyCounter.cs | 2 +-
osu.Game/Screens/Play/KeyCounter.cs | 14 +++++++-------
osu.Game/Screens/Play/KeyCounterAction.cs | 2 +-
osu.Game/Screens/Play/KeyCounterDisplay.cs | 2 +-
osu.Game/Screens/Play/KeyCounterKeyboard.cs | 2 +-
osu.Game/Screens/Play/KeyCounterMouse.cs | 2 +-
9 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index cd30d8df83..1a273153bd 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -579,7 +579,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private void checkNotPressed(OsuAction action) => AddAssert($"Not pressing {action}", () => !osuInputManager.PressedActions.Contains(action));
private void checkPressed(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action));
- public partial class TestActionKeyCounter : KeyCounter.Trigger, IKeyBindingHandler
+ public partial class TestActionKeyCounter : KeyCounter.InputTrigger, IKeyBindingHandler
{
public OsuAction Action { get; }
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 60ebce4f52..f652a62489 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Gameplay
kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboard(key)));
});
- Key testKey = ((KeyCounterKeyboard)kc.Children.First().CounterTrigger).Key;
+ Key testKey = ((KeyCounterKeyboard)kc.Children.First().Trigger).Key;
void addPressKeyStep()
{
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index 0fa1f0b332..22dc6567eb 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -176,14 +176,14 @@ namespace osu.Game.Rulesets.UI
{
}
- public bool OnPressed(KeyBindingPressEvent e) => Target.Children.Where(c => c.CounterTrigger is KeyCounterAction)
- .Select(c => (KeyCounterAction)c.CounterTrigger)
+ public bool OnPressed(KeyBindingPressEvent e) => Target.Children.Where(c => c.Trigger is KeyCounterAction)
+ .Select(c => (KeyCounterAction)c.Trigger)
.Any(c => c.OnPressed(e.Action, Clock.Rate >= 0));
public void OnReleased(KeyBindingReleaseEvent e)
{
foreach (var c
- in Target.Children.Where(c => c.CounterTrigger is KeyCounterAction).Select(c => (KeyCounterAction)c.CounterTrigger))
+ in Target.Children.Where(c => c.Trigger is KeyCounterAction).Select(c => (KeyCounterAction)c.Trigger))
c.OnReleased(e.Action, Clock.Rate >= 0);
}
}
diff --git a/osu.Game/Screens/Play/DefaultKeyCounter.cs b/osu.Game/Screens/Play/DefaultKeyCounter.cs
index dcb425ae1d..93dc4abcb5 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounter.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounter.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Screens.Play
public Color4 KeyUpTextColor { get; set; } = Color4.White;
public double FadeTime { get; set; }
- public DefaultKeyCounter(Trigger trigger)
+ public DefaultKeyCounter(InputTrigger trigger)
: base(trigger)
{
}
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index b111305b22..a1950a49f4 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -10,7 +10,7 @@ namespace osu.Game.Screens.Play
{
public abstract partial class KeyCounter : Container
{
- public readonly Trigger CounterTrigger;
+ public readonly InputTrigger Trigger;
protected Bindable IsCountingBindable = new BindableBool(true);
@@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play
private set => PressesCount.Value = value;
}
- protected KeyCounter(Trigger trigger)
+ protected KeyCounter(InputTrigger trigger)
{
InternalChildren = new Drawable[]
{
@@ -43,10 +43,10 @@ namespace osu.Game.Screens.Play
{
RelativeSizeAxes = Axes.Both
},
- CounterTrigger = trigger,
+ Trigger = trigger,
};
- CounterTrigger.Target = this;
+ Trigger.Target = this;
Name = trigger.Name;
}
@@ -68,9 +68,9 @@ namespace osu.Game.Screens.Play
CountPresses--;
}
- protected override bool Handle(UIEvent e) => CounterTrigger.TriggerEvent(e);
+ protected override bool Handle(UIEvent e) => Trigger.TriggerEvent(e);
- public abstract partial class Trigger : Component
+ public abstract partial class InputTrigger : Component
{
private KeyCounter? target;
@@ -79,7 +79,7 @@ namespace osu.Game.Screens.Play
set => target = value;
}
- protected Trigger(string name)
+ protected InputTrigger(string name)
{
Name = name;
}
diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterAction.cs
index 058dbb1480..4926970960 100644
--- a/osu.Game/Screens/Play/KeyCounterAction.cs
+++ b/osu.Game/Screens/Play/KeyCounterAction.cs
@@ -7,7 +7,7 @@ using System.Collections.Generic;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterAction : KeyCounter.Trigger
+ public partial class KeyCounterAction : KeyCounter.InputTrigger
where T : struct
{
public T Action { get; }
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index b06d1adfa0..fc6fa12f10 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -81,7 +81,7 @@ namespace osu.Game.Screens.Play
this.receptor = receptor;
}
- public virtual KeyCounter CreateKeyCounter(KeyCounter.Trigger trigger) => new DefaultKeyCounter(trigger);
+ public virtual KeyCounter CreateKeyCounter(KeyCounter.InputTrigger trigger) => new DefaultKeyCounter(trigger);
public partial class Receptor : Drawable
{
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboard.cs
index 4306efd360..6ae1a2c5bc 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboard.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboard.cs
@@ -8,7 +8,7 @@ using osuTK.Input;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterKeyboard : KeyCounter.Trigger
+ public partial class KeyCounterKeyboard : KeyCounter.InputTrigger
{
public Key Key { get; }
diff --git a/osu.Game/Screens/Play/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouse.cs
index 00fca47ba2..40674cdbcd 100644
--- a/osu.Game/Screens/Play/KeyCounterMouse.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouse.cs
@@ -9,7 +9,7 @@ using osuTK;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterMouse : KeyCounter.Trigger
+ public partial class KeyCounterMouse : KeyCounter.InputTrigger
{
public MouseButton Button { get; }
From df0633858cb9aa0734a95e5f67fc284313571485 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 23:20:23 +0000
Subject: [PATCH 030/317] fix(KeyCounter): don't override Handle
This caused the Keyboard inputs to register twice, which is not what we
want.
---
osu.Game/Screens/Play/KeyCounter.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index a1950a49f4..cd306dfb9b 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -4,7 +4,6 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Input.Events;
namespace osu.Game.Screens.Play
{
@@ -68,8 +67,6 @@ namespace osu.Game.Screens.Play
CountPresses--;
}
- protected override bool Handle(UIEvent e) => Trigger.TriggerEvent(e);
-
public abstract partial class InputTrigger : Component
{
private KeyCounter? target;
From a644fae3649f29eacf612b2bd920fc4ad0a8ec48 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 23:22:50 +0000
Subject: [PATCH 031/317] style(KeyCounter): rename `(Un)lit` methods to
`(Un)light`
---
osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 4 ++--
osu.Game/Screens/Play/KeyCounter.cs | 4 ++--
osu.Game/Screens/Play/KeyCounterAction.cs | 4 ++--
osu.Game/Screens/Play/KeyCounterKeyboard.cs | 6 ++++--
osu.Game/Screens/Play/KeyCounterMouse.cs | 4 ++--
5 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 1a273153bd..6068cf50b6 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -593,7 +593,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
if (e.Action == Action)
{
- Lit();
+ Light();
}
return false;
@@ -602,7 +602,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public void OnReleased(KeyBindingReleaseEvent e)
{
if (e.Action == Action)
- Unlit();
+ Unlight();
}
}
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index cd306dfb9b..4a7203870c 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -81,7 +81,7 @@ namespace osu.Game.Screens.Play
Name = name;
}
- protected void Lit(bool increment = true)
+ protected void Light(bool increment = true)
{
if (target == null) return;
@@ -90,7 +90,7 @@ namespace osu.Game.Screens.Play
target.Increment();
}
- protected void Unlit(bool preserve = true)
+ protected void Unlight(bool preserve = true)
{
if (target == null) return;
diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterAction.cs
index 4926970960..65a0bc2ca7 100644
--- a/osu.Game/Screens/Play/KeyCounterAction.cs
+++ b/osu.Game/Screens/Play/KeyCounterAction.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return false;
- Lit(forwards);
+ Light(forwards);
return false;
}
@@ -32,7 +32,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return;
- Unlit(forwards);
+ Unlight(forwards);
}
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboard.cs
index 6ae1a2c5bc..ef1f207556 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboard.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboard.cs
@@ -21,7 +21,9 @@ namespace osu.Game.Screens.Play
protected override bool OnKeyDown(KeyDownEvent e)
{
if (e.Key == Key)
- Lit();
+ {
+ Light();
+ }
return base.OnKeyDown(e);
}
@@ -29,7 +31,7 @@ namespace osu.Game.Screens.Play
protected override void OnKeyUp(KeyUpEvent e)
{
if (e.Key == Key)
- Unlit();
+ Unlight();
base.OnKeyUp(e);
}
diff --git a/osu.Game/Screens/Play/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouse.cs
index 40674cdbcd..cf0e0a394f 100644
--- a/osu.Game/Screens/Play/KeyCounterMouse.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouse.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Screens.Play
protected override bool OnMouseDown(MouseDownEvent e)
{
if (e.Button == Button)
- Lit();
+ Light();
return base.OnMouseDown(e);
}
@@ -47,7 +47,7 @@ namespace osu.Game.Screens.Play
protected override void OnMouseUp(MouseUpEvent e)
{
if (e.Button == Button)
- Unlit();
+ Unlight();
base.OnMouseUp(e);
}
From 076eb81b212caaa61546ad3d3d0605b5e072eb46 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Mon, 13 Feb 2023 23:49:57 +0000
Subject: [PATCH 032/317] refactor: rename trigger classes
Makes it better to understand their purpose
---
.../TestSceneOsuTouchInput.cs | 8 ++++----
.../Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +-
.../Visual/Gameplay/TestSceneKeyCounter.cs | 12 ++++++------
.../Gameplay/TestSceneSkinEditorMultipleSkins.cs | 2 +-
.../Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +-
osu.Game/Rulesets/UI/RulesetInputManager.cs | 8 ++++----
...eyCounterAction.cs => KeyCounterActionTrigger.cs} | 4 ++--
...unterKeyboard.cs => KeyCounterKeyboardTrigger.cs} | 4 ++--
...{KeyCounterMouse.cs => KeyCounterMouseTrigger.cs} | 4 ++--
9 files changed, 23 insertions(+), 23 deletions(-)
rename osu.Game/Screens/Play/{KeyCounterAction.cs => KeyCounterActionTrigger.cs} (86%)
rename osu.Game/Screens/Play/{KeyCounterKeyboard.cs => KeyCounterKeyboardTrigger.cs} (85%)
rename osu.Game/Screens/Play/{KeyCounterMouse.cs => KeyCounterMouseTrigger.cs} (90%)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 6068cf50b6..950e034d8f 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -59,14 +59,14 @@ namespace osu.Game.Rulesets.Osu.Tests
Origin = Anchor.Centre,
Children = new Drawable[]
{
- leftKeyCounter = new DefaultKeyCounter(new TestActionKeyCounter(OsuAction.LeftButton))
+ leftKeyCounter = new DefaultKeyCounter(new TestActionKeyCounterTrigger(OsuAction.LeftButton))
{
Anchor = Anchor.Centre,
Origin = Anchor.CentreRight,
Depth = float.MinValue,
X = -100,
},
- rightKeyCounter = new DefaultKeyCounter(new TestActionKeyCounter(OsuAction.RightButton))
+ rightKeyCounter = new DefaultKeyCounter(new TestActionKeyCounterTrigger(OsuAction.RightButton))
{
Anchor = Anchor.Centre,
Origin = Anchor.CentreLeft,
@@ -579,11 +579,11 @@ namespace osu.Game.Rulesets.Osu.Tests
private void checkNotPressed(OsuAction action) => AddAssert($"Not pressing {action}", () => !osuInputManager.PressedActions.Contains(action));
private void checkPressed(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action));
- public partial class TestActionKeyCounter : KeyCounter.InputTrigger, IKeyBindingHandler
+ public partial class TestActionKeyCounterTrigger : KeyCounter.InputTrigger, IKeyBindingHandler
{
public OsuAction Action { get; }
- public TestActionKeyCounter(OsuAction action)
+ public TestActionKeyCounterTrigger(OsuAction action)
: base(action.ToString())
{
Action = action;
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
index 4055ef9d3a..af79650d29 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
@@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.Gameplay
hudOverlay = new HUDOverlay(null, Array.Empty());
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboard(Key.Space)));
+ hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboardTrigger(Key.Space)));
scoreProcessor.Combo.Value = 1;
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index f652a62489..975a5c9465 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -25,20 +25,20 @@ namespace osu.Game.Tests.Visual.Gameplay
Anchor = Anchor.Centre,
Children = new[]
{
- testCounter = new DefaultKeyCounter(new KeyCounterKeyboard(Key.X)),
- new DefaultKeyCounter(new KeyCounterKeyboard(Key.X)),
- new DefaultKeyCounter(new KeyCounterMouse(MouseButton.Left)),
- new DefaultKeyCounter(new KeyCounterMouse(MouseButton.Right)),
+ testCounter = new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
+ new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
},
};
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
- kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboard(key)));
+ kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboardTrigger(key)));
});
- Key testKey = ((KeyCounterKeyboard)kc.Children.First().Trigger).Key;
+ Key testKey = ((KeyCounterKeyboardTrigger)kc.Children.First().Trigger).Key;
void addPressKeyStep()
{
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
index 56cf56efd9..432ff2fc7e 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay
};
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboard(Key.Space)));
+ hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboardTrigger(Key.Space)));
scoreProcessor.Combo.Value = 1;
return new Container
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
index f713bca081..24de29fa03 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
@@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay
hudOverlay = new HUDOverlay(null, Array.Empty());
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboard(Key.Space)));
+ hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboardTrigger(Key.Space)));
action?.Invoke(hudOverlay);
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index 22dc6567eb..6a38fa4824 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -166,7 +166,7 @@ namespace osu.Game.Rulesets.UI
.Select(b => b.GetAction())
.Distinct()
.OrderBy(action => action)
- .Select(action => keyCounter.CreateKeyCounter(new KeyCounterAction(action))));
+ .Select(action => keyCounter.CreateKeyCounter(new KeyCounterActionTrigger(action))));
}
private partial class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler
@@ -176,14 +176,14 @@ namespace osu.Game.Rulesets.UI
{
}
- public bool OnPressed(KeyBindingPressEvent e) => Target.Children.Where(c => c.Trigger is KeyCounterAction)
- .Select(c => (KeyCounterAction)c.Trigger)
+ public bool OnPressed(KeyBindingPressEvent e) => Target.Children.Where(c => c.Trigger is KeyCounterActionTrigger)
+ .Select(c => (KeyCounterActionTrigger)c.Trigger)
.Any(c => c.OnPressed(e.Action, Clock.Rate >= 0));
public void OnReleased(KeyBindingReleaseEvent e)
{
foreach (var c
- in Target.Children.Where(c => c.Trigger is KeyCounterAction).Select(c => (KeyCounterAction)c.Trigger))
+ in Target.Children.Where(c => c.Trigger is KeyCounterActionTrigger).Select(c => (KeyCounterActionTrigger)c.Trigger))
c.OnReleased(e.Action, Clock.Rate >= 0);
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
similarity index 86%
rename from osu.Game/Screens/Play/KeyCounterAction.cs
rename to osu.Game/Screens/Play/KeyCounterActionTrigger.cs
index 65a0bc2ca7..51b82ac5e5 100644
--- a/osu.Game/Screens/Play/KeyCounterAction.cs
+++ b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
@@ -7,12 +7,12 @@ using System.Collections.Generic;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterAction : KeyCounter.InputTrigger
+ public partial class KeyCounterActionTrigger : KeyCounter.InputTrigger
where T : struct
{
public T Action { get; }
- public KeyCounterAction(T action)
+ public KeyCounterActionTrigger(T action)
: base($"B{(int)(object)action + 1}")
{
Action = action;
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
similarity index 85%
rename from osu.Game/Screens/Play/KeyCounterKeyboard.cs
rename to osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
index ef1f207556..fee716abf4 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboard.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
@@ -8,11 +8,11 @@ using osuTK.Input;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterKeyboard : KeyCounter.InputTrigger
+ public partial class KeyCounterKeyboardTrigger : KeyCounter.InputTrigger
{
public Key Key { get; }
- public KeyCounterKeyboard(Key key)
+ public KeyCounterKeyboardTrigger(Key key)
: base(key.ToString())
{
Key = key;
diff --git a/osu.Game/Screens/Play/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
similarity index 90%
rename from osu.Game/Screens/Play/KeyCounterMouse.cs
rename to osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
index cf0e0a394f..a693db9b19 100644
--- a/osu.Game/Screens/Play/KeyCounterMouse.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
@@ -9,11 +9,11 @@ using osuTK;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterMouse : KeyCounter.InputTrigger
+ public partial class KeyCounterMouseTrigger : KeyCounter.InputTrigger
{
public MouseButton Button { get; }
- public KeyCounterMouse(MouseButton button)
+ public KeyCounterMouseTrigger(MouseButton button)
: base(getStringRepresentation(button))
{
Button = button;
From b0a2e69f951910907559d16fc2392a4d9867cd99 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 15 Feb 2023 22:06:10 +0000
Subject: [PATCH 033/317] style: nullable pass on `KeyCounterDisplay`
---
osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs | 11 +++++------
osu.Game/Screens/Play/KeyCounterDisplay.cs | 6 ++----
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
index d643070e06..332474a517 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
@@ -24,12 +24,11 @@ namespace osu.Game.Screens.Play
public DefaultKeyCounterDisplay()
{
- InternalChild = KeyFlow = new FillFlowContainer
- {
- Direction = FillDirection.Horizontal,
- AutoSizeAxes = Axes.Both,
- Alpha = 0,
- };
+ KeyFlow.Direction = FillDirection.Horizontal;
+ KeyFlow.AutoSizeAxes = Axes.Both;
+ KeyFlow.Alpha = 0;
+
+ InternalChild = KeyFlow;
}
protected override void Update()
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index fc6fa12f10..f5af67caea 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Linq;
using osu.Framework.Allocation;
@@ -19,7 +17,7 @@ namespace osu.Game.Screens.Play
{
protected readonly Bindable ConfigVisibility = new Bindable();
- protected FillFlowContainer KeyFlow;
+ protected FillFlowContainer KeyFlow = new FillFlowContainer();
protected override Container Content => KeyFlow;
@@ -71,7 +69,7 @@ namespace osu.Game.Screens.Play
public override bool HandleNonPositionalInput => receptor == null;
public override bool HandlePositionalInput => receptor == null;
- private Receptor receptor;
+ private Receptor? receptor;
public void SetReceptor(Receptor receptor)
{
From e9dcc257b48ae26302c598df7d433e09007a40ba Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 15 Feb 2023 22:06:35 +0000
Subject: [PATCH 034/317] reafactor: simplify type checking
---
osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs | 6 +++---
osu.Game/Screens/Play/KeyCounterDisplay.cs | 5 ++++-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
index 332474a517..b69ecfd7ae 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
@@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -43,14 +42,15 @@ namespace osu.Game.Screens.Play
public override void Add(KeyCounter key)
{
base.Add(key);
- if (key is not DefaultKeyCounter defaultKey)
- throw new ArgumentException($"{key.GetType()} is not a supported {nameof(KeyCounter)}.", nameof(key));
+ DefaultKeyCounter defaultKey = (DefaultKeyCounter)key;
defaultKey.FadeTime = key_fade_time;
defaultKey.KeyDownTextColor = KeyDownTextColor;
defaultKey.KeyUpTextColor = KeyUpTextColor;
}
+ protected override bool CheckType(KeyCounter key) => key is DefaultKeyCounter;
+
protected override void UpdateVisibility() =>
// Isolate changing visibility of the key counters from fading this component.
KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index f5af67caea..ed47af11a3 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -29,12 +29,15 @@ namespace osu.Game.Screens.Play
public override void Add(KeyCounter key)
{
- ArgumentNullException.ThrowIfNull(key);
+ if (!CheckType(key))
+ throw new ArgumentException($"{key.GetType()} is not a supported {nameof(KeyCounter)}.", nameof(key));
base.Add(key);
key.IsCounting = IsCounting;
}
+ protected virtual bool CheckType(KeyCounter key) => true;
+
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
From 74e7cc205601bc4edb9d88e12afb8c63f8e967d2 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 15 Feb 2023 22:18:02 +0000
Subject: [PATCH 035/317] feat: implement new design of key counter
---
.../Visual/Gameplay/TestSceneKeyCounter.cs | 39 +++++++---
osu.Game/Screens/Play/ArgonKeyCounter.cs | 76 +++++++++++++++++++
.../Screens/Play/ArgonKeyCounterDisplay.cs | 42 ++++++++++
3 files changed, 147 insertions(+), 10 deletions(-)
create mode 100644 osu.Game/Screens/Play/ArgonKeyCounter.cs
create mode 100644 osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 975a5c9465..41add82245 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Screens.Play;
+using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
@@ -18,24 +19,44 @@ namespace osu.Game.Tests.Visual.Gameplay
public TestSceneKeyCounter()
{
DefaultKeyCounter testCounter;
+ KeyCounterDisplay kc;
+ KeyCounterDisplay argonKc;
- KeyCounterDisplay kc = new DefaultKeyCounterDisplay
+ Children = new Drawable[]
{
- Origin = Anchor.Centre,
- Anchor = Anchor.Centre,
- Children = new[]
+ kc = new DefaultKeyCounterDisplay
{
- testCounter = new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
- new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
- new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
- new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
+ Origin = Anchor.Centre,
+ Anchor = Anchor.Centre,
+ Position = new Vector2(0, -50),
+ Children = new[]
+ {
+ testCounter = new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
+ new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
+ },
},
+ argonKc = new ArgonKeyCounterDisplay
+ {
+ Origin = Anchor.Centre,
+ Anchor = Anchor.Centre,
+ Position = new Vector2(0, 50),
+ Children = new[]
+ {
+ new ArgonKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new ArgonKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new ArgonKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
+ new ArgonKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
+ },
+ }
};
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboardTrigger(key)));
+ argonKc.Add(argonKc.CreateKeyCounter(new KeyCounterKeyboardTrigger(key)));
});
Key testKey = ((KeyCounterKeyboardTrigger)kc.Children.First().Trigger).Key;
@@ -52,8 +73,6 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("Disable counting", () => testCounter.IsCounting = false);
addPressKeyStep();
AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2);
-
- Add(kc);
}
}
}
diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs
new file mode 100644
index 0000000000..a275a7e017
--- /dev/null
+++ b/osu.Game/Screens/Play/ArgonKeyCounter.cs
@@ -0,0 +1,76 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Shapes;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+
+namespace osu.Game.Screens.Play
+{
+ public partial class ArgonKeyCounter : KeyCounter
+ {
+ private Circle inputIndicator = null!;
+ private OsuSpriteText countText = null!;
+
+ // These values were taken from Figma
+ private const float line_height = 3;
+ private const float name_font_size = 10;
+ private const float count_font_size = 14;
+
+ // Make things look bigger without using Scale
+ private const float scale_factor = 1.5f;
+
+ public ArgonKeyCounter(InputTrigger trigger)
+ : base(trigger)
+ {
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ Children = new Drawable[]
+ {
+ inputIndicator = new Circle
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.X,
+ Height = line_height * scale_factor,
+ Alpha = 0.5f
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Position = new Vector2(0, -13) * scale_factor,
+ Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold),
+ Colour = colours.Blue0,
+ Text = Name
+ },
+ countText = new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold),
+ Text = "0"
+ },
+ };
+
+ // Values from Figma didn't match visually
+ // So these were just eyeballed
+ Height = 30 * scale_factor;
+ Width = 35 * scale_factor;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ IsLit.BindValueChanged(e => inputIndicator.Alpha = e.NewValue ? 1 : 0.5f, true);
+ PressesCount.BindValueChanged(e => countText.Text = e.NewValue.ToString(@"#,0"), true);
+ }
+ }
+}
diff --git a/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
new file mode 100644
index 0000000000..da34a64a4c
--- /dev/null
+++ b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
@@ -0,0 +1,42 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osuTK;
+
+namespace osu.Game.Screens.Play
+{
+ public partial class ArgonKeyCounterDisplay : KeyCounterDisplay
+ {
+ private const int duration = 100;
+
+ public new IReadOnlyList Children
+ {
+ get => (IReadOnlyList)base.Children;
+ set => base.Children = value;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ KeyFlow.Direction = FillDirection.Horizontal;
+ KeyFlow.AutoSizeAxes = Axes.Both;
+ KeyFlow.Spacing = new Vector2(2);
+
+ InternalChildren = new[]
+ {
+ KeyFlow
+ };
+ }
+
+ protected override bool CheckType(KeyCounter key) => key is ArgonKeyCounter;
+
+ protected override void UpdateVisibility()
+ => KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
+
+ public override KeyCounter CreateKeyCounter(KeyCounter.InputTrigger trigger) => new ArgonKeyCounter(trigger);
+ }
+}
From 6340730427908b839aaa3d00c82497818cec93e1 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Thu, 16 Feb 2023 21:59:39 +0000
Subject: [PATCH 036/317] refactor(KeyCounter): remove circularity
---
.../TestSceneOsuTouchInput.cs | 2 +-
osu.Game/Screens/Play/KeyCounter.cs | 52 +++++++++++--------
.../Screens/Play/KeyCounterActionTrigger.cs | 2 +-
.../Screens/Play/KeyCounterKeyboardTrigger.cs | 2 +-
.../Screens/Play/KeyCounterMouseTrigger.cs | 2 +-
5 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 950e034d8f..c73025ebb9 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -593,7 +593,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
if (e.Action == Action)
{
- Light();
+ LightUp();
}
return false;
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 4a7203870c..3748792383 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -45,7 +46,9 @@ namespace osu.Game.Screens.Play
Trigger = trigger,
};
- Trigger.Target = this;
+ Trigger.OnLightUp += LightUp;
+ Trigger.OnUnlight += Unlight;
+
Name = trigger.Name;
}
@@ -67,37 +70,40 @@ namespace osu.Game.Screens.Play
CountPresses--;
}
+ protected virtual void LightUp(bool increment = true)
+ {
+ IsLit.Value = true;
+ if (increment)
+ Increment();
+ }
+
+ protected virtual void Unlight(bool preserve = true)
+ {
+ IsLit.Value = false;
+ if (!preserve)
+ Decrement();
+ }
+
+ protected override void Dispose(bool isDisposing)
+ {
+ base.Dispose(isDisposing);
+ Trigger.OnLightUp -= LightUp;
+ Trigger.OnUnlight -= Unlight;
+ }
+
public abstract partial class InputTrigger : Component
{
- private KeyCounter? target;
-
- public KeyCounter Target
- {
- set => target = value;
- }
+ public event Action? OnLightUp;
+ public event Action? OnUnlight;
protected InputTrigger(string name)
{
Name = name;
}
- protected void Light(bool increment = true)
- {
- if (target == null) return;
+ protected void LightUp(bool increment = true) => OnLightUp?.Invoke(increment);
- target.IsLit.Value = true;
- if (increment)
- target.Increment();
- }
-
- protected void Unlight(bool preserve = true)
- {
- if (target == null) return;
-
- target.IsLit.Value = false;
- if (!preserve)
- target.Decrement();
- }
+ protected void Unlight(bool preserve = true) => OnUnlight?.Invoke(preserve);
}
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
index 51b82ac5e5..c6acb3f95f 100644
--- a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return false;
- Light(forwards);
+ LightUp(forwards);
return false;
}
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
index fee716abf4..18eb6b7612 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
@@ -22,7 +22,7 @@ namespace osu.Game.Screens.Play
{
if (e.Key == Key)
{
- Light();
+ LightUp();
}
return base.OnKeyDown(e);
diff --git a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
index a693db9b19..1446494b5b 100644
--- a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Screens.Play
protected override bool OnMouseDown(MouseDownEvent e)
{
if (e.Button == Button)
- Light();
+ LightUp();
return base.OnMouseDown(e);
}
From ddd6c1a1c671c24f33479eceff34f7acf05b5cc7 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Thu, 16 Feb 2023 22:20:34 +0000
Subject: [PATCH 037/317] refactor(KeyCounter): address bindables issues
`IsCounting` is back being an auto-property.
`countPresses` is now encapsulated and being exposed as an
`IBindable` via `CountPresses`
---
.../Visual/Gameplay/TestSceneAutoplay.cs | 4 ++--
.../Gameplay/TestSceneGameplayRewinding.cs | 4 ++--
.../Visual/Gameplay/TestSceneKeyCounter.cs | 6 +++---
.../Visual/Gameplay/TestSceneReplay.cs | 2 +-
.../TestSceneChangeAndUseGameplayBindings.cs | 4 ++--
osu.Game/Screens/Play/DefaultKeyCounter.cs | 4 ++--
osu.Game/Screens/Play/KeyCounter.cs | 20 +++++--------------
7 files changed, 17 insertions(+), 27 deletions(-)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
index 5442b3bfef..4b6e1f089f 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
@@ -35,14 +35,14 @@ namespace osu.Game.Tests.Visual.Gameplay
var referenceBeatmap = CreateBeatmap(new OsuRuleset().RulesetInfo);
AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
- AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
+ AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses.Value > 2));
seekTo(referenceBeatmap.Breaks[0].StartTime);
AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
AddAssert("overlay displays 100% accuracy", () => Player.BreakOverlay.ChildrenOfType().Single().AccuracyDisplay.Current.Value == 1);
AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
- AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
+ AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses.Value == 0));
seekTo(referenceBeatmap.HitObjects[^1].GetEndTime());
AddUntilStep("results displayed", () => getResultsScreen()?.IsLoaded == true);
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
index 1dffeed01b..9f485cd7bf 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
@@ -31,11 +31,11 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
addSeekStep(3000);
AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
- AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Select(kc => kc.CountPresses).Sum() == 15);
+ AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Select(kc => kc.CountPresses.Value).Sum() == 15);
AddStep("clear results", () => Player.Results.Clear());
addSeekStep(0);
AddAssert("none judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
- AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
+ AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses.Value == 0));
AddAssert("no results triggered", () => Player.Results.Count == 0);
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 975a5c9465..9eeee800d9 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -46,12 +46,12 @@ namespace osu.Game.Tests.Visual.Gameplay
}
addPressKeyStep();
- AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 1);
+ AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 1);
addPressKeyStep();
- AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 2);
+ AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 2);
AddStep("Disable counting", () => testCounter.IsCounting = false);
addPressKeyStep();
- AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2);
+ AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses.Value == 2);
Add(kc);
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs
index c476aae202..542686f0cd 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override void AddCheckSteps()
{
AddUntilStep("score above zero", () => ((ScoreAccessibleReplayPlayer)Player).ScoreProcessor.TotalScore.Value > 0);
- AddUntilStep("key counter counted keys", () => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0));
+ AddUntilStep("key counter counted keys", () => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses.Value > 0));
AddAssert("cannot fail", () => !((ScoreAccessibleReplayPlayer)Player).AllowFail);
}
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs
index d937b9e6d7..59a0f9cea8 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs
@@ -69,10 +69,10 @@ namespace osu.Game.Tests.Visual.Navigation
AddUntilStep("wait for gameplay", () => player?.IsBreakTime.Value == false);
AddStep("press 'z'", () => InputManager.Key(Key.Z));
- AddAssert("key counter didn't increase", () => keyCounter.CountPresses == 0);
+ AddAssert("key counter didn't increase", () => keyCounter.CountPresses.Value == 0);
AddStep("press 's'", () => InputManager.Key(Key.S));
- AddAssert("key counter did increase", () => keyCounter.CountPresses == 1);
+ AddAssert("key counter did increase", () => keyCounter.CountPresses.Value == 1);
}
private KeyBindingsSubsection osuBindingSubsection => keyBindingPanel
diff --git a/osu.Game/Screens/Play/DefaultKeyCounter.cs b/osu.Game/Screens/Play/DefaultKeyCounter.cs
index 93dc4abcb5..52d54b9d4a 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounter.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounter.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Screens.Play
},
countSpriteText = new OsuSpriteText
{
- Text = CountPresses.ToString(@"#,0"),
+ Text = CountPresses.Value.ToString(@"#,0"),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativePositionAxes = Axes.Both,
@@ -83,7 +83,7 @@ namespace osu.Game.Screens.Play
Width = buttonSprite.DrawWidth;
IsLit.BindValueChanged(e => updateGlowSprite(e.NewValue), true);
- PressesCount.BindValueChanged(e => countSpriteText.Text = e.NewValue.ToString(@"#,0"), true);
+ CountPresses.BindValueChanged(e => countSpriteText.Text = e.NewValue.ToString(@"#,0"), true);
}
private void updateGlowSprite(bool show)
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 3748792383..23afa97597 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -12,28 +12,18 @@ namespace osu.Game.Screens.Play
{
public readonly InputTrigger Trigger;
- protected Bindable IsCountingBindable = new BindableBool(true);
-
private readonly Container content;
protected override Container Content => content;
- protected Bindable PressesCount = new BindableInt
+ private readonly Bindable countPresses = new BindableInt
{
MinValue = 0
};
- public bool IsCounting
- {
- get => IsCountingBindable.Value;
- set => IsCountingBindable.Value = value;
- }
+ public bool IsCounting { get; set; } = true;
- public int CountPresses
- {
- get => PressesCount.Value;
- private set => PressesCount.Value = value;
- }
+ public IBindable CountPresses => countPresses;
protected KeyCounter(InputTrigger trigger)
{
@@ -59,7 +49,7 @@ namespace osu.Game.Screens.Play
if (!IsCounting)
return;
- CountPresses++;
+ countPresses.Value++;
}
public void Decrement()
@@ -67,7 +57,7 @@ namespace osu.Game.Screens.Play
if (!IsCounting)
return;
- CountPresses--;
+ countPresses.Value--;
}
protected virtual void LightUp(bool increment = true)
From c61fac578ca53fa4dba22ac7ec85aa0cc335c762 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Thu, 16 Feb 2023 23:15:03 +0000
Subject: [PATCH 038/317] style(KeyCounter): rename methods and arguments
As for the second suggestion in
https://github.com/ppy/osu/pull/22654#discussion_r1109047998,
I went with the first one as only one Trigger actually uses this
argument for rewinding.
---
.../TestSceneOsuTouchInput.cs | 4 ++--
osu.Game/Screens/Play/KeyCounter.cs | 20 +++++++++----------
.../Screens/Play/KeyCounterActionTrigger.cs | 4 ++--
.../Screens/Play/KeyCounterKeyboardTrigger.cs | 4 ++--
.../Screens/Play/KeyCounterMouseTrigger.cs | 4 ++--
5 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index c73025ebb9..8a933c6b24 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -593,7 +593,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
if (e.Action == Action)
{
- LightUp();
+ Activate();
}
return false;
@@ -602,7 +602,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public void OnReleased(KeyBindingReleaseEvent e)
{
if (e.Action == Action)
- Unlight();
+ Deactivate();
}
}
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 23afa97597..a276c9d59e 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -36,8 +36,8 @@ namespace osu.Game.Screens.Play
Trigger = trigger,
};
- Trigger.OnLightUp += LightUp;
- Trigger.OnUnlight += Unlight;
+ Trigger.OnActivate += Activate;
+ Trigger.OnDeactivate += Deactivate;
Name = trigger.Name;
}
@@ -60,14 +60,14 @@ namespace osu.Game.Screens.Play
countPresses.Value--;
}
- protected virtual void LightUp(bool increment = true)
+ protected virtual void Activate(bool increment = true)
{
IsLit.Value = true;
if (increment)
Increment();
}
- protected virtual void Unlight(bool preserve = true)
+ protected virtual void Deactivate(bool preserve = true)
{
IsLit.Value = false;
if (!preserve)
@@ -77,23 +77,23 @@ namespace osu.Game.Screens.Play
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
- Trigger.OnLightUp -= LightUp;
- Trigger.OnUnlight -= Unlight;
+ Trigger.OnActivate -= Activate;
+ Trigger.OnDeactivate -= Deactivate;
}
public abstract partial class InputTrigger : Component
{
- public event Action? OnLightUp;
- public event Action? OnUnlight;
+ public event Action? OnActivate;
+ public event Action? OnDeactivate;
protected InputTrigger(string name)
{
Name = name;
}
- protected void LightUp(bool increment = true) => OnLightUp?.Invoke(increment);
+ protected void Activate(bool forwardPlayback = true) => OnActivate?.Invoke(forwardPlayback);
- protected void Unlight(bool preserve = true) => OnUnlight?.Invoke(preserve);
+ protected void Deactivate(bool forwardPlayback = true) => OnDeactivate?.Invoke(forwardPlayback);
}
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
index c6acb3f95f..8bb9bdc886 100644
--- a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return false;
- LightUp(forwards);
+ Activate(forwards);
return false;
}
@@ -32,7 +32,7 @@ namespace osu.Game.Screens.Play
if (!EqualityComparer.Default.Equals(action, Action))
return;
- Unlight(forwards);
+ Deactivate(forwards);
}
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
index 18eb6b7612..56c5ab0083 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
@@ -22,7 +22,7 @@ namespace osu.Game.Screens.Play
{
if (e.Key == Key)
{
- LightUp();
+ Activate();
}
return base.OnKeyDown(e);
@@ -31,7 +31,7 @@ namespace osu.Game.Screens.Play
protected override void OnKeyUp(KeyUpEvent e)
{
if (e.Key == Key)
- Unlight();
+ Deactivate();
base.OnKeyUp(e);
}
diff --git a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
index 1446494b5b..66890073a8 100644
--- a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Screens.Play
protected override bool OnMouseDown(MouseDownEvent e)
{
if (e.Button == Button)
- LightUp();
+ Activate();
return base.OnMouseDown(e);
}
@@ -47,7 +47,7 @@ namespace osu.Game.Screens.Play
protected override void OnMouseUp(MouseUpEvent e)
{
if (e.Button == Button)
- Unlight();
+ Deactivate();
base.OnMouseUp(e);
}
From e3ca751027af079ac74e73ad7e88d59c8dc82d24 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Thu, 16 Feb 2023 23:17:47 +0000
Subject: [PATCH 039/317] refactor: make `FillFlowContainer` read-only
---
osu.Game/Screens/Play/KeyCounterDisplay.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index ed47af11a3..0f2f8e43c9 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play
{
protected readonly Bindable ConfigVisibility = new Bindable();
- protected FillFlowContainer KeyFlow = new FillFlowContainer();
+ protected readonly FillFlowContainer KeyFlow = new FillFlowContainer();
protected override Container Content => KeyFlow;
From 6193aeed120f2bc85768a47efafa21b95695119e Mon Sep 17 00:00:00 2001
From: tsrk
Date: Fri, 17 Feb 2023 00:13:45 +0000
Subject: [PATCH 040/317] fix(TestSceneOsuTouchInput): missing Value call
---
osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 8a933c6b24..4cb017cc56 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -562,8 +562,8 @@ namespace osu.Game.Rulesets.Osu.Tests
private void assertKeyCounter(int left, int right)
{
- AddAssert($"The left key was pressed {left} times", () => leftKeyCounter.CountPresses, () => Is.EqualTo(left));
- AddAssert($"The right key was pressed {right} times", () => rightKeyCounter.CountPresses, () => Is.EqualTo(right));
+ AddAssert($"The left key was pressed {left} times", () => leftKeyCounter.CountPresses.Value, () => Is.EqualTo(left));
+ AddAssert($"The right key was pressed {right} times", () => rightKeyCounter.CountPresses.Value, () => Is.EqualTo(right));
}
private void releaseAllTouches()
From d0e8d65766df488c98bf99ccdef7c05df3f694d8 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Fri, 17 Feb 2023 00:40:01 +0000
Subject: [PATCH 041/317] style(KeyCounter): rename `IsLit` to `IsActive`
---
osu.Game/Screens/Play/DefaultKeyCounter.cs | 2 +-
osu.Game/Screens/Play/KeyCounter.cs | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Screens/Play/DefaultKeyCounter.cs b/osu.Game/Screens/Play/DefaultKeyCounter.cs
index 52d54b9d4a..3673281577 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounter.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounter.cs
@@ -82,7 +82,7 @@ namespace osu.Game.Screens.Play
Height = buttonSprite.DrawHeight;
Width = buttonSprite.DrawWidth;
- IsLit.BindValueChanged(e => updateGlowSprite(e.NewValue), true);
+ IsActive.BindValueChanged(e => updateGlowSprite(e.NewValue), true);
CountPresses.BindValueChanged(e => countSpriteText.Text = e.NewValue.ToString(@"#,0"), true);
}
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index a276c9d59e..212843cbe9 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Screens.Play
Name = trigger.Name;
}
- protected Bindable IsLit = new BindableBool();
+ protected Bindable IsActive = new BindableBool();
public void Increment()
{
@@ -62,14 +62,14 @@ namespace osu.Game.Screens.Play
protected virtual void Activate(bool increment = true)
{
- IsLit.Value = true;
+ IsActive.Value = true;
if (increment)
Increment();
}
protected virtual void Deactivate(bool preserve = true)
{
- IsLit.Value = false;
+ IsActive.Value = false;
if (!preserve)
Decrement();
}
From c94e647e21902db2fc98bc3a42ad1b2a75246842 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Fri, 17 Feb 2023 09:09:56 +0000
Subject: [PATCH 042/317] style(KeyCounterDisplay): remove type check
---
osu.Game/Screens/Play/KeyCounterDisplay.cs | 5 -----
1 file changed, 5 deletions(-)
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index 0f2f8e43c9..d2b50ff73d 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -29,15 +29,10 @@ namespace osu.Game.Screens.Play
public override void Add(KeyCounter key)
{
- if (!CheckType(key))
- throw new ArgumentException($"{key.GetType()} is not a supported {nameof(KeyCounter)}.", nameof(key));
-
base.Add(key);
key.IsCounting = IsCounting;
}
- protected virtual bool CheckType(KeyCounter key) => true;
-
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
From 8830e0658834095dd87e3d9b82b425528021b93a Mon Sep 17 00:00:00 2001
From: tsrk
Date: Fri, 17 Feb 2023 09:17:11 +0000
Subject: [PATCH 043/317] fix: compilation
---
osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
index b69ecfd7ae..fbf1b87395 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
@@ -49,8 +49,6 @@ namespace osu.Game.Screens.Play
defaultKey.KeyUpTextColor = KeyUpTextColor;
}
- protected override bool CheckType(KeyCounter key) => key is DefaultKeyCounter;
-
protected override void UpdateVisibility() =>
// Isolate changing visibility of the key counters from fading this component.
KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
From 5bec2d7c525fac4fd975f0abb3e5fd19a37ef843 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Tue, 21 Feb 2023 19:02:56 +0000
Subject: [PATCH 044/317] style(KeyCounter): `forwardPlayback`
---
osu.Game/Screens/Play/KeyCounter.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 212843cbe9..a07c650736 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -60,17 +60,17 @@ namespace osu.Game.Screens.Play
countPresses.Value--;
}
- protected virtual void Activate(bool increment = true)
+ protected virtual void Activate(bool forwardPlayback = true)
{
IsActive.Value = true;
- if (increment)
+ if (forwardPlayback)
Increment();
}
- protected virtual void Deactivate(bool preserve = true)
+ protected virtual void Deactivate(bool forwardPlayback = true)
{
IsActive.Value = false;
- if (!preserve)
+ if (!forwardPlayback)
Decrement();
}
From 42a5a06b9d6e8e1416c2aaf828dfe236e9617b6e Mon Sep 17 00:00:00 2001
From: tsrk
Date: Tue, 21 Feb 2023 19:10:37 +0000
Subject: [PATCH 045/317] style(KeyCounter): fields and methods visiblity
---
osu.Game/Screens/Play/KeyCounter.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index a07c650736..4bad6920e3 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -42,9 +42,9 @@ namespace osu.Game.Screens.Play
Name = trigger.Name;
}
- protected Bindable IsActive = new BindableBool();
+ protected readonly Bindable IsActive = new BindableBool();
- public void Increment()
+ private void increment()
{
if (!IsCounting)
return;
@@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play
countPresses.Value++;
}
- public void Decrement()
+ private void decrement()
{
if (!IsCounting)
return;
@@ -64,14 +64,14 @@ namespace osu.Game.Screens.Play
{
IsActive.Value = true;
if (forwardPlayback)
- Increment();
+ increment();
}
protected virtual void Deactivate(bool forwardPlayback = true)
{
IsActive.Value = false;
if (!forwardPlayback)
- Decrement();
+ decrement();
}
protected override void Dispose(bool isDisposing)
From 1beec7103725ca9ade4b081804d8a7cc83e5c912 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 22 Feb 2023 14:58:27 +0000
Subject: [PATCH 046/317] refactor(KeyCounterDisplay): apply suggestions
I also took the freedom to add type checking, as we can't limit the
usage of `Add()` since it's a Container. The exception thrown also
advises of using the suggested `AddTrigger()` instead.
---
.../Visual/Gameplay/TestSceneAutoplay.cs | 2 +-
.../Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +-
.../Visual/Gameplay/TestSceneKeyCounter.cs | 4 +-
.../TestSceneSkinEditorMultipleSkins.cs | 2 +-
.../Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +-
osu.Game/Rulesets/UI/RulesetInputManager.cs | 10 +--
.../Screens/Play/DefaultKeyCounterDisplay.cs | 27 ++++--
osu.Game/Screens/Play/KeyCounter.cs | 6 +-
osu.Game/Screens/Play/KeyCounterDisplay.cs | 84 +++++++++++--------
osu.Game/Screens/Play/Player.cs | 7 +-
10 files changed, 86 insertions(+), 60 deletions(-)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
index 4b6e1f089f..903cd178b7 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses.Value > 2));
seekTo(referenceBeatmap.Breaks[0].StartTime);
- AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
+ AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting.Value);
AddAssert("overlay displays 100% accuracy", () => Player.BreakOverlay.ChildrenOfType().Single().AccuracyDisplay.Current.Value == 1);
AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
index af79650d29..a586d798f5 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
@@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.Gameplay
hudOverlay = new HUDOverlay(null, Array.Empty());
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboardTrigger(Key.Space)));
+ hudOverlay.KeyCounter.AddTrigger(new KeyCounterKeyboardTrigger(Key.Space));
scoreProcessor.Combo.Value = 1;
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 9eeee800d9..5405274cd0 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
- kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboardTrigger(key)));
+ kc.AddTrigger(new KeyCounterKeyboardTrigger(key));
});
Key testKey = ((KeyCounterKeyboardTrigger)kc.Children.First().Trigger).Key;
@@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 1);
addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 2);
- AddStep("Disable counting", () => testCounter.IsCounting = false);
+ AddStep("Disable counting", () => testCounter.IsCounting.Value = false);
addPressKeyStep();
AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses.Value == 2);
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
index 432ff2fc7e..e4f257582d 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay
};
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboardTrigger(Key.Space)));
+ hudOverlay.KeyCounter.AddTrigger(new KeyCounterKeyboardTrigger(Key.Space));
scoreProcessor.Combo.Value = 1;
return new Container
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
index 24de29fa03..9848894f84 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
@@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay
hudOverlay = new HUDOverlay(null, Array.Empty());
// Add any key just to display the key counter visually.
- hudOverlay.KeyCounter.Add(hudOverlay.KeyCounter.CreateKeyCounter(new KeyCounterKeyboardTrigger(Key.Space)));
+ hudOverlay.KeyCounter.AddTrigger(new KeyCounterKeyboardTrigger(Key.Space));
action?.Invoke(hudOverlay);
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index 6a38fa4824..32b2a19e21 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -162,11 +162,11 @@ namespace osu.Game.Rulesets.UI
KeyBindingContainer.Add(receptor);
keyCounter.SetReceptor(receptor);
- keyCounter.AddRange(KeyBindingContainer.DefaultKeyBindings
- .Select(b => b.GetAction())
- .Distinct()
- .OrderBy(action => action)
- .Select(action => keyCounter.CreateKeyCounter(new KeyCounterActionTrigger(action))));
+ keyCounter.AddTriggerRange(KeyBindingContainer.DefaultKeyBindings
+ .Select(b => b.GetAction())
+ .Distinct()
+ .OrderBy(action => action)
+ .Select(action => new KeyCounterActionTrigger(action)));
}
private partial class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler
diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
index fbf1b87395..367eb483a0 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
@@ -13,7 +13,9 @@ namespace osu.Game.Screens.Play
private const int duration = 100;
private const double key_fade_time = 80;
- protected override Container Content => KeyFlow;
+ private readonly FillFlowContainer keyFlow = new FillFlowContainer();
+
+ protected override Container Content => keyFlow;
public new IReadOnlyList Children
{
@@ -22,12 +24,13 @@ namespace osu.Game.Screens.Play
}
public DefaultKeyCounterDisplay()
+ : base(typeof(DefaultKeyCounter))
{
- KeyFlow.Direction = FillDirection.Horizontal;
- KeyFlow.AutoSizeAxes = Axes.Both;
- KeyFlow.Alpha = 0;
+ keyFlow.Direction = FillDirection.Horizontal;
+ keyFlow.AutoSizeAxes = Axes.Both;
+ keyFlow.Alpha = 0;
- InternalChild = KeyFlow;
+ InternalChild = keyFlow;
}
protected override void Update()
@@ -36,12 +39,22 @@ namespace osu.Game.Screens.Play
// Don't use autosize as it will shrink to zero when KeyFlow is hidden.
// In turn this can cause the display to be masked off screen and never become visible again.
- Size = KeyFlow.Size;
+ Size = keyFlow.Size;
+ }
+
+ public override void AddTrigger(KeyCounter.InputTrigger trigger)
+ {
+ DefaultKeyCounter key = new DefaultKeyCounter(trigger);
+ Add(key);
+ key.FadeTime = key_fade_time;
+ key.KeyDownTextColor = KeyDownTextColor;
+ key.KeyUpTextColor = KeyUpTextColor;
}
public override void Add(KeyCounter key)
{
base.Add(key);
+
DefaultKeyCounter defaultKey = (DefaultKeyCounter)key;
defaultKey.FadeTime = key_fade_time;
@@ -51,7 +64,7 @@ namespace osu.Game.Screens.Play
protected override void UpdateVisibility() =>
// Isolate changing visibility of the key counters from fading this component.
- KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
+ keyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
private Color4 keyDownTextColor = Color4.DarkGray;
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 4bad6920e3..26bb6f1a22 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -21,7 +21,7 @@ namespace osu.Game.Screens.Play
MinValue = 0
};
- public bool IsCounting { get; set; } = true;
+ public Bindable IsCounting { get; } = new BindableBool(true);
public IBindable CountPresses => countPresses;
@@ -46,7 +46,7 @@ namespace osu.Game.Screens.Play
private void increment()
{
- if (!IsCounting)
+ if (!IsCounting.Value)
return;
countPresses.Value++;
@@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play
private void decrement()
{
- if (!IsCounting)
+ if (!IsCounting.Value)
return;
countPresses.Value--;
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index d2b50ff73d..d1fbfe166d 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -2,9 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
@@ -15,22 +17,58 @@ namespace osu.Game.Screens.Play
{
public abstract partial class KeyCounterDisplay : Container
{
- protected readonly Bindable ConfigVisibility = new Bindable();
-
- protected readonly FillFlowContainer KeyFlow = new FillFlowContainer();
-
- protected override Container Content => KeyFlow;
-
///
/// Whether the key counter should be visible regardless of the configuration value.
/// This is true by default, but can be changed.
///
- public readonly Bindable AlwaysVisible = new Bindable(true);
+ public Bindable AlwaysVisible { get; } = new Bindable(true);
+
+ public Bindable IsCounting { get; } = new BindableBool(true);
+
+ public IReadOnlyList Triggers
+ {
+ get => Children.Select(c => c.Trigger).ToArray();
+ set
+ {
+ Clear();
+ value.ForEach(AddTrigger);
+ }
+ }
+
+ protected readonly Bindable ConfigVisibility = new Bindable();
+
+ protected abstract void UpdateVisibility();
+
+ private Receptor? receptor;
+
+ private readonly Type[] acceptedTypes;
+
+ protected KeyCounterDisplay(params Type[] acceptedTypes)
+ {
+ this.acceptedTypes = acceptedTypes;
+ }
+
+ public void SetReceptor(Receptor receptor)
+ {
+ if (this.receptor != null)
+ throw new InvalidOperationException("Cannot set a new receptor when one is already active");
+
+ this.receptor = receptor;
+ }
+
+ public abstract void AddTrigger(KeyCounter.InputTrigger trigger);
+
+ public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger);
+
+ private bool checkType(KeyCounter key) => acceptedTypes.Length == 0 || acceptedTypes.Any(t => t.IsInstanceOfType(key));
public override void Add(KeyCounter key)
{
+ if (!checkType(key))
+ throw new InvalidOperationException($"{key.GetType()} is not a supported counter type. (hint: you may want to use {nameof(AddTrigger)} instead.)");
+
base.Add(key);
- key.IsCounting = IsCounting;
+ key.IsCounting.BindTo(IsCounting);
}
[BackgroundDependencyLoader]
@@ -47,38 +85,10 @@ namespace osu.Game.Screens.Play
ConfigVisibility.BindValueChanged(_ => UpdateVisibility(), true);
}
- private bool isCounting = true;
-
- public bool IsCounting
- {
- get => isCounting;
- set
- {
- if (value == isCounting) return;
-
- isCounting = value;
- foreach (var child in Children)
- child.IsCounting = value;
- }
- }
-
- protected abstract void UpdateVisibility();
-
public override bool HandleNonPositionalInput => receptor == null;
+
public override bool HandlePositionalInput => receptor == null;
- private Receptor? receptor;
-
- public void SetReceptor(Receptor receptor)
- {
- if (this.receptor != null)
- throw new InvalidOperationException("Cannot set a new receptor when one is already active");
-
- this.receptor = receptor;
- }
-
- public virtual KeyCounter CreateKeyCounter(KeyCounter.InputTrigger trigger) => new DefaultKeyCounter(trigger);
-
public partial class Receptor : Drawable
{
protected readonly KeyCounterDisplay Target;
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 6dc4854e80..b141848a21 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -440,8 +440,11 @@ namespace osu.Game.Screens.Play
},
KeyCounter =
{
+ IsCounting =
+ {
+ Value = false
+ },
AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded },
- IsCounting = false
},
Anchor = Anchor.Centre,
Origin = Anchor.Centre
@@ -481,7 +484,7 @@ namespace osu.Game.Screens.Play
{
updateGameplayState();
updatePauseOnFocusLostState();
- HUDOverlay.KeyCounter.IsCounting = !isBreakTime.NewValue;
+ HUDOverlay.KeyCounter.IsCounting.Value = !isBreakTime.NewValue;
}
private void updateGameplayState()
From 8c94b77de18e4ce57edd57aa50db5848f4d8e60b Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 22 Feb 2023 15:03:44 +0000
Subject: [PATCH 047/317] refactor(InputTrigger): move out of KCD
I love JetBrains Rider.
---
.../TestSceneOsuTouchInput.cs | 2 +-
.../Screens/Play/DefaultKeyCounterDisplay.cs | 2 +-
osu.Game/Screens/Play/InputTrigger.cs | 23 +++++++++++++++++++
osu.Game/Screens/Play/KeyCounter.cs | 16 -------------
.../Screens/Play/KeyCounterActionTrigger.cs | 2 +-
osu.Game/Screens/Play/KeyCounterDisplay.cs | 6 ++---
.../Screens/Play/KeyCounterKeyboardTrigger.cs | 2 +-
.../Screens/Play/KeyCounterMouseTrigger.cs | 2 +-
8 files changed, 31 insertions(+), 24 deletions(-)
create mode 100644 osu.Game/Screens/Play/InputTrigger.cs
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 4cb017cc56..ec8fad9bf3 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -579,7 +579,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private void checkNotPressed(OsuAction action) => AddAssert($"Not pressing {action}", () => !osuInputManager.PressedActions.Contains(action));
private void checkPressed(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action));
- public partial class TestActionKeyCounterTrigger : KeyCounter.InputTrigger, IKeyBindingHandler
+ public partial class TestActionKeyCounterTrigger : InputTrigger, IKeyBindingHandler
{
public OsuAction Action { get; }
diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
index 367eb483a0..10f5a3cfe0 100644
--- a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Screens.Play
Size = keyFlow.Size;
}
- public override void AddTrigger(KeyCounter.InputTrigger trigger)
+ public override void AddTrigger(InputTrigger trigger)
{
DefaultKeyCounter key = new DefaultKeyCounter(trigger);
Add(key);
diff --git a/osu.Game/Screens/Play/InputTrigger.cs b/osu.Game/Screens/Play/InputTrigger.cs
new file mode 100644
index 0000000000..b8951b0f8e
--- /dev/null
+++ b/osu.Game/Screens/Play/InputTrigger.cs
@@ -0,0 +1,23 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Framework.Graphics;
+
+namespace osu.Game.Screens.Play
+{
+ public abstract partial class InputTrigger : Component
+ {
+ public event Action? OnActivate;
+ public event Action? OnDeactivate;
+
+ protected InputTrigger(string name)
+ {
+ Name = name;
+ }
+
+ protected void Activate(bool forwardPlayback = true) => OnActivate?.Invoke(forwardPlayback);
+
+ protected void Deactivate(bool forwardPlayback = true) => OnDeactivate?.Invoke(forwardPlayback);
+ }
+}
diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs
index 26bb6f1a22..7ee9c94f62 100644
--- a/osu.Game/Screens/Play/KeyCounter.cs
+++ b/osu.Game/Screens/Play/KeyCounter.cs
@@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -80,20 +79,5 @@ namespace osu.Game.Screens.Play
Trigger.OnActivate -= Activate;
Trigger.OnDeactivate -= Deactivate;
}
-
- public abstract partial class InputTrigger : Component
- {
- public event Action? OnActivate;
- public event Action? OnDeactivate;
-
- protected InputTrigger(string name)
- {
- Name = name;
- }
-
- protected void Activate(bool forwardPlayback = true) => OnActivate?.Invoke(forwardPlayback);
-
- protected void Deactivate(bool forwardPlayback = true) => OnDeactivate?.Invoke(forwardPlayback);
- }
}
}
diff --git a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
index 8bb9bdc886..be0d259f85 100644
--- a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterActionTrigger.cs
@@ -7,7 +7,7 @@ using System.Collections.Generic;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterActionTrigger : KeyCounter.InputTrigger
+ public partial class KeyCounterActionTrigger : InputTrigger
where T : struct
{
public T Action { get; }
diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs
index d1fbfe166d..01686ae6de 100644
--- a/osu.Game/Screens/Play/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Screens.Play
public Bindable IsCounting { get; } = new BindableBool(true);
- public IReadOnlyList Triggers
+ public IReadOnlyList Triggers
{
get => Children.Select(c => c.Trigger).ToArray();
set
@@ -56,9 +56,9 @@ namespace osu.Game.Screens.Play
this.receptor = receptor;
}
- public abstract void AddTrigger(KeyCounter.InputTrigger trigger);
+ public abstract void AddTrigger(InputTrigger trigger);
- public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger);
+ public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger);
private bool checkType(KeyCounter key) => acceptedTypes.Length == 0 || acceptedTypes.Any(t => t.IsInstanceOfType(key));
diff --git a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
index 56c5ab0083..1d89c58fc3 100644
--- a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs
@@ -8,7 +8,7 @@ using osuTK.Input;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterKeyboardTrigger : KeyCounter.InputTrigger
+ public partial class KeyCounterKeyboardTrigger : InputTrigger
{
public Key Key { get; }
diff --git a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
index 66890073a8..e710c6e33f 100644
--- a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
+++ b/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs
@@ -9,7 +9,7 @@ using osuTK;
namespace osu.Game.Screens.Play
{
- public partial class KeyCounterMouseTrigger : KeyCounter.InputTrigger
+ public partial class KeyCounterMouseTrigger : InputTrigger
{
public MouseButton Button { get; }
From 6307b3948a2ace0140cdf9c43fe4c6b7cbe7f7db Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 22 Feb 2023 17:59:39 +0000
Subject: [PATCH 048/317] style: use Trigger initialisation
---
.../Visual/Gameplay/TestSceneKeyCounter.cs | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 5405274cd0..12cd7e1be9 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -17,21 +17,21 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public TestSceneKeyCounter()
{
- DefaultKeyCounter testCounter;
-
KeyCounterDisplay kc = new DefaultKeyCounterDisplay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
- Children = new[]
+ Triggers = new InputTrigger[]
{
- testCounter = new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
- new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
- new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
- new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
- },
+ new KeyCounterKeyboardTrigger(Key.X),
+ new KeyCounterKeyboardTrigger(Key.X),
+ new KeyCounterMouseTrigger(MouseButton.Left),
+ new KeyCounterMouseTrigger(MouseButton.Right),
+ }
};
+ var testCounter = (DefaultKeyCounter)kc.Children.First();
+
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
From a705698ab64c7cfe63c82f7be048ed03de54aed8 Mon Sep 17 00:00:00 2001
From: cdwcgt
Date: Sun, 26 Feb 2023 21:13:05 +0900
Subject: [PATCH 049/317] beatmapset that already deletePending should not be
fetched
---
osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs
index 8908163646..8ee2cc6241 100644
--- a/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs
+++ b/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs
@@ -24,6 +24,6 @@ namespace osu.Game.Scoring.Legacy
}
protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId)?.CreateInstance();
- protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash));
+ protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash && !b.BeatmapSet.DeletePending));
}
}
From dc669835e264546a4e6555ae15417c2a17a0d2bb Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Fri, 3 Mar 2023 15:25:55 +0900
Subject: [PATCH 050/317] Show count of visible beatmaps at song select
---
osu.Game/Localisation/SongSelectStrings.cs | 7 +-
osu.Game/Screens/Select/BeatmapCarousel.cs | 12 ++
osu.Game/Screens/Select/FilterControl.cs | 126 ++++++++++++---------
osu.Game/Screens/Select/SongSelect.cs | 2 +
4 files changed, 90 insertions(+), 57 deletions(-)
diff --git a/osu.Game/Localisation/SongSelectStrings.cs b/osu.Game/Localisation/SongSelectStrings.cs
index 12f70cd967..046aec6bcf 100644
--- a/osu.Game/Localisation/SongSelectStrings.cs
+++ b/osu.Game/Localisation/SongSelectStrings.cs
@@ -1,4 +1,4 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Localisation;
@@ -19,6 +19,11 @@ namespace osu.Game.Localisation
///
public static LocalisableString LocallyModifiedTooltip => new TranslatableString(getKey(@"locally_modified_tooltip"), @"Has been locally modified");
+ ///
+ /// "{0} beatmaps displayed"
+ ///
+ public static LocalisableString BeatmapsDisplayed(int arg0) => new TranslatableString(getKey(@"beatmaps_displayed"), @"{0:#,0} beatmaps displayed", arg0);
+
private static string getKey(string key) => $@"{prefix}:{key}";
}
}
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index 774ecc2c9c..68d3247275 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -49,6 +49,11 @@ namespace osu.Game.Screens.Select
///
public Action? BeatmapSetsChanged;
+ ///
+ /// Triggered after filter conditions have finished being applied to the model hierarchy.
+ ///
+ public Action? FilterApplied;
+
///
/// The currently selected beatmap.
///
@@ -56,6 +61,11 @@ namespace osu.Game.Screens.Select
private CarouselBeatmap? selectedBeatmap => selectedBeatmapSet?.Beatmaps.FirstOrDefault(s => s.State.Value == CarouselItemState.Selected);
+ ///
+ /// The total count of non-filtered beatmaps displayed.
+ ///
+ public int CountDisplayed => beatmapSets.Where(s => !s.Filtered.Value).Sum(s => s.Beatmaps.Count(b => !b.Filtered.Value));
+
///
/// The currently selected beatmap set.
///
@@ -639,6 +649,8 @@ namespace osu.Game.Screens.Select
if (alwaysResetScrollPosition || !Scroll.UserScrolling)
ScrollToSelected(true);
+
+ FilterApplied?.Invoke();
}
}
diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs
index 2f21ffbe6a..b5469abffe 100644
--- a/osu.Game/Screens/Select/FilterControl.cs
+++ b/osu.Game/Screens/Select/FilterControl.cs
@@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
+using osu.Framework.Localisation;
using osu.Game.Collections;
using osu.Game.Configuration;
using osu.Game.Graphics;
@@ -27,13 +28,20 @@ namespace osu.Game.Screens.Select
{
public partial class FilterControl : Container
{
- public const float HEIGHT = 2 * side_margin + 85;
- private const float side_margin = 20;
+ public const float HEIGHT = 2 * side_margin + 120;
+
+ private const float side_margin = 10;
public Action FilterChanged;
public Bindable CurrentTextSearch => searchTextBox.Current;
+ public LocalisableString InformationalText
+ {
+ get => filterText.Text;
+ set => filterText.Text = value;
+ }
+
private OsuTabControl sortTabs;
private Bindable sortMode;
@@ -44,6 +52,8 @@ namespace osu.Game.Screens.Select
private CollectionDropdown collectionDropdown;
+ private OsuSpriteText filterText;
+
public FilterCriteria CreateCriteria()
{
string query = searchTextBox.Text;
@@ -99,72 +109,76 @@ namespace osu.Game.Screens.Select
{
RelativeSizeAxes = Axes.Both,
Spacing = new Vector2(0, 5),
- Children = new[]
+ Children = new Drawable[]
{
+ searchTextBox = new SeekLimitedSearchTextBox { RelativeSizeAxes = Axes.X },
new Container
{
RelativeSizeAxes = Axes.X,
- Height = 60,
+ AutoSizeAxes = Axes.Y,
+ AutoSizeDuration = 200,
+ AutoSizeEasing = Easing.OutQuint,
Children = new Drawable[]
{
- searchTextBox = new SeekLimitedSearchTextBox { RelativeSizeAxes = Axes.X },
- new Box
+ filterText = new OsuSpriteText
{
- RelativeSizeAxes = Axes.X,
- Height = 1,
- Colour = OsuColour.Gray(80),
- Origin = Anchor.BottomLeft,
- Anchor = Anchor.BottomLeft,
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ Font = OsuFont.Default.With(size: 12),
},
- new GridContainer
+ }
+ },
+ new Box
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 1,
+ Colour = OsuColour.Gray(80),
+ },
+ new GridContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ ColumnDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(GridSizeMode.Absolute, OsuTabControl.HORIZONTAL_SPACING),
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, OsuTabControl.HORIZONTAL_SPACING),
+ new Dimension(GridSizeMode.AutoSize),
+ },
+ RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
+ Content = new[]
+ {
+ new[]
{
- Anchor = Anchor.BottomRight,
- Origin = Anchor.BottomRight,
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- ColumnDimensions = new[]
+ new OsuSpriteText
{
- new Dimension(GridSizeMode.AutoSize),
- new Dimension(GridSizeMode.Absolute, OsuTabControl.HORIZONTAL_SPACING),
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, OsuTabControl.HORIZONTAL_SPACING),
- new Dimension(GridSizeMode.AutoSize),
+ Text = SortStrings.Default,
+ Font = OsuFont.GetFont(size: 14),
+ Margin = new MarginPadding(5),
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
},
- RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
- Content = new[]
+ Empty(),
+ sortTabs = new OsuTabControl
{
- new[]
- {
- new OsuSpriteText
- {
- Text = SortStrings.Default,
- Font = OsuFont.GetFont(size: 14),
- Margin = new MarginPadding(5),
- Anchor = Anchor.BottomRight,
- Origin = Anchor.BottomRight,
- },
- Empty(),
- sortTabs = new OsuTabControl
- {
- RelativeSizeAxes = Axes.X,
- Height = 24,
- AutoSort = true,
- Anchor = Anchor.BottomRight,
- Origin = Anchor.BottomRight,
- AccentColour = colours.GreenLight,
- Current = { BindTarget = sortMode }
- },
- Empty(),
- new OsuTabControlCheckbox
- {
- Text = "Show converted",
- Current = config.GetBindable(OsuSetting.ShowConvertedBeatmaps),
- Anchor = Anchor.BottomRight,
- Origin = Anchor.BottomRight,
- },
- }
- }
- },
+ RelativeSizeAxes = Axes.X,
+ Height = 24,
+ AutoSort = true,
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
+ AccentColour = colours.GreenLight,
+ Current = { BindTarget = sortMode }
+ },
+ Empty(),
+ new OsuTabControlCheckbox
+ {
+ Text = "Show converted",
+ Current = config.GetBindable(OsuSetting.ShowConvertedBeatmaps),
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
+ },
+ }
}
},
new Container
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index 661eec8e97..9f8c3f1a2c 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -40,6 +40,7 @@ using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
+using osu.Game.Localisation;
namespace osu.Game.Screens.Select
{
@@ -162,6 +163,7 @@ namespace osu.Game.Screens.Select
BleedBottom = Footer.HEIGHT,
SelectionChanged = updateSelectedBeatmap,
BeatmapSetsChanged = carouselBeatmapsLoaded,
+ FilterApplied = () => FilterControl.InformationalText = SongSelectStrings.BeatmapsDisplayed(Carousel.CountDisplayed),
GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s),
}, c => carouselContainer.Child = c);
From 21bdbb20e6b362f96f53863614474dfae32f1726 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 7 Mar 2023 14:22:12 +0900
Subject: [PATCH 051/317] Add optional support for cyclic selection to
`BlueprintContainer`
---
.../SkinEditor/SkinBlueprintContainer.cs | 2 +
.../Compose/Components/BlueprintContainer.cs | 72 +++++++++++++++----
2 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs
index 3f8d9f80d4..db27e20010 100644
--- a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs
+++ b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs
@@ -25,6 +25,8 @@ namespace osu.Game.Overlays.SkinEditor
[Resolved]
private SkinEditor editor { get; set; } = null!;
+ protected override bool AllowCyclicSelection => true;
+
public SkinBlueprintContainer(ISerialisableDrawableContainer targetContainer)
{
this.targetContainer = targetContainer;
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index e4e67d10d7..87cee59d83 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -45,6 +45,15 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected readonly BindableList SelectedItems = new BindableList();
+ ///
+ /// Whether to allow cyclic selection on clicking multiple times.
+ ///
+ ///
+ /// Disabled by default as it does not work well with editors that support double-clicking or other advanced interactions.
+ /// Can probably be made to work with more thought.
+ ///
+ protected virtual bool AllowCyclicSelection => false;
+
protected BlueprintContainer()
{
RelativeSizeAxes = Axes.Both;
@@ -167,7 +176,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
Schedule(() =>
{
endClickSelection(e);
- clickSelectionBegan = false;
+ clickSelectionHandled = false;
isDraggingBlueprint = false;
});
@@ -339,7 +348,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
///
/// Whether a blueprint was selected by a previous click event.
///
- private bool clickSelectionBegan;
+ private bool clickSelectionHandled;
+
+ ///
+ /// Whether the selected blueprint(s) were already selected on mouse down. Generally used to perform selection cycling on mouse up in such a case.
+ ///
+ private bool selectedBlueprintAlreadySelectedOnMouseDown;
///
/// Attempts to select any hovered blueprints.
@@ -354,7 +368,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
if (!blueprint.IsHovered) continue;
- return clickSelectionBegan = SelectionHandler.MouseDownSelectionRequested(blueprint, e);
+ selectedBlueprintAlreadySelectedOnMouseDown = blueprint.State == SelectionState.Selected;
+ return clickSelectionHandled = SelectionHandler.MouseDownSelectionRequested(blueprint, e);
}
return false;
@@ -367,18 +382,45 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// Whether a click selection was active.
private bool endClickSelection(MouseButtonEvent e)
{
- if (!clickSelectionBegan && !isDraggingBlueprint)
+ if (!clickSelectionHandled && !isDraggingBlueprint)
{
- // if a selection didn't occur, we may want to trigger a deselection.
- if (e.ControlPressed && e.Button == MouseButton.Left)
+ if (e.Button == MouseButton.Left)
{
- // Iterate from the top of the input stack (blueprints closest to the front of the screen first).
- // Priority is given to already-selected blueprints.
- foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.Reverse().OrderByDescending(b => b.IsSelected))
+ if (e.ControlPressed)
{
- if (!blueprint.IsHovered) continue;
+ // if a selection didn't occur, we may want to trigger a deselection.
- return clickSelectionBegan = SelectionHandler.MouseUpSelectionRequested(blueprint, e);
+ // Iterate from the top of the input stack (blueprints closest to the front of the screen first).
+ // Priority is given to already-selected blueprints.
+ foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.OrderByDescending(b => b.IsSelected))
+ {
+ if (!blueprint.IsHovered) continue;
+
+ return clickSelectionHandled = SelectionHandler.MouseUpSelectionRequested(blueprint, e);
+ }
+ }
+ else if (selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection)
+ {
+ // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag,
+ // cycle between other blueprints which are also under the cursor.
+
+ // The depth of blueprints is constantly changing (see above where selected blueprints are brought to the front).
+ // For this logic, we want a stable sort order so we can correctly cycle, thus using the blueprintMap instead.
+ IEnumerable> cyclingSelectionBlueprints = blueprintMap.Values;
+
+ // If there's already a selection, let's start from the blueprint after the selection.
+ cyclingSelectionBlueprints = cyclingSelectionBlueprints.SkipWhile(b => !b.IsSelected).Skip(1);
+
+ // Add the blueprints from before the selection to the end of the enumerable to allow for cyclic selection.
+ cyclingSelectionBlueprints = cyclingSelectionBlueprints.Concat(blueprintMap.Values.TakeWhile(b => !b.IsSelected));
+
+ foreach (SelectionBlueprint blueprint in cyclingSelectionBlueprints)
+ {
+ if (!blueprint.IsHovered) continue;
+
+ // We are performing a mouse up, but selection handlers perform selection on mouse down, so we need to call that instead.
+ return clickSelectionHandled = SelectionHandler.MouseDownSelectionRequested(blueprint, e);
+ }
}
}
@@ -441,7 +483,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
private Vector2[][] movementBlueprintsOriginalPositions;
private SelectionBlueprint[] movementBlueprints;
- private bool isDraggingBlueprint;
+
+ ///
+ /// Whether a blueprint is currently being dragged.
+ ///
+ private bool isDraggingBlueprint { get; set; }
///
/// Attempts to begin the movement of any selected blueprints.
@@ -454,7 +500,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
// Any selected blueprint that is hovered can begin the movement of the group, however only the first item (according to SortForMovement) is used for movement.
// A special case is added for when a click selection occurred before the drag
- if (!clickSelectionBegan && !SelectionHandler.SelectedBlueprints.Any(b => b.IsHovered))
+ if (!clickSelectionHandled && !SelectionHandler.SelectedBlueprints.Any(b => b.IsHovered))
return false;
// Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item
From d2fcdf6e0e464ec389cff62ca715411402df6323 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 7 Mar 2023 14:22:19 +0900
Subject: [PATCH 052/317] Add test coverage of cyclic selection in skin editor
---
.../Visual/Gameplay/TestSceneSkinEditor.cs | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs
index 9690d00d4c..7af2b7d6fe 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs
@@ -17,6 +17,8 @@ using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Play.HUD.HitErrorMeters;
using osu.Game.Skinning;
+using osu.Game.Skinning.Components;
+using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
@@ -52,6 +54,44 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("wait for loaded", () => skinEditor.IsLoaded);
}
+ [Test]
+ public void TestCyclicSelection()
+ {
+ SkinBlueprint[] blueprints = null!;
+
+ AddStep("Add big black boxes", () =>
+ {
+ InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First());
+ InputManager.Click(MouseButton.Left);
+ InputManager.Click(MouseButton.Left);
+ InputManager.Click(MouseButton.Left);
+ });
+
+ AddAssert("Three black boxes added", () => targetContainer.Components.OfType().Count(), () => Is.EqualTo(3));
+
+ AddStep("Store black box blueprints", () =>
+ {
+ blueprints = skinEditor.ChildrenOfType