From 4d8f49b9bc5ab17cbe1eb70a41794227ddf856c1 Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 24 Jun 2019 23:17:07 +0200 Subject: [PATCH 01/24] update code to work with https://github.com/ppy/osu-framework/pull/2568 --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 7 ++++++- osu.Game/Graphics/UserInterface/OsuMenu.cs | 3 +++ osu.Game/Graphics/UserInterface/OsuTabControl.cs | 2 +- .../Overlays/Settings/Sections/General/LoginSettings.cs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 8245de9f70..2aa4734476 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; @@ -95,7 +96,11 @@ namespace osu.Game.Graphics.UserInterface } } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; + protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical); + + protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuScrollContainer(direction); + + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; #region DrawableOsuDropdownMenuItem diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index f8234cb81f..74ca809395 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; @@ -44,6 +45,8 @@ namespace osu.Game.Graphics.UserInterface } } + protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuScrollContainer(direction); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index fadc905541..11f41b1a48 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -210,7 +210,7 @@ namespace osu.Game.Graphics.UserInterface MaxHeight = 400; } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem { diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 1454b6592d..66fec1ecf9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -319,7 +319,7 @@ namespace osu.Game.Overlays.Settings.Sections.General BackgroundColour = colours.Gray3; } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem { From 7dd1479050e3ecd1b61b3476c5aae69a33b30b67 Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Wed, 26 Jun 2019 00:20:33 -0500 Subject: [PATCH 02/24] Add combobreak sound --- osu.Game/Screens/Play/Player.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c3e351a0ca..530145a604 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -66,6 +66,7 @@ namespace osu.Game.Screens.Play private IAPIProvider api; private SampleChannel sampleRestart; + private SampleChannel sampleComboBreak; protected ScoreProcessor ScoreProcessor { get; private set; } protected DrawableRuleset DrawableRuleset { get; private set; } @@ -80,6 +81,8 @@ namespace osu.Game.Screens.Play [Cached(Type = typeof(IBindable>))] protected new readonly Bindable> Mods = new Bindable>(Array.Empty()); + protected readonly BindableInt Combo = new BindableInt(); + private readonly bool allowPause; private readonly bool showResults; @@ -107,12 +110,15 @@ namespace osu.Game.Screens.Play return; sampleRestart = audio.Samples.Get(@"Gameplay/restart"); + sampleComboBreak = audio.Samples.Get(@"Gameplay/combobreak"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); + ScoreProcessor.Combo.BindTo(Combo); + Combo.BindValueChanged(onComboChange); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); @@ -264,6 +270,12 @@ namespace osu.Game.Screens.Play private ScheduledDelegate onCompletionEvent; + private void onComboChange(ValueChangedEvent combo) + { + if (combo.NewValue == 0 && combo.OldValue > 20) + sampleComboBreak?.Play(); + } + private void onCompletion() { // Only show the completion screen if the player hasn't failed From 826699a7e75d33527da0b723878a47fcabd26e7d Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Wed, 26 Jun 2019 12:16:44 -0500 Subject: [PATCH 03/24] Remove unneeded bindable --- osu.Game/Screens/Play/Player.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 530145a604..f620c790aa 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -81,8 +81,6 @@ namespace osu.Game.Screens.Play [Cached(Type = typeof(IBindable>))] protected new readonly Bindable> Mods = new Bindable>(Array.Empty()); - protected readonly BindableInt Combo = new BindableInt(); - private readonly bool allowPause; private readonly bool showResults; @@ -117,8 +115,7 @@ namespace osu.Game.Screens.Play ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); - ScoreProcessor.Combo.BindTo(Combo); - Combo.BindValueChanged(onComboChange); + ScoreProcessor.Combo.BindValueChanged(onComboChange); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); From f3aab143aa5b204c98d0e357acc8cb3d897bcd15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 13:16:16 +0900 Subject: [PATCH 04/24] Fix settings subpanels dimming main content --- osu.Game/Overlays/SettingsSubPanel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/SettingsSubPanel.cs b/osu.Game/Overlays/SettingsSubPanel.cs index 576be71ee6..7f794e2927 100644 --- a/osu.Game/Overlays/SettingsSubPanel.cs +++ b/osu.Game/Overlays/SettingsSubPanel.cs @@ -34,6 +34,8 @@ namespace osu.Game.Overlays }); } + protected override bool DimMainContent => false; // dimming is handled by main overlay + private class BackButton : OsuClickableContainer, IKeyBindingHandler { private AspectContainer aspect; From f6f547a91b4fa5bbe86c0392bbce9619d969b085 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 18:25:38 +0900 Subject: [PATCH 05/24] Fix ruleset selector line not moving on first display --- .../TestSceneToolbarRulesetSelector.cs | 55 ++++++++++++++++--- .../Toolbar/ToolbarRulesetSelector.cs | 17 ++++-- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs index 582303024b..0da256855a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -7,7 +7,10 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.MathUtils; +using osu.Game.Rulesets; namespace osu.Game.Tests.Visual.UserInterface { @@ -19,17 +22,24 @@ namespace osu.Game.Tests.Visual.UserInterface typeof(ToolbarRulesetTabButton), }; - public TestSceneToolbarRulesetSelector() - { - ToolbarRulesetSelector selector; + [Resolved] + private RulesetStore rulesets { get; set; } - Add(new Container + [Test] + public void TestDisplay() + { + ToolbarRulesetSelector selector = null; + + AddStep("create selector", () => { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.X, - Height = Toolbar.HEIGHT, - Child = selector = new ToolbarRulesetSelector() + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + Height = Toolbar.HEIGHT, + Child = selector = new ToolbarRulesetSelector() + }; }); AddStep("Select random", () => @@ -38,5 +48,32 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddStep("Toggle disabled state", () => selector.Current.Disabled = !selector.Current.Disabled); } + + [Test] + public void TestNonFirstRulesetInitialState() + { + TestSelector selector = null; + + AddStep("create selector", () => + { + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + Height = Toolbar.HEIGHT, + Child = selector = new TestSelector() + }; + + selector.Current.Value = rulesets.GetRuleset(2); + }); + + AddAssert("mode line has moved", () => selector.ModeButtonLine.DrawPosition.X > 0); + } + + private class TestSelector : ToolbarRulesetSelector + { + public new Drawable ModeButtonLine => base.ModeButtonLine; + } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 95d7d3f73a..f4272ab15c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Toolbar { private const float padding = 10; - private Drawable modeButtonLine; + protected Drawable ModeButtonLine { get; private set; } public ToolbarRulesetSelector() { @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Toolbar { Depth = 1, }, - modeButtonLine = new Container + ModeButtonLine = new Container { Size = new Vector2(padding * 2 + ToolbarButton.WIDTH, 3), Anchor = Anchor.BottomLeft, @@ -66,17 +66,22 @@ namespace osu.Game.Overlays.Toolbar Current.BindValueChanged(_ => moveLineToCurrent(), true); } - private void moveLineToCurrent() + private bool hasInitialPosition; + + // Scheduled to allow the flow layout to be computed before the line position is updated + private void moveLineToCurrent() => ScheduleAfterChildren(() => { - foreach (TabItem tabItem in TabContainer) + foreach (var tabItem in TabContainer) { if (tabItem.Value == Current.Value) { - modeButtonLine.MoveToX(tabItem.DrawPosition.X, 200, Easing.OutQuint); + ModeButtonLine.MoveToX(tabItem.DrawPosition.X, !hasInitialPosition ? 0 : 200, Easing.OutQuint); break; } } - } + + hasInitialPosition = true; + }); public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; From ba48331fcbdbb8159aa73915dcfca0eee5230b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 17:37:43 +0900 Subject: [PATCH 06/24] Remove no longer necessary HandleInput overrides --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 1cce5598e1..35c3a0e5e4 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -77,10 +77,6 @@ namespace osu.Game.Rulesets.Objects.Drawables private bool judgementOccurred; - public bool Interactive = true; - public override bool HandleNonPositionalInput => Interactive; - public override bool HandlePositionalInput => Interactive; - public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; From 72bb6f8c12c5361b1574406b1ae5a662728554b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 16:53:44 +0900 Subject: [PATCH 07/24] Fix download buttons not correctly finding existing downloads --- osu.Game/Database/DownloadableArchiveModelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 647eb3cbd3..2e7d70c941 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -20,7 +20,7 @@ namespace osu.Game.Database /// The model type. /// The associated file join type. public abstract class DownloadableArchiveModelManager : ArchiveModelManager, IModelDownloader - where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete + where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete, IEquatable where TFileModel : INamedFileInfo, new() { public event Action> DownloadBegan; From 61260cf599f07cbaaeaa7a2e03c744b8dcd8e5cf Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 27 Jun 2019 15:14:57 +0530 Subject: [PATCH 08/24] Hand off comparison logic for database query to implementors Equals overrides are not used in EF queries without running the comaprison locally instead of on the database, so to preserve that the comparison logic is instead implemented on a per manager basis. --- osu.Game/Beatmaps/BeatmapManager.cs | 2 ++ osu.Game/Database/DownloadableArchiveModelManager.cs | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index d5b19485de..fe8fef3e07 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -145,6 +145,8 @@ namespace osu.Game.Beatmaps void resetIds() => beatmapSet.Beatmaps.ForEach(b => b.OnlineBeatmapID = null); } + protected override bool CheckLocalAvailability(BeatmapSetInfo model, IQueryable items) => items.Any(b => b.OnlineBeatmapSetID == model.OnlineBeatmapSetID); + /// /// Delete a beatmap difficulty. /// diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 2e7d70c941..78c0837ce9 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -110,7 +110,15 @@ namespace osu.Game.Database return true; } - public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); + public bool IsAvailableLocally(TModel model) => CheckLocalAvailability(model, modelStore.ConsumableItems.Where(m => !m.DeletePending)); + + /// + /// Performs implementation specific comparisons to determine whether a given model is present in the local store. + /// + /// The whose existence needs to be checked. + /// The usable items present in the store. + /// Whether the exists. + protected abstract bool CheckLocalAvailability(TModel model, IQueryable items); public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Model.Equals(model)); From e7419f382e81444a44ccaec61c4b232de68ef430 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 27 Jun 2019 19:19:22 +0900 Subject: [PATCH 09/24] Fix TestSceneHyperDash in test browser --- osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 9cbff8c5d3..a603d96201 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Tests.Visual; @@ -17,8 +16,8 @@ namespace osu.Game.Rulesets.Catch.Tests { } - [BackgroundDependencyLoader] - private void load() + [Test] + public void TestHyperDash() { AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); } From 3cfa5a767f6daef49737d1f5c13ae64ffd9d543f Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 27 Jun 2019 17:31:21 +0530 Subject: [PATCH 10/24] Add test for download button states --- .../Online/TestSceneDirectDownloadButton.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs index ceb19a3ec6..5a5833feb6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs @@ -3,11 +3,15 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; +using osu.Game.Online; using osu.Game.Overlays.Direct; using osu.Game.Rulesets.Osu; +using osu.Game.Tests.Resources; using osuTK; namespace osu.Game.Tests.Visual.Online @@ -21,6 +25,9 @@ namespace osu.Game.Tests.Visual.Online private TestDownloadButton downloadButton; + [Resolved] + private BeatmapManager beatmaps { get; set; } + [Test] public void TestDownloadableBeatmap() { @@ -35,11 +42,66 @@ namespace osu.Game.Tests.Visual.Online assertEnabled(false); } + [Test] + public void TestDownloadState() + { + AddUntilStep("ensure manager loaded", () => beatmaps != null); + ensureSoleilyRemoved(); + createButtonWithBeatmap(createSoleily()); + AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded); + AddStep("import soleily", () => beatmaps.Import(new[] { TestResources.GetTestBeatmapForImport() })); + AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526)); + createButtonWithBeatmap(createSoleily()); + AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable); + ensureSoleilyRemoved(); + AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded); + } + + private void ensureSoleilyRemoved() + { + AddStep("remove soleily", () => + { + var beatmap = beatmaps.QueryBeatmapSet(b => b.OnlineBeatmapSetID == 241526); + + if (beatmap != null) beatmaps.Delete(beatmap); + }); + } + private void assertEnabled(bool enabled) { AddAssert($"button {(enabled ? "enabled" : "disabled")}", () => downloadButton.DownloadEnabled == enabled); } + private BeatmapSetInfo createSoleily() + { + return new BeatmapSetInfo + { + ID = 1, + OnlineBeatmapSetID = 241526, + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = false, + ExternalLink = string.Empty, + }, + }, + }; + } + + private void createButtonWithBeatmap(BeatmapSetInfo beatmap) + { + AddStep("create button", () => + { + Child = downloadButton = new TestDownloadButton(beatmap) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(75, 50), + }; + }); + } + private void createButton(bool downloadable) { AddStep("create button", () => @@ -85,6 +147,8 @@ namespace osu.Game.Tests.Visual.Online { public new bool DownloadEnabled => base.DownloadEnabled; + public DownloadState DownloadState => State.Value; + public TestDownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) : base(beatmapSet, noVideo) { From 6d0cc1f7706d3a720bda383e4071581ea51fc6ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 15:58:50 +0900 Subject: [PATCH 11/24] Remove GC debug setting --- .../Settings/Sections/Debug/GCSettings.cs | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs index 8ed196fd01..6897b42f4f 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Runtime; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -14,37 +12,17 @@ namespace osu.Game.Overlays.Settings.Sections.Debug { protected override string Header => "Garbage Collector"; - private readonly Bindable latencyMode = new Bindable(); - private Bindable configLatencyMode; - [BackgroundDependencyLoader] private void load(FrameworkDebugConfigManager config) { Children = new Drawable[] { - new SettingsEnumDropdown - { - LabelText = "Active mode", - Bindable = latencyMode - }, new SettingsButton { Text = "Force garbage collection", Action = GC.Collect }, }; - - configLatencyMode = config.GetBindable(DebugSetting.ActiveGCMode); - configLatencyMode.BindValueChanged(mode => latencyMode.Value = (LatencyMode)mode.NewValue, true); - latencyMode.BindValueChanged(mode => configLatencyMode.Value = (GCLatencyMode)mode.NewValue); - } - - private enum LatencyMode - { - Batch = GCLatencyMode.Batch, - Interactive = GCLatencyMode.Interactive, - LowLatency = GCLatencyMode.LowLatency, - SustainedLowLatency = GCLatencyMode.SustainedLowLatency } } } From c2f82f86d61051c76c82a3eb9d75ebef85c1ffad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 18:14:08 +0900 Subject: [PATCH 12/24] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b4af007447..9612ffb81a 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9f21af05a1..ce8b62cc3f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 02541ee6e59c8abb82d5e5df0201e2266cd265ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 19:57:23 +0900 Subject: [PATCH 13/24] Add missing info.plist identifier --- osu.iOS/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 0627feab78..d7992353cf 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -6,6 +6,8 @@ sh.ppy.osulazer CFBundleName osu! + CFBundleDisplayName + osu! CFBundleShortVersionString 0.1 CFBundleVersion From d5577371438ae1339b3d563c040c9a57e0e335e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 20:37:53 +0900 Subject: [PATCH 14/24] Fix windows updater showing false failures --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index e2c7a5e892..0819801f1d 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.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 System; @@ -46,7 +46,7 @@ namespace osu.Desktop.Updater private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) { //should we schedule a retry on completion of this check? - bool scheduleRetry = true; + bool scheduleRecheck = true; try { @@ -86,10 +86,12 @@ namespace osu.Desktop.Updater //could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959) //try again without deltas. checkForUpdateAsync(false, notification); - scheduleRetry = false; + scheduleRecheck = false; } else { + if (notification != null) + notification.State = ProgressNotificationState.Cancelled; Logger.Error(e, @"update failed!"); } } @@ -100,11 +102,8 @@ namespace osu.Desktop.Updater } finally { - if (scheduleRetry) + if (scheduleRecheck) { - if (notification != null) - notification.State = ProgressNotificationState.Cancelled; - //check again in 30 minutes. Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30); } From 1898a6750dccd647ae7576ab2766200ba540a30a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 20:45:25 +0900 Subject: [PATCH 15/24] Fix stutter during update process --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 0819801f1d..cc9cd2843a 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -133,8 +133,8 @@ namespace osu.Desktop.Updater Text = @"Update ready to install. Click to restart!", Activated = () => { - updateManager.PrepareUpdate(); - game.GracefullyExit(); + updateManager.PrepareUpdateAsync() + .ContinueWith(_ => Schedule(() => game.GracefullyExit())); return true; } }; From 1289b7f5fe1f24982efd454be008f9bb49cea112 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 21:03:35 +0900 Subject: [PATCH 16/24] Commit missing piece of puzzle --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index cc9cd2843a..7e7130d554 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -25,11 +25,7 @@ namespace osu.Desktop.Updater private UpdateManager updateManager; private NotificationOverlay notificationOverlay; - public void PrepareUpdate() - { - // Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here - UpdateManager.RestartAppWhenExited().Wait(); - } + public Task PrepareUpdate() => UpdateManager.RestartAppWhenExited(); [BackgroundDependencyLoader] private void load(NotificationOverlay notification, OsuGameBase game) From c9104e91766273aa5654649ace9354f5c7298d9b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 21:26:31 +0900 Subject: [PATCH 17/24] Fix remaining issues --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 7e7130d554..69064a40cb 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -25,7 +25,7 @@ namespace osu.Desktop.Updater private UpdateManager updateManager; private NotificationOverlay notificationOverlay; - public Task PrepareUpdate() => UpdateManager.RestartAppWhenExited(); + public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited(); [BackgroundDependencyLoader] private void load(NotificationOverlay notification, OsuGameBase game) @@ -86,8 +86,7 @@ namespace osu.Desktop.Updater } else { - if (notification != null) - notification.State = ProgressNotificationState.Cancelled; + notification.State = ProgressNotificationState.Cancelled; Logger.Error(e, @"update failed!"); } } @@ -130,7 +129,7 @@ namespace osu.Desktop.Updater Activated = () => { updateManager.PrepareUpdateAsync() - .ContinueWith(_ => Schedule(() => game.GracefullyExit())); + .ContinueWith(_ => Schedule(() => game.GracefullyExit())); return true; } }; From a57218e50ee3883d4fc938b87b7cbdf7f1998a2d Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Fri, 28 Jun 2019 20:45:11 -0500 Subject: [PATCH 18/24] Move to LocalSkinOverride --- .../Gameplay/TestSceneSkinReloadable.cs | 5 ++-- osu.Game/Screens/Play/Player.cs | 11 +------- .../Skinning/LocalSkinOverrideContainer.cs | 26 ++++++++++++++++++- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs index c7a0df6e9f..f03ffea5dc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs @@ -4,6 +4,7 @@ using System; using NUnit.Framework; using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -28,7 +29,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = new LocalSkinOverrideContainer(secondarySource) + Child = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) { RelativeSizeAxes = Axes.Both, Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true) @@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = target = new LocalSkinOverrideContainer(secondarySource) + Child = target = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f620c790aa..55d43bb4c8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -66,7 +66,6 @@ namespace osu.Game.Screens.Play private IAPIProvider api; private SampleChannel sampleRestart; - private SampleChannel sampleComboBreak; protected ScoreProcessor ScoreProcessor { get; private set; } protected DrawableRuleset DrawableRuleset { get; private set; } @@ -108,14 +107,12 @@ namespace osu.Game.Screens.Play return; sampleRestart = audio.Samples.Get(@"Gameplay/restart"); - sampleComboBreak = audio.Samples.Get(@"Gameplay/combobreak"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); - ScoreProcessor.Combo.BindValueChanged(onComboChange); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); @@ -127,7 +124,7 @@ namespace osu.Game.Screens.Play StoryboardContainer = CreateStoryboardContainer(), new ScalingContainer(ScalingMode.Gameplay) { - Child = new LocalSkinOverrideContainer(working.Skin) + Child = new LocalSkinOverrideContainer(working.Skin, ScoreProcessor.Combo) { RelativeSizeAxes = Axes.Both, Child = DrawableRuleset @@ -267,12 +264,6 @@ namespace osu.Game.Screens.Play private ScheduledDelegate onCompletionEvent; - private void onComboChange(ValueChangedEvent combo) - { - if (combo.NewValue == 0 && combo.OldValue > 20) - sampleComboBreak?.Play(); - } - private void onCompletion() { // Only show the completion screen if the player hasn't failed diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index f1ed14595e..a3606ef00c 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -23,11 +24,15 @@ namespace osu.Game.Skinning private readonly Bindable beatmapHitsounds = new Bindable(); private readonly ISkin skin; + + private readonly ComboEffects comboEffects; + private ISkinSource fallbackSource; - public LocalSkinOverrideContainer(ISkin skin) + public LocalSkinOverrideContainer(ISkin skin, BindableInt combo) { this.skin = skin; + comboEffects = new ComboEffects(combo); } public Drawable GetDrawableComponent(string componentName) @@ -87,6 +92,9 @@ namespace osu.Game.Skinning beatmapSkins.BindValueChanged(_ => onSourceChanged()); beatmapHitsounds.BindValueChanged(_ => onSourceChanged()); + AudioManager audio = dependencies.Get(); + comboEffects.SampleComboBreak = GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); + return dependencies; } @@ -100,5 +108,21 @@ namespace osu.Game.Skinning if (fallbackSource != null) fallbackSource.SourceChanged -= onSourceChanged; } + + private class ComboEffects + { + public SampleChannel SampleComboBreak; + + public ComboEffects(BindableInt combo) + { + combo.BindValueChanged(onComboChange); + } + + private void onComboChange(ValueChangedEvent combo) + { + if (combo.NewValue == 0 && combo.OldValue > 20) + SampleComboBreak?.Play(); + } + } } } From a22c166575f50867c3761739834c2a490d80863c Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Sat, 29 Jun 2019 11:28:40 -0500 Subject: [PATCH 19/24] Make ComboEffects its own class --- .../Gameplay/TestSceneSkinReloadable.cs | 5 ++- osu.Game/Screens/Play/ComboEffects.cs | 35 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 8 +++-- .../Skinning/LocalSkinOverrideContainer.cs | 25 +------------ 4 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 osu.Game/Screens/Play/ComboEffects.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs index f03ffea5dc..c7a0df6e9f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs @@ -4,7 +4,6 @@ using System; using NUnit.Framework; using osu.Framework.Audio.Sample; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) + Child = new LocalSkinOverrideContainer(secondarySource) { RelativeSizeAxes = Axes.Both, Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true) @@ -54,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = target = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) + Child = target = new LocalSkinOverrideContainer(secondarySource) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs new file mode 100644 index 0000000000..d752f4a556 --- /dev/null +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -0,0 +1,35 @@ +// 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.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Scoring; +using osu.Game.Skinning; + +namespace osu.Game.Screens.Play +{ + public class ComboEffects : CompositeDrawable + { + private SampleChannel sampleComboBreak; + + public ComboEffects(ScoreProcessor processor) + { + processor.Combo.BindValueChanged(onComboChange); + } + + private void onComboChange(ValueChangedEvent combo) + { + if (combo.NewValue == 0 && combo.OldValue > 20) + sampleComboBreak?.Play(); + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, AudioManager audio) + { + sampleComboBreak = skin.GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); + } + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 55d43bb4c8..7c4863fbf5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -124,10 +124,14 @@ namespace osu.Game.Screens.Play StoryboardContainer = CreateStoryboardContainer(), new ScalingContainer(ScalingMode.Gameplay) { - Child = new LocalSkinOverrideContainer(working.Skin, ScoreProcessor.Combo) + Child = new LocalSkinOverrideContainer(working.Skin) { RelativeSizeAxes = Axes.Both, - Child = DrawableRuleset + Children = new Drawable[] + { + DrawableRuleset, + new ComboEffects(ScoreProcessor) + } } }, new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index a3606ef00c..37f4cc28a2 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -25,14 +24,11 @@ namespace osu.Game.Skinning private readonly ISkin skin; - private readonly ComboEffects comboEffects; - private ISkinSource fallbackSource; - public LocalSkinOverrideContainer(ISkin skin, BindableInt combo) + public LocalSkinOverrideContainer(ISkin skin) { this.skin = skin; - comboEffects = new ComboEffects(combo); } public Drawable GetDrawableComponent(string componentName) @@ -92,9 +88,6 @@ namespace osu.Game.Skinning beatmapSkins.BindValueChanged(_ => onSourceChanged()); beatmapHitsounds.BindValueChanged(_ => onSourceChanged()); - AudioManager audio = dependencies.Get(); - comboEffects.SampleComboBreak = GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); - return dependencies; } @@ -108,21 +101,5 @@ namespace osu.Game.Skinning if (fallbackSource != null) fallbackSource.SourceChanged -= onSourceChanged; } - - private class ComboEffects - { - public SampleChannel SampleComboBreak; - - public ComboEffects(BindableInt combo) - { - combo.BindValueChanged(onComboChange); - } - - private void onComboChange(ValueChangedEvent combo) - { - if (combo.NewValue == 0 && combo.OldValue > 20) - SampleComboBreak?.Play(); - } - } } } From dbb1369eaffc650371d99af750e1eb566d44e91f Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Sat, 29 Jun 2019 11:54:02 -0500 Subject: [PATCH 20/24] Use resources build 627 --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9dd8c8572e..5f02a75470 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + From 5b26ef75b173da1c577fc35f6f48da33b4a3c95a Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 30 Jun 2019 12:31:31 +0200 Subject: [PATCH 21/24] allow exiting editor again --- osu.Game/Screens/Edit/Editor.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 660c1235d1..82d820c925 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -24,11 +24,13 @@ using osu.Game.Screens.Edit.Design; using osuTK.Input; using System.Collections.Generic; using osu.Framework; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; using osu.Game.Users; namespace osu.Game.Screens.Edit { - public class Editor : OsuScreen + public class Editor : OsuScreen, IKeyBindingHandler { protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); @@ -206,6 +208,19 @@ namespace osu.Game.Screens.Edit return true; } + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + this.Exit(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; + public override void OnResuming(IScreen last) { Beatmap.Value.Track?.Stop(); From fa879b4b60603c5c2124fddf2bc1985697dc73a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Jun 2019 20:46:51 +0900 Subject: [PATCH 22/24] Add a note explaining why manual handling is required --- osu.Game/Screens/Edit/Editor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 82d820c925..89da9ae063 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -212,6 +212,7 @@ namespace osu.Game.Screens.Edit { if (action == GlobalAction.Back) { + // as we don't want to display the back button, manual handling of exit action is required. this.Exit(); return true; } From 60ea3d4e1aeeed90a359ad4155f00c2bafc9c7b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Jun 2019 21:58:30 +0900 Subject: [PATCH 23/24] Fix skinning support for combobreak --- .../Objects/JuiceStream.cs | 4 +- .../Beatmaps/ManiaBeatmapConverter.cs | 2 +- .../Legacy/DistanceObjectPatternGenerator.cs | 6 +- .../Legacy/EndTimeObjectPatternGenerator.cs | 6 +- .../Legacy/HitObjectPatternGenerator.cs | 8 +-- .../TestSceneSlider.cs | 10 +-- osu.Game.Rulesets.Osu/Objects/Slider.cs | 10 +-- .../TestSceneInputDrum.cs | 2 +- .../Audio/DrumSampleMapping.cs | 6 +- .../Beatmaps/TaikoBeatmapConverter.cs | 14 ++-- .../Drawables/DrawableTaikoHitObject.cs | 2 +- .../Formats/LegacyBeatmapDecoderTest.cs | 38 +++++----- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 4 +- osu.Game/Audio/HitSampleInfo.cs | 70 +++++++++++++++++++ osu.Game/Audio/ISampleInfo.cs | 17 +++++ osu.Game/Audio/SampleInfo.cs | 65 +++-------------- .../ControlPoints/SampleControlPoint.cs | 18 ++--- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 +- .../Objects/Drawables/DrawableHitObject.cs | 4 +- osu.Game/Rulesets/Objects/HitObject.cs | 6 +- .../Legacy/Catch/ConvertHitObjectParser.cs | 2 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 32 ++++----- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Legacy/Mania/ConvertHitObjectParser.cs | 2 +- .../Legacy/Osu/ConvertHitObjectParser.cs | 2 +- .../Legacy/Taiko/ConvertHitObjectParser.cs | 2 +- .../Rulesets/Objects/Types/IHasRepeats.cs | 2 +- osu.Game/Screens/Play/ComboEffects.cs | 31 ++++---- osu.Game/Skinning/SkinnableSound.cs | 16 +++-- 29 files changed, 222 insertions(+), 165 deletions(-) create mode 100644 osu.Game/Audio/HitSampleInfo.cs create mode 100644 osu.Game/Audio/ISampleInfo.cs diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index a9fd34455a..0952e8981a 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Objects { base.CreateNestedHitObjects(); - var tickSamples = Samples.Select(s => new SampleInfo + var tickSamples = Samples.Select(s => new HitSampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Catch.Objects public double Distance => Path.Distance; - public List> NodeSamples { get; set; } = new List>(); + public List> NodeSamples { get; set; } = new List>(); public double? LegacyLastTickOffset { get; set; } } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 704deba78b..e10602312e 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -255,7 +255,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// /// The time to retrieve the sample info list from. /// - private List sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 1b6ff16388..ea418eedb4 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH; + bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH; bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability); canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample); @@ -443,7 +443,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy noteCount = 0; noteCount = Math.Min(TotalColumns - 1, noteCount); - bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP); + bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == HitSampleInfo.HIT_WHISTLE || s.Name == HitSampleInfo.HIT_FINISH || s.Name == HitSampleInfo.HIT_CLAP); var rowPattern = new Pattern(); @@ -472,7 +472,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// The time to retrieve the sample info list from. /// - private List sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 9e95be35fa..b3be08e1f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy switch (TotalColumns) { - case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000: + case 8 when HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000: addToPattern(pattern, 0, generateHold); break; @@ -72,9 +72,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy }; if (hold.Head.Samples == null) - hold.Head.Samples = new List(); + hold.Head.Samples = new List(); - hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL }); + hold.Head.Samples.Add(new HitSampleInfo { Name = HitSampleInfo.HIT_NORMAL }); hold.Tail.Samples = HitObject.Samples; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index d13b21183b..decd159ee9 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (!convertType.HasFlag(PatternType.KeepSingle)) { - if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8) + if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && TotalColumns != 8) convertType |= PatternType.Mirror; - else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) + else if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)) convertType |= PatternType.Gathered; } } @@ -263,7 +263,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// Whether this hit object can generate a note in the special column. /// - private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH); + private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH); /// /// Generates a random pattern. @@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) + if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)) p2 = 1; return GetRandomNoteCount(p2, p3, p4, p5); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index 1ba6d107be..c5a27205d6 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -248,9 +248,9 @@ namespace osu.Game.Rulesets.Osu.Tests private void createCatmull(int repeats = 0) { - var repeatSamples = new List>(); + var repeatSamples = new List>(); for (int i = 0; i < repeats; i++) - repeatSamples.Add(new List()); + repeatSamples.Add(new List()); var slider = new Slider { @@ -270,11 +270,11 @@ namespace osu.Game.Rulesets.Osu.Tests addSlider(slider, 3, 1); } - private List> createEmptySamples(int repeats) + private List> createEmptySamples(int repeats) { - var repeatSamples = new List>(); + var repeatSamples = new List>(); for (int i = 0; i < repeats; i++) - repeatSamples.Add(new List()); + repeatSamples.Add(new List()); return repeatSamples; } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index a8aec005d1..a4638c31f2 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// internal float LazyTravelDistance; - public List> NodeSamples { get; set; } = new List>(); + public List> NodeSamples { get; set; } = new List>(); private int repeatCount; @@ -157,12 +157,12 @@ namespace osu.Game.Rulesets.Osu.Objects foreach (var e in SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset)) { - var firstSample = Samples.Find(s => s.Name == SampleInfo.HIT_NORMAL) + var firstSample = Samples.Find(s => s.Name == HitSampleInfo.HIT_NORMAL) ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933) - var sampleList = new List(); + var sampleList = new List(); if (firstSample != null) - sampleList.Add(new SampleInfo + sampleList.Add(new HitSampleInfo { Bank = firstSample.Bank, Volume = firstSample.Volume, @@ -225,7 +225,7 @@ namespace osu.Game.Rulesets.Osu.Objects } } - private List getNodeSamples(int nodeIndex) => + private List getNodeSamples(int nodeIndex) => nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples; public override Judgement CreateJudgement() => new OsuJudgement(); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs index 02300a5dde..8c1b0c4c62 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Taiko.Tests { typeof(InputDrum), typeof(DrumSampleMapping), - typeof(SampleInfo), + typeof(HitSampleInfo), typeof(SampleControlPoint) }; diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs index d7fa661e8a..ad2596931d 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Audio foreach (var s in samplePoints) { var centre = s.GetSampleInfo(); - var rim = s.GetSampleInfo(SampleInfo.HIT_CLAP); + var rim = s.GetSampleInfo(HitSampleInfo.HIT_CLAP); // todo: this is ugly centre.Namespace = "taiko"; @@ -43,9 +43,9 @@ namespace osu.Game.Rulesets.Taiko.Audio } } - private SkinnableSound addSound(SampleInfo sampleInfo) + private SkinnableSound addSound(HitSampleInfo hitSampleInfo) { - var drawable = new SkinnableSound(sampleInfo); + var drawable = new SkinnableSound(hitSampleInfo); Sounds.Add(drawable); return drawable; } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index f8672037cd..f0cf8d9c7d 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps var curveData = obj as IHasCurve; // Old osu! used hit sounding to determine various hit type information - List samples = obj.Samples; + List samples = obj.Samples; - bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH); + bool strong = samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH); if (distanceData != null) { @@ -117,15 +117,15 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { - List> allSamples = curveData != null ? curveData.NodeSamples : new List>(new[] { samples }); + List> allSamples = curveData != null ? curveData.NodeSamples : new List>(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) { - List currentSamples = allSamples[i]; - bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); - strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH); + List currentSamples = allSamples[i]; + bool isRim = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE); + strong = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_FINISH); if (isRim) { @@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps } else { - bool isRim = samples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); + bool isRim = samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE); if (isRim) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 119940536e..bd45b52d7b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } // Normal and clap samples are handled by the drum - protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != SampleInfo.HIT_NORMAL && s.Name != SampleInfo.HIT_CLAP); + protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP); protected override string SampleNamespace => "Taiko"; diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 5fd5fe342d..d087251e7e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -354,14 +354,14 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsNotNull(curveData); Assert.AreEqual(new Vector2(192, 168), positionData.Position); Assert.AreEqual(956, hitObjects[0].StartTime); - Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL)); + Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL)); positionData = hitObjects[1] as IHasPosition; Assert.IsNotNull(positionData); Assert.AreEqual(new Vector2(304, 56), positionData.Position); Assert.AreEqual(1285, hitObjects[1].StartTime); - Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)); + Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)); } } @@ -384,7 +384,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("soft-hitnormal8", getTestableSampleInfo(hitObjects[4]).LookupNames.First()); } - SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } [Test] @@ -402,7 +402,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("normal-hitnormal3", getTestableSampleInfo(hitObjects[2]).LookupNames.First()); } - SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } [Test] @@ -422,7 +422,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(70, getTestableSampleInfo(hitObjects[3]).Volume); } - SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } [Test] @@ -438,34 +438,34 @@ namespace osu.Game.Tests.Beatmaps.Formats var slider1 = (ConvertSlider)hitObjects[0]; Assert.AreEqual(1, slider1.NodeSamples[0].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name); Assert.AreEqual(1, slider1.NodeSamples[1].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name); Assert.AreEqual(1, slider1.NodeSamples[2].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name); var slider2 = (ConvertSlider)hitObjects[1]; Assert.AreEqual(2, slider2.NodeSamples[0].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name); Assert.AreEqual(2, slider2.NodeSamples[1].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name); Assert.AreEqual(2, slider2.NodeSamples[2].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name); var slider3 = (ConvertSlider)hitObjects[2]; Assert.AreEqual(2, slider3.NodeSamples[0].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name); - Assert.AreEqual(SampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name); Assert.AreEqual(1, slider3.NodeSamples[1].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name); Assert.AreEqual(2, slider3.NodeSamples[2].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 39b7735a55..a725c58462 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -101,14 +101,14 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsNotNull(curveData); Assert.AreEqual(new Vector2(192, 168), positionData.Position); Assert.AreEqual(956, beatmap.HitObjects[0].StartTime); - Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL)); + Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL)); positionData = beatmap.HitObjects[1] as IHasPosition; Assert.IsNotNull(positionData); Assert.AreEqual(new Vector2(304, 56), positionData.Position); Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime); - Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)); + Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)); } [TestCase(normal)] diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs new file mode 100644 index 0000000000..23a74d3fa6 --- /dev/null +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -0,0 +1,70 @@ +// 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; + +namespace osu.Game.Audio +{ + /// + /// Describes a gameplay hit sample. + /// + [Serializable] + public class HitSampleInfo : ISampleInfo + { + public const string HIT_WHISTLE = @"hitwhistle"; + public const string HIT_FINISH = @"hitfinish"; + public const string HIT_NORMAL = @"hitnormal"; + public const string HIT_CLAP = @"hitclap"; + + /// + /// An optional ruleset namespace. + /// + public string Namespace; + + /// + /// The bank to load the sample from. + /// + public string Bank; + + /// + /// The name of the sample to load. + /// + public string Name; + + /// + /// An optional suffix to provide priority lookup. Falls back to non-suffixed . + /// + public string Suffix; + + /// + /// The sample volume. + /// + public int Volume { get; set; } + + /// + /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). + /// + public virtual IEnumerable LookupNames + { + get + { + if (!string.IsNullOrEmpty(Namespace)) + { + if (!string.IsNullOrEmpty(Suffix)) + yield return $"{Namespace}/{Bank}-{Name}{Suffix}"; + + yield return $"{Namespace}/{Bank}-{Name}"; + } + + // check non-namespace as a fallback even when we have a namespace + if (!string.IsNullOrEmpty(Suffix)) + yield return $"{Bank}-{Name}{Suffix}"; + + yield return $"{Bank}-{Name}"; + } + } + + public HitSampleInfo Clone() => (HitSampleInfo)MemberwiseClone(); + } +} diff --git a/osu.Game/Audio/ISampleInfo.cs b/osu.Game/Audio/ISampleInfo.cs new file mode 100644 index 0000000000..4f81d37e78 --- /dev/null +++ b/osu.Game/Audio/ISampleInfo.cs @@ -0,0 +1,17 @@ +// 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; + +namespace osu.Game.Audio +{ + public interface ISampleInfo + { + /// + /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). + /// + IEnumerable LookupNames { get; } + + int Volume { get; } + } +} diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 5bc6dce60b..66c07209f3 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -1,67 +1,24 @@ -// 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 System; using System.Collections.Generic; namespace osu.Game.Audio { - [Serializable] - public class SampleInfo + /// + /// Describes a gameplay sample. + /// + public class SampleInfo : ISampleInfo { - public const string HIT_WHISTLE = @"hitwhistle"; - public const string HIT_FINISH = @"hitfinish"; - public const string HIT_NORMAL = @"hitnormal"; - public const string HIT_CLAP = @"hitclap"; + private readonly string sampleName; - /// - /// An optional ruleset namespace. - /// - public string Namespace; - - /// - /// The bank to load the sample from. - /// - public string Bank; - - /// - /// The name of the sample to load. - /// - public string Name; - - /// - /// An optional suffix to provide priority lookup. Falls back to non-suffixed . - /// - public string Suffix; - - /// - /// The sample volume. - /// - public int Volume; - - /// - /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). - /// - public virtual IEnumerable LookupNames + public SampleInfo(string sampleName) { - get - { - if (!string.IsNullOrEmpty(Namespace)) - { - if (!string.IsNullOrEmpty(Suffix)) - yield return $"{Namespace}/{Bank}-{Name}{Suffix}"; - - yield return $"{Namespace}/{Bank}-{Name}"; - } - - // check non-namespace as a fallback even when we have a namespace - if (!string.IsNullOrEmpty(Suffix)) - yield return $"{Bank}-{Name}{Suffix}"; - - yield return $"{Bank}-{Name}"; - } + this.sampleName = sampleName; } - public SampleInfo Clone() => (SampleInfo)MemberwiseClone(); + public IEnumerable LookupNames => new[] { sampleName }; + + public int Volume { get; set; } = 100; } } diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 4c45bef862..7bc7a9056d 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -24,8 +24,8 @@ namespace osu.Game.Beatmaps.ControlPoints /// Create a SampleInfo based on the sample settings in this control point. /// /// The name of the same. - /// A populated . - public SampleInfo GetSampleInfo(string sampleName = SampleInfo.HIT_NORMAL) => new SampleInfo + /// A populated . + public HitSampleInfo GetSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) => new HitSampleInfo { Bank = SampleBank, Name = sampleName, @@ -33,15 +33,15 @@ namespace osu.Game.Beatmaps.ControlPoints }; /// - /// Applies and to a if necessary, returning the modified . + /// Applies and to a if necessary, returning the modified . /// - /// The . This will not be modified. - /// The modified . This does not share a reference with . - public virtual SampleInfo ApplyTo(SampleInfo sampleInfo) + /// The . This will not be modified. + /// The modified . This does not share a reference with . + public virtual HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo) { - var newSampleInfo = sampleInfo.Clone(); - newSampleInfo.Bank = sampleInfo.Bank ?? SampleBank; - newSampleInfo.Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume; + var newSampleInfo = hitSampleInfo.Clone(); + newSampleInfo.Bank = hitSampleInfo.Bank ?? SampleBank; + newSampleInfo.Volume = hitSampleInfo.Volume > 0 ? hitSampleInfo.Volume : SampleVolume; return newSampleInfo; } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 7b7e0e7101..7999c82761 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -193,9 +193,9 @@ namespace osu.Game.Beatmaps.Formats { public int CustomSampleBank; - public override SampleInfo ApplyTo(SampleInfo sampleInfo) + public override HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo) { - var baseInfo = base.ApplyTo(sampleInfo); + var baseInfo = base.ApplyTo(hitSampleInfo); if (string.IsNullOrEmpty(baseInfo.Suffix) && CustomSampleBank > 1) baseInfo.Suffix = CustomSampleBank.ToString(); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 35c3a0e5e4..1f6ca4dd73 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Objects.Drawables protected SkinnableSound Samples; - protected virtual IEnumerable GetSamples() => HitObject.Samples; + protected virtual IEnumerable GetSamples() => HitObject.Samples; private readonly Lazy> nestedHitObjects = new Lazy>(); public IEnumerable NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : Enumerable.Empty(); @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Objects.Drawables var samples = GetSamples().ToArray(); - if (samples.Any()) + if (samples.Length > 0) { if (HitObject.SampleControlPoint == null) throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index cede2e50d0..bf04963b76 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Objects /// public virtual double StartTime { get; set; } - private List samples; + private List samples; /// /// The samples to be played when this hit object is hit. @@ -38,9 +38,9 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public List Samples + public List Samples { - get => samples ?? (samples = new List()); + get => samples ?? (samples = new List()); set => samples = value; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs index 48f637dfe8..6e79d0b766 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { newCombo |= forceNewCombo; comboOffset += extraComboOffset; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index c14f3b6a42..f5b1cbcebf 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -180,7 +180,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } // Generate the final per-node samples - var nodeSamples = new List>(nodes); + var nodeSamples = new List>(nodes); for (int i = 0; i < nodes; i++) nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); @@ -291,7 +291,7 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The slider repeat count. /// The samples to be played when the slider nodes are hit. This includes the head and tail of the slider. /// The hit object. - protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples); + protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples); /// /// Creates a legacy Spinner-type hit object. @@ -312,14 +312,14 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The hold end time. protected abstract HitObject CreateHold(Vector2 position, bool newCombo, int comboOffset, double endTime); - private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) + private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) { // Todo: This should return the normal SampleInfos if the specified sample file isn't found, but that's a pretty edge-case scenario if (!string.IsNullOrEmpty(bankInfo.Filename)) { - return new List + return new List { - new FileSampleInfo + new FileHitSampleInfo { Filename = bankInfo.Filename, Volume = bankInfo.Volume @@ -327,12 +327,12 @@ namespace osu.Game.Rulesets.Objects.Legacy }; } - var soundTypes = new List + var soundTypes = new List { - new LegacySampleInfo + new LegacyHitSampleInfo { Bank = bankInfo.Normal, - Name = SampleInfo.HIT_NORMAL, + Name = HitSampleInfo.HIT_NORMAL, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank } @@ -340,10 +340,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (type.HasFlag(LegacySoundType.Finish)) { - soundTypes.Add(new LegacySampleInfo + soundTypes.Add(new LegacyHitSampleInfo { Bank = bankInfo.Add, - Name = SampleInfo.HIT_FINISH, + Name = HitSampleInfo.HIT_FINISH, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank }); @@ -351,10 +351,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (type.HasFlag(LegacySoundType.Whistle)) { - soundTypes.Add(new LegacySampleInfo + soundTypes.Add(new LegacyHitSampleInfo { Bank = bankInfo.Add, - Name = SampleInfo.HIT_WHISTLE, + Name = HitSampleInfo.HIT_WHISTLE, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank }); @@ -362,10 +362,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (type.HasFlag(LegacySoundType.Clap)) { - soundTypes.Add(new LegacySampleInfo + soundTypes.Add(new LegacyHitSampleInfo { Bank = bankInfo.Add, - Name = SampleInfo.HIT_CLAP, + Name = HitSampleInfo.HIT_CLAP, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank }); @@ -387,7 +387,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone(); } - private class LegacySampleInfo : SampleInfo + private class LegacyHitSampleInfo : HitSampleInfo { public int CustomSampleBank { @@ -399,7 +399,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } } - private class FileSampleInfo : SampleInfo + private class FileHitSampleInfo : HitSampleInfo { public string Filename; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index bb1a5e200d..ff6b9be8b5 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Distance => Path.Distance; - public List> NodeSamples { get; set; } + public List> NodeSamples { get; set; } public int RepeatCount { get; set; } public double EndTime => StartTime + this.SpanCount() * Distance / Velocity; diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs index 8a3e232e60..b20a027e78 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs index b98de32bd0..0a4e38df02 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { newCombo |= forceNewCombo; comboOffset += extraComboOffset; diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs index bab21b31ad..7c1514c1eb 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko return new ConvertHit(); } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index 8be95c063d..697adeda98 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Objects.Types /// n-1: The last repeat.
/// n: The last node. ///
- List> NodeSamples { get; } + List> NodeSamples { get; } } public static class HasRepeatsExtensions diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs index d752f4a556..1c4ac921f0 100644 --- a/osu.Game/Screens/Play/ComboEffects.cs +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -2,10 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; +using osu.Game.Audio; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; @@ -13,23 +12,31 @@ namespace osu.Game.Screens.Play { public class ComboEffects : CompositeDrawable { - private SampleChannel sampleComboBreak; + private readonly ScoreProcessor processor; + + private SkinnableSound comboBreakSample; public ComboEffects(ScoreProcessor processor) { - processor.Combo.BindValueChanged(onComboChange); + this.processor = processor; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = comboBreakSample = new SkinnableSound(new SampleInfo("combobreak")); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + processor.Combo.BindValueChanged(onComboChange, true); } private void onComboChange(ValueChangedEvent combo) { if (combo.NewValue == 0 && combo.OldValue > 20) - sampleComboBreak?.Play(); - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, AudioManager audio) - { - sampleComboBreak = skin.GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); + comboBreakSample?.Play(); } } -} \ No newline at end of file +} diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index e88e088f5e..8e2b5cec98 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -2,6 +2,7 @@ // 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.Audio; @@ -13,14 +14,19 @@ namespace osu.Game.Skinning { public class SkinnableSound : SkinReloadableDrawable { - private readonly SampleInfo[] samples; + private readonly ISampleInfo[] hitSamples; private SampleChannel[] channels; private AudioManager audio; - public SkinnableSound(params SampleInfo[] samples) + public SkinnableSound(IEnumerable hitSamples) { - this.samples = samples; + this.hitSamples = hitSamples.ToArray(); + } + + public SkinnableSound(ISampleInfo hitSamples) + { + this.hitSamples = new[] { hitSamples }; } [BackgroundDependencyLoader] @@ -35,7 +41,7 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - channels = samples.Select(s => + channels = hitSamples.Select(s => { var ch = loadChannel(s, skin.GetSample); if (ch == null && allowFallback) @@ -44,7 +50,7 @@ namespace osu.Game.Skinning }).Where(c => c != null).ToArray(); } - private SampleChannel loadChannel(SampleInfo info, Func getSampleFunction) + private SampleChannel loadChannel(ISampleInfo info, Func getSampleFunction) { foreach (var lookup in info.LookupNames) { From 489ca7b45786c762b1fea01cdfa60fb5b3e3b40b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Jun 2019 22:26:49 +0900 Subject: [PATCH 24/24] Update resources in ios props --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index ce8b62cc3f..a8013914af 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - +