Cleanup bindable handling

This commit is contained in:
smoogipoo 2018-12-22 14:01:06 +09:00
parent 1cb69c3478
commit f1a9a352fc
13 changed files with 269 additions and 269 deletions

View File

@ -26,38 +26,54 @@ public class TestCaseMatchInfo : OsuTestCase
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(RulesetStore rulesets) private void load(RulesetStore rulesets)
{ {
Info info = new Info(new Room()); var room = new Room();
Info info = new Info(room);
Add(info); Add(info);
AddStep(@"set name", () => info.Name.Value = @"Room Name?"); AddStep(@"set name", () => room.Name.Value = @"Room Name?");
AddStep(@"set availability", () => info.Availability.Value = RoomAvailability.FriendsOnly); AddStep(@"set availability", () => room.Availability.Value = RoomAvailability.FriendsOnly);
AddStep(@"set status", () => info.Status.Value = new RoomStatusPlaying()); AddStep(@"set status", () => room.Status.Value = new RoomStatusPlaying());
AddStep(@"set beatmap", () => info.Beatmap.Value = new BeatmapInfo AddStep(@"set beatmap", () =>
{ {
StarDifficulty = 2.4, room.Playlist.Clear();
Ruleset = rulesets.GetRuleset(0), room.Playlist.Add(new PlaylistItem
Metadata = new BeatmapMetadata
{ {
Title = @"My Song", Beatmap = new BeatmapInfo
Artist = @"VisualTests", {
AuthorString = @"osu!lazer", 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 name", () => room.Name.Value = @"Room Name!");
AddStep(@"change availability", () => info.Availability.Value = RoomAvailability.InviteOnly); AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.InviteOnly);
AddStep(@"change status", () => info.Status.Value = new RoomStatusOpen()); AddStep(@"change status", () => room.Status.Value = new RoomStatusOpen());
AddStep(@"null beatmap", () => info.Beatmap.Value = null); AddStep(@"null beatmap", () => room.Playlist.Clear());
AddStep(@"change beatmap", () => info.Beatmap.Value = new BeatmapInfo AddStep(@"change beatmap", () =>
{ {
StarDifficulty = 4.2, room.Playlist.Clear();
Ruleset = rulesets.GetRuleset(3), room.Playlist.Add(new PlaylistItem
Metadata = new BeatmapMetadata
{ {
Title = @"Your Song", Beatmap = new BeatmapInfo
Artist = @"Tester", {
AuthorString = @"Someone", StarDifficulty = 4.2,
}, Ruleset = rulesets.GetRuleset(3),
Metadata = new BeatmapMetadata
{
Title = @"Your Song",
Artist = @"Tester",
AuthorString = @"Someone",
},
}
});
}); });
} }
} }

View File

@ -1,7 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Match.Components;
using osu.Game.Users; using osu.Game.Users;
@ -11,16 +13,20 @@ namespace osu.Game.Tests.Visual
[TestFixture] [TestFixture]
public class TestCaseMatchParticipants : OsuTestCase public class TestCaseMatchParticipants : OsuTestCase
{ {
private readonly Bindable<int?> maxParticipants = new Bindable<int?>();
private readonly Bindable<IEnumerable<User>> users = new Bindable<IEnumerable<User>>();
public TestCaseMatchParticipants() public TestCaseMatchParticipants()
{ {
Participants participants; Participants participants;
Add(participants = new Participants
{
RelativeSizeAxes = Axes.Both,
});
AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); Add(participants = new Participants { RelativeSizeAxes = Axes.Both });
AddStep(@"set users", () => participants.Users.Value = new[]
participants.MaxParticipants.BindTo(maxParticipants);
participants.Users.BindTo(users);
AddStep(@"set max to null", () => maxParticipants.Value = null);
AddStep(@"set users", () => users.Value = new[]
{ {
new User new User
{ {
@ -48,9 +54,9 @@ public TestCaseMatchParticipants()
}, },
}); });
AddStep(@"set max", () => participants.MaxParticipants.Value = 10); AddStep(@"set max", () => maxParticipants.Value = 10);
AddStep(@"clear users", () => participants.Users.Value = new User[] { }); AddStep(@"clear users", () => users.Value = new User[] { });
AddStep(@"set max to null", () => participants.MaxParticipants.Value = null); AddStep(@"set max to null", () => maxParticipants.Value = null);
} }
} }
} }

View File

@ -14,21 +14,6 @@ namespace osu.Game.Screens.Multi.Components
{ {
public class BeatmapTitle : CompositeDrawable 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<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>(); public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
private readonly LinkFlowContainer textFlow; private readonly LinkFlowContainer textFlow;
@ -48,6 +33,21 @@ protected override void LoadComplete()
updateText(); updateText();
} }
private float textSize = OsuSpriteText.FONT_SIZE;
public float TextSize
{
get => textSize;
set
{
if (textSize == value)
return;
textSize = value;
updateText();
}
}
private void updateText() private void updateText()
{ {
if (!IsLoaded) if (!IsLoaded)

View File

@ -18,8 +18,8 @@ public class ParticipantCount : CompositeDrawable
private readonly OsuSpriteText slash, maxText; private readonly OsuSpriteText slash, maxText;
public readonly Bindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>(); public readonly IBindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
public readonly Bindable<int?> MaxParticipants = new Bindable<int?>(); public readonly IBindable<int?> MaxParticipants = new Bindable<int?>();
public ParticipantCount() public ParticipantCount()
{ {

View File

@ -3,10 +3,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework; using osu.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -19,7 +17,6 @@
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Components;
using osu.Game.Users;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -37,18 +34,9 @@ public class DrawableRoom : OsuClickableContainer, IStateful<SelectionState>, IF
public event Action<SelectionState> StateChanged; public event Action<SelectionState> StateChanged;
private readonly RoomBindings bindings = new RoomBindings();
private readonly Box selectionBox; private readonly Box selectionBox;
private readonly Bindable<string> nameBind = new Bindable<string>();
private readonly Bindable<User> hostBind = new Bindable<User>();
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
private readonly IBindableCollection<PlaylistItem> playlistBind = new BindableCollection<PlaylistItem>();
private readonly IBindable<DateTimeOffset> endDateBind = new Bindable<DateTimeOffset>();
private readonly Bindable<BeatmapInfo> beatmap = new Bindable<BeatmapInfo>();
private UpdateableBeatmapBackgroundSprite background; private UpdateableBeatmapBackgroundSprite background;
private BeatmapTitle beatmapTitle; private BeatmapTitle beatmapTitle;
private ModeTypeInfo modeTypeInfo; private ModeTypeInfo modeTypeInfo;
@ -92,6 +80,7 @@ public bool MatchingFilter
public DrawableRoom(Room room) public DrawableRoom(Room room)
{ {
Room = room; Room = room;
bindings.Room = room;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = height + SELECTION_BORDER_WIDTH * 2; 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; status.Text = s.Message;
@ -230,31 +219,15 @@ private void load(OsuColour colours)
d.FadeColour(s.GetAppropriateColour(colours), transition_duration); 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); bindings.Name.BindValueChanged(n => name.Text = n, true);
hostBind.BindTo(Room.Host); bindings.EndDate.BindValueChanged(d => endDate.Date = d, true);
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();
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -262,14 +235,5 @@ protected override void LoadComplete()
base.LoadComplete(); base.LoadComplete();
this.FadeInFromZero(transition_duration); 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;
}
} }
} }

View File

@ -21,8 +21,8 @@ public class ParticipantInfo : Container
{ {
private readonly FillFlowContainer levelRangeContainer; private readonly FillFlowContainer levelRangeContainer;
public readonly Bindable<User> Host = new Bindable<User>(); public readonly IBindable<User> Host = new Bindable<User>();
public readonly Bindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>(); public readonly IBindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
public ParticipantInfo(string rankPrefix = null) public ParticipantInfo(string rankPrefix = null)
{ {

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
@ -31,15 +30,8 @@ public class RoomInspector : Container
public readonly IBindable<Room> Room = new Bindable<Room>(); public readonly IBindable<Room> Room = new Bindable<Room>();
private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 };
private readonly Bindable<string> nameBind = new Bindable<string>();
private readonly Bindable<User> hostBind = new Bindable<User>();
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
private readonly Bindable<int?> maxParticipantsBind = new Bindable<int?>();
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
private readonly IBindableCollection<PlaylistItem> playlistBind = new BindableCollection<PlaylistItem>();
private readonly Bindable<BeatmapInfo> beatmap = new Bindable<BeatmapInfo>(); private readonly RoomBindings bindings = new RoomBindings();
private OsuColour colours; private OsuColour colours;
private Box statusStrip; private Box statusStrip;
@ -174,53 +166,27 @@ private void load(OsuColour colours)
}, },
}; };
playlistBind.ItemsAdded += _ => updatePlaylist(); participantInfo.Host.BindTo(bindings.Host);
playlistBind.ItemsRemoved += _ => updatePlaylist(); 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); bindings.Status.BindValueChanged(displayStatus);
participantsBind.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u))); bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)));
bindings.Name.BindValueChanged(n => name.Text = n);
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);
Room.BindValueChanged(updateRoom, true); Room.BindValueChanged(updateRoom, true);
} }
private Room lastRoom; private void updateRoom(Room room)
private void updateRoom(Room newRoom)
{ {
if (lastRoom != null) bindings.Room = room;
{
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);
}
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); participantsFlow.FadeIn(transition_duration);
participantCount.FadeIn(transition_duration); participantCount.FadeIn(transition_duration);
beatmapTypeInfo.FadeIn(transition_duration); beatmapTypeInfo.FadeIn(transition_duration);
@ -237,17 +203,6 @@ private void updateRoom(Room newRoom)
displayStatus(new RoomStatusNoneSelected()); 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() protected override void UpdateAfterChildren()

