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]
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",
},
}
});
});
}
}

View File

@ -1,7 +1,9 @@
// 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.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<int?> maxParticipants = new Bindable<int?>();
private readonly Bindable<IEnumerable<User>> users = new Bindable<IEnumerable<User>>();
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);
}
}
}

View File

@ -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<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
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)

View File

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

View File

@ -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<SelectionState>, IF
public event Action<SelectionState> StateChanged;
private readonly RoomBindings bindings = new RoomBindings();
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 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;
}
}
}

View File

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

View File

@ -1,7 +1,6 @@
// 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.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> Room = new Bindable<Room>();
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 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()

View File

@ -27,9 +27,9 @@ public class Header : Container
{
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 Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>();
public readonly IBindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>();
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]

View File

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

View File

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

View File

@ -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<string> nameBind = new Bindable<string>();
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 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);
}

View File

@ -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<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 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<Screen> pushGameplayScreen;
@ -58,14 +47,10 @@ public MatchScreen(Room room, Action<Screen> 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<Screen> 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<Screen> 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<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)
{
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 _:

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>();
}
}