From f1a9a352fceba6a1a98c3e943daf529bff8048f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 14:01:06 +0900 Subject: [PATCH] Cleanup bindable handling --- osu.Game.Tests/Visual/TestCaseMatchInfo.cs | 64 ++++++----- .../Visual/TestCaseMatchParticipants.cs | 24 +++-- .../Screens/Multi/Components/BeatmapTitle.cs | 30 +++--- .../Multi/Components/ParticipantCount.cs | 4 +- .../Multi/Lounge/Components/DrawableRoom.cs | 60 +++-------- .../Lounge/Components/ParticipantInfo.cs | 4 +- .../Multi/Lounge/Components/RoomInspector.cs | 73 +++---------- .../Screens/Multi/Match/Components/Header.cs | 8 +- .../Screens/Multi/Match/Components/Info.cs | 10 +- .../Multi/Match/Components/Participants.cs | 10 +- .../Match/Components/RoomSettingsOverlay.cs | 50 +++------ osu.Game/Screens/Multi/Match/MatchScreen.cs | 100 ++++++++--------- osu.Game/Screens/Multi/RoomBindings.cs | 101 ++++++++++++++++++ 13 files changed, 269 insertions(+), 269 deletions(-) create mode 100644 osu.Game/Screens/Multi/RoomBindings.cs diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs index 0d3c769dc5..be3367bf6c 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -26,38 +26,54 @@ public class TestCaseMatchInfo : OsuTestCase [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - Info info = new Info(new Room()); + var room = new Room(); + + Info info = new Info(room); Add(info); - AddStep(@"set name", () => info.Name.Value = @"Room Name?"); - AddStep(@"set availability", () => info.Availability.Value = RoomAvailability.FriendsOnly); - AddStep(@"set status", () => info.Status.Value = new RoomStatusPlaying()); - AddStep(@"set beatmap", () => info.Beatmap.Value = new BeatmapInfo + AddStep(@"set name", () => room.Name.Value = @"Room Name?"); + AddStep(@"set availability", () => room.Availability.Value = RoomAvailability.FriendsOnly); + AddStep(@"set status", () => room.Status.Value = new RoomStatusPlaying()); + AddStep(@"set beatmap", () => { - StarDifficulty = 2.4, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata + room.Playlist.Clear(); + room.Playlist.Add(new PlaylistItem { - Title = @"My Song", - Artist = @"VisualTests", - AuthorString = @"osu!lazer", - }, + Beatmap = new BeatmapInfo + { + StarDifficulty = 2.4, + Ruleset = rulesets.GetRuleset(0), + Metadata = new BeatmapMetadata + { + Title = @"My Song", + Artist = @"VisualTests", + AuthorString = @"osu!lazer", + }, + } + }); }); - AddStep(@"change name", () => info.Name.Value = @"Room Name!"); - AddStep(@"change availability", () => info.Availability.Value = RoomAvailability.InviteOnly); - AddStep(@"change status", () => info.Status.Value = new RoomStatusOpen()); - AddStep(@"null beatmap", () => info.Beatmap.Value = null); - AddStep(@"change beatmap", () => info.Beatmap.Value = new BeatmapInfo + AddStep(@"change name", () => room.Name.Value = @"Room Name!"); + AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.InviteOnly); + AddStep(@"change status", () => room.Status.Value = new RoomStatusOpen()); + AddStep(@"null beatmap", () => room.Playlist.Clear()); + AddStep(@"change beatmap", () => { - StarDifficulty = 4.2, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata + room.Playlist.Clear(); + room.Playlist.Add(new PlaylistItem { - Title = @"Your Song", - Artist = @"Tester", - AuthorString = @"Someone", - }, + Beatmap = new BeatmapInfo + { + StarDifficulty = 4.2, + Ruleset = rulesets.GetRuleset(3), + Metadata = new BeatmapMetadata + { + Title = @"Your Song", + Artist = @"Tester", + AuthorString = @"Someone", + }, + } + }); }); } } diff --git a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs index 67a56e525f..27aeb9b5eb 100644 --- a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs +++ b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs @@ -1,7 +1,9 @@ // 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 NUnit.Framework; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Users; @@ -11,16 +13,20 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseMatchParticipants : OsuTestCase { + private readonly Bindable maxParticipants = new Bindable(); + private readonly Bindable> users = new Bindable>(); + public TestCaseMatchParticipants() { Participants participants; - Add(participants = new Participants - { - RelativeSizeAxes = Axes.Both, - }); - AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); - AddStep(@"set users", () => participants.Users.Value = new[] + Add(participants = new Participants { RelativeSizeAxes = Axes.Both }); + + participants.MaxParticipants.BindTo(maxParticipants); + participants.Users.BindTo(users); + + AddStep(@"set max to null", () => maxParticipants.Value = null); + AddStep(@"set users", () => users.Value = new[] { new User { @@ -48,9 +54,9 @@ public TestCaseMatchParticipants() }, }); - AddStep(@"set max", () => participants.MaxParticipants.Value = 10); - AddStep(@"clear users", () => participants.Users.Value = new User[] { }); - AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); + AddStep(@"set max", () => maxParticipants.Value = 10); + AddStep(@"clear users", () => users.Value = new User[] { }); + AddStep(@"set max to null", () => maxParticipants.Value = null); } } } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index 67d414a080..d609f7a70d 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -14,21 +14,6 @@ namespace osu.Game.Screens.Multi.Components { public class BeatmapTitle : CompositeDrawable { - private float textSize = OsuSpriteText.FONT_SIZE; - - public float TextSize - { - get => textSize; - set - { - if (textSize == value) - return; - textSize = value; - - updateText(); - } - } - public readonly IBindable Beatmap = new Bindable(); private readonly LinkFlowContainer textFlow; @@ -48,6 +33,21 @@ protected override void LoadComplete() updateText(); } + private float textSize = OsuSpriteText.FONT_SIZE; + + public float TextSize + { + get => textSize; + set + { + if (textSize == value) + return; + textSize = value; + + updateText(); + } + } + private void updateText() { if (!IsLoaded) diff --git a/osu.Game/Screens/Multi/Components/ParticipantCount.cs b/osu.Game/Screens/Multi/Components/ParticipantCount.cs index 66f13ed683..8665678562 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantCount.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantCount.cs @@ -18,8 +18,8 @@ public class ParticipantCount : CompositeDrawable private readonly OsuSpriteText slash, maxText; - public readonly Bindable> Participants = new Bindable>(); - public readonly Bindable MaxParticipants = new Bindable(); + public readonly IBindable> Participants = new Bindable>(); + public readonly IBindable MaxParticipants = new Bindable(); public ParticipantCount() { diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index f4e304d0a8..d6bc0018e4 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -3,10 +3,8 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -19,7 +17,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; -using osu.Game.Users; using osuTK; using osuTK.Graphics; @@ -37,18 +34,9 @@ public class DrawableRoom : OsuClickableContainer, IStateful, IF public event Action StateChanged; + private readonly RoomBindings bindings = new RoomBindings(); + private readonly Box selectionBox; - - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable hostBind = new Bindable(); - private readonly Bindable statusBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable> participantsBind = new Bindable>(); - private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly IBindable endDateBind = new Bindable(); - - private readonly Bindable beatmap = new Bindable(); - private UpdateableBeatmapBackgroundSprite background; private BeatmapTitle beatmapTitle; private ModeTypeInfo modeTypeInfo; @@ -92,6 +80,7 @@ public bool MatchingFilter public DrawableRoom(Room room) { Room = room; + bindings.Room = room; RelativeSizeAxes = Axes.X; Height = height + SELECTION_BORDER_WIDTH * 2; @@ -222,7 +211,7 @@ private void load(OsuColour colours) }, }; - statusBind.ValueChanged += s => + bindings.Status.ValueChanged += s => { status.Text = s.Message; @@ -230,31 +219,15 @@ private void load(OsuColour colours) d.FadeColour(s.GetAppropriateColour(colours), transition_duration); }; - nameBind.BindValueChanged(n => name.Text = n); + background.Beatmap.BindTo(bindings.CurrentBeatmap); + modeTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTitle.Beatmap.BindTo(bindings.CurrentBeatmap); + modeTypeInfo.Type.BindTo(bindings.Type); + participantInfo.Host.BindTo(bindings.Host); + participantInfo.Participants.BindTo(bindings.Participants); - nameBind.BindTo(Room.Name); - hostBind.BindTo(Room.Host); - statusBind.BindTo(Room.Status); - typeBind.BindTo(Room.Type); - playlistBind.BindTo(Room.Playlist); - participantsBind.BindTo(Room.Participants); - endDateBind.BindTo(Room.EndDate); - - endDateBind.BindValueChanged(d => endDate.Date = d, true); - - background.Beatmap.BindTo(beatmap); - modeTypeInfo.Beatmap.BindTo(beatmap); - beatmapTitle.Beatmap.BindTo(beatmap); - - modeTypeInfo.Type.BindTo(typeBind); - - participantInfo.Host.BindTo(hostBind); - participantInfo.Participants.BindTo(participantsBind); - - playlistBind.ItemsAdded += _ => updatePlaylist(); - playlistBind.ItemsRemoved += _ => updatePlaylist(); - - updatePlaylist(); + bindings.Name.BindValueChanged(n => name.Text = n, true); + bindings.EndDate.BindValueChanged(d => endDate.Date = d, true); } protected override void LoadComplete() @@ -262,14 +235,5 @@ protected override void LoadComplete() base.LoadComplete(); this.FadeInFromZero(transition_duration); } - - private void updatePlaylist() - { - if (playlistBind.Count == 0) - return; - - // For now, only the first playlist item is supported - beatmap.Value = playlistBind.First().Beatmap; - } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 042dd96b61..b0ce800d4b 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -21,8 +21,8 @@ public class ParticipantInfo : Container { private readonly FillFlowContainer levelRangeContainer; - public readonly Bindable Host = new Bindable(); - public readonly Bindable> Participants = new Bindable>(); + public readonly IBindable Host = new Bindable(); + public readonly IBindable> Participants = new Bindable>(); public ParticipantInfo(string rankPrefix = null) { diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index f290830334..08beace4ca 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -1,7 +1,6 @@ // 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.Allocation; using osu.Framework.Configuration; @@ -31,15 +30,8 @@ public class RoomInspector : Container public readonly IBindable Room = new Bindable(); private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable hostBind = new Bindable(); - private readonly Bindable statusBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly Bindable> participantsBind = new Bindable>(); - private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly Bindable beatmap = new Bindable(); + private readonly RoomBindings bindings = new RoomBindings(); private OsuColour colours; private Box statusStrip; @@ -174,53 +166,27 @@ private void load(OsuColour colours) }, }; - playlistBind.ItemsAdded += _ => updatePlaylist(); - playlistBind.ItemsRemoved += _ => updatePlaylist(); + participantInfo.Host.BindTo(bindings.Host); + participantInfo.Participants.BindTo(bindings.Participants); + participantCount.Participants.BindTo(bindings.Participants); + participantCount.MaxParticipants.BindTo(bindings.MaxParticipants); + beatmapTypeInfo.Type.BindTo(bindings.Type); + background.Beatmap.BindTo(bindings.CurrentBeatmap); + beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap); - statusBind.BindValueChanged(displayStatus); - participantsBind.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); - - nameBind.BindValueChanged(n => name.Text = n); - - participantInfo.Host.BindTo(hostBind); - participantInfo.Participants.BindTo(participantsBind); - - participantCount.Participants.BindTo(participantsBind); - participantCount.MaxParticipants.BindTo(maxParticipantsBind); - - beatmapTypeInfo.Type.BindTo(typeBind); - - background.Beatmap.BindTo(beatmap); - beatmapTypeInfo.Beatmap.BindTo(beatmap); + bindings.Status.BindValueChanged(displayStatus); + bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); + bindings.Name.BindValueChanged(n => name.Text = n); Room.BindValueChanged(updateRoom, true); } - private Room lastRoom; - - private void updateRoom(Room newRoom) + private void updateRoom(Room room) { - if (lastRoom != null) - { - nameBind.UnbindFrom(lastRoom.Name); - hostBind.UnbindFrom(lastRoom.Host); - statusBind.UnbindFrom(lastRoom.Status); - typeBind.UnbindFrom(lastRoom.Type); - playlistBind.UnbindFrom(lastRoom.Playlist); - maxParticipantsBind.UnbindFrom(lastRoom.MaxParticipants); - participantsBind.UnbindFrom(lastRoom.Participants); - } + bindings.Room = room; - if (newRoom != null) + if (room != null) { - nameBind.BindTo(newRoom.Name); - hostBind.BindTo(newRoom.Host); - statusBind.BindTo(newRoom.Status); - typeBind.BindTo(newRoom.Type); - playlistBind.BindTo(newRoom.Playlist); - maxParticipantsBind.BindTo(newRoom.MaxParticipants); - participantsBind.BindTo(newRoom.Participants); - participantsFlow.FadeIn(transition_duration); participantCount.FadeIn(transition_duration); beatmapTypeInfo.FadeIn(transition_duration); @@ -237,17 +203,6 @@ private void updateRoom(Room newRoom) displayStatus(new RoomStatusNoneSelected()); } - - lastRoom = newRoom; - } - - private void updatePlaylist() - { - if (playlistBind.Count == 0) - return; - - // For now, only the first playlist item is supported - beatmap.Value = playlistBind.First().Beatmap; } protected override void UpdateAfterChildren() diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 3f4f137413..f306ee698f 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -27,9 +27,9 @@ public class Header : Container { public const float HEIGHT = 200; - public readonly Bindable Beatmap = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); public readonly IBindable Type = new Bindable(); - public readonly Bindable> Mods = new Bindable>(); + public readonly IBindable> Mods = new Bindable>(); private readonly Box tabStrip; @@ -116,11 +116,11 @@ public Header(Room room) beatmapTypeInfo.Beatmap.BindTo(Beatmap); beatmapTypeInfo.Type.BindTo(Type); - modDisplay.Current.BindTo(Mods); + background.Beatmap.BindTo(Beatmap); + Mods.BindValueChanged(m => modDisplay.Current.Value = m, true); beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); - background.Beatmap.BindTo(Beatmap); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index de02899a01..b849cae5d0 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -26,11 +26,11 @@ public class Info : Container private OsuColour colours; - public readonly Bindable Name = new Bindable(); - public readonly Bindable Availability = new Bindable(); - public readonly Bindable Status = new Bindable(); - public readonly Bindable Beatmap = new Bindable(); - public readonly Bindable EndDate = new Bindable(); + public readonly IBindable Name = new Bindable(); + public readonly IBindable Availability = new Bindable(); + public readonly IBindable Status = new Bindable(); + public readonly IBindable Beatmap = new Bindable(); + public readonly IBindable EndDate = new Bindable(); public Info(Room room) { diff --git a/osu.Game/Screens/Multi/Match/Components/Participants.cs b/osu.Game/Screens/Multi/Match/Components/Participants.cs index 92732dc045..4f18fc9f4c 100644 --- a/osu.Game/Screens/Multi/Match/Components/Participants.cs +++ b/osu.Game/Screens/Multi/Match/Components/Participants.cs @@ -15,14 +15,8 @@ namespace osu.Game.Screens.Multi.Match.Components { public class Participants : CompositeDrawable { - public readonly Bindable> Users = new Bindable>(); - public readonly Bindable MaxParticipants = new Bindable(); - - public new MarginPadding Padding - { - get => base.Padding; - set => base.Padding = value; - } + public readonly IBindable> Users = new Bindable>(); + public readonly IBindable MaxParticipants = new Bindable(); public Participants() { diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index bab44d62b2..65e1f068a8 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -4,7 +4,6 @@ using System; using Humanizer; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -24,12 +23,7 @@ public class RoomSettingsOverlay : FocusedOverlayContainer private const float transition_duration = 350; private const float field_padding = 45; - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable availabilityBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly IBindableCollection playlistBind = new BindableCollection(); - private readonly Bindable durationBind = new Bindable(); + private readonly RoomBindings bindings = new RoomBindings(); private readonly Container content; @@ -51,6 +45,8 @@ public RoomSettingsOverlay(Room room) { this.room = room; + bindings.Room = room; + Masking = true; Child = content = new Container @@ -189,11 +185,11 @@ public RoomSettingsOverlay(Room room) TypePicker.Current.ValueChanged += t => typeLabel.Text = t.Name; - nameBind.ValueChanged += n => NameField.Text = n; - availabilityBind.ValueChanged += a => AvailabilityPicker.Current.Value = a; - typeBind.ValueChanged += t => TypePicker.Current.Value = t; - maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); - durationBind.ValueChanged += d => DurationField.Current.Value = d; + bindings.Name.BindValueChanged(n => NameField.Text = n, true); + bindings.Availability.BindValueChanged(a => AvailabilityPicker.Current.Value = a, true); + bindings.Type.BindValueChanged(t => TypePicker.Current.Value = t, true); + bindings.MaxParticipants.BindValueChanged(m => MaxParticipantsField.Text = m?.ToString(), true); + bindings.Duration.BindValueChanged(d => DurationField.Current.Value = d, true); } [BackgroundDependencyLoader] @@ -201,13 +197,6 @@ private void load(OsuColour colours) { typeLabel.Colour = colours.Yellow; - nameBind.BindTo(room.Name); - playlistBind.BindTo(room.Playlist); - availabilityBind.BindTo(room.Availability); - typeBind.BindTo(room.Type); - maxParticipantsBind.BindTo(room.MaxParticipants); - durationBind.BindTo(room.Duration); - MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; AvailabilityPicker.ReadOnly.Value = true; @@ -222,19 +211,10 @@ protected override void Update() ApplyButton.Enabled.Value = hasValidSettings; } - private bool hasValidSettings => NameField.Text.Length > 0 && playlistBind.Count > 0; + private bool hasValidSettings => NameField.Text.Length > 0 && bindings.Playlist.Count > 0; protected override void PopIn() { - // reapply the rooms values if the overlay was completely closed - if (content.Y == -1) - { - nameBind.TriggerChange(); - availabilityBind.TriggerChange(); - typeBind.TriggerChange(); - maxParticipantsBind.TriggerChange(); - } - content.MoveToY(0, transition_duration, Easing.OutQuint); } @@ -245,16 +225,16 @@ protected override void PopOut() private void apply() { - nameBind.Value = NameField.Text; - availabilityBind.Value = AvailabilityPicker.Current.Value; - typeBind.Value = TypePicker.Current.Value; + bindings.Name.Value = NameField.Text; + bindings.Availability.Value = AvailabilityPicker.Current.Value; + bindings.Type.Value = TypePicker.Current.Value; if (int.TryParse(MaxParticipantsField.Text, out int max)) - maxParticipantsBind.Value = max; + bindings.MaxParticipants.Value = max; else - maxParticipantsBind.Value = null; + bindings.MaxParticipants.Value = null; - durationBind.Value = DurationField.Current.Value; + bindings.Duration.Value = DurationField.Current.Value; manager?.CreateRoom(room); } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index dfedf6d7a1..98a980afb2 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -5,39 +5,28 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +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 osu.Game.Users; namespace osu.Game.Screens.Multi.Match { public class MatchScreen : MultiplayerScreen { - private readonly Bindable nameBind = new Bindable(); - private readonly Bindable statusBind = new Bindable(); - private readonly Bindable availabilityBind = new Bindable(); - private readonly Bindable typeBind = new Bindable(); - private readonly Bindable maxParticipantsBind = new Bindable(); - private readonly Bindable> participantsBind = new Bindable>(); - private readonly BindableCollection playlistBind = new BindableCollection(); - private readonly Bindable endDateBind = new Bindable(); - public override bool AllowBeatmapRulesetChange => false; - public override string Title => room.Name.Value; - public override string ShortTitle => "room"; - private readonly Components.Header header; - private readonly Info info; + private readonly RoomBindings bindings = new RoomBindings(); + private readonly MatchLeaderboard leaderboard; private readonly Action pushGameplayScreen; @@ -58,14 +47,10 @@ public MatchScreen(Room room, Action pushGameplayScreen) this.room = room; this.pushGameplayScreen = pushGameplayScreen; - nameBind.BindTo(room.Name); - statusBind.BindTo(room.Status); - availabilityBind.BindTo(room.Availability); - typeBind.BindTo(room.Type); - participantsBind.BindTo(room.Participants); - maxParticipantsBind.BindTo(room.MaxParticipants); - endDateBind.BindTo(room.EndDate); + bindings.Room = room; + Info info; + Components.Header header; RoomSettingsOverlay settings; Children = new Drawable[] @@ -113,7 +98,6 @@ public MatchScreen(Room room, Action pushGameplayScreen) }; header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem }); - header.Tabs.Current.ValueChanged += t => { if (t is SettingsMatchPage) @@ -122,55 +106,55 @@ public MatchScreen(Room room, Action pushGameplayScreen) settings.Hide(); }; - info.Name.BindTo(nameBind); - info.Status.BindTo(statusBind); - info.Availability.BindTo(availabilityBind); - info.EndDate.BindTo(endDateBind); - - header.Type.BindTo(typeBind); - - playlistBind.ItemsAdded += _ => setFromPlaylist(); - playlistBind.ItemsRemoved += _ => setFromPlaylist(); + info.Name.BindTo(bindings.Name); + info.Status.BindTo(bindings.Status); + info.Availability.BindTo(bindings.Availability); + info.EndDate.BindTo(bindings.EndDate); + info.Beatmap.BindTo(bindings.CurrentBeatmap); + header.Type.BindTo(bindings.Type); + header.Beatmap.BindTo(bindings.CurrentBeatmap); + header.Mods.BindTo(bindings.CurrentMods); } protected override void LoadComplete() { base.LoadComplete(); - playlistBind.BindTo(room.Playlist); + bindings.CurrentBeatmap.BindValueChanged(setBeatmap, true); + bindings.CurrentMods.BindValueChanged(setMods, true); + bindings.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 setMods(IEnumerable mods) + { + Beatmap.Value.Mods.Value = mods.ToArray(); + } + + private void setRuleset(RulesetInfo ruleset) + { + if (ruleset == null) + return; + + game.ForcefullySetRuleset(ruleset); } private void addPlaylistItem(PlaylistItem item) { - playlistBind.Clear(); - playlistBind.Add(item); - } - - private void setFromPlaylist() - { - if (playlistBind.Count == 0) - return; - - // For now, only the first playlist item is supported - var item = playlistBind.First(); - - header.Beatmap.Value = item.Beatmap; - header.Mods.Value = item.RequiredMods; - info.Beatmap.Value = item.Beatmap; - - // Todo: item.Beatmap can be null here... - var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.BeatmapID) ?? item.Beatmap; - - var newBeatmap = beatmapManager.GetWorkingBeatmap(localBeatmap); - newBeatmap.Mods.Value = item.RequiredMods.ToArray(); - - game.ForcefullySetBeatmap(newBeatmap); - game.ForcefullySetRuleset(item.Ruleset); + bindings.Playlist.Clear(); + bindings.Playlist.Add(item); } private void onStart() { - switch (typeBind.Value) + switch (bindings.Type.Value) { default: case GameTypeTimeshift _: diff --git a/osu.Game/Screens/Multi/RoomBindings.cs b/osu.Game/Screens/Multi/RoomBindings.cs new file mode 100644 index 0000000000..b5854bf957 --- /dev/null +++ b/osu.Game/Screens/Multi/RoomBindings.cs @@ -0,0 +1,101 @@ +// 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.Framework.Configuration; +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 +{ + /// + /// Helper class which binds to values from a . + /// + public class RoomBindings + { + public RoomBindings() + { + Playlist.ItemsAdded += _ => updatePlaylist(); + Playlist.ItemsRemoved += _ => updatePlaylist(); + } + + private Room room; + + /// + /// The to bind to. + /// + public Room Room + { + get => room; + set + { + if (room == value) + return; + + if (room != null) + { + Name.UnbindFrom(room.Name); + Host.UnbindFrom(room.Host); + Status.UnbindFrom(room.Status); + Type.UnbindFrom(room.Type); + Playlist.UnbindFrom(room.Playlist); + MaxParticipants.UnbindFrom(room.MaxParticipants); + Participants.UnbindFrom(room.Participants); + Availability.UnbindFrom(room.Availability); + Duration.UnbindFrom(room.Duration); + } + + room = value; + + if (room != null) + { + Name.BindTo(room.Name); + Host.BindTo(room.Host); + Status.BindTo(room.Status); + Type.BindTo(room.Type); + Playlist.BindTo(room.Playlist); + MaxParticipants.BindTo(room.MaxParticipants); + Participants.BindTo(room.Participants); + Availability.BindTo(room.Availability); + Duration.BindTo(room.Duration); + } + } + } + + 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; + } + + public readonly Bindable Name = new Bindable(); + public readonly Bindable Host = new Bindable(); + public readonly Bindable Status = new Bindable(); + public readonly Bindable Type = new Bindable(); + public readonly BindableCollection Playlist = new BindableCollection(); + public readonly Bindable> Participants = new Bindable>(); + public readonly Bindable MaxParticipants = new Bindable(); + public readonly Bindable EndDate = new Bindable(); + public readonly Bindable Availability = new Bindable(); + public readonly Bindable Duration = new Bindable(); + + private readonly Bindable currentBeatmap = new Bindable(); + public IBindable CurrentBeatmap => currentBeatmap; + + private readonly Bindable> currentMods = new Bindable>(); + public IBindable> CurrentMods => currentMods; + + private readonly Bindable currentRuleset = new Bindable(); + public IBindable CurrentRuleset = new Bindable(); + } +}