View File

@ -27,9 +27,9 @@ public class Header : Container
{ {
public const float HEIGHT = 200; public const float HEIGHT = 200;
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>(); public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
public readonly IBindable<GameType> Type = new Bindable<GameType>(); public readonly IBindable<GameType> Type = new Bindable<GameType>();
public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>(); public readonly IBindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>();
private readonly Box tabStrip; private readonly Box tabStrip;
@ -116,11 +116,11 @@ public Header(Room room)
beatmapTypeInfo.Beatmap.BindTo(Beatmap); beatmapTypeInfo.Beatmap.BindTo(Beatmap);
beatmapTypeInfo.Type.BindTo(Type); beatmapTypeInfo.Type.BindTo(Type);
modDisplay.Current.BindTo(Mods); background.Beatmap.BindTo(Beatmap);
Mods.BindValueChanged(m => modDisplay.Current.Value = m, true);
beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke();
background.Beatmap.BindTo(Beatmap);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -26,11 +26,11 @@ public class Info : Container
private OsuColour colours; private OsuColour colours;
public readonly Bindable<string> Name = new Bindable<string>(); public readonly IBindable<string> Name = new Bindable<string>();
public readonly Bindable<RoomAvailability> Availability = new Bindable<RoomAvailability>(); public readonly IBindable<RoomAvailability> Availability = new Bindable<RoomAvailability>();
public readonly Bindable<RoomStatus> Status = new Bindable<RoomStatus>(); public readonly IBindable<RoomStatus> Status = new Bindable<RoomStatus>();
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>(); public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
public readonly Bindable<DateTimeOffset> EndDate = new Bindable<DateTimeOffset>(); public readonly IBindable<DateTimeOffset> EndDate = new Bindable<DateTimeOffset>();
public Info(Room room) public Info(Room room)
{ {

View File

@ -15,14 +15,8 @@ namespace osu.Game.Screens.Multi.Match.Components
{ {
public class Participants : CompositeDrawable public class Participants : CompositeDrawable
{ {
public readonly Bindable<IEnumerable<User>> Users = new Bindable<IEnumerable<User>>(); public readonly IBindable<IEnumerable<User>> Users = new Bindable<IEnumerable<User>>();
public readonly Bindable<int?> MaxParticipants = new Bindable<int?>(); public readonly IBindable<int?> MaxParticipants = new Bindable<int?>();
public new MarginPadding Padding
{
get => base.Padding;
set => base.Padding = value;
}
public Participants() public Participants()
{ {

View File

@ -4,7 +4,6 @@
using System; using System;
using Humanizer; using Humanizer;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -24,12 +23,7 @@ public class RoomSettingsOverlay : FocusedOverlayContainer
private const float transition_duration = 350; private const float transition_duration = 350;
private const float field_padding = 45; private const float field_padding = 45;
private readonly Bindable<string> nameBind = new Bindable<string>(); private readonly RoomBindings bindings = new RoomBindings();
private readonly Bindable<RoomAvailability> availabilityBind = new Bindable<RoomAvailability>();
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
private readonly Bindable<int?> maxParticipantsBind = new Bindable<int?>();
private readonly IBindableCollection<PlaylistItem> playlistBind = new BindableCollection<PlaylistItem>();
private readonly Bindable<TimeSpan> durationBind = new Bindable<TimeSpan>();
private readonly Container content; private readonly Container content;
@ -51,6 +45,8 @@ public RoomSettingsOverlay(Room room)
{ {
this.room = room; this.room = room;
bindings.Room = room;
Masking = true; Masking = true;
Child = content = new Container Child = content = new Container
@ -189,11 +185,11 @@ public RoomSettingsOverlay(Room room)
TypePicker.Current.ValueChanged += t => typeLabel.Text = t.Name; TypePicker.Current.ValueChanged += t => typeLabel.Text = t.Name;
nameBind.ValueChanged += n => NameField.Text = n; bindings.Name.BindValueChanged(n => NameField.Text = n, true);
availabilityBind.ValueChanged += a => AvailabilityPicker.Current.Value = a; bindings.Availability.BindValueChanged(a => AvailabilityPicker.Current.Value = a, true);
typeBind.ValueChanged += t => TypePicker.Current.Value = t; bindings.Type.BindValueChanged(t => TypePicker.Current.Value = t, true);
maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); bindings.MaxParticipants.BindValueChanged(m => MaxParticipantsField.Text = m?.ToString(), true);
durationBind.ValueChanged += d => DurationField.Current.Value = d; bindings.Duration.BindValueChanged(d => DurationField.Current.Value = d, true);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -201,13 +197,6 @@ private void load(OsuColour colours)
{ {
typeLabel.Colour = colours.Yellow; 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; MaxParticipantsField.ReadOnly = true;
PasswordField.ReadOnly = true; PasswordField.ReadOnly = true;
AvailabilityPicker.ReadOnly.Value = true; AvailabilityPicker.ReadOnly.Value = true;
@ -222,19 +211,10 @@ protected override void Update()
ApplyButton.Enabled.Value = hasValidSettings; 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() 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); content.MoveToY(0, transition_duration, Easing.OutQuint);
} }
@ -245,16 +225,16 @@ protected override void PopOut()
private void apply() private void apply()
{ {
nameBind.Value = NameField.Text; bindings.Name.Value = NameField.Text;
availabilityBind.Value = AvailabilityPicker.Current.Value; bindings.Availability.Value = AvailabilityPicker.Current.Value;
typeBind.Value = TypePicker.Current.Value; bindings.Type.Value = TypePicker.Current.Value;
if (int.TryParse(MaxParticipantsField.Text, out int max)) if (int.TryParse(MaxParticipantsField.Text, out int max))
maxParticipantsBind.Value = max; bindings.MaxParticipants.Value = max;
else else
maxParticipantsBind.Value = null; bindings.MaxParticipants.Value = null;
durationBind.Value = DurationField.Current.Value; bindings.Duration.Value = DurationField.Current.Value;
manager?.CreateRoom(room); manager?.CreateRoom(room);
} }

View File

@ -5,39 +5,28 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer; 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.Match.Components;
using osu.Game.Screens.Multi.Play; using osu.Game.Screens.Multi.Play;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Users;
namespace osu.Game.Screens.Multi.Match namespace osu.Game.Screens.Multi.Match
{ {
public class MatchScreen : MultiplayerScreen public class MatchScreen : MultiplayerScreen
{ {
private readonly Bindable<string> nameBind = new Bindable<string>();
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
private readonly Bindable<RoomAvailability> availabilityBind = new Bindable<RoomAvailability>();
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
private readonly Bindable<int?> maxParticipantsBind = new Bindable<int?>();
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
private readonly BindableCollection<PlaylistItem> playlistBind = new BindableCollection<PlaylistItem>();
private readonly Bindable<DateTimeOffset> endDateBind = new Bindable<DateTimeOffset>();
public override bool AllowBeatmapRulesetChange => false; public override bool AllowBeatmapRulesetChange => false;
public override string Title => room.Name.Value; public override string Title => room.Name.Value;
public override string ShortTitle => "room"; public override string ShortTitle => "room";
private readonly Components.Header header; private readonly RoomBindings bindings = new RoomBindings();
private readonly Info info;
private readonly MatchLeaderboard leaderboard; private readonly MatchLeaderboard leaderboard;
private readonly Action<Screen> pushGameplayScreen; private readonly Action<Screen> pushGameplayScreen;
@ -58,14 +47,10 @@ public MatchScreen(Room room, Action<Screen> pushGameplayScreen)
this.room = room; this.room = room;
this.pushGameplayScreen = pushGameplayScreen; this.pushGameplayScreen = pushGameplayScreen;
nameBind.BindTo(room.Name); bindings.Room = room;
statusBind.BindTo(room.Status);
availabilityBind.BindTo(room.Availability);
typeBind.BindTo(room.Type);
participantsBind.BindTo(room.Participants);
maxParticipantsBind.BindTo(room.MaxParticipants);
endDateBind.BindTo(room.EndDate);
Info info;
Components.Header header;
RoomSettingsOverlay settings; RoomSettingsOverlay settings;
Children = new Drawable[] Children = new Drawable[]
@ -113,7 +98,6 @@ public MatchScreen(Room room, Action<Screen> pushGameplayScreen)
}; };
header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem }); header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem });
header.Tabs.Current.ValueChanged += t => header.Tabs.Current.ValueChanged += t =>
{ {
if (t is SettingsMatchPage) if (t is SettingsMatchPage)
@ -122,55 +106,55 @@ public MatchScreen(Room room, Action<Screen> pushGameplayScreen)
settings.Hide(); settings.Hide();
}; };
info.Name.BindTo(nameBind); info.Name.BindTo(bindings.Name);
info.Status.BindTo(statusBind); info.Status.BindTo(bindings.Status);
info.Availability.BindTo(availabilityBind); info.Availability.BindTo(bindings.Availability);
info.EndDate.BindTo(endDateBind); info.EndDate.BindTo(bindings.EndDate);
info.Beatmap.BindTo(bindings.CurrentBeatmap);
header.Type.BindTo(typeBind); header.Type.BindTo(bindings.Type);
header.Beatmap.BindTo(bindings.CurrentBeatmap);
playlistBind.ItemsAdded += _ => setFromPlaylist(); header.Mods.BindTo(bindings.CurrentMods);
playlistBind.ItemsRemoved += _ => setFromPlaylist();
} }
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.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<Mod> mods)
{
Beatmap.Value.Mods.Value = mods.ToArray();
}
private void setRuleset(RulesetInfo ruleset)
{
if (ruleset == null)
return;
game.ForcefullySetRuleset(ruleset);
} }
private void addPlaylistItem(PlaylistItem item) private void addPlaylistItem(PlaylistItem item)
{ {
playlistBind.Clear(); bindings.Playlist.Clear();
playlistBind.Add(item); bindings.Playlist.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);
} }
private void onStart() private void onStart()
{ {
switch (typeBind.Value) switch (bindings.Type.Value)
{ {
default: default:
case GameTypeTimeshift _: case GameTypeTimeshift _:

View File

@ -0,0 +1,101 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// 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
{
/// <summary>
/// Helper class which binds to values from a <see cref="Room"/>.
/// </summary>
public class RoomBindings
{
public RoomBindings()
{
Playlist.ItemsAdded += _ => updatePlaylist();
Playlist.ItemsRemoved += _ => updatePlaylist();
}
private Room room;
/// <summary>
/// The <see cref="Room"/> to bind to.
/// </summary>
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<Mod>();
currentRuleset.Value = playlistItem?.Ruleset;
}
public readonly Bindable<string> Name = new Bindable<string>();
public readonly Bindable<User> Host = new Bindable<User>();
public readonly Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
public readonly Bindable<GameType> Type = new Bindable<GameType>();
public readonly BindableCollection<PlaylistItem> Playlist = new BindableCollection<PlaylistItem>();
public readonly Bindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
public readonly Bindable<int?> MaxParticipants = new Bindable<int?>();
public readonly Bindable<DateTimeOffset> EndDate = new Bindable<DateTimeOffset>();
public readonly Bindable<RoomAvailability> Availability = new Bindable<RoomAvailability>();
public readonly Bindable<TimeSpan> Duration = new Bindable<TimeSpan>();
private readonly Bindable<BeatmapInfo> currentBeatmap = new Bindable<BeatmapInfo>();
public IBindable<BeatmapInfo> CurrentBeatmap => currentBeatmap;
private readonly Bindable<IEnumerable<Mod>> currentMods = new Bindable<IEnumerable<Mod>>();
public IBindable<IEnumerable<Mod>> CurrentMods => currentMods;
private readonly Bindable<RulesetInfo> currentRuleset = new Bindable<RulesetInfo>();
public IBindable<RulesetInfo> CurrentRuleset = new Bindable<RulesetInfo>();
}
}