diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleLongCombo.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleLongCombo.cs new file mode 100644 index 0000000000..f5fe36b56a --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleLongCombo.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Osu.Objects; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public class TestCaseHitCircleLongCombo : Game.Tests.Visual.TestCasePlayer + { + public TestCaseHitCircleLongCombo() + : base(new OsuRuleset()) + { + } + + protected override IBeatmap CreateBeatmap(Ruleset ruleset) + { + var beatmap = new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, + Ruleset = ruleset.RulesetInfo + } + }; + + for (int i = 0; i < 512; i++) + beatmap.HitObjects.Add(new HitCircle { Position = new Vector2(256, 192), StartTime = i * 100 }); + + return beatmap; + } + } +} diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index 3fef769174..3167e93923 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, IBindableBeatmap beatmap) + private void load(OsuConfigManager config, IBindable beatmap) { InternalChild = expandTarget = new Container { diff --git a/osu.Game.Tests/Visual/TestCaseDisclaimer.cs b/osu.Game.Tests/Visual/TestCaseDisclaimer.cs index d3a53e4a05..3ceb3eb4bd 100644 --- a/osu.Game.Tests/Visual/TestCaseDisclaimer.cs +++ b/osu.Game.Tests/Visual/TestCaseDisclaimer.cs @@ -2,27 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; using osu.Game.Screens.Menu; -using osuTK.Graphics; namespace osu.Game.Tests.Visual { - public class TestCaseDisclaimer : OsuTestCase + public class TestCaseDisclaimer : ScreenTestCase { [BackgroundDependencyLoader] private void load() { - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - new Disclaimer() - }; + LoadScreen(new Disclaimer()); } } } diff --git a/osu.Game.Tests/Visual/TestCaseDrawings.cs b/osu.Game.Tests/Visual/TestCaseDrawings.cs index 51f34d54db..aad135b71f 100644 --- a/osu.Game.Tests/Visual/TestCaseDrawings.cs +++ b/osu.Game.Tests/Visual/TestCaseDrawings.cs @@ -9,11 +9,11 @@ using osu.Game.Screens.Tournament.Teams; namespace osu.Game.Tests.Visual { [Description("for tournament use")] - public class TestCaseDrawings : OsuTestCase + public class TestCaseDrawings : ScreenTestCase { public TestCaseDrawings() { - Add(new Drawings + LoadScreen(new Drawings { TeamList = new TestTeamList(), }); diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 7e6edf78fc..a2f40f1903 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(IAdjustableClock adjustableClock, IBindableBeatmap beatmap) + private void load(IAdjustableClock adjustableClock, IBindable beatmap) { this.adjustableClock = adjustableClock; this.beatmap.BindTo(beatmap); diff --git a/osu.Game.Tests/Visual/TestCaseMatchResults.cs b/osu.Game.Tests/Visual/TestCaseMatchResults.cs index 9ef520af4b..582c035e82 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchResults.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchResults.cs @@ -40,10 +40,10 @@ namespace osu.Game.Tests.Visual Room.RoomID.Value = 1; Room.Name.Value = "an awesome room"; - Child = new TestMatchResults(new ScoreInfo + LoadScreen(new TestMatchResults(new ScoreInfo { User = new User { Id = 10 }, - }); + })); } private class TestMatchResults : MatchResults @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual { } - protected override IEnumerable CreateResultPages() => new[] { new TestRoomLeaderboardPageInfo(Score, Beatmap) }; + protected override IEnumerable CreateResultPages() => new[] { new TestRoomLeaderboardPageInfo(Score, Beatmap.Value) }; } private class TestRoomLeaderboardPageInfo : RoomLeaderboardPageInfo diff --git a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs index d83b90d6e1..fc4037f58b 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs @@ -12,7 +12,7 @@ using osu.Game.Screens.Multi.Lounge.Components; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestCaseMultiScreen : OsuTestCase + public class TestCaseMultiScreen : ScreenTestCase { public override IReadOnlyList RequiredTypes => new[] { @@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual { Multiplayer multi = new Multiplayer(); - AddStep(@"show", () => Add(multi)); + AddStep(@"show", () => LoadScreen(multi)); AddWaitStep(5); AddStep(@"exit", multi.Exit); } diff --git a/osu.Game.Tests/Visual/TestCaseOsuGame.cs b/osu.Game.Tests/Visual/TestCaseOsuGame.cs index 16087b5ad8..c527bce683 100644 --- a/osu.Game.Tests/Visual/TestCaseOsuGame.cs +++ b/osu.Game.Tests/Visual/TestCaseOsuGame.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Framework.Screens; using osu.Game.Screens; using osu.Game.Screens.Menu; using osuTK.Graphics; @@ -29,7 +30,10 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both, Colour = Color4.Black, }, - new Loader() + new ScreenStack(new Loader()) + { + RelativeSizeAxes = Axes.Both, + } }; } } diff --git a/osu.Game.Tests/Visual/TestCaseParallaxContainer.cs b/osu.Game.Tests/Visual/TestCaseParallaxContainer.cs index f9804655ea..41b029d69e 100644 --- a/osu.Game.Tests/Visual/TestCaseParallaxContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseParallaxContainer.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics; +using osu.Framework.Screens; using osu.Game.Graphics.Containers; using osu.Game.Screens.Backgrounds; @@ -14,7 +16,10 @@ namespace osu.Game.Tests.Visual Add(parallax = new ParallaxContainer { - Child = new BackgroundScreenDefault { Alpha = 0.8f } + Child = new ScreenStack(new BackgroundScreenDefault { Alpha = 0.8f }) + { + RelativeSizeAxes = Axes.Both, + } }); AddStep("default parallax", () => parallax.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT); diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index dedcc24e53..78e90987b1 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -12,6 +12,7 @@ using osu.Framework.Configuration; using osu.Framework.Extensions; using osu.Framework.MathUtils; using osu.Framework.Platform; +using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Rulesets; @@ -25,7 +26,7 @@ using osu.Game.Screens.Select.Filter; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestCasePlaySongSelect : OsuTestCase + public class TestCasePlaySongSelect : ScreenTestCase { private BeatmapManager manager; @@ -102,21 +103,16 @@ namespace osu.Game.Tests.Visual } [SetUp] - public virtual void SetUp() - { - Schedule(() => - { - manager?.Delete(manager.GetAllUsableBeatmapSets()); - Child = songSelect = new TestSongSelect(); - }); - } + public virtual void SetUp() => + Schedule(() => { manager?.Delete(manager.GetAllUsableBeatmapSets()); }); [Test] public void TestDummy() { + createSongSelect(); AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap); - AddAssert("dummy shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap == defaultBeatmap); + AddUntilStep(() => songSelect.CurrentBeatmapDetailsBeatmap == defaultBeatmap, "dummy shown on wedge"); addManyTestMaps(); AddWaitStep(3); @@ -127,6 +123,7 @@ namespace osu.Game.Tests.Visual [Test] public void TestSorting() { + createSongSelect(); addManyTestMaps(); AddWaitStep(3); @@ -142,6 +139,7 @@ namespace osu.Game.Tests.Visual [Ignore("needs fixing")] public void TestImportUnderDifferentRuleset() { + createSongSelect(); changeRuleset(2); importForRuleset(0); AddUntilStep(() => songSelect.Carousel.SelectedBeatmap == null, "no selection"); @@ -150,6 +148,7 @@ namespace osu.Game.Tests.Visual [Test] public void TestImportUnderCurrentRuleset() { + createSongSelect(); changeRuleset(2); importForRuleset(2); importForRuleset(1); @@ -165,6 +164,7 @@ namespace osu.Game.Tests.Visual [Test] public void TestRulesetChangeResetsMods() { + createSongSelect(); changeRuleset(0); changeMods(new OsuModHardRock()); @@ -194,6 +194,7 @@ namespace osu.Game.Tests.Visual [Test] public void TestStartAfterUnMatchingFilterDoesNotStart() { + createSongSelect(); addManyTestMaps(); AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "has selection"); @@ -221,6 +222,12 @@ namespace osu.Game.Tests.Visual private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id)); + private void createSongSelect() + { + AddStep("create song select", () => LoadScreen(songSelect = new TestSongSelect())); + AddUntilStep(() => songSelect.IsCurrentScreen(), "wait for present"); + } + private void addManyTestMaps() { AddStep("import test maps", () => diff --git a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs index 82ce7e125a..16cb94c65e 100644 --- a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs @@ -3,6 +3,7 @@ using System.Threading; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Screens.Play; @@ -12,28 +13,37 @@ namespace osu.Game.Tests.Visual public class TestCasePlayerLoader : ManualInputManagerTestCase { private PlayerLoader loader; + private ScreenStack stack; [BackgroundDependencyLoader] private void load(OsuGameBase game) { Beatmap.Value = new DummyWorkingBeatmap(game); - AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(() => new Player + InputManager.Add(stack = new ScreenStack { RelativeSizeAxes = Axes.Both }); + + AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player { AllowPause = false, AllowLeadIn = false, AllowResults = false, }))); + AddUntilStep(() => loader.IsCurrentScreen(), "wait for current"); + AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre)); AddUntilStep(() => !loader.IsCurrentScreen(), "wait for no longer current"); + AddStep("exit loader", () => loader.Exit()); + + AddUntilStep(() => !loader.IsAlive, "wait for no longer alive"); + AddStep("load slow dummy beatmap", () => { SlowLoadPlayer slow = null; - Add(loader = new PlayerLoader(() => slow = new SlowLoadPlayer + stack.Push(loader = new PlayerLoader(() => slow = new SlowLoadPlayer { AllowPause = false, AllowLeadIn = false, diff --git a/osu.Game.Tests/Visual/TestCaseResults.cs b/osu.Game.Tests/Visual/TestCaseResults.cs index 403742a7b5..c2880c1ea2 100644 --- a/osu.Game.Tests/Visual/TestCaseResults.cs +++ b/osu.Game.Tests/Visual/TestCaseResults.cs @@ -16,7 +16,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestCaseResults : OsuTestCase + public class TestCaseResults : ScreenTestCase { private BeatmapManager beatmaps; @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual if (beatmapInfo != null) Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo); - Add(new SoloResults(new ScoreInfo + LoadScreen(new SoloResults(new ScoreInfo { TotalScore = 2845370, Accuracy = 0.98, diff --git a/osu.Game/Beatmaps/BindableBeatmap.cs b/osu.Game/Beatmaps/BindableBeatmap.cs index bbd0fbfb06..ca03aac685 100644 --- a/osu.Game/Beatmaps/BindableBeatmap.cs +++ b/osu.Game/Beatmaps/BindableBeatmap.cs @@ -12,9 +12,9 @@ namespace osu.Game.Beatmaps { /// /// A for the beatmap. - /// This should be used sparingly in-favour of . + /// This should be used sparingly in-favour of . /// - public abstract class BindableBeatmap : NonNullableBindable, IBindableBeatmap + public abstract class BindableBeatmap : NonNullableBindable { private AudioManager audioManager; private WorkingBeatmap lastBeatmap; @@ -62,9 +62,6 @@ namespace osu.Game.Beatmaps lastBeatmap = beatmap; } - [NotNull] - IBindableBeatmap IBindableBeatmap.GetBoundCopy() => GetBoundCopy(); - /// /// Retrieve a new instance weakly bound to this . /// If you are further binding to events of the retrieved , ensure a local reference is held. diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index c66052052f..d1d30a7c29 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -13,7 +13,7 @@ namespace osu.Game.Beatmaps.Drawables /// public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { - public readonly IBindable Beatmap = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game/Beatmaps/IBindableBeatmap.cs b/osu.Game/Beatmaps/IBindableBeatmap.cs deleted file mode 100644 index 22b7a5a956..0000000000 --- a/osu.Game/Beatmaps/IBindableBeatmap.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Configuration; - -namespace osu.Game.Beatmaps -{ - /// - /// Read-only interface for the beatmap. - /// - public interface IBindableBeatmap : IBindable - { - /// - /// Retrieve a new instance weakly bound to this . - /// If you are further binding to events of the retrieved , ensure a local reference is held. - /// - IBindableBeatmap GetBoundCopy(); - } -} diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 31eea2cd0c..b929217ae4 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -74,7 +74,7 @@ namespace osu.Game.Graphics.Containers } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap) + private void load(IBindable beatmap) { Beatmap.BindTo(beatmap); } diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 81690f3728..aeb974681d 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -9,12 +9,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Framework.Platform; namespace osu.Game.Graphics.UserInterface { - public class OsuPasswordTextBox : OsuTextBox + public class OsuPasswordTextBox : OsuTextBox, ISuppressKeyEventLogging { protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize); diff --git a/osu.Game/Online/Multiplayer/PlaylistItem.cs b/osu.Game/Online/Multiplayer/PlaylistItem.cs index ff3ae240cb..e47d497d94 100644 --- a/osu.Game/Online/Multiplayer/PlaylistItem.cs +++ b/osu.Game/Online/Multiplayer/PlaylistItem.cs @@ -1,9 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; @@ -37,10 +37,10 @@ namespace osu.Game.Online.Multiplayer public RulesetInfo Ruleset { get; set; } [JsonIgnore] - public readonly BindableList AllowedMods = new BindableList(); + public readonly List AllowedMods = new List(); [JsonIgnore] - public readonly BindableList RequiredMods = new BindableList(); + public readonly List RequiredMods = new List(); [JsonProperty("beatmap")] private APIBeatmap apiBeatmap { get; set; } diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 0d5b168dcb..2dcc7369f9 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -31,6 +31,10 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("playlist")] public BindableList Playlist { get; private set; } = new BindableList(); + [Cached] + [JsonIgnore] + public Bindable CurrentItem { get; private set; } = new Bindable(); + [Cached] [JsonProperty("channel_id")] public Bindable ChannelId { get; private set; } = new Bindable(); @@ -66,6 +70,18 @@ namespace osu.Game.Online.Multiplayer [Cached] public Bindable ParticipantCount { get; private set; } = new Bindable(); + public Room() + { + Playlist.ItemsAdded += updateCurrent; + Playlist.ItemsRemoved += updateCurrent; + updateCurrent(Playlist); + } + + private void updateCurrent(IEnumerable playlist) + { + CurrentItem.Value = playlist.FirstOrDefault(); + } + // todo: TEMPORARY [JsonProperty("participant_count")] private int? participantCount diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b1f18341d2..7b4ff3d295 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -292,7 +292,7 @@ namespace osu.Game return; } - if ((screenStack.CurrentScreen as IOsuScreen)?.AllowExternalScreenChange != true) + if ((screenStack.CurrentScreen as IOsuScreen)?.AllowExternalScreenChange == false) { notifications.Post(new SimpleNotification { @@ -311,7 +311,7 @@ namespace osu.Game void loadScore() { - if (!menuScreen.IsCurrentScreen()) + if (!menuScreen.IsCurrentScreen() || Beatmap.Disabled) { menuScreen.MakeCurrent(); this.Delay(500).Schedule(loadScore, out scoreLoad); @@ -337,6 +337,11 @@ namespace osu.Game { base.LoadComplete(); + // The next time this is updated is in UpdateAfterChildren, which occurs too late and results + // in the cursor being shown for a few frames during the intro. + // This prevents the cursor from showing until we have a screen with CursorVisible = true + MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false; + // todo: all archive managers should be able to be looped here. SkinManager.PostNotification = n => notifications?.Post(n); SkinManager.GetStableStorage = GetStorageForStableInstall; @@ -723,46 +728,13 @@ namespace osu.Game { base.UpdateAfterChildren(); - // we only want to apply these restrictions when we are inside a screen stack. - // the use case for not applying is in visual/unit tests. - bool applyBeatmapRulesetRestrictions = !(screenStack.CurrentScreen as IOsuScreen)?.AllowBeatmapRulesetChange ?? false; - - ruleset.Disabled = applyBeatmapRulesetRestrictions; - Beatmap.Disabled = applyBeatmapRulesetRestrictions; - screenContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; MenuCursorContainer.CanShowCursor = (screenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } - /// - /// Sets while ignoring any beatmap. - /// - /// The beatmap to set. - public void ForcefullySetBeatmap(WorkingBeatmap beatmap) - { - var beatmapDisabled = Beatmap.Disabled; - - Beatmap.Disabled = false; - Beatmap.Value = beatmap; - Beatmap.Disabled = beatmapDisabled; - } - - /// - /// Sets while ignoring any ruleset restrictions. - /// - /// The beatmap to set. - public void ForcefullySetRuleset(RulesetInfo ruleset) - { - var rulesetDisabled = this.ruleset.Disabled; - - this.ruleset.Disabled = false; - this.ruleset.Value = ruleset; - this.ruleset.Disabled = rulesetDisabled; - } - - protected virtual void ScreenChanged(IScreen lastScreen, IScreen newScreen) + protected virtual void ScreenChanged(IScreen current, IScreen newScreen) { switch (newScreen) { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8154466c4f..b6fe20b3a8 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -69,8 +69,9 @@ namespace osu.Game protected override Container Content => content; - private OsuBindableBeatmap beatmap; - protected BindableBeatmap Beatmap => beatmap; + private Bindable beatmap; + + protected Bindable Beatmap => beatmap; private Bindable fpsDisplayVisible; @@ -155,7 +156,6 @@ namespace osu.Game dependencies.CacheAs(API); var defaultBeatmap = new DummyWorkingBeatmap(this); - beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); dependencies.Cache(RulesetStore = new RulesetStore(contextFactory)); dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage)); @@ -174,8 +174,10 @@ namespace osu.Game // this adds a global reduction of track volume for the time being. Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); - dependencies.CacheAs(beatmap); - dependencies.CacheAs(beatmap); + beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); + + dependencies.CacheAs>(beatmap); + dependencies.CacheAs(beatmap); FileStore.Cleanup(); diff --git a/osu.Game/Overlays/AccountCreationOverlay.cs b/osu.Game/Overlays/AccountCreationOverlay.cs index dab960db25..bc780538d5 100644 --- a/osu.Game/Overlays/AccountCreationOverlay.cs +++ b/osu.Game/Overlays/AccountCreationOverlay.cs @@ -70,7 +70,10 @@ namespace osu.Game.Overlays Colour = Color4.Black, Alpha = 0.9f, }, - welcomeScreen = new ScreenWelcome(), + new ScreenStack(welcomeScreen = new ScreenWelcome()) + { + RelativeSizeAxes = Axes.Both, + }, } } } diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index f255403e81..d9eb827834 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -11,6 +11,9 @@ using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Direct { + /// + /// A component which tracks a beatmap through potential download/import/deletion. + /// public abstract class DownloadTrackingComposite : CompositeDrawable { public readonly Bindable BeatmapSet = new Bindable(); @@ -51,6 +54,7 @@ namespace osu.Game.Overlays.Direct }; beatmaps.ItemAdded += setAdded; + beatmaps.ItemRemoved += setRemoved; } #region Disposal @@ -105,27 +109,22 @@ namespace osu.Game.Overlays.Direct } } - private void onRequestSuccess(string data) - { - Schedule(() => State.Value = DownloadState.Downloaded); - } + private void onRequestSuccess(string _) => Schedule(() => State.Value = DownloadState.Downloaded); - private void onRequestProgress(float progress) - { - Schedule(() => Progress.Value = progress); - } + private void onRequestProgress(float progress) => Schedule(() => Progress.Value = progress); - private void onRequestFailure(Exception e) - { - Schedule(() => attachDownload(null)); - } + private void onRequestFailure(Exception e) => Schedule(() => attachDownload(null)); - private void setAdded(BeatmapSetInfo s, bool existing, bool silent) + private void setAdded(BeatmapSetInfo s, bool existing, bool silent) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); + + private void setRemoved(BeatmapSetInfo s) => setDownloadStateFromManager(s, DownloadState.NotDownloaded); + + private void setDownloadStateFromManager(BeatmapSetInfo s, DownloadState state) => Schedule(() => { if (s.OnlineBeatmapSetID != BeatmapSet.Value?.OnlineBeatmapSetID) return; - Schedule(() => State.Value = DownloadState.LocallyAvailable); - } + State.Value = state; + }); } } diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index b8cf7abd63..b388bb1632 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Music } [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, IBindableBeatmap beatmap) + private void load(BeatmapManager beatmaps, IBindable beatmap) { beatmaps.GetAllUsableBeatmapSets().ForEach(b => addBeatmapSet(b, false, false)); beatmaps.ItemAdded += addBeatmapSet; diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 7b5a59836f..5b1b7f4da9 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Music private PlaylistList list; [BackgroundDependencyLoader] - private void load(OsuColour colours, BindableBeatmap beatmap, BeatmapManager beatmaps) + private void load(OsuColour colours, Bindable beatmap, BeatmapManager beatmaps) { this.beatmap.BindTo(beatmap); this.beatmaps = beatmaps; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a70dc63c50..5218edd7d5 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -66,7 +66,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(BindableBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours) + private void load(Bindable beatmap, BeatmapManager beatmaps, OsuColour colours) { this.beatmap.BindTo(beatmap); this.beatmaps = beatmaps; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 122f74b0b1..635e32d489 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Edit } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, IFrameBasedClock framedClock) + private void load(IBindable beatmap, IFrameBasedClock framedClock) { Beatmap.BindTo(beatmap); diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index cff64bc447..3ab62160cd 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Edit } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, IAdjustableClock clock) + private void load(IBindable beatmap, IAdjustableClock clock) { this.beatmap.BindTo(beatmap); diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index f0a0de6604..572f41b7e6 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.UI private WorkingBeatmap beatmap; [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap) + private void load(IBindable beatmap) { this.beatmap = beatmap.Value; } diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 4d466d743a..726f6d2025 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Edit.Components } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, OsuColour colours) + private void load(IBindable beatmap, OsuColour colours) { Beatmap.BindTo(beatmap); background.Colour = colours.Gray1; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index f07fd59afd..edf7baf687 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap) + private void load(IBindable beatmap) { Beatmap.BindTo(beatmap); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index c0ad53b4bf..b00d0b0b46 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private WaveformGraph waveform; [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, IAdjustableClock adjustableClock, OsuColour colours) + private void load(IBindable beatmap, IAdjustableClock adjustableClock, OsuColour colours) { this.adjustableClock = adjustableClock; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index ac5ff504a2..b147679cca 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -29,7 +29,8 @@ namespace osu.Game.Screens.Edit protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); public override bool HideOverlaysOnEnter => true; - public override bool AllowBeatmapRulesetChange => false; + + public override bool DisallowExternalBeatmapRulesetChanges => true; private Box bottomBackground; private Container screenContainer; diff --git a/osu.Game/Screens/Edit/EditorScreen.cs b/osu.Game/Screens/Edit/EditorScreen.cs index ededd90a14..bfe0423c8a 100644 --- a/osu.Game/Screens/Edit/EditorScreen.cs +++ b/osu.Game/Screens/Edit/EditorScreen.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Edit } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap) + private void load(IBindable beatmap) { Beatmap.BindTo(beatmap); } diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 532d4963a0..9e28de5593 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -1,8 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Configuration; using osu.Framework.Screens; +using osu.Game.Beatmaps; using osu.Game.Overlays; +using osu.Game.Rulesets; namespace osu.Game.Screens { @@ -12,8 +15,12 @@ namespace osu.Game.Screens /// Whether the beatmap or ruleset should be allowed to be changed by the user or game. /// Used to mark exclusive areas where this is strongly prohibited, like gameplay. /// - bool AllowBeatmapRulesetChange { get; } + bool DisallowExternalBeatmapRulesetChanges { get; } + /// + /// Whether a top-level component should be allowed to exit the current screen to, for example, + /// complete an import. + /// bool AllowExternalScreenChange { get; } /// @@ -35,5 +42,9 @@ namespace osu.Game.Screens /// The amount of parallax to be applied while this screen is displayed. /// float BackgroundParallaxAmount { get; } + + Bindable Beatmap { get; } + + Bindable Ruleset { get; } } } diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 9703d79442..0db0f1a1a3 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -21,6 +21,8 @@ namespace osu.Game.Screens public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; + public override bool CursorVisible => false; + protected override bool AllowBackButton => false; public Loader() diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 3a347342d7..10cfc4a299 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -28,8 +28,6 @@ namespace osu.Game.Screens.Menu /// public bool DidLoadMenu; - private readonly Bindable beatmap = new Bindable(); - private MainMenu mainMenu; private SampleChannel welcome; private SampleChannel seeya; @@ -47,10 +45,8 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap introBeatmap; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap) + private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) { - this.beatmap.BindTo(beatmap); - menuVoice = config.GetBindable(OsuSetting.MenuVoice); menuMusic = config.GetBindable(OsuSetting.MenuMusic); @@ -95,7 +91,7 @@ namespace osu.Game.Screens.Menu if (!resuming) { - beatmap.Value = introBeatmap; + Beatmap.Value = introBeatmap; if (menuVoice) welcome.Play(); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index a87b7aea40..2534c57b1e 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -74,7 +74,7 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(ShaderManager shaders, IBindableBeatmap beatmap) + private void load(ShaderManager shaders, IBindable beatmap) { this.beatmap.BindTo(beatmap); shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 40ae8a25c5..7288cc8db5 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, OsuColour colours) + private void load(IBindable beatmap, OsuColour colours) { this.beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index dca0545035..7a513a7f5f 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load() { - CurrentBeatmap.BindValueChanged(v => updateText(), true); + CurrentItem.BindValueChanged(v => updateText(), true); } private float textSize = OsuSpriteText.FONT_SIZE; @@ -48,12 +48,14 @@ namespace osu.Game.Screens.Multi.Components private void updateText() { - if (!IsLoaded) + if (LoadState < LoadState.Loading) return; textFlow.Clear(); - if (CurrentBeatmap.Value == null) + var beatmap = CurrentItem.Value?.Beatmap; + + if (beatmap == null) textFlow.AddText("No beatmap selected", s => { s.TextSize = TextSize; @@ -65,7 +67,7 @@ namespace osu.Game.Screens.Multi.Components { new OsuSpriteText { - Text = new LocalisedString((CurrentBeatmap.Value.Metadata.ArtistUnicode, CurrentBeatmap.Value.Metadata.Artist)), + Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)), TextSize = TextSize, }, new OsuSpriteText @@ -75,10 +77,10 @@ namespace osu.Game.Screens.Multi.Components }, new OsuSpriteText { - Text = new LocalisedString((CurrentBeatmap.Value.Metadata.TitleUnicode, CurrentBeatmap.Value.Metadata.Title)), + Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title)), TextSize = TextSize, } - }, null, LinkAction.OpenBeatmap, CurrentBeatmap.Value.OnlineBeatmapID.ToString(), "Open beatmap"); + }, null, LinkAction.OpenBeatmap, beatmap.OnlineBeatmapID.ToString(), "Open beatmap"); } } } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index 3904df2069..4f432a232c 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -51,14 +51,16 @@ namespace osu.Game.Screens.Multi.Components } }; - CurrentBeatmap.BindValueChanged(v => + CurrentItem.BindValueChanged(item => { beatmapAuthor.Clear(); - if (v != null) + var beatmap = item?.Beatmap; + + if (beatmap != null) { beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); - beatmapAuthor.AddLink(v.Metadata.Author.Username, null, LinkAction.OpenUserProfile, v.Metadata.Author.Id.ToString(), "View Profile"); + beatmapAuthor.AddLink(beatmap.Metadata.Author.Username, null, LinkAction.OpenUserProfile, beatmap.Metadata.Author.Id.ToString(), "View Profile"); } }, true); } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 97ea1b5f36..0d49f75b46 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps.Drawables; +using osu.Game.Online.Multiplayer; using osuTK; namespace osu.Game.Screens.Multi.Components @@ -45,17 +46,17 @@ namespace osu.Game.Screens.Multi.Components }, }; - CurrentBeatmap.BindValueChanged(_ => updateBeatmap()); - CurrentRuleset.BindValueChanged(_ => updateBeatmap(), true); + CurrentItem.BindValueChanged(updateBeatmap, true); + Type.BindValueChanged(v => gameTypeContainer.Child = new DrawableGameType(v) { Size = new Vector2(height) }, true); } - private void updateBeatmap() + private void updateBeatmap(PlaylistItem item) { - if (CurrentBeatmap.Value != null) + if (item?.Beatmap != null) { rulesetContainer.FadeIn(transition_duration); - rulesetContainer.Child = new DifficultyIcon(CurrentBeatmap.Value, CurrentRuleset.Value) { Size = new Vector2(height) }; + rulesetContainer.Child = new DifficultyIcon(item.Beatmap, item.Ruleset) { Size = new Vector2(height) }; } else rulesetContainer.FadeOut(transition_duration); diff --git a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs index 8eff7b14af..06d5e585ab 100644 --- a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs +++ b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Multi.Components InternalChild = sprite = CreateBackgroundSprite(); - sprite.Beatmap.BindTo(CurrentBeatmap); + CurrentItem.BindValueChanged(i => sprite.Beatmap.Value = i?.Beatmap, true); } protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 1229d071ef..71205dc199 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -23,16 +22,13 @@ namespace osu.Game.Screens.Multi.Lounge protected readonly FilterControl Filter; private readonly Container content; - private readonly Action pushGameplayScreen; private readonly ProcessingOverlay processingOverlay; [Resolved] private Bindable currentRoom { get; set; } - public LoungeSubScreen(Action pushGameplayScreen) + public LoungeSubScreen() { - this.pushGameplayScreen = pushGameplayScreen; - InternalChildren = new Drawable[] { Filter = new FilterControl { Depth = -1 }, @@ -83,8 +79,8 @@ namespace osu.Game.Screens.Multi.Lounge content.Padding = new MarginPadding { Top = Filter.DrawHeight, - Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH + OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - Right = SearchableListOverlay.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING, + Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH + HORIZONTAL_OVERFLOW_PADDING, + Right = SearchableListOverlay.WIDTH_PADDING + HORIZONTAL_OVERFLOW_PADDING, }; } @@ -114,7 +110,7 @@ namespace osu.Game.Screens.Multi.Lounge private void joinRequested(Room room) { processingOverlay.Show(); - Manager?.JoinRoom(room, r => + RoomManager?.JoinRoom(room, r => { Open(room); processingOverlay.Hide(); @@ -132,7 +128,7 @@ namespace osu.Game.Screens.Multi.Lounge currentRoom.Value = room; - this.Push(new MatchSubScreen(room, s => pushGameplayScreen?.Invoke(s))); + this.Push(new MatchSubScreen(room)); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 137c0aa939..9a0fdbd4e7 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentMods.BindValueChanged(m => modDisplay.Current.Value = m, true); + CurrentItem.BindValueChanged(i => modDisplay.Current.Value = i?.RequiredMods, true); beatmapButton.Action = () => RequestBeatmapSelection?.Invoke(); } diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index ec6dbb6d12..b27c5b0ab4 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -92,8 +92,12 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - viewBeatmapButton.Beatmap.BindTo(CurrentBeatmap); - readyButton.Beatmap.BindTo(CurrentBeatmap); + CurrentItem.BindValueChanged(item => + { + viewBeatmapButton.Beatmap.Value = item?.Beatmap; + readyButton.Beatmap.Value = item?.Beatmap; + }, true); + hostInfo.Host.BindTo(Host); } } diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index eaa5cbdce9..50cf2addeb 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -14,13 +14,13 @@ namespace osu.Game.Screens.Multi.Match.Components { public class ReadyButton : HeaderButton { - public readonly IBindable Beatmap = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); [Resolved(typeof(Room), nameof(Room.EndDate))] private Bindable endDate { get; set; } [Resolved] - private IBindableBeatmap gameBeatmap { get; set; } + private IBindable gameBeatmap { get; set; } [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs index 9970894ffc..e26a6b7e20 100644 --- a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Multi.Match.Components { public class ViewBeatmapButton : HeaderButton { - public readonly IBindable Beatmap = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); [Resolved(CanBeNull = true)] private OsuGame osuGame { get; set; } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 9685962f9e..d97b32e54a 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -1,7 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -11,17 +11,17 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.GameTypes; -using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; -using osu.Game.Screens.Play; using osu.Game.Screens.Select; +using PlaylistItem = osu.Game.Online.Multiplayer.PlaylistItem; namespace osu.Game.Screens.Multi.Match { public class MatchSubScreen : MultiplayerSubScreen { - public override bool AllowBeatmapRulesetChange => false; + public override bool DisallowExternalBeatmapRulesetChanges => true; public override string Title { get; } @@ -33,223 +33,215 @@ namespace osu.Game.Screens.Multi.Match [Resolved(typeof(Room), nameof(Room.Name))] private Bindable name { get; set; } - [Resolved(typeof(Room), nameof(Room.Playlist))] - private BindableList playlist { get; set; } + [Resolved(typeof(Room), nameof(Room.Type))] + private Bindable type { get; set; } - public MatchSubScreen(Room room, Action pushGameplayScreen) + [Resolved(typeof(Room))] + protected BindableList Playlist { get; private set; } + + [Resolved(typeof(Room))] + protected Bindable CurrentItem { get; private set; } + + [Resolved] + protected Bindable> CurrentMods { get; private set; } + + [Resolved] + private BeatmapManager beatmapManager { get; set; } + + [Resolved(CanBeNull = true)] + private OsuGame game { get; set; } + + private MatchLeaderboard leaderboard; + + public MatchSubScreen(Room room) { Title = room.RoomID.Value == null ? "New room" : room.Name; + } - InternalChild = new Match(pushGameplayScreen) + [BackgroundDependencyLoader] + private void load() + { + MatchChatDisplay chat; + Components.Header header; + Info info; + GridContainer bottomRow; + MatchSettingsOverlay settings; + + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.Both, - RequestBeatmapSelection = () => this.Push(new MatchSongSelect + new GridContainer { - Selected = item => + RelativeSizeAxes = Axes.Both, + Content = new[] { - playlist.Clear(); - playlist.Add(item); + new Drawable[] + { + header = new Components.Header + { + Depth = -1, + RequestBeatmapSelection = () => + { + this.Push(new MatchSongSelect + { + Selected = item => + { + Playlist.Clear(); + Playlist.Add(item); + } + }); + } + } + }, + new Drawable[] { info = new Info { OnStart = onStart } }, + new Drawable[] + { + bottomRow = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + leaderboard = new MatchLeaderboard + { + Padding = new MarginPadding + { + Left = 10 + HORIZONTAL_OVERFLOW_PADDING, + Right = 10, + Vertical = 10, + }, + RelativeSizeAxes = Axes.Both + }, + new Container + { + Padding = new MarginPadding + { + Left = 10, + Right = 10 + HORIZONTAL_OVERFLOW_PADDING, + Vertical = 10, + }, + RelativeSizeAxes = Axes.Both, + Child = chat = new MatchChatDisplay + { + RelativeSizeAxes = Axes.Both + } + }, + }, + }, + } + }, }, - }), - RequestExit = () => + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed), + } + }, + new Container { - if (this.IsCurrentScreen()) - this.Exit(); - } + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = Components.Header.HEIGHT }, + Child = settings = new MatchSettingsOverlay { RelativeSizeAxes = Axes.Both }, + }, }; + + header.Tabs.Current.BindValueChanged(t => + { + const float fade_duration = 500; + if (t is SettingsMatchPage) + { + settings.Show(); + info.FadeOut(fade_duration, Easing.OutQuint); + bottomRow.FadeOut(fade_duration, Easing.OutQuint); + } + else + { + settings.Hide(); + info.FadeIn(fade_duration, Easing.OutQuint); + bottomRow.FadeIn(fade_duration, Easing.OutQuint); + } + }, true); + + chat.Exit += () => + { + if (this.IsCurrentScreen()) + this.Exit(); + }; + + beatmapManager.ItemAdded += beatmapAdded; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + CurrentItem.BindValueChanged(currentItemChanged, true); } public override bool OnExiting(IScreen next) { - Manager?.PartRoom(); + RoomManager?.PartRoom(); return base.OnExiting(next); } - private class Match : MultiplayerComposite + /// + /// Handles propagation of the current playlist item's content to game-wide mechanisms. + /// + private void currentItemChanged(PlaylistItem item) { - public Action RequestBeatmapSelection; - public Action RequestExit; + // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info + var localBeatmap = item?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.Beatmap.OnlineBeatmapID); - private readonly Action pushGameplayScreen; + Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); + CurrentMods.Value = item?.RequiredMods ?? Enumerable.Empty(); + if (item?.Ruleset != null) + Ruleset.Value = item.Ruleset; + } - private MatchLeaderboard leaderboard; + /// + /// Handle the case where a beatmap is imported (and can be used by this match). + /// + private void beatmapAdded(BeatmapSetInfo model, bool existing, bool silent) => Schedule(() => + { + if (Beatmap.Value != beatmapManager.DefaultBeatmap) + return; - [Resolved] - private IBindableBeatmap gameBeatmap { get; set; } + if (Beatmap.Value == null) + return; - [Resolved] - private BeatmapManager beatmapManager { get; set; } + // Try to retrieve the corresponding local beatmap + var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == CurrentItem.Value.Beatmap.OnlineBeatmapID); - [Resolved(CanBeNull = true)] - private OsuGame game { get; set; } + if (localBeatmap != null) + Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); + }); - public Match(Action pushGameplayScreen) + [Resolved(canBeNull: true)] + private Multiplayer multiplayer { get; set; } + + private void onStart() + { + Beatmap.Value.Mods.Value = CurrentMods.Value.ToArray(); + + switch (type.Value) { - this.pushGameplayScreen = pushGameplayScreen; - } - - [BackgroundDependencyLoader] - private void load() - { - MatchChatDisplay chat; - Components.Header header; - Info info; - GridContainer bottomRow; - MatchSettingsOverlay settings; - - InternalChildren = new Drawable[] - { - new GridContainer + default: + case GameTypeTimeshift _: + multiplayer?.Start(() => new TimeshiftPlayer(CurrentItem) { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - header = new Components.Header - { - Depth = -1, - RequestBeatmapSelection = () => RequestBeatmapSelection?.Invoke() - } - }, - new Drawable[] { info = new Info { OnStart = onStart } }, - new Drawable[] - { - bottomRow = new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - leaderboard = new MatchLeaderboard - { - Padding = new MarginPadding - { - Left = 10 + OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - Right = 10, - Vertical = 10, - }, - RelativeSizeAxes = Axes.Both - }, - new Container - { - Padding = new MarginPadding - { - Left = 10, - Right = 10 + OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - Vertical = 10, - }, - RelativeSizeAxes = Axes.Both, - Child = chat = new MatchChatDisplay - { - RelativeSizeAxes = Axes.Both - } - }, - }, - }, - } - }, - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed), - } - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Components.Header.HEIGHT }, - Child = settings = new MatchSettingsOverlay { RelativeSizeAxes = Axes.Both }, - }, - }; - - header.Tabs.Current.BindValueChanged(t => - { - const float fade_duration = 500; - if (t is SettingsMatchPage) - { - settings.Show(); - info.FadeOut(fade_duration, Easing.OutQuint); - bottomRow.FadeOut(fade_duration, Easing.OutQuint); - } - else - { - settings.Hide(); - info.FadeIn(fade_duration, Easing.OutQuint); - bottomRow.FadeIn(fade_duration, Easing.OutQuint); - } - }, true); - - chat.Exit += () => RequestExit?.Invoke(); - - beatmapManager.ItemAdded += beatmapAdded; + Exited = () => leaderboard.RefreshScores() + }); + break; } + } - protected override void LoadComplete() - { - base.LoadComplete(); + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); - CurrentBeatmap.BindValueChanged(setBeatmap, true); - CurrentRuleset.BindValueChanged(setRuleset, true); - } - - private void setBeatmap(BeatmapInfo beatmap) - { - // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info - var localBeatmap = beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID); - - game?.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); - } - - private void setRuleset(RulesetInfo ruleset) - { - if (ruleset == null) - return; - - game?.ForcefullySetRuleset(ruleset); - } - - private void beatmapAdded(BeatmapSetInfo model, bool existing, bool silent) => Schedule(() => - { - if (gameBeatmap.Value != beatmapManager.DefaultBeatmap) - return; - - if (CurrentBeatmap.Value == null) - return; - - // Try to retrieve the corresponding local beatmap - var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == CurrentBeatmap.Value.OnlineBeatmapID); - - if (localBeatmap != null) - game?.ForcefullySetBeatmap(beatmapManager.GetWorkingBeatmap(localBeatmap)); - }); - - private void onStart() - { - gameBeatmap.Value.Mods.Value = CurrentMods.Value.ToArray(); - - switch (Type.Value) - { - default: - case GameTypeTimeshift _: - pushGameplayScreen?.Invoke(new PlayerLoader(() => new TimeshiftPlayer(Playlist.First()) - { - Exited = () => leaderboard.RefreshScores() - })); - break; - } - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (beatmapManager != null) - beatmapManager.ItemAdded -= beatmapAdded; - } + if (beatmapManager != null) + beatmapManager.ItemAdded -= beatmapAdded; } } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 69a9a2fc66..32eea88fbc 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -8,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Logging; using osu.Framework.Screens; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; @@ -16,32 +16,22 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; -using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Menu; using osu.Game.Screens.Multi.Lounge; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; +using osu.Game.Screens.Play; using osuTK; namespace osu.Game.Screens.Multi { [Cached] - public class Multiplayer : CompositeDrawable, IOsuScreen, IOnlineComponent + public class Multiplayer : OsuScreen, IOnlineComponent { - public bool AllowBeatmapRulesetChange => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.AllowBeatmapRulesetChange ?? true; - public bool AllowExternalScreenChange => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.AllowExternalScreenChange ?? true; - public bool CursorVisible => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.AllowExternalScreenChange ?? true; + public override bool CursorVisible => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.CursorVisible ?? true; - public bool HideOverlaysOnEnter => false; - public OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; - - public float BackgroundParallaxAmount => 1; - - public bool ValidForResume { get; set; } = true; - public bool ValidForPush { get; set; } = true; - - public override bool RemoveWhenNotAlive => false; + public override bool DisallowExternalBeatmapRulesetChanges => true; private readonly MultiplayerWaveContainer waves; @@ -55,14 +45,11 @@ namespace osu.Game.Screens.Multi private readonly Bindable currentRoom = new Bindable(); [Cached] - private readonly Bindable currentFilter = new Bindable(); + private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; - [Resolved] - private IBindableBeatmap beatmap { get; set; } - [Resolved] private OsuGameBase game { get; set; } @@ -77,64 +64,61 @@ namespace osu.Game.Screens.Multi Anchor = Anchor.Centre; Origin = Anchor.Centre; RelativeSizeAxes = Axes.Both; + Padding = new MarginPadding { Horizontal = -HORIZONTAL_OVERFLOW_PADDING }; InternalChild = waves = new MultiplayerWaveContainer { RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"3e3a44"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"3c3842"), + ColourDark = OsuColour.FromHex(@"393540"), + TriangleScale = 5, + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = Header.HEIGHT }, + Child = screenStack = new ScreenStack(loungeSubScreen = new LoungeSubScreen()) { RelativeSizeAxes = Axes.Both } + }, + new Header(screenStack), + createButton = new HeaderButton + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.None, + Size = new Vector2(150, Header.HEIGHT - 20), + Margin = new MarginPadding + { + Top = 10, + Right = 10 + HORIZONTAL_OVERFLOW_PADDING, + }, + Text = "Create room", + Action = () => loungeSubScreen.Open(new Room + { + Name = { Value = $"{api.LocalUser}'s awesome room" } + }), + }, + roomManager = new RoomManager() + } }; - screenStack = new ScreenStack(loungeSubScreen = new LoungeSubScreen(pushGameplayScreen)) { RelativeSizeAxes = Axes.Both }; - Padding = new MarginPadding { Horizontal = -OsuScreen.HORIZONTAL_OVERFLOW_PADDING }; - - waves.AddRange(new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"3e3a44"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"3c3842"), - ColourDark = OsuColour.FromHex(@"393540"), - TriangleScale = 5, - }, - }, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = screenStack - }, - new Header(screenStack), - createButton = new HeaderButton - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.None, - Size = new Vector2(150, Header.HEIGHT - 20), - Margin = new MarginPadding - { - Top = 10, - Right = 10 + OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - }, - Text = "Create room", - Action = () => loungeSubScreen.Open(new Room - { - Name = { Value = $"{api.LocalUser}'s awesome room" } - }), - }, - roomManager = new RoomManager() - }); - screenStack.ScreenPushed += screenPushed; screenStack.ScreenExited += screenExited; } @@ -154,11 +138,9 @@ namespace osu.Game.Screens.Multi isIdle.BindValueChanged(updatePollingRate, true); } - private CachedModelDependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - dependencies = new CachedModelDependencyContainer(base.CreateChildDependencies(parent)); + var dependencies = new CachedModelDependencyContainer(base.CreateChildDependencies(parent)); dependencies.Model.BindTo(currentRoom); return dependencies; } @@ -169,12 +151,16 @@ namespace osu.Game.Screens.Multi Logger.Log($"Polling adjusted to {roomManager.TimeBetweenPolls}"); } - private void pushGameplayScreen(IScreen gameplayScreen) + /// + /// Push a to the main screen stack to begin gameplay. + /// Generally called from a via DI resolution. + /// + public void Start(Func player) { if (!this.IsCurrentScreen()) return; - this.Push(gameplayScreen); + this.Push(new PlayerLoader(player)); } public void APIStateChanged(APIAccess api, APIState state) @@ -195,14 +181,13 @@ namespace osu.Game.Screens.Multi } } - public void OnEntering(IScreen last) + public override void OnEntering(IScreen last) { this.FadeIn(); - waves.Show(); } - public bool OnExiting(IScreen next) + public override bool OnExiting(IScreen next) { waves.Hide(); @@ -215,23 +200,29 @@ namespace osu.Game.Screens.Multi updatePollingRate(isIdle.Value); - // the wave overlay transition takes longer than expected to run. - logo?.AppendAnimatingAction(() => logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut(), false); - + base.OnExiting(next); return false; } - public void OnResuming(IScreen last) + protected override void LogoExiting(OsuLogo logo) + { + base.LogoExiting(logo); + + // the wave overlay transition takes longer than expected to run. + logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut(); + } + + public override void OnResuming(IScreen last) { this.FadeIn(250); this.ScaleTo(1, 250, Easing.OutSine); - logo?.AppendAnimatingAction(() => OsuScreen.ApplyLogoArrivingDefaults(logo), true); + base.OnResuming(last); updatePollingRate(isIdle.Value); } - public void OnSuspending(IScreen next) + public override void OnSuspending(IScreen next) { this.ScaleTo(1.1f, 250, Easing.InSine); this.FadeOut(250); @@ -242,7 +233,8 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - var track = beatmap?.Value?.Track; + var track = Beatmap?.Value?.Track; + if (track != null) track.Looping = false; } @@ -255,7 +247,7 @@ namespace osu.Game.Screens.Multi if (screenStack.CurrentScreen is MatchSubScreen) { - var track = beatmap.Value.Track; + var track = Beatmap.Value.Track; if (track != null) { track.Looping = true; @@ -263,7 +255,7 @@ namespace osu.Game.Screens.Multi if (!track.IsRunning) { game.Audio.AddItemToList(track); - track.Seek(beatmap.Value.Metadata.PreviewTime); + track.Seek(Beatmap.Value.Metadata.PreviewTime); track.Start(); } } diff --git a/osu.Game/Screens/Multi/MultiplayerComposite.cs b/osu.Game/Screens/Multi/MultiplayerComposite.cs index 1a16db97a4..245a6ac358 100644 --- a/osu.Game/Screens/Multi/MultiplayerComposite.cs +++ b/osu.Game/Screens/Multi/MultiplayerComposite.cs @@ -3,14 +3,10 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Users; namespace osu.Game.Screens.Multi @@ -35,6 +31,9 @@ namespace osu.Game.Screens.Multi [Resolved(typeof(Room))] protected BindableList Playlist { get; private set; } + [Resolved(typeof(Room))] + protected Bindable CurrentItem { get; private set; } + [Resolved(typeof(Room))] protected Bindable> Participants { get; private set; } @@ -52,35 +51,5 @@ namespace osu.Game.Screens.Multi [Resolved(typeof(Room))] protected Bindable Duration { get; private set; } - - private readonly Bindable currentBeatmap = new Bindable(); - protected IBindable CurrentBeatmap => currentBeatmap; - - private readonly Bindable> currentMods = new Bindable>(); - protected IBindable> CurrentMods => currentMods; - - private readonly Bindable currentRuleset = new Bindable(); - protected IBindable CurrentRuleset => currentRuleset; - - protected override void LoadComplete() - { - base.LoadComplete(); - - Playlist.ItemsAdded += _ => updatePlaylist(); - Playlist.ItemsRemoved += _ => updatePlaylist(); - - updatePlaylist(); - } - - private void updatePlaylist() - { - // Todo: We only ever have one playlist item for now. In the future, this will be user-settable - - var playlistItem = Playlist.FirstOrDefault(); - - currentBeatmap.Value = playlistItem?.Beatmap; - currentMods.Value = playlistItem?.RequiredMods ?? Enumerable.Empty(); - currentRuleset.Value = playlistItem?.Ruleset; - } } } diff --git a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs index ddea4d5dad..ad72072981 100644 --- a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs +++ b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs @@ -3,43 +3,26 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Screens; -using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Input.Bindings; -using osu.Game.Overlays; namespace osu.Game.Screens.Multi { - public abstract class MultiplayerSubScreen : CompositeDrawable, IMultiplayerSubScreen, IKeyBindingHandler + public abstract class MultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen, IKeyBindingHandler { - public virtual bool AllowBeatmapRulesetChange => true; - public bool AllowExternalScreenChange => true; - public bool CursorVisible => true; - - public bool HideOverlaysOnEnter => false; - public OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; - - public float BackgroundParallaxAmount => 1; - - public bool ValidForResume { get; set; } = true; - public bool ValidForPush { get; set; } = true; + public override bool DisallowExternalBeatmapRulesetChanges => false; public override bool RemoveWhenNotAlive => false; - public abstract string Title { get; } public virtual string ShortTitle => Title; - [Resolved] - protected IBindableBeatmap Beatmap { get; private set; } - [Resolved(CanBeNull = true)] protected OsuGame Game { get; private set; } [Resolved(CanBeNull = true)] - protected IRoomManager Manager { get; private set; } + protected IRoomManager RoomManager { get; private set; } protected MultiplayerSubScreen() { @@ -48,14 +31,14 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both; } - public virtual void OnEntering(IScreen last) + public override void OnEntering(IScreen last) { this.FadeInFromZero(WaveContainer.APPEAR_DURATION, Easing.OutQuint); this.FadeInFromZero(WaveContainer.APPEAR_DURATION, Easing.OutQuint); this.MoveToX(200).MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); } - public virtual bool OnExiting(IScreen next) + public override bool OnExiting(IScreen next) { this.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); this.MoveToX(200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); @@ -63,19 +46,19 @@ namespace osu.Game.Screens.Multi return false; } - public virtual void OnResuming(IScreen last) + public override void OnResuming(IScreen last) { this.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint); this.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); } - public virtual void OnSuspending(IScreen next) + public override void OnSuspending(IScreen next) { this.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); this.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); } - public virtual bool OnPressed(GlobalAction action) + public override bool OnPressed(GlobalAction action) { if (!this.IsCurrentScreen()) return false; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index ba5c7b2f0a..b8d6fda97d 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -50,15 +50,28 @@ namespace osu.Game.Screens protected new OsuGameBase Game => base.Game as OsuGameBase; - public virtual bool AllowBeatmapRulesetChange => true; + /// + /// Whether to disallow changes to game-wise Beatmap/Ruleset bindables for this screen (and all children). + /// + public virtual bool DisallowExternalBeatmapRulesetChanges => false; - protected readonly Bindable Beatmap = new Bindable(); + private SampleChannel sampleExit; public virtual float BackgroundParallaxAmount => 1; - protected readonly Bindable Ruleset = new Bindable(); + public Bindable Beatmap { get; set; } - private SampleChannel sampleExit; + public Bindable Ruleset { get; set; } + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var deps = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, base.CreateChildDependencies(parent)); + + Beatmap = deps.Beatmap; + Ruleset = deps.Ruleset; + + return deps; + } protected BackgroundScreen Background => backgroundStack?.CurrentScreen as BackgroundScreen; @@ -77,11 +90,8 @@ namespace osu.Game.Screens } [BackgroundDependencyLoader(true)] - private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable ruleset) + private void load(OsuGame osu, AudioManager audio) { - Beatmap.BindTo(beatmap); - Ruleset.BindTo(ruleset); - sampleExit = audio.Sample.Get(@"UI/screen-back"); } @@ -134,7 +144,6 @@ namespace osu.Game.Screens if (localBackground != null && backgroundStack?.CurrentScreen == localBackground) backgroundStack?.Exit(); - Beatmap.UnbindAll(); return false; } diff --git a/osu.Game/Screens/OsuScreenDependencies.cs b/osu.Game/Screens/OsuScreenDependencies.cs new file mode 100644 index 0000000000..b51ce0d33f --- /dev/null +++ b/osu.Game/Screens/OsuScreenDependencies.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; + +namespace osu.Game.Screens +{ + public class OsuScreenDependencies : DependencyContainer + { + public Bindable Beatmap { get; } + + public Bindable Ruleset { get; } + + public OsuScreenDependencies(bool requireLease, IReadOnlyDependencyContainer parent) + : base(parent) + { + if (requireLease) + { + Beatmap = parent.Get>()?.GetBoundCopy(); + if (Beatmap == null) + { + Cache(Beatmap = parent.Get>().BeginLease(false)); + } + + Ruleset = parent.Get>()?.GetBoundCopy(); + if (Ruleset == null) + { + Cache(Ruleset = parent.Get>().BeginLease(true)); + } + } + else + { + Beatmap = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); + Ruleset = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); + } + } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 71b7b77e5d..2ab207e47a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -383,7 +383,7 @@ namespace osu.Game.Screens.Play return true; } - if ((!AllowPause || HasFailed || !ValidForResume || pauseContainer?.IsPaused != false || RulesetContainer?.HasReplayLoaded != false) && (!pauseContainer?.IsResuming ?? true)) + if ((!AllowPause || HasFailed || !ValidForResume || pauseContainer?.IsPaused.Value != false || RulesetContainer?.HasReplayLoaded.Value != false) && (!pauseContainer?.IsResuming ?? true)) { // In the case of replays, we may have changed the playback rate. applyRateFromMods(); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 58e59604dd..c55c05f61c 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -37,6 +37,8 @@ namespace osu.Game.Screens.Play private bool hideOverlays; public override bool HideOverlaysOnEnter => hideOverlays; + public override bool DisallowExternalBeatmapRulesetChanges => true; + private Task loadTask; public PlayerLoader(Func createPlayer) diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 3317deca8b..3190139378 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play protected override void LoadComplete() { base.LoadComplete(); - RulesetContainer.SetReplayScore(score); + RulesetContainer?.SetReplayScore(score); } protected override ScoreInfo CreateScore() => score.ScoreInfo; diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 93ec7347c8..7e01a84da2 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -18,8 +18,6 @@ namespace osu.Game.Screens.Play protected new BackgroundScreenBeatmap Background => base.Background as BackgroundScreenBeatmap; - public override bool AllowBeatmapRulesetChange => false; - protected const float BACKGROUND_FADE_DURATION = 800; protected float BackgroundOpacity => 1 - (float)DimLevel; diff --git a/osu.Game/Screens/Play/SoloResults.cs b/osu.Game/Screens/Play/SoloResults.cs index 54392abe61..2b9aec257c 100644 --- a/osu.Game/Screens/Play/SoloResults.cs +++ b/osu.Game/Screens/Play/SoloResults.cs @@ -17,8 +17,8 @@ namespace osu.Game.Screens.Play protected override IEnumerable CreateResultPages() => new IResultPageInfo[] { - new ScoreOverviewPageInfo(Score, Beatmap), - new LocalLeaderboardPageInfo(Score, Beatmap) + new ScoreOverviewPageInfo(Score, Beatmap.Value), + new LocalLeaderboardPageInfo(Score, Beatmap.Value) }; } } diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 31863cea9b..a70d6bd87f 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Ranking private ResultModeTabControl modeChangeButtons; - public override bool AllowBeatmapRulesetChange => false; + public override bool DisallowExternalBeatmapRulesetChanges => true; protected readonly ScoreInfo Score; diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 298e936c1c..cfeaa1785e 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -40,5 +40,21 @@ namespace osu.Game.Screens.Select return true; } + + public override bool OnExiting(IScreen next) + { + Beatmap.Disabled = true; + Ruleset.Disabled = true; + + return base.OnExiting(next); + } + + public override void OnEntering(IScreen last) + { + base.OnEntering(last); + + Beatmap.Disabled = false; + Ruleset.Disabled = false; + } } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 982a44a8d3..b5e9cd5f41 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -15,6 +15,8 @@ namespace osu.Game.Screens.Select private bool removeAutoModOnResume; private OsuScreen player; + public override bool AllowExternalScreenChange => true; + [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -58,7 +60,6 @@ namespace osu.Game.Screens.Select } Beatmap.Value.Track.Looping = false; - Beatmap.Disabled = true; SampleConfirm?.Play(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f3091f7d4e..3be4dd8c0b 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -45,8 +45,6 @@ namespace osu.Game.Screens.Select protected virtual bool ShowFooter => true; - public override bool AllowExternalScreenChange => true; - /// /// Can be null if is false. /// @@ -78,7 +76,7 @@ namespace osu.Game.Screens.Select protected readonly BeatmapDetailArea BeatmapDetails; - protected new readonly Bindable Ruleset = new Bindable(); + private readonly Bindable decoupledRuleset = new Bindable(); [Cached] [Cached(Type = typeof(IBindable>))] @@ -268,8 +266,8 @@ namespace osu.Game.Screens.Select { dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs(this); - dependencies.CacheAs(Ruleset); - dependencies.CacheAs>(Ruleset); + dependencies.CacheAs(decoupledRuleset); + dependencies.CacheAs>(decoupledRuleset); return dependencies; } @@ -334,9 +332,9 @@ namespace osu.Game.Screens.Select if (this.IsCurrentScreen() && !Carousel.SelectBeatmap(beatmap?.BeatmapInfo, false)) // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch - if (beatmap?.BeatmapInfo?.Ruleset != null && beatmap.BeatmapInfo.Ruleset != Ruleset.Value) + if (beatmap?.BeatmapInfo?.Ruleset != null && beatmap.BeatmapInfo.Ruleset != decoupledRuleset.Value) { - base.Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + Ruleset.Value = beatmap.BeatmapInfo.Ruleset; Carousel.SelectBeatmap(beatmap.BeatmapInfo); } } @@ -377,12 +375,12 @@ namespace osu.Game.Screens.Select bool preview = false; - if (ruleset?.Equals(Ruleset.Value) == false) + if (ruleset?.Equals(decoupledRuleset.Value) == false) { - Logger.Log($"ruleset changed from \"{Ruleset.Value}\" to \"{ruleset}\""); + Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); Beatmap.Value.Mods.Value = Enumerable.Empty(); - Ruleset.Value = ruleset; + decoupledRuleset.Value = ruleset; // force a filter before attempting to change the beatmap. // we may still be in the wrong ruleset as there is a debounce delay on ruleset changes. @@ -539,7 +537,7 @@ namespace osu.Game.Screens.Select { base.Dispose(isDisposing); - Ruleset.UnbindAll(); + decoupledRuleset.UnbindAll(); if (beatmaps != null) { @@ -600,9 +598,11 @@ namespace osu.Game.Screens.Select if (rulesetNoDebounce == null) { // manual binding to parent ruleset to allow for delayed load in the incoming direction. - rulesetNoDebounce = Ruleset.Value = base.Ruleset.Value; - base.Ruleset.ValueChanged += updateSelectedRuleset; - Ruleset.ValueChanged += r => base.Ruleset.Value = r; + rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; + Ruleset.ValueChanged += updateSelectedRuleset; + + decoupledRuleset.ValueChanged += r => Ruleset.Value = r; + decoupledRuleset.DisabledChanged += r => Ruleset.Disabled = r; Beatmap.BindDisabledChanged(disabled => Carousel.AllowSelection = !disabled, true); Beatmap.BindValueChanged(workingBeatmapChanged); diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 80f79129c9..5dfefcb777 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -58,7 +58,14 @@ namespace osu.Game.Skinning componentName = "hit300"; break; case "Play/osu/number-text": - return !hasFont(Configuration.HitCircleFont) ? null : new LegacySpriteText(Textures, Configuration.HitCircleFont) { Scale = new Vector2(0.96f) }; + return !hasFont(Configuration.HitCircleFont) + ? null + : new LegacySpriteText(Textures, Configuration.HitCircleFont) + { + Scale = new Vector2(0.96f), + // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size + Spacing = new Vector2(-Configuration.HitCircleOverlap * 0.89f, 0) + }; } var texture = GetTexture(componentName); diff --git a/osu.Game/Skinning/LegacySkinDecoder.cs b/osu.Game/Skinning/LegacySkinDecoder.cs index 44bb9c3f41..96a9116c51 100644 --- a/osu.Game/Skinning/LegacySkinDecoder.cs +++ b/osu.Game/Skinning/LegacySkinDecoder.cs @@ -46,6 +46,9 @@ namespace osu.Game.Skinning case "HitCirclePrefix": skin.HitCircleFont = pair.Value; break; + case "HitCircleOverlap": + skin.HitCircleOverlap = int.Parse(pair.Value); + break; } break; diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a8091d1f36..82faec4e9d 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -23,6 +23,8 @@ namespace osu.Game.Skinning public string HitCircleFont { get; set; } = "default"; + public int HitCircleOverlap { get; set; } + public bool? CursorExpand { get; set; } = true; } } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index 22175cf24b..94bb4f2525 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -3,6 +3,7 @@ using osuTK; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Textures; @@ -63,7 +64,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, TextureStore textureStore) + private void load(IBindable beatmap, TextureStore textureStore) { var basePath = Animation.Path.ToLowerInvariant(); for (var frame = 0; frame < Animation.FrameCount; frame++) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index e94a03fc16..1591823bc1 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -4,6 +4,7 @@ using System.IO; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Beatmaps; @@ -28,7 +29,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap) + private void load(IBindable beatmap) { // Try first with the full name, then attempt with no path channel = beatmap.Value.Skin.GetSample(sample.Path) ?? beatmap.Value.Skin.GetSample(Path.ChangeExtension(sample.Path, null)); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index f904d7cc28..05cde37eb7 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -3,6 +3,7 @@ using osuTK; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; @@ -62,7 +63,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, TextureStore textureStore) + private void load(IBindable beatmap, TextureStore textureStore) { var spritePath = Sprite.Path.ToLowerInvariant(); var path = beatmap.Value.BeatmapSetInfo.Files.Find(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath; diff --git a/osu.Game/Tests/OsuTestBrowser.cs b/osu.Game/Tests/OsuTestBrowser.cs index ae347965a9..71b0b02fa6 100644 --- a/osu.Game/Tests/OsuTestBrowser.cs +++ b/osu.Game/Tests/OsuTestBrowser.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics; using osu.Framework.Platform; +using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Screens.Backgrounds; @@ -14,10 +16,10 @@ namespace osu.Game.Tests { base.LoadComplete(); - LoadComponentAsync(new BackgroundScreenDefault + LoadComponentAsync(new ScreenStack(new BackgroundScreenDefault { Colour = OsuColour.Gray(0.5f) }) { - Colour = OsuColour.Gray(0.5f), - Depth = 10 + Depth = 10, + RelativeSizeAxes = Axes.Both, }, AddInternal); // Have to construct this here, rather than in the constructor, because diff --git a/osu.Game/Tests/Visual/MultiplayerTestCase.cs b/osu.Game/Tests/Visual/MultiplayerTestCase.cs index 6efdddbfee..578ef6632c 100644 --- a/osu.Game/Tests/Visual/MultiplayerTestCase.cs +++ b/osu.Game/Tests/Visual/MultiplayerTestCase.cs @@ -7,7 +7,7 @@ using osu.Game.Online.Multiplayer; namespace osu.Game.Tests.Visual { - public class MultiplayerTestCase : OsuTestCase + public abstract class MultiplayerTestCase : ScreenTestCase { [Cached] private readonly Bindable currentRoom = new Bindable(new Room()); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 8a723ec647..6bff4c0291 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -32,8 +32,8 @@ namespace osu.Game.Tests.Visual // This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures beatmap.Default = new DummyWorkingBeatmap(Dependencies.Get()); - Dependencies.CacheAs(beatmap); - Dependencies.CacheAs(beatmap); + Dependencies.CacheAs>(beatmap); + Dependencies.CacheAs>(beatmap); Dependencies.CacheAs(Ruleset); Dependencies.CacheAs>(Ruleset); @@ -58,11 +58,7 @@ namespace osu.Game.Tests.Visual { base.Dispose(isDisposing); - if (beatmap != null) - { - beatmap.Disabled = true; - beatmap.Value.Track.Stop(); - } + beatmap?.Value.Track.Stop(); if (localStorage.IsValueCreated) { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e87b43ac93..6b94fa4f98 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 0d8a7e3a34..d677ef4e21 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 3f5bd9d34d..5efd16c357 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -68,6 +68,7 @@ HINT HINT HINT + HINT HINT WARNING WARNING @@ -204,6 +205,7 @@ HID HUD ID + IL IP IPC LTRB