From 3795411fd13cb9c6ae64d840dfdcdbfcd2914244 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Fri, 12 Jan 2018 23:33:24 +0300 Subject: [PATCH 01/83] Do not assign hudOverlay's and breakOverlay's members in Player class --- .../Play/BreaksOverlay/BreakOverlay.cs | 7 +++++- osu.Game/Screens/Play/HUDOverlay.cs | 20 ++++++++++++++--- osu.Game/Screens/Play/Player.cs | 22 ++++--------------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 735c81aedf..7a510aa738 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -41,6 +41,11 @@ namespace osu.Game.Screens.Play.BreaksOverlay private readonly InfoContainer info; private readonly ArrowsOverlay arrowsOverlay; + public BreakOverlay(bool letterboxing, ScoreProcessor scoreProcessor) : this(letterboxing) + { + bindProcessor(scoreProcessor); + } + public BreakOverlay(bool letterboxing) { this.letterboxing = letterboxing; @@ -148,7 +153,7 @@ namespace osu.Game.Screens.Play.BreaksOverlay arrowsOverlay.Hide(); } - public void BindProcessor(ScoreProcessor processor) + private void bindProcessor(ScoreProcessor processor) { info.AccuracyDisplay.Current.BindTo(processor.Accuracy); info.GradeDisplay.Current.BindTo(processor.Rank); diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 721b5344ff..92a0f2ee98 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -6,6 +6,8 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using osu.Framework.Timing; +using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -39,7 +41,7 @@ namespace osu.Game.Screens.Play private static bool hasShownNotificationOnce; - public HUDOverlay() + public HUDOverlay(ScoreProcessor scoreProcessor, RulesetContainer rulesetContainer, DecoupleableInterpolatingFramedClock decoupledClock, WorkingBeatmap working, IAdjustableClock adjustableSourceClock) { RelativeSizeAxes = Axes.Both; @@ -59,6 +61,18 @@ namespace osu.Game.Screens.Play ReplaySettingsOverlay = CreateReplaySettingsOverlay(), } }); + + BindProcessor(scoreProcessor); + BindRulesetContainer(rulesetContainer); + + Progress.Objects = rulesetContainer.Objects; + Progress.AudioClock = decoupledClock; + Progress.AllowSeeking = rulesetContainer.HasReplayLoaded; + Progress.OnSeek = pos => decoupledClock.Seek(pos); + + ModDisplay.Current.BindTo(working.Mods); + + ReplaySettingsOverlay.PlaybackSettings.AdjustableClock = adjustableSourceClock; } [BackgroundDependencyLoader(true)] @@ -91,7 +105,7 @@ namespace osu.Game.Screens.Play } } - public virtual void BindRulesetContainer(RulesetContainer rulesetContainer) + protected virtual void BindRulesetContainer(RulesetContainer rulesetContainer) { (rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter); @@ -184,7 +198,7 @@ namespace osu.Game.Screens.Play protected virtual ReplaySettingsOverlay CreateReplaySettingsOverlay() => new ReplaySettingsOverlay(); - public virtual void BindProcessor(ScoreProcessor processor) + protected virtual void BindProcessor(ScoreProcessor processor) { ScoreCounter?.Current.BindTo(processor.TotalScore); AccuracyCounter?.Current.BindTo(processor.Accuracy); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fc8b0f2c88..58f33fd8db 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -152,6 +152,8 @@ namespace osu.Game.Screens.Play userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); + scoreProcessor = RulesetContainer.CreateScoreProcessor(); + Children = new Drawable[] { storyboardContainer = new Container @@ -183,12 +185,12 @@ namespace osu.Game.Screens.Play Clock = offsetClock, Child = RulesetContainer, }, - hudOverlay = new HUDOverlay + hudOverlay = new HUDOverlay(scoreProcessor, RulesetContainer, decoupledClock, working, adjustableSourceClock) { Anchor = Anchor.Centre, Origin = Anchor.Centre }, - breakOverlay = new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks) + breakOverlay = new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, scoreProcessor) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -213,25 +215,9 @@ namespace osu.Game.Screens.Play } }; - scoreProcessor = RulesetContainer.CreateScoreProcessor(); - if (showStoryboard) initializeStoryboard(false); - hudOverlay.BindProcessor(scoreProcessor); - hudOverlay.BindRulesetContainer(RulesetContainer); - - hudOverlay.Progress.Objects = RulesetContainer.Objects; - hudOverlay.Progress.AudioClock = decoupledClock; - hudOverlay.Progress.AllowSeeking = RulesetContainer.HasReplayLoaded; - hudOverlay.Progress.OnSeek = pos => decoupledClock.Seek(pos); - - hudOverlay.ModDisplay.Current.BindTo(working.Mods); - - breakOverlay.BindProcessor(scoreProcessor); - - hudOverlay.ReplaySettingsOverlay.PlaybackSettings.AdjustableClock = adjustableSourceClock; - // Bind ScoreProcessor to ourselves scoreProcessor.AllJudged += onCompletion; scoreProcessor.Failed += onFail; From 0c4fcdf6d80cad8da7f019715744d537989e84fa Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Fri, 12 Jan 2018 23:59:36 +0300 Subject: [PATCH 02/83] Remove not used breakOverlay field --- osu.Game/Screens/Play/Player.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 58f33fd8db..980d9a6101 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -76,7 +76,6 @@ namespace osu.Game.Screens.Play #endregion - private BreakOverlay breakOverlay; private Container storyboardContainer; private DrawableStoryboard storyboard; @@ -190,7 +189,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, - breakOverlay = new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, scoreProcessor) + new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, scoreProcessor) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From 9277586907600f6ae9ace884fea751d431359bbf Mon Sep 17 00:00:00 2001 From: aQaTL Date: Tue, 16 Jan 2018 17:46:54 +0100 Subject: [PATCH 03/83] Toggle mute/unmute keyboard shortcut --- .../UserInterface/Volume/VolumeControl.cs | 4 ++++ .../Graphics/UserInterface/Volume/VolumeMeter.cs | 16 +++++++++++++++- .../Bindings/GlobalKeyBindingInputManager.cs | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 33888e57e0..63b14713e2 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -76,6 +76,10 @@ namespace osu.Game.Graphics.UserInterface.Volume else volumeMeterMaster.Increase(); return true; + case GlobalAction.ToggleMute: + Show(); + volumeMeterMaster.ToogleMute(); + return true; } return false; diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index 8323dade44..dc1b2e85eb 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -18,6 +18,9 @@ namespace osu.Game.Graphics.UserInterface.Volume private readonly Box meterFill; public BindableDouble Bindable { get; } = new BindableDouble(); + private double lastVolume; + public bool IsMuted { get; private set; } + public VolumeMeter(string meterName) { Size = new Vector2(40, 180); @@ -70,16 +73,19 @@ namespace osu.Game.Graphics.UserInterface.Volume public double Volume { - get { return Bindable.Value; } + get => Bindable.Value; private set { Bindable.Value = value; + if (value > 0) + IsMuted = false; } } public void Increase() { Volume += 0.05f; + IsMuted = false; } public void Decrease() @@ -87,6 +93,14 @@ namespace osu.Game.Graphics.UserInterface.Volume Volume -= 0.05f; } + public void ToogleMute() + { + IsMuted = !IsMuted; + if (IsMuted) + lastVolume = Volume; + Volume = IsMuted ? 0.0 : lastVolume; + } + private void updateFill() => meterFill.ScaleTo(new Vector2(1, (float)Volume), 300, Easing.OutQuint); public bool OnPressed(GlobalAction action) diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index f5e54775fb..6c317890af 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -33,6 +33,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.MouseWheelUp }, GlobalAction.IncreaseVolume), new KeyBinding(new[] { InputKey.Down }, GlobalAction.DecreaseVolume), new KeyBinding(new[] { InputKey.MouseWheelDown }, GlobalAction.DecreaseVolume), + new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), }; public IEnumerable InGameKeyBindings => new[] @@ -62,6 +63,8 @@ namespace osu.Game.Input.Bindings IncreaseVolume, [Description("Decrease Volume")] DecreaseVolume, + [Description("Toggle mute")] + ToggleMute, // In-Game Keybindings [Description("Skip Cutscene")] From 0340e4f8dcccbf6f5d09189f95aea5543bdca92a Mon Sep 17 00:00:00 2001 From: aQaTL Date: Tue, 16 Jan 2018 20:33:30 +0100 Subject: [PATCH 04/83] Option in settings to toggle mute/unmute when losing/gaining window focus --- osu.Game/Configuration/OsuConfigManager.cs | 3 +++ .../UserInterface/Volume/VolumeControl.cs | 18 ++++++++++++++ osu.Game/OsuGame.cs | 24 +++++++++++++++++++ .../Settings/Sections/Audio/VolumeSettings.cs | 4 +++- 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 23f7fd6ac1..0c90b2c2ec 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -39,6 +39,8 @@ namespace osu.Game.Configuration }; // Audio + Set(OsuSetting.MuteWhenInactive, false); + Set(OsuSetting.MenuVoice, true); Set(OsuSetting.MenuMusic, true); @@ -101,6 +103,7 @@ namespace osu.Game.Configuration MouseDisableButtons, MouseDisableWheel, AudioOffset, + MuteWhenInactive, MenuMusic, MenuVoice, CursorRotation, diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 63b14713e2..7a1a2de50d 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -91,6 +91,24 @@ namespace osu.Game.Graphics.UserInterface.Volume schedulePopOut(); } + public bool IsMuted => volumeMeterMaster.IsMuted; + + public void Mute() + { + if (!IsMuted) + { + volumeMeterMaster.ToogleMute(); + } + } + + public void Unmute() + { + if (IsMuted) + { + volumeMeterMaster.ToogleMute(); + } + } + [BackgroundDependencyLoader] private void load(AudioManager audio) { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 124b9364b3..56cfffdeae 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -115,6 +115,8 @@ namespace osu.Game configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; + + muteWhenInactive = LocalConfig.GetBindable(OsuSetting.MuteWhenInactive); } private ScheduledDelegate scoreLoad; @@ -386,6 +388,28 @@ namespace osu.Game return false; } + private Bindable muteWhenInactive = new Bindable(); + private bool wasMuted; + + protected override void OnDeactivated() + { + base.OnDeactivated(); + if (muteWhenInactive) + { + wasMuted = volume.IsMuted; + volume.Mute(); + } + } + + protected override void OnActivated() + { + base.OnActivated(); + if (IsLoaded && muteWhenInactive && !wasMuted) + { + volume.Unmute(); + } + } + public bool OnReleased(GlobalAction action) => false; private Container mainContent; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index 40b9ff069b..01bcf989dc 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; +using osu.Game.Configuration; namespace osu.Game.Overlays.Settings.Sections.Audio { @@ -12,13 +13,14 @@ namespace osu.Game.Overlays.Settings.Sections.Audio protected override string Header => "Volume"; [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(AudioManager audio, OsuConfigManager config) { Children = new Drawable[] { new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.1f }, new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.1f }, new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.1f }, + new SettingsCheckbox { LabelText = "Mute osu! when inactive", Bindable = config.GetBindable(OsuSetting.MuteWhenInactive) } }; } } From 538c20a947d0e231ff9b84ba9ce36bac78c52c70 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Tue, 16 Jan 2018 21:30:48 +0100 Subject: [PATCH 05/83] Prevent not saving audio levels when user alt tabs before the window closes --- osu.Game/OsuGame.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 56cfffdeae..de923b3451 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -79,6 +79,8 @@ namespace osu.Game private SettingsOverlay settings; + private bool exiting; + public OsuGame(string[] args = null) { this.args = args; @@ -117,6 +119,13 @@ namespace osu.Game Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; muteWhenInactive = LocalConfig.GetBindable(OsuSetting.MuteWhenInactive); + Host.Window.Exited += () => + { + //Prevent not saving audio levels when user alt tabs before the window closes + if (volume.IsMuted) + volume.Unmute(); + exiting = true; + }; } private ScheduledDelegate scoreLoad; @@ -394,7 +403,7 @@ namespace osu.Game protected override void OnDeactivated() { base.OnDeactivated(); - if (muteWhenInactive) + if (muteWhenInactive && !exiting) { wasMuted = volume.IsMuted; volume.Mute(); @@ -404,7 +413,7 @@ namespace osu.Game protected override void OnActivated() { base.OnActivated(); - if (IsLoaded && muteWhenInactive && !wasMuted) + if (IsLoaded && muteWhenInactive && !wasMuted && !exiting) { volume.Unmute(); } From 0b7e1ce667dae810a2fc9d7e2d1ad3b3ada05007 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Jan 2018 19:45:18 +0900 Subject: [PATCH 06/83] Add a way to have ruleset-specific configs --- .../Configuration/IRulesetConfigManager.cs | 9 +++++++ .../Configuration/RulesetConfigManager.cs | 24 +++++++++++++++++++ osu.Game/Rulesets/Ruleset.cs | 6 +++++ osu.Game/Screens/Play/Player.cs | 12 +++++++++- osu.Game/osu.Game.csproj | 2 ++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs create mode 100644 osu.Game/Rulesets/Configuration/RulesetConfigManager.cs diff --git a/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs new file mode 100644 index 0000000000..08fb6f53d6 --- /dev/null +++ b/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs @@ -0,0 +1,9 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Configuration +{ + public interface IRulesetConfigManager + { + } +} diff --git a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs new file mode 100644 index 0000000000..633d8f3951 --- /dev/null +++ b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Platform; + +namespace osu.Game.Rulesets.Configuration +{ + public abstract class RulesetConfigManager : ConfigManager, IRulesetConfigManager + where T : struct + { + protected override string Filename => ruleset?.ShortName; + private readonly Ruleset ruleset; + + protected RulesetConfigManager(Ruleset ruleset, Storage storage) + : base(storage) + { + this.ruleset = ruleset; + + // Re-load with the ruleset + Load(); + } + } +} diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 4f256621fb..c1aba5b403 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -9,6 +9,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -89,6 +90,11 @@ namespace osu.Game.Rulesets /// A descriptive name of the variant. public virtual string GetVariantName(int variant) => string.Empty; + /// + /// The that is used for settings specific to this . + /// + public virtual IRulesetConfigManager CreateConfigManager() => null; + /// /// Create a ruleset info based on this ruleset. /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 31d9fac2ad..b78f92f6b7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,6 +24,7 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Cursor; +using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; @@ -88,8 +89,13 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, APIAccess api) + private void load(AudioManager audio, OsuConfigManager config, APIAccess api, Storage storage) { this.api = api; @@ -129,6 +135,10 @@ namespace osu.Game.Screens.Play if (!RulesetContainer.Objects.Any()) throw new InvalidOperationException("Beatmap contains no hit objects!"); + + var rulesetConfig = rulesetInstance.CreateConfigManager(); + if (rulesetConfig != null) + dependencies.Cache(rulesetConfig); } catch (Exception e) { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 85da54e317..05728c2b41 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -314,6 +314,8 @@ + + From 9f4ebad6e3c05f25aced5dc2d20538e92466903f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Jan 2018 20:10:35 +0900 Subject: [PATCH 07/83] Add mania config manager --- .../Configuration/ManiaConfigManager.cs | 21 +++++++++++++++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 5 +++++ .../osu.Game.Rulesets.Mania.csproj | 1 + osu.Game/Rulesets/Ruleset.cs | 3 ++- 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs new file mode 100644 index 0000000000..aa288818c5 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Platform; +using osu.Game.Rulesets.Configuration; + +namespace osu.Game.Rulesets.Mania.Configuration +{ + public class ManiaConfigManager : RulesetConfigManager + { + public ManiaConfigManager(Ruleset ruleset, Storage storage) + : base(ruleset, storage) + { + } + } + + public enum ManiaSetting + { + ScrollSpeed + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index e8b9828bff..2709683eb4 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -9,7 +9,10 @@ using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; +using osu.Framework.Platform; using osu.Game.Graphics; +using osu.Game.Rulesets.Configuration; +using osu.Game.Rulesets.Mania.Configuration; namespace osu.Game.Rulesets.Mania { @@ -154,5 +157,7 @@ namespace osu.Game.Rulesets.Mania } public override string GetVariantName(int variant) => $"{variant}K"; + + public override IRulesetConfigManager CreateConfigManager(Storage storage) => new ManiaConfigManager(this, storage); } } diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 39f8333413..3c4e843dff 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -58,6 +58,7 @@ + diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index c1aba5b403..e736e0ac27 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; +using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Settings; @@ -93,7 +94,7 @@ namespace osu.Game.Rulesets /// /// The that is used for settings specific to this . /// - public virtual IRulesetConfigManager CreateConfigManager() => null; + public virtual IRulesetConfigManager CreateConfigManager(Storage storage) => null; /// /// Create a ruleset info based on this ruleset. From 92da02db8731b2b9eeb699481503c1a3c652903a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Jan 2018 21:07:37 +0900 Subject: [PATCH 08/83] Add extension to filename --- osu.Game/Rulesets/Configuration/RulesetConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs index 633d8f3951..9106485253 100644 --- a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Configuration public abstract class RulesetConfigManager : ConfigManager, IRulesetConfigManager where T : struct { - protected override string Filename => ruleset?.ShortName; + protected override string Filename => ruleset?.ShortName == null ? null : $"{ruleset.ShortName}.ini"; private readonly Ruleset ruleset; protected RulesetConfigManager(Ruleset ruleset, Storage storage) From d96234bf4063117ed10e391a7d4bbb98a25cd916 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Jan 2018 21:08:23 +0900 Subject: [PATCH 09/83] Enforce that there's only one configmanager per ruleset --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 10 +++++++++- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 2709683eb4..9519de8b53 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -158,6 +158,6 @@ namespace osu.Game.Rulesets.Mania public override string GetVariantName(int variant) => $"{variant}K"; - public override IRulesetConfigManager CreateConfigManager(Storage storage) => new ManiaConfigManager(this, storage); + protected override IRulesetConfigManager CreateConfigManager(Storage storage) => new ManiaConfigManager(this, storage); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index e736e0ac27..faadbd24f7 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -91,10 +91,18 @@ namespace osu.Game.Rulesets /// A descriptive name of the variant. public virtual string GetVariantName(int variant) => string.Empty; + private static readonly Dictionary config_manager_cache = new Dictionary(); + public IRulesetConfigManager GetConfigManager(Storage storage) + { + if (config_manager_cache.TryGetValue(GetType(), out var existing)) + return existing; + return config_manager_cache[GetType()] = CreateConfigManager(storage); + } + /// /// The that is used for settings specific to this . /// - public virtual IRulesetConfigManager CreateConfigManager(Storage storage) => null; + protected virtual IRulesetConfigManager CreateConfigManager(Storage storage) => null; /// /// Create a ruleset info based on this ruleset. diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index b78f92f6b7..0ad2a4a78d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -136,7 +136,7 @@ namespace osu.Game.Screens.Play if (!RulesetContainer.Objects.Any()) throw new InvalidOperationException("Beatmap contains no hit objects!"); - var rulesetConfig = rulesetInstance.CreateConfigManager(); + var rulesetConfig = rulesetInstance.GetConfigManager(storage); if (rulesetConfig != null) dependencies.Cache(rulesetConfig); } From db27faa4717b0a4e142b09e5c608bd063add07f4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Jan 2018 21:13:14 +0900 Subject: [PATCH 10/83] Add a ScrollTime config setting to osu!mania --- .../Configuration/ManiaConfigManager.cs | 9 ++++++++- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs index aa288818c5..4972e3092a 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs @@ -12,10 +12,17 @@ namespace osu.Game.Rulesets.Mania.Configuration : base(ruleset, storage) { } + + protected override void InitialiseDefaults() + { + base.InitialiseDefaults(); + + Set(ManiaSetting.ScrollTime, 1500.0, 50.0, 10000.0, 50.0); + } } public enum ManiaSetting { - ScrollSpeed + ScrollTime } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 7d3df6cda7..868f4b143c 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI @@ -161,8 +162,10 @@ namespace osu.Game.Rulesets.Mania.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, ManiaConfigManager maniaConfig) { + maniaConfig.BindWith(ManiaSetting.ScrollTime, VisibleTimeRange); + normalColumnColours = new List { colours.RedDark, From ac41cb59eabaed0034fa34ab6a5a0a5938673cb1 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 17 Jan 2018 14:36:33 +0100 Subject: [PATCH 11/83] Typo fix, removed unnecessary braces --- .../Graphics/UserInterface/Volume/VolumeControl.cs | 10 +++------- osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 7a1a2de50d..04c48c629d 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -78,7 +78,7 @@ namespace osu.Game.Graphics.UserInterface.Volume return true; case GlobalAction.ToggleMute: Show(); - volumeMeterMaster.ToogleMute(); + volumeMeterMaster.ToggleMute(); return true; } @@ -96,17 +96,13 @@ namespace osu.Game.Graphics.UserInterface.Volume public void Mute() { if (!IsMuted) - { - volumeMeterMaster.ToogleMute(); - } + volumeMeterMaster.ToggleMute(); } public void Unmute() { if (IsMuted) - { - volumeMeterMaster.ToogleMute(); - } + volumeMeterMaster.ToggleMute(); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index dc1b2e85eb..aac969b84f 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface.Volume Volume -= 0.05f; } - public void ToogleMute() + public void ToggleMute() { IsMuted = !IsMuted; if (IsMuted) From 1440edbf8b14bf3577461247f51758abf72ab92e Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 17 Jan 2018 17:15:13 +0100 Subject: [PATCH 12/83] Use AudioManager adjustments to mute volume --- .../UserInterface/Volume/VolumeControl.cs | 28 ++++++++++++++----- .../UserInterface/Volume/VolumeMeter.cs | 17 +---------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 04c48c629d..d5645d6f24 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -7,12 +7,15 @@ using osu.Framework.Threading; using OpenTK; using osu.Framework.Audio; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface.Volume { public class VolumeControl : OverlayContainer { + private AudioManager audio; + private readonly VolumeMeter volumeMeterMaster; protected override bool BlockPassThroughMouse => false; @@ -77,8 +80,10 @@ namespace osu.Game.Graphics.UserInterface.Volume volumeMeterMaster.Increase(); return true; case GlobalAction.ToggleMute: - Show(); - volumeMeterMaster.ToggleMute(); + if (IsMuted) + Unmute(); + else + Mute(); return true; } @@ -91,23 +96,32 @@ namespace osu.Game.Graphics.UserInterface.Volume schedulePopOut(); } - public bool IsMuted => volumeMeterMaster.IsMuted; + private readonly BindableDouble muteBindable = new BindableDouble(); + + public bool IsMuted { get; private set; } public void Mute() { - if (!IsMuted) - volumeMeterMaster.ToggleMute(); + if (IsMuted) + return; + + audio.AddAdjustment(AdjustableProperty.Volume, muteBindable); + IsMuted = true; } public void Unmute() { - if (IsMuted) - volumeMeterMaster.ToggleMute(); + if (!IsMuted) + return; + + audio.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); + IsMuted = false; } [BackgroundDependencyLoader] private void load(AudioManager audio) { + this.audio = audio; volumeMeterMaster.Bindable.BindTo(audio.Volume); volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index aac969b84f..a1acb5d2ff 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -19,7 +19,6 @@ namespace osu.Game.Graphics.UserInterface.Volume public BindableDouble Bindable { get; } = new BindableDouble(); private double lastVolume; - public bool IsMuted { get; private set; } public VolumeMeter(string meterName) { @@ -74,18 +73,12 @@ namespace osu.Game.Graphics.UserInterface.Volume public double Volume { get => Bindable.Value; - private set - { - Bindable.Value = value; - if (value > 0) - IsMuted = false; - } + private set => Bindable.Value = value; } public void Increase() { Volume += 0.05f; - IsMuted = false; } public void Decrease() @@ -93,14 +86,6 @@ namespace osu.Game.Graphics.UserInterface.Volume Volume -= 0.05f; } - public void ToggleMute() - { - IsMuted = !IsMuted; - if (IsMuted) - lastVolume = Volume; - Volume = IsMuted ? 0.0 : lastVolume; - } - private void updateFill() => meterFill.ScaleTo(new Vector2(1, (float)Volume), 300, Easing.OutQuint); public bool OnPressed(GlobalAction action) From a8fb732256d35c18c99cbf902d8b5fe8efe453de Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 17 Jan 2018 20:43:08 +0100 Subject: [PATCH 13/83] Added muted/unmuted icon --- .../UserInterface/Volume/VolumeControl.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index d5645d6f24..2d350a3474 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -17,6 +17,7 @@ namespace osu.Game.Graphics.UserInterface.Volume private AudioManager audio; private readonly VolumeMeter volumeMeterMaster; + private readonly IconButton muteIcon; protected override bool BlockPassThroughMouse => false; @@ -37,12 +38,23 @@ namespace osu.Game.Graphics.UserInterface.Volume Spacing = new Vector2(15, 0), Children = new Drawable[] { + muteIcon = new IconButton(), volumeMeterMaster = new VolumeMeter("Master"), volumeMeterEffect = new VolumeMeter("Effects"), volumeMeterMusic = new VolumeMeter("Music") } } }; + + muteIcon.Icon = FontAwesome.fa_volume_up; + muteIcon.Scale = new Vector2(2.0f); + muteIcon.Action = () => + { + if (IsMuted) + Unmute(); + else + Mute(); + }; } protected override void LoadComplete() @@ -80,6 +92,8 @@ namespace osu.Game.Graphics.UserInterface.Volume volumeMeterMaster.Increase(); return true; case GlobalAction.ToggleMute: + if (State == Visibility.Hidden) + Show(); if (IsMuted) Unmute(); else @@ -107,6 +121,7 @@ namespace osu.Game.Graphics.UserInterface.Volume audio.AddAdjustment(AdjustableProperty.Volume, muteBindable); IsMuted = true; + muteIcon.Icon = FontAwesome.fa_volume_off; } public void Unmute() @@ -116,6 +131,7 @@ namespace osu.Game.Graphics.UserInterface.Volume audio.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); IsMuted = false; + muteIcon.Icon = FontAwesome.fa_volume_up; } [BackgroundDependencyLoader] From 8471a579e056db875a198921ba3dab1042c4cae0 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 17 Jan 2018 20:56:44 +0100 Subject: [PATCH 14/83] Removed no longer neccessary "exiting" flag --- osu.Game/OsuGame.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index de923b3451..56cfffdeae 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -79,8 +79,6 @@ namespace osu.Game private SettingsOverlay settings; - private bool exiting; - public OsuGame(string[] args = null) { this.args = args; @@ -119,13 +117,6 @@ namespace osu.Game Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; muteWhenInactive = LocalConfig.GetBindable(OsuSetting.MuteWhenInactive); - Host.Window.Exited += () => - { - //Prevent not saving audio levels when user alt tabs before the window closes - if (volume.IsMuted) - volume.Unmute(); - exiting = true; - }; } private ScheduledDelegate scoreLoad; @@ -403,7 +394,7 @@ namespace osu.Game protected override void OnDeactivated() { base.OnDeactivated(); - if (muteWhenInactive && !exiting) + if (muteWhenInactive) { wasMuted = volume.IsMuted; volume.Mute(); @@ -413,7 +404,7 @@ namespace osu.Game protected override void OnActivated() { base.OnActivated(); - if (IsLoaded && muteWhenInactive && !wasMuted && !exiting) + if (IsLoaded && muteWhenInactive && !wasMuted) { volume.Unmute(); } From 18ff57fdf9589a8d2cfffa943ae7bd4fb1733960 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 17 Jan 2018 21:09:46 +0100 Subject: [PATCH 15/83] Inline changing mute icon properties with object creation --- .../UserInterface/Volume/VolumeControl.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 2d350a3474..2f565eba22 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -38,23 +38,24 @@ namespace osu.Game.Graphics.UserInterface.Volume Spacing = new Vector2(15, 0), Children = new Drawable[] { - muteIcon = new IconButton(), + muteIcon = new IconButton + { + Icon = FontAwesome.fa_volume_up, + Scale = new Vector2(2.0f), + Action = () => + { + if (IsMuted) + Unmute(); + else + Mute(); + }, + }, volumeMeterMaster = new VolumeMeter("Master"), volumeMeterEffect = new VolumeMeter("Effects"), volumeMeterMusic = new VolumeMeter("Music") } } }; - - muteIcon.Icon = FontAwesome.fa_volume_up; - muteIcon.Scale = new Vector2(2.0f); - muteIcon.Action = () => - { - if (IsMuted) - Unmute(); - else - Mute(); - }; } protected override void LoadComplete() From 9c09b33e4e75b49090fa7bf0679865c19cbcac02 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 17 Jan 2018 23:17:59 +0100 Subject: [PATCH 16/83] Removed no longer used "lastVolume" field --- osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index a1acb5d2ff..ef3702fdf3 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -18,8 +18,6 @@ namespace osu.Game.Graphics.UserInterface.Volume private readonly Box meterFill; public BindableDouble Bindable { get; } = new BindableDouble(); - private double lastVolume; - public VolumeMeter(string meterName) { Size = new Vector2(40, 180); From 09dfea7e29bffd26a98c4c9457dd45655a0eabfe Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 18 Jan 2018 15:26:03 +0900 Subject: [PATCH 17/83] Use tracked settings from ConfigManager changes --- osu-framework | 2 +- osu.Game/Overlays/OnScreenDisplay.cs | 72 +++++++++++++++------------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/osu-framework b/osu-framework index 8f36ddab94..c0c21831ce 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 8f36ddab946ff538620081ede7719461d4732b79 +Subproject commit c0c21831cef6b2946c5b067f5c4bbd929e89c2ec diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 65803b477b..354c29531d 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -118,43 +117,50 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) { - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.FrameSync), v => display(v, "Frame Limiter", v.GetDescription(), "Ctrl+F7")); - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.AudioDevice), v => display(v, "Audio Device", string.IsNullOrEmpty(v) ? "Default" : v, v)); - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay), v => display(v, "Debug Logs", v ? "visible" : "hidden", "Ctrl+F10")); - - void displayResolution() => display(null, "Screen Resolution", frameworkConfig.Get(FrameworkSetting.Width) + "x" + frameworkConfig.Get(FrameworkSetting.Height)); - - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Width), v => displayResolution()); - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Height), v => displayResolution()); - - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity), v => display(v, "Cursor Sensitivity", v.ToString(@"0.##x"), "Ctrl+Alt+R to reset")); - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.ActiveInputHandlers), - delegate (string v) - { - bool raw = v.Contains("Raw"); - display(raw, "Raw Input", raw ? "enabled" : "disabled", "Ctrl+Alt+R to reset"); - }); - - trackSetting(frameworkConfig.GetBindable(FrameworkSetting.WindowMode), v => display(v, "Screen Mode", v.ToString(), "Alt+Enter")); + Register(frameworkConfig); } - private readonly List references = new List(); + private readonly Dictionary trackedConfigManagers = new Dictionary(); - private void trackSetting(Bindable bindable, Action action) + public void Register(ConfigManager configManager) + where T : struct { - // we need to keep references as we bind - references.Add(bindable); + if (configManager == null) throw new ArgumentNullException(nameof(configManager)); - bindable.ValueChanged += action; + if (trackedConfigManagers.ContainsKey(configManager)) + throw new InvalidOperationException($"{nameof(configManager)} is already registered."); + + var trackedSettings = configManager.CreateTrackedSettings(); + if (trackedSettings == null) + return; + + trackedSettings.LoadFrom(configManager); + trackedSettings.SettingChanged += display; + + trackedConfigManagers.Add(configManager, trackedSettings); } - private void display(object rawValue, string settingName, string settingValue, string shortcut = @"") + public void Unregister(ConfigManager configManager) + where T : struct + { + if (configManager == null) throw new ArgumentNullException(nameof(configManager)); + + if (!trackedConfigManagers.TryGetValue(configManager, out var existing)) + return; + + existing.Unload(); + existing.SettingChanged -= display; + + trackedConfigManagers.Remove(configManager); + } + + private void display(SettingDescription description) { Schedule(() => { - textLine1.Text = settingName.ToUpper(); - textLine2.Text = settingValue; - textLine3.Text = shortcut.ToUpper(); + textLine1.Text = description.Name.ToUpper(); + textLine2.Text = description.Value; + textLine3.Text = description.Shortcut.ToUpper(); box.Animate( b => b.FadeIn(500, Easing.OutQuint), @@ -167,16 +173,16 @@ namespace osu.Game.Overlays int optionCount = 0; int selectedOption = -1; - if (rawValue is bool) + if (description.RawValue is bool) { optionCount = 1; - if ((bool)rawValue) selectedOption = 0; + if ((bool)description.RawValue) selectedOption = 0; } - else if (rawValue is Enum) + else if (description.RawValue is Enum) { - var values = Enum.GetValues(rawValue.GetType()); + var values = Enum.GetValues(description.RawValue.GetType()); optionCount = values.Length; - selectedOption = Convert.ToInt32(rawValue); + selectedOption = Convert.ToInt32(description.RawValue); } textLine2.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; From c2c478750d0a48a84a79c1b9ad81a60ce1824ba9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 18 Jan 2018 16:57:32 +0900 Subject: [PATCH 18/83] Remove generics from OSD registration methods --- osu.Game/Overlays/OnScreenDisplay.cs | 14 +++++++------- .../Configuration/IRulesetConfigManager.cs | 5 ++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 354c29531d..cc47f3bfa0 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Configuration.Tracking; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -120,28 +121,27 @@ namespace osu.Game.Overlays Register(frameworkConfig); } - private readonly Dictionary trackedConfigManagers = new Dictionary(); + private readonly Dictionary trackedConfigManagers = new Dictionary(); - public void Register(ConfigManager configManager) - where T : struct + public void Register(ITrackableConfigManager configManager) { if (configManager == null) throw new ArgumentNullException(nameof(configManager)); if (trackedConfigManagers.ContainsKey(configManager)) - throw new InvalidOperationException($"{nameof(configManager)} is already registered."); + return; var trackedSettings = configManager.CreateTrackedSettings(); if (trackedSettings == null) return; - trackedSettings.LoadFrom(configManager); + configManager.LoadInto(trackedSettings); + trackedSettings.SettingChanged += display; trackedConfigManagers.Add(configManager, trackedSettings); } - public void Unregister(ConfigManager configManager) - where T : struct + public void Unregister(ITrackableConfigManager configManager) { if (configManager == null) throw new ArgumentNullException(nameof(configManager)); diff --git a/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs index 08fb6f53d6..8d386242a9 100644 --- a/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs @@ -1,9 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; +using osu.Framework.Configuration.Tracking; + namespace osu.Game.Rulesets.Configuration { - public interface IRulesetConfigManager + public interface IRulesetConfigManager : ITrackableConfigManager, IConfigManager { } } From 7910b47868657dacbf90eacddc01d334a424bae1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 18 Jan 2018 17:00:23 +0900 Subject: [PATCH 19/83] Move ConfigManager registration/dependency injection to RulesetContainer --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 5 --- .../UI/ManiaRulesetContainer.cs | 5 +++ osu.Game/OsuGame.cs | 4 +- osu.Game/Rulesets/Ruleset.cs | 15 -------- osu.Game/Rulesets/UI/RulesetContainer.cs | 38 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 12 +----- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 9519de8b53..e8b9828bff 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -9,10 +9,7 @@ using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; -using osu.Framework.Platform; using osu.Game.Graphics; -using osu.Game.Rulesets.Configuration; -using osu.Game.Rulesets.Mania.Configuration; namespace osu.Game.Rulesets.Mania { @@ -157,7 +154,5 @@ namespace osu.Game.Rulesets.Mania } public override string GetVariantName(int variant) => $"{variant}K"; - - protected override IRulesetConfigManager CreateConfigManager(Storage storage) => new ManiaConfigManager(this, storage); } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 5bb980adb2..1ffdb55136 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -9,9 +9,12 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.MathUtils; +using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Replays; @@ -98,5 +101,7 @@ namespace osu.Game.Rulesets.Mania.UI protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(1, 0.8f); protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this); + + protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, Storage storage) => new ManiaConfigManager(ruleset, storage); } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b48e25f1fe..b090cc7927 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -71,6 +71,7 @@ namespace osu.Game private OsuScreen screenStack; private VolumeControl volume; + private OnScreenDisplay onscreenDisplay; private Bindable configRuleset; public Bindable Ruleset = new Bindable(); @@ -195,7 +196,7 @@ namespace osu.Game }, overlayContent.Add); loadComponentSingleFile(volume = new VolumeControl(), Add); - loadComponentSingleFile(new OnScreenDisplay(), Add); + loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); //overlay elements loadComponentSingleFile(direct = new DirectOverlay { Depth = -1 }, mainContent.Add); @@ -232,6 +233,7 @@ namespace osu.Game forwardLoggedErrorsToNotifications(); dependencies.Cache(settings); + dependencies.Cache(onscreenDisplay); dependencies.Cache(social); dependencies.Cache(direct); dependencies.Cache(chat); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index faadbd24f7..4f256621fb 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -6,11 +6,9 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; -using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Settings; -using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -91,19 +89,6 @@ namespace osu.Game.Rulesets /// A descriptive name of the variant. public virtual string GetVariantName(int variant) => string.Empty; - private static readonly Dictionary config_manager_cache = new Dictionary(); - public IRulesetConfigManager GetConfigManager(Storage storage) - { - if (config_manager_cache.TryGetValue(GetType(), out var existing)) - return existing; - return config_manager_cache[GetType()] = CreateConfigManager(storage); - } - - /// - /// The that is used for settings specific to this . - /// - protected virtual IRulesetConfigManager CreateConfigManager(Storage storage) => null; - /// /// Create a ruleset info based on this ruleset. /// diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 626b56ad67..5d1c57a7a5 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -15,6 +15,9 @@ using System.Diagnostics; using System.Linq; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; +using osu.Framework.Platform; +using osu.Game.Overlays; +using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using OpenTK; @@ -64,6 +67,13 @@ namespace osu.Game.Rulesets.UI protected readonly Ruleset Ruleset; + private IRulesetConfigManager rulesetConfig; + + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + /// /// A visual representation of a . /// @@ -76,6 +86,26 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } + [BackgroundDependencyLoader] + private void load(Storage storage, OnScreenDisplay onScreenDisplay) + { + rulesetConfig = getConfig(storage); + + if (rulesetConfig != null) + { + dependencies.Cache(rulesetConfig); + onScreenDisplay?.Register(rulesetConfig); + } + } + + private static readonly Dictionary config_cache = new Dictionary(); + private IRulesetConfigManager getConfig(Storage storage) + { + if (config_cache.TryGetValue(GetType(), out var existing)) + return existing; + return config_cache[GetType()] = CreateConfig(Ruleset, storage); + } + public abstract ScoreProcessor CreateScoreProcessor(); /// @@ -107,11 +137,19 @@ namespace osu.Game.Rulesets.UI /// protected virtual CursorContainer CreateCursor() => null; + protected virtual IRulesetConfigManager CreateConfig(Ruleset ruleset, Storage storage) => null; + /// /// Creates a Playfield. /// /// The Playfield. protected abstract Playfield CreatePlayfield(); + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + rulesetConfig.Save(); + } } /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0ad2a4a78d..31d9fac2ad 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,7 +24,6 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Cursor; -using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; @@ -89,13 +88,8 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, APIAccess api, Storage storage) + private void load(AudioManager audio, OsuConfigManager config, APIAccess api) { this.api = api; @@ -135,10 +129,6 @@ namespace osu.Game.Screens.Play if (!RulesetContainer.Objects.Any()) throw new InvalidOperationException("Beatmap contains no hit objects!"); - - var rulesetConfig = rulesetInstance.GetConfigManager(storage); - if (rulesetConfig != null) - dependencies.Cache(rulesetConfig); } catch (Exception e) { From 89f4bfa7b540d8bf24909bc56498c476de446ddf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 18 Jan 2018 17:00:41 +0900 Subject: [PATCH 20/83] Track mania scroll speed --- osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs index 4972e3092a..0f062ed72a 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration.Tracking; using osu.Framework.Platform; using osu.Game.Rulesets.Configuration; @@ -19,6 +20,11 @@ namespace osu.Game.Rulesets.Mania.Configuration Set(ManiaSetting.ScrollTime, 1500.0, 50.0, 10000.0, 50.0); } + + public override TrackedSettings CreateTrackedSettings() => new TrackedSettings + { + new TrackedSetting(ManiaSetting.ScrollTime, v => new SettingDescription(v, "Scroll Time", $"{v}ms")) + }; } public enum ManiaSetting From dee298c395c26e465bca5037bb0924051e32d969 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 18 Jan 2018 17:40:05 +0900 Subject: [PATCH 21/83] No more statics + better unregistration --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 8 +++++++ osu.Game/Overlays/OnScreenDisplay.cs | 16 +++++++------- .../Configuration/IRulesetConfigManager.cs | 3 +-- osu.Game/Rulesets/UI/RulesetContainer.cs | 22 +++++++++---------- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 868f4b143c..7af675cc6a 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -161,11 +161,19 @@ namespace osu.Game.Rulesets.Mania.UI judgements.Scale = Scale; } + private Bindable scrollTime; + [BackgroundDependencyLoader] private void load(OsuColour colours, ManiaConfigManager maniaConfig) { maniaConfig.BindWith(ManiaSetting.ScrollTime, VisibleTimeRange); + // Todo: The following two lines shouldn't be required, but is an effect of not having config databased + // 1. ValueChanged is run prior to values being propagated + // 2. We want the config to be saved ASAP, in-case a new ManiaPlayfield is instantiated + scrollTime = maniaConfig.GetBindable(ManiaSetting.ScrollTime); + scrollTime.ValueChanged += v => maniaConfig.Save(); + normalColumnColours = new List { colours.RedDark, diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index cc47f3bfa0..b9d0213aa6 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -118,16 +118,16 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) { - Register(frameworkConfig); + Register(this, frameworkConfig); } - private readonly Dictionary trackedConfigManagers = new Dictionary(); + private readonly Dictionary<(IDisposable, IConfigManager), TrackedSettings> trackedConfigManagers = new Dictionary<(IDisposable, IConfigManager), TrackedSettings>(); - public void Register(ITrackableConfigManager configManager) + public void Register(IDisposable source, ITrackableConfigManager configManager) { if (configManager == null) throw new ArgumentNullException(nameof(configManager)); - if (trackedConfigManagers.ContainsKey(configManager)) + if (trackedConfigManagers.ContainsKey((source, configManager))) return; var trackedSettings = configManager.CreateTrackedSettings(); @@ -138,20 +138,20 @@ namespace osu.Game.Overlays trackedSettings.SettingChanged += display; - trackedConfigManagers.Add(configManager, trackedSettings); + trackedConfigManagers.Add((source, configManager), trackedSettings); } - public void Unregister(ITrackableConfigManager configManager) + public void Unregister(IDisposable source, ITrackableConfigManager configManager) { if (configManager == null) throw new ArgumentNullException(nameof(configManager)); - if (!trackedConfigManagers.TryGetValue(configManager, out var existing)) + if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing)) return; existing.Unload(); existing.SettingChanged -= display; - trackedConfigManagers.Remove(configManager); + trackedConfigManagers.Remove((source, configManager)); } private void display(SettingDescription description) diff --git a/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs index 8d386242a9..56eac730b0 100644 --- a/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/IRulesetConfigManager.cs @@ -1,12 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; namespace osu.Game.Rulesets.Configuration { - public interface IRulesetConfigManager : ITrackableConfigManager, IConfigManager + public interface IRulesetConfigManager : ITrackableConfigManager { } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 5d1c57a7a5..d4cfb3a3b3 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.UI protected readonly Ruleset Ruleset; private IRulesetConfigManager rulesetConfig; + private OnScreenDisplay onScreenDisplay; private DependencyContainer dependencies; @@ -89,23 +90,17 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load(Storage storage, OnScreenDisplay onScreenDisplay) { - rulesetConfig = getConfig(storage); + this.onScreenDisplay = onScreenDisplay; + + rulesetConfig = CreateConfig(Ruleset, storage); if (rulesetConfig != null) { dependencies.Cache(rulesetConfig); - onScreenDisplay?.Register(rulesetConfig); + onScreenDisplay?.Register(this, rulesetConfig); } } - private static readonly Dictionary config_cache = new Dictionary(); - private IRulesetConfigManager getConfig(Storage storage) - { - if (config_cache.TryGetValue(GetType(), out var existing)) - return existing; - return config_cache[GetType()] = CreateConfig(Ruleset, storage); - } - public abstract ScoreProcessor CreateScoreProcessor(); /// @@ -148,7 +143,12 @@ namespace osu.Game.Rulesets.UI protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - rulesetConfig.Save(); + + if (rulesetConfig != null) + { + onScreenDisplay?.Unregister(this, rulesetConfig); + rulesetConfig = null; + } } } From a94ea7025e3cf2a48a308097afe208d59e76b523 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 18 Jan 2018 18:45:48 +0900 Subject: [PATCH 22/83] Register/Unregister -> BeginTracking/StopTracking and add exceptions --- osu.Game/Overlays/OnScreenDisplay.cs | 27 ++++++++++++++++++------ osu.Game/Rulesets/UI/RulesetContainer.cs | 4 ++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index b9d0213aa6..bbb2c476f4 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -118,35 +118,48 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) { - Register(this, frameworkConfig); + BeginTracking(this, frameworkConfig); } - private readonly Dictionary<(IDisposable, IConfigManager), TrackedSettings> trackedConfigManagers = new Dictionary<(IDisposable, IConfigManager), TrackedSettings>(); + private readonly Dictionary<(object, IConfigManager), TrackedSettings> trackedConfigManagers = new Dictionary<(object, IConfigManager), TrackedSettings>(); - public void Register(IDisposable source, ITrackableConfigManager configManager) + /// + /// Registers a to have its settings tracked by this . + /// + /// The object that is registering the to be tracked. + /// The to be tracked. + /// If is null. + /// If is already being tracked from the same . + public void BeginTracking(object source, ITrackableConfigManager configManager) { if (configManager == null) throw new ArgumentNullException(nameof(configManager)); if (trackedConfigManagers.ContainsKey((source, configManager))) - return; + throw new InvalidOperationException($"{nameof(configManager)} is already registered."); var trackedSettings = configManager.CreateTrackedSettings(); if (trackedSettings == null) return; configManager.LoadInto(trackedSettings); - trackedSettings.SettingChanged += display; trackedConfigManagers.Add((source, configManager), trackedSettings); } - public void Unregister(IDisposable source, ITrackableConfigManager configManager) + /// + /// Unregisters a from having its settings tracked by this . + /// + /// The object that registered the to be tracked. + /// The that is being tracked. + /// If is null. + /// If is not being tracked from the same . + public void StopTracking(object source, ITrackableConfigManager configManager) { if (configManager == null) throw new ArgumentNullException(nameof(configManager)); if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing)) - return; + throw new InvalidOperationException($"{nameof(configManager)} is not registered."); existing.Unload(); existing.SettingChanged -= display; diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index d4cfb3a3b3..45c112f669 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.UI if (rulesetConfig != null) { dependencies.Cache(rulesetConfig); - onScreenDisplay?.Register(this, rulesetConfig); + onScreenDisplay?.BeginTracking(this, rulesetConfig); } } @@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.UI if (rulesetConfig != null) { - onScreenDisplay?.Unregister(this, rulesetConfig); + onScreenDisplay?.StopTracking(this, rulesetConfig); rulesetConfig = null; } } From 4a85266fca02c4375fafc572fc2c524b08aa9643 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Thu, 18 Jan 2018 17:23:02 +0100 Subject: [PATCH 23/83] Using BindableBool to mute the volume when it's value changes --- .../UserInterface/Volume/VolumeControl.cs | 39 ++++++++----------- osu.Game/OsuGame.cs | 2 - 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 2f565eba22..e611c0dfd0 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -14,8 +14,6 @@ namespace osu.Game.Graphics.UserInterface.Volume { public class VolumeControl : OverlayContainer { - private AudioManager audio; - private readonly VolumeMeter volumeMeterMaster; private readonly IconButton muteIcon; @@ -42,13 +40,7 @@ namespace osu.Game.Graphics.UserInterface.Volume { Icon = FontAwesome.fa_volume_up, Scale = new Vector2(2.0f), - Action = () => - { - if (IsMuted) - Unmute(); - else - Mute(); - }, + Action = () => Adjust(GlobalAction.ToggleMute), }, volumeMeterMaster = new VolumeMeter("Master"), volumeMeterEffect = new VolumeMeter("Effects"), @@ -113,35 +105,36 @@ namespace osu.Game.Graphics.UserInterface.Volume private readonly BindableDouble muteBindable = new BindableDouble(); - public bool IsMuted { get; private set; } + private readonly BindableBool muted = new BindableBool(); + + public bool IsMuted => muted.Value; public void Mute() { - if (IsMuted) - return; - - audio.AddAdjustment(AdjustableProperty.Volume, muteBindable); - IsMuted = true; - muteIcon.Icon = FontAwesome.fa_volume_off; + muted.Value = true; } public void Unmute() { - if (!IsMuted) - return; - - audio.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); - IsMuted = false; - muteIcon.Icon = FontAwesome.fa_volume_up; + muted.Value = false; } [BackgroundDependencyLoader] private void load(AudioManager audio) { - this.audio = audio; volumeMeterMaster.Bindable.BindTo(audio.Volume); volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); + + muted.ValueChanged += mute => + { + if (mute) + audio.AddAdjustment(AdjustableProperty.Volume, muteBindable); + else + audio.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); + + muteIcon.Icon = mute ? FontAwesome.fa_volume_off : FontAwesome.fa_volume_up; + }; } private ScheduledDelegate popOutDelegate; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 56cfffdeae..f1fb2a4f0a 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -405,9 +405,7 @@ namespace osu.Game { base.OnActivated(); if (IsLoaded && muteWhenInactive && !wasMuted) - { volume.Unmute(); - } } public bool OnReleased(GlobalAction action) => false; From c4feb67bceede170fa341a2fe9f56fc7f43c83ca Mon Sep 17 00:00:00 2001 From: aQaTL Date: Sat, 20 Jan 2018 11:45:04 +0100 Subject: [PATCH 24/83] Using field properties to set mute / unmute instead of separate methods --- .../UserInterface/Volume/VolumeControl.cs | 28 ++++++++----------- osu.Game/OsuGame.cs | 6 ++-- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index e611c0dfd0..60242393ab 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -85,12 +85,8 @@ namespace osu.Game.Graphics.UserInterface.Volume volumeMeterMaster.Increase(); return true; case GlobalAction.ToggleMute: - if (State == Visibility.Hidden) - Show(); - if (IsMuted) - Unmute(); - else - Mute(); + Show(); + Muted = !Muted; return true; } @@ -107,16 +103,10 @@ namespace osu.Game.Graphics.UserInterface.Volume private readonly BindableBool muted = new BindableBool(); - public bool IsMuted => muted.Value; - - public void Mute() + public bool Muted { - muted.Value = true; - } - - public void Unmute() - { - muted.Value = false; + get => muted.Value; + set => muted.Value = value; } [BackgroundDependencyLoader] @@ -129,11 +119,15 @@ namespace osu.Game.Graphics.UserInterface.Volume muted.ValueChanged += mute => { if (mute) + { audio.AddAdjustment(AdjustableProperty.Volume, muteBindable); + muteIcon.Icon = FontAwesome.fa_volume_off; + } else + { audio.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); - - muteIcon.Icon = mute ? FontAwesome.fa_volume_off : FontAwesome.fa_volume_up; + muteIcon.Icon = FontAwesome.fa_volume_up; + } }; } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f1fb2a4f0a..b938595d57 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -396,8 +396,8 @@ namespace osu.Game base.OnDeactivated(); if (muteWhenInactive) { - wasMuted = volume.IsMuted; - volume.Mute(); + wasMuted = volume.Muted; + volume.Muted = true; } } @@ -405,7 +405,7 @@ namespace osu.Game { base.OnActivated(); if (IsLoaded && muteWhenInactive && !wasMuted) - volume.Unmute(); + volume.Muted = false; } public bool OnReleased(GlobalAction action) => false; From ad2df8d8dfdfc775098ae07725adaa03a00f47b0 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Sun, 21 Jan 2018 20:09:44 -0500 Subject: [PATCH 25/83] Fixed tilde-key crash at end of beatmap. --- osu.Game/Screens/Play/Player.cs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8d26d63d41..d50f463c2c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -88,6 +88,9 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; + private bool allowRestart = true; + private bool exited = false; + [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config, APIAccess api) { @@ -208,10 +211,12 @@ namespace osu.Game.Screens.Play new HotkeyRetryOverlay { Action = () => { - //we want to hide the hitrenderer immediately (looks better). - //we may be able to remove this once the mouse cursor trail is improved. - RulesetContainer?.Hide(); - Restart(); + if (allowRestart) { + //we want to hide the hitrenderer immediately (looks better). + //we may be able to remove this once the mouse cursor trail is improved. + RulesetContainer?.Hide(); + Restart(); + } }, } }; @@ -266,6 +271,7 @@ namespace osu.Game.Screens.Play public void Restart() { + exited = true; sampleRestart?.Play(); ValidForResume = false; RestartRequested?.Invoke(); @@ -288,6 +294,11 @@ namespace osu.Game.Screens.Play { onCompletionEvent = Schedule(delegate { + // This is here to mimic OsuStable behavior. It could be placed outside the delay timer, + // which would remove the need for the check on Push() below, and would make it impossible + // to quick-restart after hitting the last note. + allowRestart = false; + var score = new Score { Beatmap = Beatmap.Value.BeatmapInfo, @@ -295,7 +306,7 @@ namespace osu.Game.Screens.Play }; scoreProcessor.PopulateScore(score); score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; - Push(new Results(score)); + if (!exited) Push(new Results(score)); }); } } From 806da2176051fa3748a3617a1e1fdf862a54e881 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Sun, 21 Jan 2018 20:24:19 -0500 Subject: [PATCH 26/83] Removed rreduntant initialization. --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d50f463c2c..2885427e88 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -89,7 +89,7 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; private bool allowRestart = true; - private bool exited = false; + private bool exited; [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config, APIAccess api) From 964c6da9a436319f69c7f67fc62a2bdfa0da2413 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Sun, 21 Jan 2018 22:00:18 -0500 Subject: [PATCH 27/83] Use IsCurrentScreen instead of a bool --- osu.Game/Screens/Play/Player.cs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2885427e88..4f7f145ed0 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -89,7 +89,6 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; private bool allowRestart = true; - private bool exited; [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config, APIAccess api) @@ -271,7 +270,6 @@ namespace osu.Game.Screens.Play public void Restart() { - exited = true; sampleRestart?.Play(); ValidForResume = false; RestartRequested?.Invoke(); @@ -294,19 +292,19 @@ namespace osu.Game.Screens.Play { onCompletionEvent = Schedule(delegate { - // This is here to mimic OsuStable behavior. It could be placed outside the delay timer, - // which would remove the need for the check on Push() below, and would make it impossible - // to quick-restart after hitting the last note. - allowRestart = false; - - var score = new Score + if (IsCurrentScreen) { - Beatmap = Beatmap.Value.BeatmapInfo, - Ruleset = ruleset - }; - scoreProcessor.PopulateScore(score); - score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; - if (!exited) Push(new Results(score)); + allowRestart = false; + + var score = new Score + { + Beatmap = Beatmap.Value.BeatmapInfo, + Ruleset = ruleset + }; + scoreProcessor.PopulateScore(score); + score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; + Push(new Results(score)); + } }); } } From 530e0afa2c89acda8dc9cc26100501ebd015ba51 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Sun, 21 Jan 2018 22:27:15 -0500 Subject: [PATCH 28/83] Use IsCurrentScreen instead of a bool for both checks now. --- osu.Game/Screens/Play/Player.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 4f7f145ed0..e29ff8edd3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -88,8 +88,6 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; - private bool allowRestart = true; - [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config, APIAccess api) { @@ -210,7 +208,7 @@ namespace osu.Game.Screens.Play new HotkeyRetryOverlay { Action = () => { - if (allowRestart) { + if (IsCurrentScreen) { //we want to hide the hitrenderer immediately (looks better). //we may be able to remove this once the mouse cursor trail is improved. RulesetContainer?.Hide(); @@ -294,8 +292,6 @@ namespace osu.Game.Screens.Play { if (IsCurrentScreen) { - allowRestart = false; - var score = new Score { Beatmap = Beatmap.Value.BeatmapInfo, From b98d8361bd6556d7c98fcea48bf98de0f5d46d20 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Sun, 21 Jan 2018 23:59:35 -0500 Subject: [PATCH 29/83] Use obtained value for displayed name. --- osu.Game/Overlays/Toolbar/ToolbarUserButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index c2dfea9a08..16586adc0c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Toolbar avatar.User = new User(); break; case APIState.Online: - Text = api.Username; + Text = api.LocalUser.Value.Username; avatar.User = api.LocalUser; break; } From 19321ca880c40b2647284e6642141c817b4c6546 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Mon, 22 Jan 2018 00:16:38 -0500 Subject: [PATCH 30/83] Save the obtained username when online. --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index ef02f1a7ec..fad0c8c3d9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -200,7 +200,7 @@ namespace osu.Game switch (state) { case APIState.Online: - LocalConfig.Set(OsuSetting.Username, LocalConfig.Get(OsuSetting.SaveUsername) ? API.Username : string.Empty); + LocalConfig.Set(OsuSetting.Username, LocalConfig.Get(OsuSetting.SaveUsername) ? API.LocalUser.Value.Username : string.Empty); break; } } From c4252ee022635332a3f1c62c26f1b6ed5ad379f3 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Sun, 21 Jan 2018 23:59:35 -0500 Subject: [PATCH 31/83] Use obtained value for displayed name. --- osu.Game/Overlays/Toolbar/ToolbarUserButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index c2dfea9a08..16586adc0c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Toolbar avatar.User = new User(); break; case APIState.Online: - Text = api.Username; + Text = api.LocalUser.Value.Username; avatar.User = api.LocalUser; break; } From 87ec36060d2eca78491d08f5d42940a9a29faf02 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Mon, 22 Jan 2018 00:16:38 -0500 Subject: [PATCH 32/83] Save the obtained username when online. --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index ef02f1a7ec..fad0c8c3d9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -200,7 +200,7 @@ namespace osu.Game switch (state) { case APIState.Online: - LocalConfig.Set(OsuSetting.Username, LocalConfig.Get(OsuSetting.SaveUsername) ? API.Username : string.Empty); + LocalConfig.Set(OsuSetting.Username, LocalConfig.Get(OsuSetting.SaveUsername) ? API.LocalUser.Value.Username : string.Empty); break; } } From 794ae5380a341b83feb61377f9710369211bfe0d Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Mon, 22 Jan 2018 01:06:27 -0500 Subject: [PATCH 33/83] Intverted conditionals. --- osu-framework | 2 +- osu.Game/Screens/Play/Player.cs | 31 +++++++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/osu-framework b/osu-framework index 26c01ca606..8f36ddab94 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 26c01ca6069296621f76d8ffbfe31ecf8074c687 +Subproject commit 8f36ddab946ff538620081ede7719461d4732b79 diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e29ff8edd3..a53d598730 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -208,12 +208,12 @@ namespace osu.Game.Screens.Play new HotkeyRetryOverlay { Action = () => { - if (IsCurrentScreen) { - //we want to hide the hitrenderer immediately (looks better). - //we may be able to remove this once the mouse cursor trail is improved. - RulesetContainer?.Hide(); - Restart(); - } + if (!IsCurrentScreen) return; + + //we want to hide the hitrenderer immediately (looks better). + //we may be able to remove this once the mouse cursor trail is improved. + RulesetContainer?.Hide(); + Restart(); }, } }; @@ -290,17 +290,16 @@ namespace osu.Game.Screens.Play { onCompletionEvent = Schedule(delegate { - if (IsCurrentScreen) + if (!IsCurrentScreen) return; + + var score = new Score { - var score = new Score - { - Beatmap = Beatmap.Value.BeatmapInfo, - Ruleset = ruleset - }; - scoreProcessor.PopulateScore(score); - score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; - Push(new Results(score)); - } + Beatmap = Beatmap.Value.BeatmapInfo, + Ruleset = ruleset + }; + scoreProcessor.PopulateScore(score); + score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; + Push(new Results(score)); }); } } From 64d7868c035e6330a525eda5e3ef2fc2ef9e54d1 Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Mon, 22 Jan 2018 01:19:22 -0500 Subject: [PATCH 34/83] Update APi.Username in APIAccess intead of ignoring it. --- osu-framework | 2 +- osu.Game/Online/API/APIAccess.cs | 1 + osu.Game/OsuGameBase.cs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 26c01ca606..8f36ddab94 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 26c01ca6069296621f76d8ffbfe31ecf8074c687 +Subproject commit 8f36ddab946ff538620081ede7719461d4732b79 diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 5559aadeb4..1d657b8664 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -126,6 +126,7 @@ namespace osu.Game.Online.API userReq.Success += u => { LocalUser.Value = u; + Username = LocalUser.Value.Username; failureCount = 0; //we're connected! diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index fad0c8c3d9..ef02f1a7ec 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -200,7 +200,7 @@ namespace osu.Game switch (state) { case APIState.Online: - LocalConfig.Set(OsuSetting.Username, LocalConfig.Get(OsuSetting.SaveUsername) ? API.LocalUser.Value.Username : string.Empty); + LocalConfig.Set(OsuSetting.Username, LocalConfig.Get(OsuSetting.SaveUsername) ? API.Username : string.Empty); break; } } From 66176f2882895dd9ecb93e42f28388da5995065d Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 22 Jan 2018 12:36:38 +0100 Subject: [PATCH 35/83] fix RepeatPoint animations - FadeIn and -Out for RepeatPoints are now calculated instead of fixed values - TimePreempt is now cut down if too long for RepeatPoints following the first one to only show up to two RepeatPoints at any given time --- .../Objects/Drawables/DrawableRepeatPoint.cs | 16 ++++++++-------- .../Objects/Drawables/DrawableSlider.cs | 14 ++++---------- osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs | 14 ++++++++++++++ osu.Game.Rulesets.Osu/Objects/Slider.cs | 17 +++++++++-------- osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs | 1 + 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 28ff4b4cdf..520b4eccfa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly DrawableSlider drawableSlider; public double FadeInTime; - public double FadeOutTime; + private double animDuration; public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) : base(repeatPoint) @@ -48,11 +48,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdatePreemptState() { - var animIn = Math.Min(150, repeatPoint.StartTime - FadeInTime); + animDuration = Math.Min(150, repeatPoint.StartTime - FadeInTime); - this.FadeIn(animIn).ScaleTo(1.2f, animIn) + this.FadeIn(animDuration).ScaleTo(1.2f, animDuration / 2) .Then() - .ScaleTo(1, 150, Easing.Out); + .ScaleTo(1, animDuration / 2, Easing.Out); } protected override void UpdateCurrentState(ArmedState state) @@ -60,14 +60,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables switch (state) { case ArmedState.Idle: - this.Delay(FadeOutTime - repeatPoint.StartTime).FadeOut(); + this.Delay(HitObject.TimePreempt).FadeOut(); break; case ArmedState.Miss: - this.FadeOut(160); + this.FadeOut(animDuration); break; case ArmedState.Hit: - this.FadeOut(120, Easing.OutQuint) - .ScaleTo(Scale * 1.5f, 120, Easing.OutQuint); + this.FadeOut(animDuration, Easing.OutQuint) + .ScaleTo(Scale * 1.5f, animDuration, Easing.OutQuint); break; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 232964587c..99c664a575 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -72,12 +72,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AddNested(InitialCircle); - var repeatDuration = s.Curve.Distance / s.Velocity; foreach (var tick in s.NestedHitObjects.OfType()) { - var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration; + var repeatStartTime = s.StartTime + tick.RepeatIndex * s.RepeatDuration; var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2); - var fadeOutTime = repeatStartTime + repeatDuration; + var fadeOutTime = repeatStartTime + s.RepeatDuration; var drawableTick = new DrawableSliderTick(tick) { @@ -92,15 +91,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables foreach (var repeatPoint in s.NestedHitObjects.OfType()) { - var repeatStartTime = s.StartTime + repeatPoint.RepeatIndex * repeatDuration; - var fadeInTime = repeatStartTime + (repeatPoint.StartTime - repeatStartTime) / 2 - (repeatPoint.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2); - var fadeOutTime = repeatStartTime + repeatDuration; - var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) { - FadeInTime = fadeInTime, - FadeOutTime = fadeOutTime, - Position = repeatPoint.Position, + FadeInTime = repeatPoint.StartTime - s.RepeatDuration / 2, + Position = repeatPoint.Position }; repeatPoints.Add(drawableRepeatPoint); diff --git a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs index abdbb97072..42aff7ebaf 100644 --- a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs @@ -1,10 +1,24 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; + namespace osu.Game.Rulesets.Osu.Objects { public class RepeatPoint : OsuHitObject { public int RepeatIndex { get; set; } + public double RepeatDuration { get; set; } + + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaultsToSelf(controlPointInfo, difficulty); + + // We want to show the first RepeatPoint as the TimePreempt dictates but on short (and possibly fast) sliders + // we may need to cut down this time on following RepeatPoints to only show up to two RepeatPoints at any given time. + if (RepeatIndex > 1 && TimePreempt > RepeatDuration * 2) + TimePreempt = (float)RepeatDuration * 2; + } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 2da285a434..55de38a602 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -60,6 +60,11 @@ namespace osu.Game.Rulesets.Osu.Objects public List> RepeatSamples { get; set; } = new List>(); public int RepeatCount { get; set; } = 1; + /// + /// The length of one repeat if any repeats are present, otherwise it equals the . + /// + public double RepeatDuration => RepeatCount > 1 ? Distance / Velocity : Duration; + private int stackHeight; public override int StackHeight @@ -114,13 +119,12 @@ namespace osu.Game.Rulesets.Osu.Objects var length = Curve.Distance; var tickDistance = Math.Min(TickDistance, length); - var repeatDuration = length / Velocity; var minDistanceFromEnd = Velocity * 0.01; for (var repeat = 0; repeat < RepeatCount; repeat++) { - var repeatStartTime = StartTime + repeat * repeatDuration; + var repeatStartTime = StartTime + repeat * RepeatDuration; var reversed = repeat % 2 == 1; for (var d = tickDistance; d <= length; d += tickDistance) @@ -145,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Objects AddNested(new SliderTick { RepeatIndex = repeat, - StartTime = repeatStartTime + timeProgress * repeatDuration, + StartTime = repeatStartTime + timeProgress * RepeatDuration, Position = Curve.PositionAt(distanceProgress), StackHeight = StackHeight, Scale = Scale, @@ -158,16 +162,13 @@ namespace osu.Game.Rulesets.Osu.Objects private void createRepeatPoints() { - var repeatDuration = Distance / Velocity; - for (var repeat = 1; repeat < RepeatCount; repeat++) { - var repeatStartTime = StartTime + repeat * repeatDuration; - AddNested(new RepeatPoint { RepeatIndex = repeat, - StartTime = repeatStartTime, + RepeatDuration = RepeatDuration, + StartTime = StartTime + repeat * RepeatDuration, Position = Curve.PositionAt(repeat % 2), StackHeight = StackHeight, Scale = Scale, diff --git a/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs b/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs index c395c5edb8..2e47b2c72a 100644 --- a/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs +++ b/osu.Game.Rulesets.Osu/Tests/TestCaseSlider.cs @@ -63,6 +63,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("Fast Short Slider", () => testShortHighSpeed()); AddStep("Fast Short Slider 1 Repeat", () => testShortHighSpeed(1)); AddStep("Fast Short Slider 2 Repeats", () => testShortHighSpeed(2)); + AddStep("Fast Short Slider 6 Repeats", () => testShortHighSpeed(6)); AddStep("Perfect Curve", testCurve); // TODO more curve types? From b726f90c3714ff85f0714eee7d0f1ba0d4cbf8d1 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 22 Jan 2018 12:44:55 +0100 Subject: [PATCH 36/83] remove unnecessary variable --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs | 3 +-- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 520b4eccfa..b62c1fa984 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -16,7 +16,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly RepeatPoint repeatPoint; private readonly DrawableSlider drawableSlider; - public double FadeInTime; private double animDuration; public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) @@ -48,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdatePreemptState() { - animDuration = Math.Min(150, repeatPoint.StartTime - FadeInTime); + animDuration = Math.Min(150, repeatPoint.RepeatDuration / 2); this.FadeIn(animDuration).ScaleTo(1.2f, animDuration / 2) .Then() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 99c664a575..044bce7eca 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) { - FadeInTime = repeatPoint.StartTime - s.RepeatDuration / 2, Position = repeatPoint.Position }; From 5689e93bedd4390e8e3e783d7b1677fd72804ef6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Jan 2018 16:24:08 +0900 Subject: [PATCH 37/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index c0c21831ce..736a139a74 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit c0c21831cef6b2946c5b067f5c4bbd929e89c2ec +Subproject commit 736a139a748eba7cebea41a09b404d47ca589522 From 1fda45fe1098c6a1ef1aa3067c7d0715978d5819 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Jan 2018 16:40:18 +0900 Subject: [PATCH 38/83] Fix broken formatting --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 3b552629cf..9911be9daa 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.UI return null; } - private Bindable scrollTime; + private Bindable scrollTime; [BackgroundDependencyLoader] private void load(ManiaConfigManager maniaConfig) From b197cd56af28b58c77eedda97b324d1ca96d39de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Jan 2018 16:42:31 +0900 Subject: [PATCH 39/83] Allow DI'd OnScreenDisplay to be null --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 69249c1fe6..f9a7bbe4c8 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(Storage storage, OnScreenDisplay onScreenDisplay) { this.onScreenDisplay = onScreenDisplay; From 2c0dd1815cdcb0c98d65b8310bfd4fffd9a0ec09 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 23 Jan 2018 09:09:19 +0100 Subject: [PATCH 40/83] Updated submodule osu-framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 26c01ca606..736a139a74 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 26c01ca6069296621f76d8ffbfe31ecf8074c687 +Subproject commit 736a139a748eba7cebea41a09b404d47ca589522 From fa800f097787f2beb1cb20f76cee250c170aca5e Mon Sep 17 00:00:00 2001 From: james58899 Date: Tue, 23 Jan 2018 18:18:54 +0800 Subject: [PATCH 41/83] fix storyboard path --- .../Beatmaps/Formats/LegacyStoryboardDecoderTest.cs | 4 ++-- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index cd3f6d066f..dce6c0f55b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -70,7 +70,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(new Vector2(320, 240), sprite.InitialPosition); Assert.IsTrue(sprite.IsDrawable); Assert.AreEqual(Anchor.Centre, sprite.Origin); - Assert.AreEqual(Path.Combine("SB", "lyric", "ja-21.png"), sprite.Path); + Assert.AreEqual("SB/lyric/ja-21.png", sprite.Path); var animation = background.Elements.ElementAt(12) as StoryboardAnimation; Assert.NotNull(animation); @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(animation.IsDrawable); Assert.AreEqual(AnimationLoopType.LoopForever, animation.LoopType); Assert.AreEqual(Anchor.Centre, animation.Origin); - Assert.AreEqual(Path.Combine("SB", "red jitter", "red_0000.jpg"), animation.Path); + Assert.AreEqual("SB/red jitter/red_0000.jpg", animation.Path); Assert.AreEqual(78993, animation.StartTime); } } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index d60297a26c..a4ff060c83 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -301,6 +301,6 @@ namespace osu.Game.Beatmaps.Formats } } - private string cleanFilename(string path) => FileSafety.PathSanitise(path.Trim('\"')); + private string cleanFilename(string path) => FileSafety.PathStandardise(FileSafety.PathSanitise(path.Trim('\"'))); } } From 4baadfdd16beac1cd024cc7ac143792e472e823a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 23 Jan 2018 16:44:33 +0100 Subject: [PATCH 42/83] fix oversight --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index faf0da8339..073ff476c1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// /// The length of one repeat if any repeats are present, otherwise it equals the . /// - public double SpanDuration => RepeatCount > 1 ? Distance / Velocity : Duration; + public double SpanDuration => RepeatCount > 0 ? Distance / Velocity : Duration; private int stackHeight; From 6dfd0b5cc244387e2f59355d6038465419b5763f Mon Sep 17 00:00:00 2001 From: Michael Manis Date: Tue, 23 Jan 2018 10:54:42 -0500 Subject: [PATCH 43/83] Unnecessary because of prior commit. --- osu.Game/Overlays/Toolbar/ToolbarUserButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index 16586adc0c..c2dfea9a08 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Toolbar avatar.User = new User(); break; case APIState.Online: - Text = api.LocalUser.Value.Username; + Text = api.Username; avatar.User = api.LocalUser; break; } From 205d3ed896d228f58006bc98562e72368233537d Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 23 Jan 2018 19:42:21 +0100 Subject: [PATCH 44/83] fix settings not getting injected --- osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index 64fa763a0b..1b0c821b54 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Toolbar } [BackgroundDependencyLoader(true)] - private void load(SettingsOverlay settings) + private void load(MainSettings settings) { StateContainer = settings; } From 52c4d22c410e31cfe0d1b592893736cea067248e Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 24 Jan 2018 09:44:50 +0100 Subject: [PATCH 45/83] review changes - use doubles instead of floats - simplify logic --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs | 5 +++-- osu.Game.Rulesets.Osu/Objects/Slider.cs | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index d42338f20e..3dad5b508c 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; - float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - float stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 3a486e7763..b4dd08eadb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; public override double ScoreMultiplier => 1.06; - private const float fade_in_duration_multiplier = 0.4f; + private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; public void ApplyToDrawableHitObjects(IEnumerable drawables) diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 0e7c2f3d4d..f217ae89e9 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Osu.Objects public double HitWindow100 = 80; public double HitWindow300 = 30; - public float TimePreempt = 600; - public float TimeFadein = 400; + public double TimePreempt = 600; + public double TimeFadein = 400; public Vector2 Position { get; set; } public float X => Position.X; diff --git a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs index c55235611c..eaaa8d7a7e 100644 --- a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -17,8 +18,8 @@ namespace osu.Game.Rulesets.Osu.Objects // We want to show the first RepeatPoint as the TimePreempt dictates but on short (and possibly fast) sliders // we may need to cut down this time on following RepeatPoints to only show up to two RepeatPoints at any given time. - if (RepeatIndex > 0 && TimePreempt > SpanDuration * 2) - TimePreempt = (float)SpanDuration * 2; + if (RepeatIndex > 0) + TimePreempt = Math.Min(SpanDuration * 2, TimePreempt); } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 073ff476c1..79bb14a475 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -61,9 +61,9 @@ namespace osu.Game.Rulesets.Osu.Objects public int RepeatCount { get; set; } /// - /// The length of one repeat if any repeats are present, otherwise it equals the . + /// The length of one span of this . /// - public double SpanDuration => RepeatCount > 0 ? Distance / Velocity : Duration; + public double SpanDuration => Duration / this.SpanCount(); private int stackHeight; From 5a00ae36d124621188096546dfb5b172a7428d4e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jan 2018 17:35:37 +0900 Subject: [PATCH 46/83] Add database-based configuration for rulesets --- .../Configuration/ManiaConfigManager.cs | 6 +- .../UI/ManiaRulesetContainer.cs | 4 +- .../Configuration/DatabasedConfigManager.cs | 67 ++++ osu.Game/Configuration/DatabasedSetting.cs | 31 ++ osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Configuration/Setting.cs | 41 +++ osu.Game/Configuration/SettingsStore.cs | 42 +++ osu.Game/Database/DatabaseBackedStore.cs | 10 +- osu.Game/Database/OsuDbContext.cs | 8 +- .../20180124024000_AddSettings.Designer.cs | 327 ++++++++++++++++++ .../Migrations/20180124024000_AddSettings.cs | 56 +++ .../Migrations/OsuDbContextModelSnapshot.cs | 22 +- osu.Game/OsuGameBase.cs | 3 + .../Configuration/RulesetConfigManager.cs | 15 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 8 +- .../Components/DrawingsConfigManager.cs | 2 +- osu.Game/osu.Game.csproj | 8 + 17 files changed, 624 insertions(+), 28 deletions(-) create mode 100644 osu.Game/Configuration/DatabasedConfigManager.cs create mode 100644 osu.Game/Configuration/DatabasedSetting.cs create mode 100644 osu.Game/Configuration/Setting.cs create mode 100644 osu.Game/Configuration/SettingsStore.cs create mode 100644 osu.Game/Migrations/20180124024000_AddSettings.Designer.cs create mode 100644 osu.Game/Migrations/20180124024000_AddSettings.cs diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs index 0f062ed72a..3167d8300d 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs @@ -2,15 +2,15 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Configuration.Tracking; -using osu.Framework.Platform; +using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; namespace osu.Game.Rulesets.Mania.Configuration { public class ManiaConfigManager : RulesetConfigManager { - public ManiaConfigManager(Ruleset ruleset, Storage storage) - : base(ruleset, storage) + public ManiaConfigManager(RulesetInfo ruleset, SettingsStore settings) + : base(ruleset, settings) { } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 109c967ded..f517d6b041 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -8,9 +8,9 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.MathUtils; -using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Mods; @@ -107,6 +107,6 @@ namespace osu.Game.Rulesets.Mania.UI protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this); - protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, Storage storage) => new ManiaConfigManager(ruleset, storage); + protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => new ManiaConfigManager(Ruleset.RulesetInfo, settings); } } diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs new file mode 100644 index 0000000000..f982490523 --- /dev/null +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Configuration; +using osu.Game.Rulesets; + +namespace osu.Game.Configuration +{ + public abstract class DatabasedConfigManager : ConfigManager + where T : struct + { + private readonly SettingsStore settings; + + private readonly List databasedSettings; + + private readonly RulesetInfo ruleset; + + protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null) + { + this.settings = settings; + this.ruleset = ruleset; + + databasedSettings = settings.Query(ruleset?.ID); + + InitialiseDefaults(); + } + + protected override void PerformLoad() + { + } + + protected override bool PerformSave() + { + return true; + } + + protected override void AddBindable(T lookup, Bindable bindable) + { + base.AddBindable(lookup, bindable); + + var setting = databasedSettings.FirstOrDefault(s => (int)s.Key == (int)(object)lookup); + if (setting != null) + { + bindable.Parse(setting.Value); + } + else + { + settings.Update(setting = new DatabasedSetting + { + Key = lookup, + Value = bindable.Value, + RulesetID = ruleset?.ID + }); + + databasedSettings.Add(setting); + } + + bindable.ValueChanged += v => + { + setting.Value = v; + settings.Update(setting); + }; + } + } +} diff --git a/osu.Game/Configuration/DatabasedSetting.cs b/osu.Game/Configuration/DatabasedSetting.cs new file mode 100644 index 0000000000..b1644a3cd3 --- /dev/null +++ b/osu.Game/Configuration/DatabasedSetting.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.ComponentModel.DataAnnotations.Schema; +using osu.Game.Database; + +namespace osu.Game.Configuration +{ + [Table("Settings")] + public class DatabasedSetting : Setting, IHasPrimaryKey + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int ID { get; set; } + + public int? RulesetID { get; set; } + + [Column("Key")] + public int IntKey + { + get => (int)Key; + private set => Key = value; + } + + [Column("Value")] + public string StringValue + { + get => Value.ToString(); + set => Value = value; + } + } +} diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 23f7fd6ac1..33810c9712 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -8,7 +8,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Configuration { - public class OsuConfigManager : ConfigManager + public class OsuConfigManager : IniConfigManager { protected override void InitialiseDefaults() { diff --git a/osu.Game/Configuration/Setting.cs b/osu.Game/Configuration/Setting.cs new file mode 100644 index 0000000000..8c1d967ad9 --- /dev/null +++ b/osu.Game/Configuration/Setting.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Configuration +{ + /// + /// A binding of a to an action. + /// + public class Setting + { + /// + /// The combination of keys which will trigger this binding. + /// + public object Key; + + /// + /// The resultant action which is triggered by this binding. + /// + public object Value; + + /// + /// Construct a new instance. + /// + /// The combination of keys which will trigger this binding. + /// The resultant action which is triggered by this binding. Usually an enum type. + public Setting(object key, object value) + { + Key = key; + Value = value; + } + + /// + /// Constructor for derived classes that may require serialisation. + /// + public Setting() + { + } + + public override string ToString() => $"{Key}=>{Value}"; + } +} diff --git a/osu.Game/Configuration/SettingsStore.cs b/osu.Game/Configuration/SettingsStore.cs new file mode 100644 index 0000000000..3bcdc05496 --- /dev/null +++ b/osu.Game/Configuration/SettingsStore.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Database; + +namespace osu.Game.Configuration +{ + public class SettingsStore : DatabaseBackedStore + { + public event Action SettingChanged; + + public SettingsStore(Func createContext) + : base(createContext) + { + } + + /// + /// Retrieve s for a specified ruleset/variant content. + /// + /// The ruleset's internal ID. + /// An optional variant. + /// + public List Query(int? rulesetId = null) => + GetContext().DatabasedSetting.Where(b => b.RulesetID == rulesetId).ToList(); + + public void Update(Setting setting) + { + var dbSetting = (DatabasedSetting)setting; + + var context = GetContext(); + + Refresh(ref dbSetting); + dbSetting.Value = setting.Value; + context.SaveChanges(); + + SettingChanged?.Invoke(); + } + } +} diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index 3184696266..ec9967e097 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -34,8 +34,14 @@ namespace osu.Game.Database if (context.Entry(obj).State != EntityState.Detached) return; var id = obj.ID; - obj = lookupSource?.SingleOrDefault(t => t.ID == id) ?? context.Find(id); - context.Entry(obj).Reload(); + var foundObject = lookupSource?.SingleOrDefault(t => t.ID == id) ?? context.Find(id); + if (foundObject != null) + { + obj = foundObject; + context.Entry(obj).Reload(); + } + else + context.Add(obj); } /// diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index 091ec3487c..be0b4f3543 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -8,9 +8,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; using osu.Framework.Logging; using osu.Game.Beatmaps; -using osu.Game.Input.Bindings; +using osu.Game.Configuration; using osu.Game.IO; using osu.Game.Rulesets; +using DatabasedKeyBinding = osu.Game.Input.Bindings.DatabasedKeyBinding; using LogLevel = Microsoft.Extensions.Logging.LogLevel; namespace osu.Game.Database @@ -22,6 +23,7 @@ namespace osu.Game.Database public DbSet BeatmapMetadata { get; set; } public DbSet BeatmapSetInfo { get; set; } public DbSet DatabasedKeyBinding { get; set; } + public DbSet DatabasedSetting { get; set; } public DbSet FileInfo { get; set; } public DbSet RulesetInfo { get; set; } @@ -86,9 +88,11 @@ namespace osu.Game.Database modelBuilder.Entity().HasIndex(b => b.DeletePending); modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); - modelBuilder.Entity().HasIndex(b => b.Variant); + modelBuilder.Entity().HasIndex(b => new { b.RulesetID, b.Variant }); modelBuilder.Entity().HasIndex(b => b.IntAction); + modelBuilder.Entity().HasIndex(b => b.RulesetID); + modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); modelBuilder.Entity().HasIndex(b => b.ReferenceCount); diff --git a/osu.Game/Migrations/20180124024000_AddSettings.Designer.cs b/osu.Game/Migrations/20180124024000_AddSettings.Designer.cs new file mode 100644 index 0000000000..5bbf382f7f --- /dev/null +++ b/osu.Game/Migrations/20180124024000_AddSettings.Designer.cs @@ -0,0 +1,327 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using osu.Game.Database; +using System; + +namespace osu.Game.Migrations +{ + [DbContext(typeof(OsuDbContext))] + [Migration("20180124024000_AddSettings")] + partial class AddSettings + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.0.0-rtm-26452"); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("ApproachRate"); + + b.Property("CircleSize"); + + b.Property("DrainRate"); + + b.Property("OverallDifficulty"); + + b.Property("SliderMultiplier"); + + b.Property("SliderTickRate"); + + b.HasKey("ID"); + + b.ToTable("BeatmapDifficulty"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("AudioLeadIn"); + + b.Property("BaseDifficultyID"); + + b.Property("BeatDivisor"); + + b.Property("BeatmapSetInfoID"); + + b.Property("Countdown"); + + b.Property("DistanceSpacing"); + + b.Property("GridSize"); + + b.Property("Hash"); + + b.Property("Hidden"); + + b.Property("LetterboxInBreaks"); + + b.Property("MD5Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapID"); + + b.Property("Path"); + + b.Property("RulesetID"); + + b.Property("SpecialStyle"); + + b.Property("StackLeniency"); + + b.Property("StarDifficulty"); + + b.Property("StoredBookmarks"); + + b.Property("TimelineZoom"); + + b.Property("Version"); + + b.Property("WidescreenStoryboard"); + + b.HasKey("ID"); + + b.HasIndex("BaseDifficultyID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MD5Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapID") + .IsUnique(); + + b.HasIndex("RulesetID"); + + b.ToTable("BeatmapInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Artist"); + + b.Property("ArtistUnicode"); + + b.Property("AudioFile"); + + b.Property("AuthorString") + .HasColumnName("Author"); + + b.Property("BackgroundFile"); + + b.Property("PreviewTime"); + + b.Property("Source"); + + b.Property("Tags"); + + b.Property("Title"); + + b.Property("TitleUnicode"); + + b.HasKey("ID"); + + b.ToTable("BeatmapMetadata"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("BeatmapSetInfoID"); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.HasKey("ID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("FileInfoID"); + + b.ToTable("BeatmapSetFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapSetID"); + + b.Property("Protected"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapSetID") + .IsUnique(); + + b.ToTable("BeatmapSetInfo"); + }); + + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntKey") + .HasColumnName("Key"); + + b.Property("IntValue") + .HasColumnName("Value"); + + b.Property("RulesetID"); + + b.HasKey("ID"); + + b.HasIndex("RulesetID"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntAction") + .HasColumnName("Action"); + + b.Property("KeysString") + .HasColumnName("Keys"); + + b.Property("RulesetID"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("IntAction"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("KeyBinding"); + }); + + modelBuilder.Entity("osu.Game.IO.FileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Hash"); + + b.Property("ReferenceCount"); + + b.HasKey("ID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("ReferenceCount"); + + b.ToTable("FileInfo"); + }); + + modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Available"); + + b.Property("InstantiationInfo"); + + b.Property("Name"); + + b.Property("ShortName"); + + b.HasKey("ID"); + + b.HasIndex("Available"); + + b.HasIndex("ShortName") + .IsUnique(); + + b.ToTable("RulesetInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty") + .WithMany() + .HasForeignKey("BaseDifficultyID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet") + .WithMany("Beatmaps") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("Beatmaps") + .HasForeignKey("MetadataID"); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo") + .WithMany("Files") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("BeatmapSets") + .HasForeignKey("MetadataID"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/osu.Game/Migrations/20180124024000_AddSettings.cs b/osu.Game/Migrations/20180124024000_AddSettings.cs new file mode 100644 index 0000000000..63cacc0645 --- /dev/null +++ b/osu.Game/Migrations/20180124024000_AddSettings.cs @@ -0,0 +1,56 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; + +namespace osu.Game.Migrations +{ + public partial class AddSettings : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_KeyBinding_Variant", + table: "KeyBinding"); + + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + ID = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(type: "INTEGER", nullable: false), + Value = table.Column(type: "INTEGER", nullable: false), + RulesetID = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.ID); + }); + + migrationBuilder.CreateIndex( + name: "IX_KeyBinding_RulesetID_Variant", + table: "KeyBinding", + columns: new[] { "RulesetID", "Variant" }); + + migrationBuilder.CreateIndex( + name: "IX_Settings_RulesetID", + table: "Settings", + column: "RulesetID"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + + migrationBuilder.DropIndex( + name: "IX_KeyBinding_RulesetID_Variant", + table: "KeyBinding"); + + migrationBuilder.CreateIndex( + name: "IX_KeyBinding_Variant", + table: "KeyBinding", + column: "Variant"); + } + } +} diff --git a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs index cd4d3c2854..37e2aee3a0 100644 --- a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs +++ b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs @@ -193,6 +193,26 @@ namespace osu.Game.Migrations b.ToTable("BeatmapSetInfo"); }); + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntKey") + .HasColumnName("Key"); + + b.Property("IntValue") + .HasColumnName("Value"); + + b.Property("RulesetID"); + + b.HasKey("ID"); + + b.HasIndex("RulesetID"); + + b.ToTable("Settings"); + }); + modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => { b.Property("ID") @@ -212,7 +232,7 @@ namespace osu.Game.Migrations b.HasIndex("IntAction"); - b.HasIndex("Variant"); + b.HasIndex("RulesetID", "Variant"); b.ToTable("KeyBinding"); }); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8b317ca59a..d0b9634696 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -44,6 +44,8 @@ namespace osu.Game protected KeyBindingStore KeyBindingStore; + protected SettingsStore SettingsStore; + protected CursorOverrideContainer CursorOverrideContainer; protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -109,6 +111,7 @@ namespace osu.Game dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory.GetContext, RulesetStore, API, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, contextFactory.GetContext, Host, BeatmapManager, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory.GetContext, RulesetStore)); + dependencies.Cache(SettingsStore = new SettingsStore(contextFactory.GetContext)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. diff --git a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs index 9106485253..4f9fbe9830 100644 --- a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs @@ -1,24 +1,15 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Configuration; -using osu.Framework.Platform; +using osu.Game.Configuration; namespace osu.Game.Rulesets.Configuration { - public abstract class RulesetConfigManager : ConfigManager, IRulesetConfigManager + public abstract class RulesetConfigManager : DatabasedConfigManager, IRulesetConfigManager where T : struct { - protected override string Filename => ruleset?.ShortName == null ? null : $"{ruleset.ShortName}.ini"; - private readonly Ruleset ruleset; - - protected RulesetConfigManager(Ruleset ruleset, Storage storage) - : base(storage) + protected RulesetConfigManager(RulesetInfo ruleset, SettingsStore settings) : base(settings, ruleset) { - this.ruleset = ruleset; - - // Re-load with the ruleset - Load(); } } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index f9a7bbe4c8..08498d48c6 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -16,7 +16,7 @@ using System.Linq; using osu.Framework.Configuration; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; -using osu.Framework.Platform; +using osu.Game.Configuration; using osu.Game.Overlays; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Replays; @@ -89,11 +89,11 @@ namespace osu.Game.Rulesets.UI } [BackgroundDependencyLoader(true)] - private void load(Storage storage, OnScreenDisplay onScreenDisplay) + private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { this.onScreenDisplay = onScreenDisplay; - rulesetConfig = CreateConfig(Ruleset, storage); + rulesetConfig = CreateConfig(Ruleset, settings); if (rulesetConfig != null) { @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.UI /// protected virtual CursorContainer CreateCursor() => null; - protected virtual IRulesetConfigManager CreateConfig(Ruleset ruleset, Storage storage) => null; + protected virtual IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => null; /// /// Creates a Playfield. diff --git a/osu.Game/Screens/Tournament/Components/DrawingsConfigManager.cs b/osu.Game/Screens/Tournament/Components/DrawingsConfigManager.cs index 0c45729a18..63000d6c54 100644 --- a/osu.Game/Screens/Tournament/Components/DrawingsConfigManager.cs +++ b/osu.Game/Screens/Tournament/Components/DrawingsConfigManager.cs @@ -6,7 +6,7 @@ using osu.Framework.Platform; namespace osu.Game.Screens.Tournament.Components { - public class DrawingsConfigManager : ConfigManager + public class DrawingsConfigManager : IniConfigManager { protected override string Filename => @"drawings.ini"; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05728c2b41..56cfe6646c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -265,10 +265,18 @@ + + + + + + + 20180124024000_AddSettings.cs + From 8d11596b2f5341f177b8b709362402e4f09a27f2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 24 Jan 2018 17:48:42 +0900 Subject: [PATCH 47/83] Minor cleanups --- osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs | 3 ++- osu.Game/Screens/Play/HUDOverlay.cs | 3 +-- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs index 7a510aa738..af7c1ef5aa 100644 --- a/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreaksOverlay/BreakOverlay.cs @@ -41,7 +41,8 @@ namespace osu.Game.Screens.Play.BreaksOverlay private readonly InfoContainer info; private readonly ArrowsOverlay arrowsOverlay; - public BreakOverlay(bool letterboxing, ScoreProcessor scoreProcessor) : this(letterboxing) + public BreakOverlay(bool letterboxing, ScoreProcessor scoreProcessor) + : this(letterboxing) { bindProcessor(scoreProcessor); } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 0cdb053e77..5fb867e151 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -41,8 +41,7 @@ namespace osu.Game.Screens.Play private static bool hasShownNotificationOnce; - public HUDOverlay(ScoreProcessor scoreProcessor, RulesetContainer rulesetContainer, DecoupleableInterpolatingFramedClock decoupledClock, WorkingBeatmap working, - IAdjustableClock adjustableSourceClock) + public HUDOverlay(ScoreProcessor scoreProcessor, RulesetContainer rulesetContainer, DecoupleableInterpolatingFramedClock decoupledClock, WorkingBeatmap working, IAdjustableClock adjustableSourceClock) { RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 6da2c0fb76..ca4cb98bc8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -176,7 +176,7 @@ namespace osu.Game.Screens.Play pauseContainer.Retries = RestartCount; hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; }, - OnResume = () => { hudOverlay.KeyCounter.IsCounting = true; }, + OnResume = () => hudOverlay.KeyCounter.IsCounting = true, Children = new Drawable[] { new Container From 49e61b565815c0c612ed2dc691e94275d59ec154 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 24 Jan 2018 17:59:27 +0900 Subject: [PATCH 48/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 8f36ddab94..736a139a74 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 8f36ddab946ff538620081ede7719461d4732b79 +Subproject commit 736a139a748eba7cebea41a09b404d47ca589522 From 29e98a58f29ea50f6d9efedf246c2caf667ece06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jan 2018 17:59:49 +0900 Subject: [PATCH 49/83] Combine Setting and DatabasedSetting --- osu.Game/Configuration/DatabasedSetting.cs | 20 ++++++++++- osu.Game/Configuration/Setting.cs | 42 +--------------------- osu.Game/Configuration/SettingsStore.cs | 9 +++-- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/osu.Game/Configuration/DatabasedSetting.cs b/osu.Game/Configuration/DatabasedSetting.cs index b1644a3cd3..c284c10872 100644 --- a/osu.Game/Configuration/DatabasedSetting.cs +++ b/osu.Game/Configuration/DatabasedSetting.cs @@ -7,7 +7,7 @@ using osu.Game.Database; namespace osu.Game.Configuration { [Table("Settings")] - public class DatabasedSetting : Setting, IHasPrimaryKey + public class DatabasedSetting : IHasPrimaryKey { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } @@ -27,5 +27,23 @@ namespace osu.Game.Configuration get => Value.ToString(); set => Value = value; } + + public object Key; + public object Value; + + public DatabasedSetting(object key, object value) + { + Key = key; + Value = value; + } + + /// + /// Constructor for derived classes that may require serialisation. + /// + public DatabasedSetting() + { + } + + public override string ToString() => $"{Key}=>{Value}"; } } diff --git a/osu.Game/Configuration/Setting.cs b/osu.Game/Configuration/Setting.cs index 8c1d967ad9..5f282702bb 100644 --- a/osu.Game/Configuration/Setting.cs +++ b/osu.Game/Configuration/Setting.cs @@ -1,41 +1 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Configuration -{ - /// - /// A binding of a to an action. - /// - public class Setting - { - /// - /// The combination of keys which will trigger this binding. - /// - public object Key; - - /// - /// The resultant action which is triggered by this binding. - /// - public object Value; - - /// - /// Construct a new instance. - /// - /// The combination of keys which will trigger this binding. - /// The resultant action which is triggered by this binding. Usually an enum type. - public Setting(object key, object value) - { - Key = key; - Value = value; - } - - /// - /// Constructor for derived classes that may require serialisation. - /// - public Setting() - { - } - - public override string ToString() => $"{Key}=>{Value}"; - } -} + \ No newline at end of file diff --git a/osu.Game/Configuration/SettingsStore.cs b/osu.Game/Configuration/SettingsStore.cs index 3bcdc05496..6bb186604f 100644 --- a/osu.Game/Configuration/SettingsStore.cs +++ b/osu.Game/Configuration/SettingsStore.cs @@ -26,14 +26,13 @@ namespace osu.Game.Configuration public List Query(int? rulesetId = null) => GetContext().DatabasedSetting.Where(b => b.RulesetID == rulesetId).ToList(); - public void Update(Setting setting) + public void Update(DatabasedSetting setting) { - var dbSetting = (DatabasedSetting)setting; - var context = GetContext(); - Refresh(ref dbSetting); - dbSetting.Value = setting.Value; + Refresh(ref setting); + + setting.Value = setting.Value; context.SaveChanges(); SettingChanged?.Invoke(); From 72df2c681b6c63a32b9d3da4c23bbed9c0613f6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jan 2018 18:01:39 +0900 Subject: [PATCH 50/83] Remove game-wise settings store for the time being --- osu.Game/OsuGameBase.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index d0b9634696..8b317ca59a 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -44,8 +44,6 @@ namespace osu.Game protected KeyBindingStore KeyBindingStore; - protected SettingsStore SettingsStore; - protected CursorOverrideContainer CursorOverrideContainer; protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -111,7 +109,6 @@ namespace osu.Game dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory.GetContext, RulesetStore, API, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, contextFactory.GetContext, Host, BeatmapManager, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory.GetContext, RulesetStore)); - dependencies.Cache(SettingsStore = new SettingsStore(contextFactory.GetContext)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. From 53c6526b22e77eecf5f6ff5c9c045422fbb31f20 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jan 2018 18:04:54 +0900 Subject: [PATCH 51/83] Remove unused code file --- osu.Game/Configuration/Setting.cs | 1 - osu.Game/osu.Game.csproj | 1 - 2 files changed, 2 deletions(-) delete mode 100644 osu.Game/Configuration/Setting.cs diff --git a/osu.Game/Configuration/Setting.cs b/osu.Game/Configuration/Setting.cs deleted file mode 100644 index 5f282702bb..0000000000 --- a/osu.Game/Configuration/Setting.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 56cfe6646c..2a09521727 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,7 +266,6 @@ - From b77f08941c6238ffb32b20a6d35a524262960f4d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 24 Jan 2018 20:05:11 +0900 Subject: [PATCH 52/83] Make mania play the next note's sounds if no note is hit Fixes #1911. This follows what osu!stable does, which is rather unfortunate, since it just plays _every_ sound for the note :|. --- osu.Game.Rulesets.Mania/UI/Column.cs | 24 ++++++++++++++++++- .../Objects/Drawables/DrawableHitObject.cs | 5 +++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 882628642b..21f00c003b 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -11,13 +11,14 @@ using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using System; +using System.Linq; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI { - public class Column : ScrollingPlayfield, IHasAccentColour + public class Column : ScrollingPlayfield, IKeyBindingHandler, IHasAccentColour { private const float key_icon_size = 10; private const float key_icon_corner_radius = 3; @@ -259,5 +260,26 @@ namespace osu.Game.Rulesets.Mania.UI public bool OnPressed(ManiaAction action) => Pressed?.Invoke(action) ?? false; public bool OnReleased(ManiaAction action) => Released?.Invoke(action) ?? false; } + + public bool OnPressed(ManiaAction action) + { + // Play the sounds of the next hitobject + if (HitObjects.AliveObjects.Any()) + { + // If there are alive hitobjects, we can abuse the fact that AliveObjects are sorted by time (see: Add()) + HitObjects.AliveObjects.First().PlaySamples(); + } + else + { + // If not, we do a slow search - we might want to do a BinarySearch here if this becomes problematic + // We fallback to LastOrDefault() if we're beyond the last note in the map + var hitObject = HitObjects.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? HitObjects.Objects.LastOrDefault(); + hitObject?.PlaySamples(); + } + + return false; + } + + public bool OnReleased(ManiaAction action) => false; } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 8680ff4e83..2db02724ed 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -136,7 +136,10 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public event Action ApplyCustomUpdateState; - protected void PlaySamples() => Samples.ForEach(s => s?.Play()); + /// + /// Plays all the hitsounds for this . + /// + public void PlaySamples() => Samples.ForEach(s => s?.Play()); protected override void Update() { From 51e188401f7a55246e04bfe9f1037f0a24aa382b Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Thu, 25 Jan 2018 00:38:22 +0300 Subject: [PATCH 53/83] Make MusicController draggable again --- osu.Game/Overlays/MusicController.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d9e08a48ba..b3140d8bd0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -5,8 +5,6 @@ using System; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -20,10 +18,12 @@ using osu.Framework.Localisation; using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.Music; -using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Music; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Overlays { @@ -65,6 +65,12 @@ namespace osu.Game.Overlays AlwaysPresent = true; } + protected override bool OnDragStart(InputState state) + { + base.OnDragStart(state); + return true; + } + protected override bool OnDrag(InputState state) { if (base.OnDrag(state)) return true; From 794d82d83fb9df18673329ff29dba77ff8fae4f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Jan 2018 10:21:52 +0900 Subject: [PATCH 54/83] Add new default hitsounds Getting these in for more widespread feedback. --- osu-resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-resources b/osu-resources index 7724abdf1d..266965f0d7 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 7724abdf1d7c9705ba2e3989a9c604e17ccdc871 +Subproject commit 266965f0d795b94a126e2da302bd2c10eadd642a From 57cd50c45ee2d45f2ba9fb6804cce7acdc219066 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jan 2018 17:39:10 +0900 Subject: [PATCH 55/83] Reorder the way input is handled for replays Fixes https://github.com/ppy/osu/issues/1625 . --- .../Objects/Drawables/DrawableHitObject.cs | 2 ++ osu.Game/Rulesets/UI/RulesetInputManager.cs | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 2db02724ed..e4f8124bce 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -71,6 +71,8 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool HandleKeyboardInput => Interactive; public override bool HandleMouseInput => Interactive; + public override bool MaskingAffectsInput => false; + public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 223586a959..e32b38a013 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -136,9 +136,20 @@ namespace osu.Game.Rulesets.UI int loops = 0; while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame) + { if (!base.UpdateSubTree()) return false; + if (isAttached) + { + // When handling replay input, we need to consider the possibility of fast-forwarding, which may cause the clock to be updated + // to a point very far into the future, then playing a frame at that time. In such a case, lifetime MUST be updated before + // input is handled. This is why base.Update is not called from the derived Update when handling replay input, and is instead + // called manually at the correct time here. + base.Update(); + } + } + return true; } @@ -173,8 +184,11 @@ namespace osu.Game.Rulesets.UI // to ensure that the its time is valid for our children before input is processed Clock.ProcessFrame(); - // Process input - base.Update(); + if (!isAttached) + { + // For non-replay input handling, this provides equivalent input ordering as if Update was not overridden + base.Update(); + } } #endregion From c2a58223c55134223ea573d6f1a6e8cb8170e900 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Jan 2018 17:55:41 +0900 Subject: [PATCH 56/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 736a139a74..8c8d8242a8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 736a139a748eba7cebea41a09b404d47ca589522 +Subproject commit 8c8d8242a8ae78ba272e5e7e89fb7662fca9a1e9 From 80b8780f560f225b184e7fe8b1a0947fd6e202ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jan 2018 18:01:39 +0900 Subject: [PATCH 57/83] Revert "Remove game-wise settings store for the time being" This reverts commit 72df2c681b6c63a32b9d3da4c23bbed9c0613f6c. --- osu.Game/OsuGameBase.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8b317ca59a..d0b9634696 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -44,6 +44,8 @@ namespace osu.Game protected KeyBindingStore KeyBindingStore; + protected SettingsStore SettingsStore; + protected CursorOverrideContainer CursorOverrideContainer; protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -109,6 +111,7 @@ namespace osu.Game dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory.GetContext, RulesetStore, API, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, contextFactory.GetContext, Host, BeatmapManager, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory.GetContext, RulesetStore)); + dependencies.Cache(SettingsStore = new SettingsStore(contextFactory.GetContext)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. From 45e8a2b69bce8a09d7c5a7cbed00b216c5431e9d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jan 2018 20:49:18 +0900 Subject: [PATCH 58/83] Remove ManiaPlayfield local scrollTime bindable Now not needed due to having this databased. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 9911be9daa..c3cbf81af1 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -80,18 +80,10 @@ namespace osu.Game.Rulesets.Mania.UI return null; } - private Bindable scrollTime; - [BackgroundDependencyLoader] private void load(ManiaConfigManager maniaConfig) { maniaConfig.BindWith(ManiaSetting.ScrollTime, VisibleTimeRange); - - // Todo: The following two lines shouldn't be required, but is an effect of not having config databased - // 1. ValueChanged is run prior to values being propagated - // 2. We want the config to be saved ASAP, in-case a new ManiaPlayfield is instantiated - scrollTime = maniaConfig.GetBindable(ManiaSetting.ScrollTime); - scrollTime.ValueChanged += v => maniaConfig.Save(); } internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) From 92df704fbd235f4637f6f31888f8bba1c9faebe8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jan 2018 21:37:38 +0900 Subject: [PATCH 59/83] Fix up taiko not having any important frames --- .../Replays/TaikoAutoGenerator.cs | 14 +++++++------- .../Replays/TaikoReplayFrame.cs | 17 +++++++++++++++++ .../osu.Game.Rulesets.Taiko.csproj | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index c1fe2c13a8..002159439d 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -35,8 +35,8 @@ namespace osu.Game.Rulesets.Taiko.Replays { bool hitButton = true; - Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None)); - Frames.Add(new ReplayFrame(Beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None)); + Frames.Add(new TaikoReplayFrame(-100000, ReplayButtonState.None)); + Frames.Add(new TaikoReplayFrame(Beatmap.HitObjects[0].StartTime - 1000, ReplayButtonState.None)); for (int i = 0; i < Beatmap.HitObjects.Count; i++) { @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Replays break; } - Frames.Add(new ReplayFrame(j, null, null, button)); + Frames.Add(new TaikoReplayFrame(j, button)); d = (d + 1) % 4; if (++count == req) break; @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Replays { foreach (var tick in drumRoll.NestedHitObjects.OfType()) { - Frames.Add(new ReplayFrame(tick.StartTime, null, null, hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2)); + Frames.Add(new TaikoReplayFrame(tick.StartTime, hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2)); hitButton = !hitButton; } } @@ -107,18 +107,18 @@ namespace osu.Game.Rulesets.Taiko.Replays button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2; } - Frames.Add(new ReplayFrame(h.StartTime, null, null, button)); + Frames.Add(new TaikoReplayFrame(h.StartTime, button)); } else throw new InvalidOperationException("Unknown hit object type."); - Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None)); + Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY, ReplayButtonState.None)); if (i < Beatmap.HitObjects.Count - 1) { double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000; if (waitTime > endTime) - Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None)); + Frames.Add(new TaikoReplayFrame(waitTime, ReplayButtonState.None)); } hitButton = !hitButton; diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs new file mode 100644 index 0000000000..0c60cdc109 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Replays; + +namespace osu.Game.Rulesets.Taiko.Replays +{ + public class TaikoReplayFrame : ReplayFrame + { + public override bool IsImportant => MouseLeft || MouseRight; + + public TaikoReplayFrame(double time, ReplayButtonState buttons) + : base(time, null, null, buttons) + { + } + } +} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 36ac9384cf..7fb764fd0b 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -91,6 +91,7 @@ + From 03154dbc6307f9ea9ac8f1fbb2cb19b15ab94432 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Jan 2018 23:41:03 +0900 Subject: [PATCH 60/83] Fix incorrect initial migration Also adds variant to settings --- .../Configuration/ManiaConfigManager.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 10 ++++------ osu.Game/Configuration/DatabasedConfigManager.cs | 4 ++-- osu.Game/Configuration/DatabasedSetting.cs | 2 ++ osu.Game/Configuration/SettingsStore.cs | 4 ++-- osu.Game/Database/OsuDbContext.cs | 2 +- ...signer.cs => 20180125143340_Settings.Designer.cs} | 12 +++++++----- ...000_AddSettings.cs => 20180125143340_Settings.cs} | 11 ++++++----- osu.Game/Migrations/OsuDbContextModelSnapshot.cs | 8 +++++--- .../Rulesets/Configuration/RulesetConfigManager.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 5 +++++ osu.Game/osu.Game.csproj | 6 +++--- 12 files changed, 40 insertions(+), 30 deletions(-) rename osu.Game/Migrations/{20180124024000_AddSettings.Designer.cs => 20180125143340_Settings.Designer.cs} (94%) rename osu.Game/Migrations/{20180124024000_AddSettings.cs => 20180125143340_Settings.cs} (80%) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs index 3167d8300d..a4de360870 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs @@ -9,8 +9,8 @@ namespace osu.Game.Rulesets.Mania.Configuration { public class ManiaConfigManager : RulesetConfigManager { - public ManiaConfigManager(RulesetInfo ruleset, SettingsStore settings) - : base(ruleset, settings) + public ManiaConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant) + : base(settings, ruleset, variant) { } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index f517d6b041..436d5c1ea6 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -80,11 +80,9 @@ namespace osu.Game.Rulesets.Mania.UI public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this); - public override PassThroughInputManager CreateInputManager() - { - var variantType = Mods.OfType().FirstOrDefault()?.PlayfieldType ?? PlayfieldType.Single; - return new ManiaInputManager(Ruleset.RulesetInfo, (int)variantType + Beatmap.TotalColumns); - } + public override int Variant => (int)(Mods.OfType().FirstOrDefault()?.PlayfieldType ?? PlayfieldType.Single) + Beatmap.TotalColumns; + + public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant); protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(IsForCurrentRuleset, WorkingBeatmap.Beatmap); @@ -107,6 +105,6 @@ namespace osu.Game.Rulesets.Mania.UI protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this); - protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => new ManiaConfigManager(Ruleset.RulesetInfo, settings); + protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => new ManiaConfigManager(settings, Ruleset.RulesetInfo, Variant); } } diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index f982490523..5505f3d31b 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -17,12 +17,12 @@ namespace osu.Game.Configuration private readonly RulesetInfo ruleset; - protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null) + protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int variant = 0) { this.settings = settings; this.ruleset = ruleset; - databasedSettings = settings.Query(ruleset?.ID); + databasedSettings = settings.Query(ruleset?.ID, variant); InitialiseDefaults(); } diff --git a/osu.Game/Configuration/DatabasedSetting.cs b/osu.Game/Configuration/DatabasedSetting.cs index c284c10872..7c2f65c854 100644 --- a/osu.Game/Configuration/DatabasedSetting.cs +++ b/osu.Game/Configuration/DatabasedSetting.cs @@ -14,6 +14,8 @@ namespace osu.Game.Configuration public int? RulesetID { get; set; } + public int? Variant { get; set; } + [Column("Key")] public int IntKey { diff --git a/osu.Game/Configuration/SettingsStore.cs b/osu.Game/Configuration/SettingsStore.cs index 6bb186604f..536b4f5786 100644 --- a/osu.Game/Configuration/SettingsStore.cs +++ b/osu.Game/Configuration/SettingsStore.cs @@ -23,8 +23,8 @@ namespace osu.Game.Configuration /// The ruleset's internal ID. /// An optional variant. /// - public List Query(int? rulesetId = null) => - GetContext().DatabasedSetting.Where(b => b.RulesetID == rulesetId).ToList(); + public List Query(int? rulesetId = null, int? variant = null) => + GetContext().DatabasedSetting.Where(b => b.RulesetID == rulesetId && b.Variant == variant).ToList(); public void Update(DatabasedSetting setting) { diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index be0b4f3543..0fa1f238a9 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -91,7 +91,7 @@ namespace osu.Game.Database modelBuilder.Entity().HasIndex(b => new { b.RulesetID, b.Variant }); modelBuilder.Entity().HasIndex(b => b.IntAction); - modelBuilder.Entity().HasIndex(b => b.RulesetID); + modelBuilder.Entity().HasIndex(b => new { b.RulesetID, b.Variant }); modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); modelBuilder.Entity().HasIndex(b => b.ReferenceCount); diff --git a/osu.Game/Migrations/20180124024000_AddSettings.Designer.cs b/osu.Game/Migrations/20180125143340_Settings.Designer.cs similarity index 94% rename from osu.Game/Migrations/20180124024000_AddSettings.Designer.cs rename to osu.Game/Migrations/20180125143340_Settings.Designer.cs index 5bbf382f7f..8e045abc6f 100644 --- a/osu.Game/Migrations/20180124024000_AddSettings.Designer.cs +++ b/osu.Game/Migrations/20180125143340_Settings.Designer.cs @@ -10,8 +10,8 @@ using System; namespace osu.Game.Migrations { [DbContext(typeof(OsuDbContext))] - [Migration("20180124024000_AddSettings")] - partial class AddSettings + [Migration("20180125143340_Settings")] + partial class Settings { protected override void BuildTargetModel(ModelBuilder modelBuilder) { @@ -202,14 +202,16 @@ namespace osu.Game.Migrations b.Property("IntKey") .HasColumnName("Key"); - b.Property("IntValue") + b.Property("RulesetID"); + + b.Property("StringValue") .HasColumnName("Value"); - b.Property("RulesetID"); + b.Property("Variant"); b.HasKey("ID"); - b.HasIndex("RulesetID"); + b.HasIndex("RulesetID", "Variant"); b.ToTable("Settings"); }); diff --git a/osu.Game/Migrations/20180124024000_AddSettings.cs b/osu.Game/Migrations/20180125143340_Settings.cs similarity index 80% rename from osu.Game/Migrations/20180124024000_AddSettings.cs rename to osu.Game/Migrations/20180125143340_Settings.cs index 63cacc0645..86a6b2dc5e 100644 --- a/osu.Game/Migrations/20180124024000_AddSettings.cs +++ b/osu.Game/Migrations/20180125143340_Settings.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace osu.Game.Migrations { - public partial class AddSettings : Migration + public partial class Settings : Migration { protected override void Up(MigrationBuilder migrationBuilder) { @@ -19,8 +19,9 @@ namespace osu.Game.Migrations ID = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), Key = table.Column(type: "INTEGER", nullable: false), - Value = table.Column(type: "INTEGER", nullable: false), - RulesetID = table.Column(type: "INTEGER", nullable: true) + RulesetID = table.Column(type: "INTEGER", nullable: true), + Value = table.Column(type: "TEXT", nullable: true), + Variant = table.Column(type: "INTEGER", nullable: true) }, constraints: table => { @@ -33,9 +34,9 @@ namespace osu.Game.Migrations columns: new[] { "RulesetID", "Variant" }); migrationBuilder.CreateIndex( - name: "IX_Settings_RulesetID", + name: "IX_Settings_RulesetID_Variant", table: "Settings", - column: "RulesetID"); + columns: new[] { "RulesetID", "Variant" }); } protected override void Down(MigrationBuilder migrationBuilder) diff --git a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs index 37e2aee3a0..157125102f 100644 --- a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs +++ b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs @@ -201,14 +201,16 @@ namespace osu.Game.Migrations b.Property("IntKey") .HasColumnName("Key"); - b.Property("IntValue") + b.Property("RulesetID"); + + b.Property("StringValue") .HasColumnName("Value"); - b.Property("RulesetID"); + b.Property("Variant"); b.HasKey("ID"); - b.HasIndex("RulesetID"); + b.HasIndex("RulesetID", "Variant"); b.ToTable("Settings"); }); diff --git a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs index 4f9fbe9830..9f244f6267 100644 --- a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs @@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Configuration public abstract class RulesetConfigManager : DatabasedConfigManager, IRulesetConfigManager where T : struct { - protected RulesetConfigManager(RulesetInfo ruleset, SettingsStore settings) : base(settings, ruleset) + protected RulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant) : base(settings, ruleset, variant) { } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 08498d48c6..8f72644b28 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -38,6 +38,11 @@ namespace osu.Game.Rulesets.UI /// public bool AspectAdjust = true; + /// + /// The selected variant. + /// + public virtual int Variant => 0; + /// /// The input manager for this RulesetContainer. /// diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2a09521727..7f88f65a24 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -272,9 +272,9 @@ - - - 20180124024000_AddSettings.cs + + + 20180125143340_Settings.cs From 3b9318e894e206d436bbb8d9a124431b8fe7a8ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Jan 2018 07:39:03 +0900 Subject: [PATCH 61/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 8c8d8242a8..332d133a66 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 8c8d8242a8ae78ba272e5e7e89fb7662fca9a1e9 +Subproject commit 332d133a667b2a4d628d08878967e26bc5aae441 From 7a2420ead273a65707e162409b6b6ed46f099ebd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Jan 2018 08:21:09 +0900 Subject: [PATCH 62/83] Fix a couple of regressions --- osu.Game/Configuration/DatabasedConfigManager.cs | 6 +++++- osu.Game/Configuration/SettingsStore.cs | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index 5505f3d31b..7d045ff6d4 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -13,6 +13,8 @@ namespace osu.Game.Configuration { private readonly SettingsStore settings; + private int variant; + private readonly List databasedSettings; private readonly RulesetInfo ruleset; @@ -21,6 +23,7 @@ namespace osu.Game.Configuration { this.settings = settings; this.ruleset = ruleset; + this.variant = variant; databasedSettings = settings.Query(ruleset?.ID, variant); @@ -51,7 +54,8 @@ namespace osu.Game.Configuration { Key = lookup, Value = bindable.Value, - RulesetID = ruleset?.ID + RulesetID = ruleset?.ID, + Variant = variant, }); databasedSettings.Add(setting); diff --git a/osu.Game/Configuration/SettingsStore.cs b/osu.Game/Configuration/SettingsStore.cs index 536b4f5786..9b18151c84 100644 --- a/osu.Game/Configuration/SettingsStore.cs +++ b/osu.Game/Configuration/SettingsStore.cs @@ -30,9 +30,12 @@ namespace osu.Game.Configuration { var context = GetContext(); + var newValue = setting.Value; + Refresh(ref setting); - setting.Value = setting.Value; + setting.Value = newValue; + context.SaveChanges(); SettingChanged?.Invoke(); From 0a505dde2e73b89ffeb259090e6e2d577a3c80d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Jan 2018 14:47:16 +0900 Subject: [PATCH 63/83] Remove MaskingAffectsInput override --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e4f8124bce..2db02724ed 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -71,8 +71,6 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool HandleKeyboardInput => Interactive; public override bool HandleMouseInput => Interactive; - public override bool MaskingAffectsInput => false; - public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; From db58e4dbfed992ba503727077b994784de30866f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Jan 2018 15:02:55 +0900 Subject: [PATCH 64/83] Update framework again --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 332d133a66..209021fb49 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 332d133a667b2a4d628d08878967e26bc5aae441 +Subproject commit 209021fb491e21625127be5dbf5efb4c409e6f06 From 81c759f1e1f6ad1e21bf6c224fca15817af2cf54 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Fri, 26 Jan 2018 15:17:56 +0900 Subject: [PATCH 65/83] Make field readonly --- osu.Game/Configuration/DatabasedConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index 7d045ff6d4..1f7a84c6d3 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -13,7 +13,7 @@ namespace osu.Game.Configuration { private readonly SettingsStore settings; - private int variant; + private readonly int variant; private readonly List databasedSettings; From 1ab2a4075f7bd25fbdc87c1365e142a8935a75ef Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Jan 2018 15:39:37 +0900 Subject: [PATCH 66/83] Update resources --- osu-resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-resources b/osu-resources index 7724abdf1d..266965f0d7 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 7724abdf1d7c9705ba2e3989a9c604e17ccdc871 +Subproject commit 266965f0d795b94a126e2da302bd2c10eadd642a From 7852015db32daf8c1ebf54413c7393e3781ae60f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Jan 2018 19:30:29 +0900 Subject: [PATCH 67/83] Remember mod selection when re-entering song select Removes mod application when exiting back to main menu. Alternative to #1968. Closes #1961. --- osu.Game/OsuGame.cs | 5 ++ osu.Game/Overlays/Mods/ModButton.cs | 16 +++--- osu.Game/Overlays/Mods/ModSection.cs | 17 +++++++ osu.Game/Overlays/Mods/ModSelectOverlay.cs | 59 +++++++++++++--------- osu.Game/Screens/Select/PlaySongSelect.cs | 9 +++- 5 files changed, 74 insertions(+), 32 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 034b857e02..7e50f84089 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Framework.Configuration; using osu.Framework.Screens; using osu.Game.Configuration; @@ -27,6 +28,7 @@ using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; using osu.Game.Screens.Play; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Mods; using OpenTK.Graphics; namespace osu.Game @@ -80,6 +82,9 @@ namespace osu.Game private SettingsOverlay settings; + // todo: move this to SongSelect once Screen has the ability to unsuspend. + public readonly Bindable> SelectedMods = new Bindable>(new List()); + public OsuGame(string[] args = null) { this.args = args; diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 80823c56bf..91063bfa38 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -188,17 +188,19 @@ namespace osu.Game.Overlays.Mods start = Mods.Length - 1; for (int i = start; i < Mods.Length && i >= 0; i += direction) - { - if (Mods[i].HasImplementation) - { - changeSelectedIndex(i); - return; - } - } + if (SelectAt(i)) return; Deselect(); } + public bool SelectAt(int index) + { + if (!Mods[index].HasImplementation) return false; + + changeSelectedIndex(index); + return true; + } + public void Deselect() => changeSelectedIndex(-1); private void displayMod(Mod mod) diff --git a/osu.Game/Overlays/Mods/ModSection.cs b/osu.Game/Overlays/Mods/ModSection.cs index a43c54f994..03c1f0468c 100644 --- a/osu.Game/Overlays/Mods/ModSection.cs +++ b/osu.Game/Overlays/Mods/ModSection.cs @@ -113,6 +113,23 @@ namespace osu.Game.Overlays.Mods } } + /// + /// Select one or more mods in this section. + /// + /// The types of s which should be deselected. + public void SelectTypes(IEnumerable mods) + { + foreach (var button in buttons) + { + for (int i = 0; i < button.Mods.Length; i++) + { + foreach (var mod in mods) + if (mod.GetType().IsInstanceOfType(button.Mods[i])) + button.SelectAt(i); + } + } + } + protected ModSection() { AutoSizeAxes = Axes.Y; diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 96faa376ba..d7268fb186 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -51,6 +51,8 @@ namespace osu.Game.Overlays.Mods [BackgroundDependencyLoader(permitNulls: true)] private void load(OsuColour colours, OsuGame osu, RulesetStore rulesets) { + SelectedMods.ValueChanged += selectedModsChanged; + LowMultiplierColour = colours.Red; HighMultiplierColour = colours.Green; @@ -63,6 +65,37 @@ namespace osu.Game.Overlays.Mods Ruleset.TriggerChange(); } + private void selectedModsChanged(IEnumerable obj) + { + foreach (ModSection section in ModSectionsContainer.Children) + section.SelectTypes(obj); + + updateMods(); + } + + private void updateMods() + { + double multiplier = 1.0; + bool ranked = true; + + foreach (Mod mod in SelectedMods.Value) + { + multiplier *= mod.ScoreMultiplier; + ranked &= mod.Ranked; + } + + MultiplierLabel.Text = $"{multiplier:N2}x"; + if (!ranked) + MultiplierLabel.Text += " (Unranked)"; + + if (multiplier > 1.0) + MultiplierLabel.FadeColour(HighMultiplierColour, 200); + else if (multiplier < 1.0) + MultiplierLabel.FadeColour(LowMultiplierColour, 200); + else + MultiplierLabel.FadeColour(Color4.White, 200); + } + protected override void PopOut() { base.PopOut(); @@ -97,6 +130,7 @@ namespace osu.Game.Overlays.Mods { foreach (ModSection section in ModSectionsContainer.Children) section.DeselectAll(); + refreshSelectedMods(); } @@ -119,30 +153,7 @@ namespace osu.Game.Overlays.Mods refreshSelectedMods(); } - private void refreshSelectedMods() - { - SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray(); - - double multiplier = 1.0; - bool ranked = true; - - foreach (Mod mod in SelectedMods.Value) - { - multiplier *= mod.ScoreMultiplier; - ranked &= mod.Ranked; - } - - MultiplierLabel.Text = $"{multiplier:N2}x"; - if (!ranked) - MultiplierLabel.Text += " (Unranked)"; - - if (multiplier > 1.0) - MultiplierLabel.FadeColour(HighMultiplierColour, 200); - else if (multiplier < 1.0) - MultiplierLabel.FadeColour(LowMultiplierColour, 200); - else - MultiplierLabel.FadeColour(Color4.White, 200); - } + private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray(); public ModSelectOverlay() { diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 6fdd38ce30..739bc39269 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays; using osu.Game.Overlays.Mods; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Edit; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; @@ -47,10 +48,13 @@ namespace osu.Game.Screens.Select private SampleChannel sampleConfirm; [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay) + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame game) { sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection"); + if (game != null) + modSelect.SelectedMods.BindTo(game.SelectedMods); + Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue); BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1); @@ -121,6 +125,9 @@ namespace osu.Game.Screens.Select if (Beatmap.Value.Track != null) Beatmap.Value.Track.Looping = false; + Beatmap.Value.Mods.UnbindBindings(); + Beatmap.Value.Mods.Value = new Mod[] { }; + return false; } From 8f0ab2040f30f6328851227e780ded1ca07ec889 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Fri, 26 Jan 2018 12:46:28 +0100 Subject: [PATCH 68/83] Add Jetbrains.Annotations NuGet package --- osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj | 4 ++++ osu.Game.Rulesets.Catch/packages.config | 1 + osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 4 ++++ osu.Game.Rulesets.Mania/packages.config | 1 + osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 4 ++++ osu.Game.Rulesets.Osu/packages.config | 1 + osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj | 4 ++++ osu.Game.Rulesets.Taiko/packages.config | 1 + osu.Game.Tests/osu.Game.Tests.csproj | 4 ++++ osu.Game.Tests/packages.config | 1 + osu.Game/osu.Game.csproj | 4 ++++ osu.Game/packages.config | 1 + 12 files changed, 30 insertions(+) diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 5f08048bf9..cdce598ce8 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -32,6 +32,10 @@ false + + $(SolutionDir)\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll + True + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True diff --git a/osu.Game.Rulesets.Catch/packages.config b/osu.Game.Rulesets.Catch/packages.config index b39a85a382..e67d3e9b34 100644 --- a/osu.Game.Rulesets.Catch/packages.config +++ b/osu.Game.Rulesets.Catch/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 9b6b546b5f..b9e7f8e60f 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -32,6 +32,10 @@ false + + $(SolutionDir)\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll + True + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True diff --git a/osu.Game.Rulesets.Mania/packages.config b/osu.Game.Rulesets.Mania/packages.config index b39a85a382..e67d3e9b34 100644 --- a/osu.Game.Rulesets.Mania/packages.config +++ b/osu.Game.Rulesets.Mania/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index a59d4607df..74a3883f0a 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -33,6 +33,10 @@ false + + $(SolutionDir)\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll + True + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True diff --git a/osu.Game.Rulesets.Osu/packages.config b/osu.Game.Rulesets.Osu/packages.config index b39a85a382..e67d3e9b34 100644 --- a/osu.Game.Rulesets.Osu/packages.config +++ b/osu.Game.Rulesets.Osu/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 36ac9384cf..90256c7d63 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -32,6 +32,10 @@ false + + $(SolutionDir)\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll + True + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True diff --git a/osu.Game.Rulesets.Taiko/packages.config b/osu.Game.Rulesets.Taiko/packages.config index b39a85a382..e67d3e9b34 100644 --- a/osu.Game.Rulesets.Taiko/packages.config +++ b/osu.Game.Rulesets.Taiko/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 059adc6d55..d30241fae4 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -33,6 +33,10 @@ $(SolutionDir)\packages\DeepEqual.1.6.0.0\lib\net40\DeepEqual.dll + + $(SolutionDir)\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll + True + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index 62ddb99609..71c79cd26e 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -5,6 +5,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste --> + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7f88f65a24..12ca9e5de7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -91,6 +91,10 @@ $(SolutionDir)\packages\Humanizer.Core.2.2.0\lib\netstandard1.0\Humanizer.dll + + $(SolutionDir)\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll + True + $(SolutionDir)\packages\Microsoft.Data.Sqlite.Core.2.0.0\lib\netstandard2.0\Microsoft.Data.Sqlite.dll diff --git a/osu.Game/packages.config b/osu.Game/packages.config index 2938739eef..0216c8ae67 100644 --- a/osu.Game/packages.config +++ b/osu.Game/packages.config @@ -47,6 +47,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste + From cff3f25cd7d41ea06e2f9067c1cabeab85510e0f Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Fri, 26 Jan 2018 12:46:58 +0100 Subject: [PATCH 69/83] make all line endings CR LF (windows style) --- osu.Game.Tests/packages.config | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index 71c79cd26e..c16d10bf45 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -1,12 +1,12 @@ - - - - - - - - + + + + + + + + \ No newline at end of file From 247833174cd567e75f3d703e029059fa9a6b0676 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 27 Jan 2018 23:20:49 +0900 Subject: [PATCH 70/83] Fix incorrect case on migration file --- 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 7f88f65a24..8be79e8279 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -273,7 +273,7 @@ - + 20180125143340_Settings.cs From b789db3a1e645c7c72dc20209932df606d99a60f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 Jan 2018 13:53:35 +0900 Subject: [PATCH 71/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 209021fb49..9c4b79ed97 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 209021fb491e21625127be5dbf5efb4c409e6f06 +Subproject commit 9c4b79ed97eb89dc163cca837e197bfbf41400e3 From fc11cac5a0362f5a4cf630c079a41d26ed6aadeb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 Jan 2018 15:03:19 +0900 Subject: [PATCH 72/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 9c4b79ed97..2610a31337 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 9c4b79ed97eb89dc163cca837e197bfbf41400e3 +Subproject commit 2610a3133721b0bc4af852342aa2a179d0e66497 From 6e0cb1adb3ad0b0d153118e9c048d24ce7066099 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 Jan 2018 15:05:07 +0900 Subject: [PATCH 73/83] Remove redundant arguments --- osu.Game/OsuGame.cs | 2 +- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 034b857e02..d1555c7270 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -111,7 +111,7 @@ namespace osu.Game Task.Run(() => BeatmapManager.Import(paths.ToArray())); } - dependencies.CacheAs(this); + dependencies.CacheAs(this); configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index d0b9634696..794e829e7b 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -95,7 +95,7 @@ namespace osu.Game dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore(Resources, @"Textures")))); - dependencies.CacheAs(this); + dependencies.CacheAs(this); dependencies.Cache(LocalConfig); runMigrations(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 79f00cc988..2421a4fdfe 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -181,7 +181,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(permitNulls: true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) { - dependencies.CacheAs(this); + dependencies.CacheAs(this); if (Footer != null) { From ef3fb8c05aa09d15920eb921d0d9251127cb49c6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 30 Jan 2018 14:49:12 +0900 Subject: [PATCH 74/83] InputManager -> Container where KeyBindings are involved --- ...ndingInputManager.cs => DatabasedKeyBindingContainer.cs} | 4 ++-- ...yBindingInputManager.cs => GlobalKeyBindingContainer.cs} | 4 ++-- osu.Game/OsuGameBase.cs | 4 ++-- osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs | 6 +++--- osu.Game/Overlays/KeyBindingOverlay.cs | 2 +- osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 +- osu.Game/osu.Game.csproj | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) rename osu.Game/Input/Bindings/{DatabasedKeyBindingInputManager.cs => DatabasedKeyBindingContainer.cs} (87%) rename osu.Game/Input/Bindings/{GlobalKeyBindingInputManager.cs => GlobalKeyBindingContainer.cs} (91%) diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs similarity index 87% rename from osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs rename to osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs index 4632c6c5f0..b6bc348a52 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Input.Bindings /// A KeyBindingInputManager with a database backing for custom overrides. /// /// The type of the custom action. - public class DatabasedKeyBindingInputManager : KeyBindingContainer + public class DatabasedKeyBindingContainer : KeyBindingContainer where T : struct { private readonly RulesetInfo ruleset; @@ -31,7 +31,7 @@ namespace osu.Game.Input.Bindings /// A reference to identify the current . Used to lookup mappings. Null for global mappings. /// An optional variant for the specified . Used when a ruleset has more than one possible keyboard layouts. /// Specify how to deal with multiple matches of s and s. - public DatabasedKeyBindingInputManager(RulesetInfo ruleset = null, int? variant = null, SimultaneousBindingMode simultaneousMode = SimultaneousBindingMode.None) + public DatabasedKeyBindingContainer(RulesetInfo ruleset = null, int? variant = null, SimultaneousBindingMode simultaneousMode = SimultaneousBindingMode.None) : base(simultaneousMode) { this.ruleset = ruleset; diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingContainer.cs similarity index 91% rename from osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs rename to osu.Game/Input/Bindings/GlobalKeyBindingContainer.cs index dcebe939d4..2b8de20c67 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingContainer.cs @@ -10,11 +10,11 @@ using osu.Framework.Input.Bindings; namespace osu.Game.Input.Bindings { - public class GlobalKeyBindingInputManager : DatabasedKeyBindingInputManager, IHandleGlobalInput + public class GlobalKeyBindingContainer : DatabasedKeyBindingContainer, IHandleGlobalInput { private readonly Drawable handler; - public GlobalKeyBindingInputManager(OsuGameBase game) + public GlobalKeyBindingContainer(OsuGameBase game) { if (game is IKeyBindingHandler) handler = game; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 794e829e7b..9823ca479b 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -212,10 +212,10 @@ namespace osu.Game { base.LoadComplete(); - GlobalKeyBindingInputManager globalBinding; + GlobalKeyBindingContainer globalBinding; CursorOverrideContainer = new CursorOverrideContainer { RelativeSizeAxes = Axes.Both }; - CursorOverrideContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) + CursorOverrideContainer.Child = globalBinding = new GlobalKeyBindingContainer(this) { RelativeSizeAxes = Axes.Both, Child = content = new OsuTooltipContainer(CursorOverrideContainer.Cursor) { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index f5b3096404..8e87cac087 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.KeyBinding public override FontAwesome Icon => FontAwesome.fa_osu_hot; public override string Header => "Global"; - public GlobalKeyBindingsSection(GlobalKeyBindingInputManager manager) + public GlobalKeyBindingsSection(GlobalKeyBindingContainer manager) { Add(new DefaultBindingsSubsection(manager)); Add(new InGameKeyBindingsSubsection(manager)); @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.KeyBinding { protected override string Header => string.Empty; - public DefaultBindingsSubsection(GlobalKeyBindingInputManager manager) + public DefaultBindingsSubsection(GlobalKeyBindingContainer manager) : base(null) { Defaults = manager.GlobalKeyBindings; @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.KeyBinding { protected override string Header => "In Game"; - public InGameKeyBindingsSubsection(GlobalKeyBindingInputManager manager) : base(null) + public InGameKeyBindingsSubsection(GlobalKeyBindingContainer manager) : base(null) { Defaults = manager.InGameKeyBindings; } diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index 18e43ad39b..b6902b1c09 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); [BackgroundDependencyLoader(permitNulls: true)] - private void load(RulesetStore rulesets, GlobalKeyBindingInputManager global) + private void load(RulesetStore rulesets, GlobalKeyBindingContainer global) { AddSection(new GlobalKeyBindingsSection(global)); diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 223586a959..6e06ca6903 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetInputManager : PassThroughInputManager, ICanAttachKeyCounter, IHasReplayHandler where T : struct { - public class RulesetKeyBindingContainer : DatabasedKeyBindingInputManager + public class RulesetKeyBindingContainer : DatabasedKeyBindingContainer { public RulesetKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5bcdd2c24d..6276797b6f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -446,8 +446,8 @@ - - + + From b4cd8ea7169efa65bf106fcefa6921d5cc930968 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 30 Jan 2018 14:54:30 +0900 Subject: [PATCH 75/83] GlobalKeyBindingContainer -> GlobalActionContainer Consitent with "FrameworkActionContainer". --- ...lobalKeyBindingContainer.cs => GlobalActionContainer.cs} | 4 ++-- osu.Game/OsuGameBase.cs | 4 ++-- osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs | 6 +++--- osu.Game/Overlays/KeyBindingOverlay.cs | 2 +- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) rename osu.Game/Input/Bindings/{GlobalKeyBindingContainer.cs => GlobalActionContainer.cs} (91%) diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs similarity index 91% rename from osu.Game/Input/Bindings/GlobalKeyBindingContainer.cs rename to osu.Game/Input/Bindings/GlobalActionContainer.cs index 2b8de20c67..46cda845aa 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -10,11 +10,11 @@ using osu.Framework.Input.Bindings; namespace osu.Game.Input.Bindings { - public class GlobalKeyBindingContainer : DatabasedKeyBindingContainer, IHandleGlobalInput + public class GlobalActionContainer : DatabasedKeyBindingContainer, IHandleGlobalInput { private readonly Drawable handler; - public GlobalKeyBindingContainer(OsuGameBase game) + public GlobalActionContainer(OsuGameBase game) { if (game is IKeyBindingHandler) handler = game; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 9823ca479b..937b204c81 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -212,10 +212,10 @@ namespace osu.Game { base.LoadComplete(); - GlobalKeyBindingContainer globalBinding; + GlobalActionContainer globalBinding; CursorOverrideContainer = new CursorOverrideContainer { RelativeSizeAxes = Axes.Both }; - CursorOverrideContainer.Child = globalBinding = new GlobalKeyBindingContainer(this) + CursorOverrideContainer.Child = globalBinding = new GlobalActionContainer(this) { RelativeSizeAxes = Axes.Both, Child = content = new OsuTooltipContainer(CursorOverrideContainer.Cursor) { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index 8e87cac087..a4c1621266 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.KeyBinding public override FontAwesome Icon => FontAwesome.fa_osu_hot; public override string Header => "Global"; - public GlobalKeyBindingsSection(GlobalKeyBindingContainer manager) + public GlobalKeyBindingsSection(GlobalActionContainer manager) { Add(new DefaultBindingsSubsection(manager)); Add(new InGameKeyBindingsSubsection(manager)); @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.KeyBinding { protected override string Header => string.Empty; - public DefaultBindingsSubsection(GlobalKeyBindingContainer manager) + public DefaultBindingsSubsection(GlobalActionContainer manager) : base(null) { Defaults = manager.GlobalKeyBindings; @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.KeyBinding { protected override string Header => "In Game"; - public InGameKeyBindingsSubsection(GlobalKeyBindingContainer manager) : base(null) + public InGameKeyBindingsSubsection(GlobalActionContainer manager) : base(null) { Defaults = manager.InGameKeyBindings; } diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index b6902b1c09..b311ee68c0 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); [BackgroundDependencyLoader(permitNulls: true)] - private void load(RulesetStore rulesets, GlobalKeyBindingContainer global) + private void load(RulesetStore rulesets, GlobalActionContainer global) { AddSection(new GlobalKeyBindingsSection(global)); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6276797b6f..4e048d60b9 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -447,7 +447,7 @@ - + From 042a34e1c23b263bd3d50f24e29e156ba8afb29b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 16:10:48 +0900 Subject: [PATCH 76/83] Add migration to ensure database aligns to changed enum --- .../20180131154205_AddMuteBinding.cs | 25 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 26 insertions(+) create mode 100644 osu.Game/Migrations/20180131154205_AddMuteBinding.cs diff --git a/osu.Game/Migrations/20180131154205_AddMuteBinding.cs b/osu.Game/Migrations/20180131154205_AddMuteBinding.cs new file mode 100644 index 0000000000..6948ad03da --- /dev/null +++ b/osu.Game/Migrations/20180131154205_AddMuteBinding.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Infrastructure; +using osu.Game.Database; +using osu.Game.Input.Bindings; + +namespace osu.Game.Migrations +{ + [DbContext(typeof(OsuDbContext))] + [Migration("20180131154205_AddMuteBinding")] + public partial class AddMuteBinding : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql($"UPDATE KeyBinding SET Action = Action + 1 WHERE RulesetID IS NULL AND Variant IS NULL AND Action >= {(int)GlobalAction.ToggleMute}"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("DELETE FROM KeyBinding WHERE RulesetID IS NULL AND Variant IS NULL AND Action = 8"); + migrationBuilder.Sql($"UPDATE KeyBinding SET Action = Action - 1 WHERE RulesetID IS NULL AND Variant IS NULL AND Action > {(int)GlobalAction.ToggleMute}"); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4e048d60b9..05cf61c23c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -280,6 +280,7 @@ 20180125143340_Settings.cs + From 5a99651561c97d2b607b69a7fd9485b17ab66817 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 16:10:55 +0900 Subject: [PATCH 77/83] Remove unnecessary arrays --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 918a4e374a..17ec2af4b9 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -29,10 +29,10 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), - new KeyBinding(new[] { InputKey.Up }, GlobalAction.IncreaseVolume), - new KeyBinding(new[] { InputKey.MouseWheelUp }, GlobalAction.IncreaseVolume), - new KeyBinding(new[] { InputKey.Down }, GlobalAction.DecreaseVolume), - new KeyBinding(new[] { InputKey.MouseWheelDown }, GlobalAction.DecreaseVolume), + new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume), + new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume), + new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume), + new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), }; From 2865dd3a10404408145ffe0a01caeef9734247a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 16:20:01 +0900 Subject: [PATCH 78/83] Replace missed hardcoded int with enum reference --- osu.Game/Migrations/20180131154205_AddMuteBinding.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Migrations/20180131154205_AddMuteBinding.cs b/osu.Game/Migrations/20180131154205_AddMuteBinding.cs index 6948ad03da..fc1f2fff55 100644 --- a/osu.Game/Migrations/20180131154205_AddMuteBinding.cs +++ b/osu.Game/Migrations/20180131154205_AddMuteBinding.cs @@ -18,7 +18,7 @@ namespace osu.Game.Migrations protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.Sql("DELETE FROM KeyBinding WHERE RulesetID IS NULL AND Variant IS NULL AND Action = 8"); + migrationBuilder.Sql($"DELETE FROM KeyBinding WHERE RulesetID IS NULL AND Variant IS NULL AND Action = {(int)GlobalAction.ToggleMute}"); migrationBuilder.Sql($"UPDATE KeyBinding SET Action = Action - 1 WHERE RulesetID IS NULL AND Variant IS NULL AND Action > {(int)GlobalAction.ToggleMute}"); } } From 97ae44f23c5b694249ad33acd27c3200a9871346 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 16:56:26 +0900 Subject: [PATCH 79/83] Remove outwards exposure of mute property --- osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 60242393ab..cfc8b81420 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -86,7 +86,7 @@ namespace osu.Game.Graphics.UserInterface.Volume return true; case GlobalAction.ToggleMute: Show(); - Muted = !Muted; + muted.Toggle(); return true; } @@ -103,12 +103,6 @@ namespace osu.Game.Graphics.UserInterface.Volume private readonly BindableBool muted = new BindableBool(); - public bool Muted - { - get => muted.Value; - set => muted.Value = value; - } - [BackgroundDependencyLoader] private void load(AudioManager audio) { From 86f5c9d6f140ce3ee117fdf56797766b4cce315d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 16:57:26 +0900 Subject: [PATCH 80/83] Add inactive volume ducking, rather than outright mute --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- osu.Game/OsuGame.cs | 16 ++++++---------- .../Settings/Sections/Audio/VolumeSettings.cs | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 230aabb2cd..c33dd91330 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -39,7 +39,7 @@ namespace osu.Game.Configuration }; // Audio - Set(OsuSetting.MuteWhenInactive, false); + Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01); Set(OsuSetting.MenuVoice, true); Set(OsuSetting.MenuMusic, true); @@ -103,7 +103,7 @@ namespace osu.Game.Configuration MouseDisableButtons, MouseDisableWheel, AudioOffset, - MuteWhenInactive, + VolumeInactive, MenuMusic, MenuVoice, CursorRotation, diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f1914b53b5..fbbc14dd5e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -19,6 +19,7 @@ using OpenTK; using System.Linq; using System.Threading; using System.Threading.Tasks; +using osu.Framework.Audio; using osu.Framework.Input.Bindings; using osu.Framework.Platform; using osu.Framework.Threading; @@ -122,7 +123,7 @@ namespace osu.Game Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; - muteWhenInactive = LocalConfig.GetBindable(OsuSetting.MuteWhenInactive); + LocalConfig.BindWith(OsuSetting.VolumeInactive, inactiveDuckVolume); } private ScheduledDelegate scoreLoad; @@ -400,24 +401,19 @@ namespace osu.Game return false; } - private Bindable muteWhenInactive = new Bindable(); - private bool wasMuted; + private readonly BindableDouble inactiveDuckVolume = new BindableDouble(); protected override void OnDeactivated() { base.OnDeactivated(); - if (muteWhenInactive) - { - wasMuted = volume.Muted; - volume.Muted = true; - } + Audio.AddAdjustment(AdjustableProperty.Volume, inactiveDuckVolume); } protected override void OnActivated() { base.OnActivated(); - if (IsLoaded && muteWhenInactive && !wasMuted) - volume.Muted = false; + Audio.RemoveAdjustment(AdjustableProperty.Volume, inactiveDuckVolume); + } public bool OnReleased(GlobalAction action) => false; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index 01bcf989dc..92ee01dd7a 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Settings.Sections.Audio Children = new Drawable[] { new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.1f }, + new SettingsSlider { LabelText = "Master (Window Inactive)", Bindable = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.1f }, new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.1f }, new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.1f }, - new SettingsCheckbox { LabelText = "Mute osu! when inactive", Bindable = config.GetBindable(OsuSetting.MuteWhenInactive) } }; } } From 93ffa1f8a2a1920e321522302dac97849db73926 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 17:36:53 +0900 Subject: [PATCH 81/83] Fix button alignment and animation --- osu.Game/Graphics/UserInterface/IconButton.cs | 4 ++-- .../Graphics/UserInterface/Volume/VolumeControl.cs | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index bcf6ab92b6..5b266d9a59 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface { public class IconButton : OsuClickableContainer { - private const float button_size = 30; + public const float BUTTON_SIZE = 30; private Color4? flashColour; /// @@ -106,7 +106,7 @@ namespace osu.Game.Graphics.UserInterface { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Size = new Vector2(button_size), + Size = new Vector2(BUTTON_SIZE), CornerRadius = 5, Masking = true, EdgeEffect = new EdgeEffectParameters diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index cfc8b81420..40c46d4ff8 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -36,11 +36,16 @@ namespace osu.Game.Graphics.UserInterface.Volume Spacing = new Vector2(15, 0), Children = new Drawable[] { - muteIcon = new IconButton + new Container { - Icon = FontAwesome.fa_volume_up, - Scale = new Vector2(2.0f), - Action = () => Adjust(GlobalAction.ToggleMute), + Size = new Vector2(IconButton.BUTTON_SIZE), + Child = muteIcon = new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_volume_up, + Action = () => Adjust(GlobalAction.ToggleMute), + } }, volumeMeterMaster = new VolumeMeter("Master"), volumeMeterEffect = new VolumeMeter("Effects"), From 47b92f3d1d6433b766d872669ec6691a63f73455 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 18:00:44 +0900 Subject: [PATCH 82/83] Fix mute button not prolonging volume control display --- .../UserInterface/Volume/VolumeControl.cs | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 40c46d4ff8..ccf70af6ed 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -59,18 +59,10 @@ namespace osu.Game.Graphics.UserInterface.Volume { base.LoadComplete(); - volumeMeterMaster.Bindable.ValueChanged += volumeChanged; - volumeMeterEffect.Bindable.ValueChanged += volumeChanged; - volumeMeterMusic.Bindable.ValueChanged += volumeChanged; - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - volumeMeterMaster.Bindable.ValueChanged -= volumeChanged; - volumeMeterEffect.Bindable.ValueChanged -= volumeChanged; - volumeMeterMusic.Bindable.ValueChanged -= volumeChanged; + volumeMeterMaster.Bindable.ValueChanged += _ => settingChanged(); + volumeMeterEffect.Bindable.ValueChanged += _ => settingChanged(); + volumeMeterMusic.Bindable.ValueChanged += _ => settingChanged(); + muted.ValueChanged += _ => settingChanged(); } public bool Adjust(GlobalAction action) @@ -98,13 +90,13 @@ namespace osu.Game.Graphics.UserInterface.Volume return false; } - private void volumeChanged(double newVolume) + private void settingChanged() { Show(); schedulePopOut(); } - private readonly BindableDouble muteBindable = new BindableDouble(); + private readonly BindableDouble muteAdjustment = new BindableDouble(); private readonly BindableBool muted = new BindableBool(); @@ -119,12 +111,12 @@ namespace osu.Game.Graphics.UserInterface.Volume { if (mute) { - audio.AddAdjustment(AdjustableProperty.Volume, muteBindable); + audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); muteIcon.Icon = FontAwesome.fa_volume_off; } else { - audio.RemoveAdjustment(AdjustableProperty.Volume, muteBindable); + audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); muteIcon.Icon = FontAwesome.fa_volume_up; } }; From fef69cea04049e376a0e29973fb9189cc859aca0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 31 Jan 2018 18:11:38 +0900 Subject: [PATCH 83/83] Revert "Add volume ducking" This reverts commit 01325de3a2897a24b2ba0f585d7e976d0fb44b70. --- osu.Game/Configuration/OsuConfigManager.cs | 3 --- osu.Game/OsuGame.cs | 18 ------------------ .../Settings/Sections/Audio/VolumeSettings.cs | 4 +--- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index c33dd91330..33810c9712 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -39,8 +39,6 @@ namespace osu.Game.Configuration }; // Audio - Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01); - Set(OsuSetting.MenuVoice, true); Set(OsuSetting.MenuMusic, true); @@ -103,7 +101,6 @@ namespace osu.Game.Configuration MouseDisableButtons, MouseDisableWheel, AudioOffset, - VolumeInactive, MenuMusic, MenuVoice, CursorRotation, diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fbbc14dd5e..bd71d37f97 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -19,7 +19,6 @@ using OpenTK; using System.Linq; using System.Threading; using System.Threading.Tasks; -using osu.Framework.Audio; using osu.Framework.Input.Bindings; using osu.Framework.Platform; using osu.Framework.Threading; @@ -122,8 +121,6 @@ namespace osu.Game configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; - - LocalConfig.BindWith(OsuSetting.VolumeInactive, inactiveDuckVolume); } private ScheduledDelegate scoreLoad; @@ -401,21 +398,6 @@ namespace osu.Game return false; } - private readonly BindableDouble inactiveDuckVolume = new BindableDouble(); - - protected override void OnDeactivated() - { - base.OnDeactivated(); - Audio.AddAdjustment(AdjustableProperty.Volume, inactiveDuckVolume); - } - - protected override void OnActivated() - { - base.OnActivated(); - Audio.RemoveAdjustment(AdjustableProperty.Volume, inactiveDuckVolume); - - } - public bool OnReleased(GlobalAction action) => false; private Container mainContent; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index 92ee01dd7a..40b9ff069b 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; -using osu.Game.Configuration; namespace osu.Game.Overlays.Settings.Sections.Audio { @@ -13,12 +12,11 @@ namespace osu.Game.Overlays.Settings.Sections.Audio protected override string Header => "Volume"; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config) + private void load(AudioManager audio) { Children = new Drawable[] { new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.1f }, - new SettingsSlider { LabelText = "Master (Window Inactive)", Bindable = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.1f }, new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.1f }, new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.1f }, };