diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs index a386a26d32..17c0a159e9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs @@ -195,7 +195,7 @@ namespace osu.Game.Tests.Visual.Multiplayer private DrawableRoom createLoungeRoom(Room room) { - room.Host.Value ??= new APIUser { Username = "peppy", Id = 2 }; + room.Host ??= new APIUser { Username = "peppy", Id = 2 }; if (room.RecentParticipants.Count == 0) { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs index c959c07ffb..1e7003c612 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs @@ -26,17 +26,14 @@ namespace osu.Game.Tests.Visual.Multiplayer SelectedRoom.Value = new Room { Name = "test room", - Host = + Host = new APIUser { - Value = new APIUser - { - Id = 2, - Username = "peppy", - } + Id = 2, + Username = "peppy", } }; - Child = list = new DrawableRoomParticipantsList + Child = list = new DrawableRoomParticipantsList(SelectedRoom.Value) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs index 8769ff2e27..7cc86e71bf 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs @@ -61,8 +61,8 @@ namespace osu.Game.Tests.Visual.Playlists setupAndCreateRoom(room => { room.Name = "my awesome room"; - room.Host.Value = API.LocalUser.Value; - room.RecentParticipants.Add(room.Host.Value); + room.Host = API.LocalUser.Value; + room.RecentParticipants.Add(room.Host); room.EndDate.Value = DateTimeOffset.Now.AddMinutes(5); room.Playlist.Add(new PlaylistItem(importedBeatmap.Beatmaps.First()) { @@ -85,8 +85,8 @@ namespace osu.Game.Tests.Visual.Playlists { room.Name = "my awesome room"; room.MaxAttempts.Value = 5; - room.Host.Value = API.LocalUser.Value; - room.RecentParticipants.Add(room.Host.Value); + room.Host = API.LocalUser.Value; + room.RecentParticipants.Add(room.Host); room.EndDate.Value = DateTimeOffset.Now.AddMinutes(5); room.Playlist.Add(new PlaylistItem(importedBeatmap.Beatmaps.First()) { @@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.Playlists setupAndCreateRoom(room => { room.Name = "my awesome room"; - room.Host.Value = API.LocalUser.Value; + room.Host = API.LocalUser.Value; room.Playlist.Add(new PlaylistItem(importedBeatmap.Beatmaps.First()) { RulesetID = new OsuRuleset().RulesetInfo.OnlineID @@ -151,7 +151,7 @@ namespace osu.Game.Tests.Visual.Playlists setupAndCreateRoom(room => { room.Name = "my awesome room"; - room.Host.Value = API.LocalUser.Value; + room.Host = API.LocalUser.Value; room.Playlist.Add(new PlaylistItem(new BeatmapInfo { MD5Hash = realHash, diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index b6ad361c44..0d2b18a483 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -528,7 +528,7 @@ namespace osu.Game.Online.Multiplayer var user = Room.Users.FirstOrDefault(u => u.UserID == userId); Room.Host = user; - APIRoom.Host.Value = user?.User; + APIRoom.Host = user?.User; RoomUpdated?.Invoke(); }, false); diff --git a/osu.Game/Online/Rooms/Room.cs b/osu.Game/Online/Rooms/Room.cs index d2aa8ee4fe..48282ba5e9 100644 --- a/osu.Game/Online/Rooms/Room.cs +++ b/osu.Game/Online/Rooms/Room.cs @@ -39,6 +39,12 @@ namespace osu.Game.Online.Rooms set => SetField(ref name, value); } + public APIUser? Host + { + get => host; + set => SetField(ref host, value); + } + /// /// Represents the current item selected within the room. /// @@ -57,13 +63,12 @@ namespace osu.Game.Online.Rooms [JsonProperty("name")] private string name = string.Empty; + [JsonProperty("host")] + private APIUser? host; + [JsonProperty("current_playlist_item")] private PlaylistItem? currentPlaylistItem; - [Cached] - [JsonProperty("host")] - public readonly Bindable Host = new Bindable(); - [Cached] [JsonProperty("playlist")] public readonly BindableList Playlist = new BindableList(); @@ -217,8 +222,8 @@ namespace osu.Game.Online.Rooms Category.Value = other.Category.Value; - if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) - Host.Value = other.Host.Value; + if (other.Host != null && Host?.Id != other.Host.Id) + Host = other.Host; ChannelId.Value = other.ChannelId.Value; Status.Value = other.Status.Value; diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index 0bb33df966..ca42e98e3c 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.OnlinePlay.Components public virtual void CreateRoom(Room room, Action? onSuccess = null, Action? onError = null) { - room.Host.Value = api.LocalUser.Value; + room.Host = api.LocalUser.Value; var req = new CreateRoomRequest(room); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index e1235ab41e..99809a2a50 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -224,7 +224,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components Children = new Drawable[] { ButtonsContainer, - drawableRoomParticipantsList = new DrawableRoomParticipantsList + drawableRoomParticipantsList = new DrawableRoomParticipantsList(Room) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs index 60e05285d9..2ffe740e24 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs @@ -1,13 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Specialized; +using System.ComponentModel; using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -16,31 +14,33 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Users.Drawables; using osuTK; +using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { public partial class DrawableRoomParticipantsList : OnlinePlayComposite { public const float SHEAR_WIDTH = 12f; - private const float avatar_size = 36; - private const float height = 60f; - private static readonly Vector2 shear = new Vector2(SHEAR_WIDTH / height, 0); - private FillFlowContainer avatarFlow; + private readonly Room room; - private CircularAvatar hostAvatar; - private LinkFlowContainer hostText; - private HiddenUserCount hiddenUsers; - private OsuSpriteText totalCount; + private FillFlowContainer avatarFlow = null!; + private CircularAvatar hostAvatar = null!; + private LinkFlowContainer hostText = null!; + private HiddenUserCount hiddenUsers = null!; + private OsuSpriteText totalCount = null!; - public DrawableRoomParticipantsList() + public DrawableRoomParticipantsList(Room room) { + this.room = room; + AutoSizeAxes = Axes.X; Height = height; } @@ -172,7 +172,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components totalCount.Text = ParticipantCount.Value.ToString(); }, true); - Host.BindValueChanged(onHostChanged, true); + room.PropertyChanged += onRoomPropertyChanged; + updateRoomHost(); } private int numberOfCircles = 4; @@ -199,7 +200,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } - private void onParticipantsChanged(object sender, NotifyCollectionChangedEventArgs e) + private void onParticipantsChanged(object? sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { @@ -269,21 +270,33 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } - private void onHostChanged(ValueChangedEvent host) + private void onRoomPropertyChanged(object? sender, PropertyChangedEventArgs e) { - hostAvatar.User = host.NewValue; + if (e.PropertyName == nameof(Room.Host)) + updateRoomHost(); + } + + private void updateRoomHost() + { + hostAvatar.User = room.Host; hostText.Clear(); - if (host.NewValue != null) + if (room.Host != null) { hostText.AddText("hosted by "); - hostText.AddUserLink(host.NewValue); + hostText.AddUserLink(room.Host); } } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + room.PropertyChanged -= onRoomPropertyChanged; + } + private partial class CircularAvatar : CompositeDrawable { - public APIUser User + public APIUser? User { get => avatar.User; set => avatar.User = value; diff --git a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index e5d3bd1586..0c993f4abf 100644 --- a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -2,12 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps.Drawables; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Rooms; using osu.Game.Resources.Localisation.Web; using osu.Game.Screens.OnlinePlay.Lounge.Components; @@ -30,7 +30,6 @@ namespace osu.Game.Screens.OnlinePlay.Match private IAPIProvider api { get; set; } = null!; private readonly BindableWithCurrent selectedItem = new BindableWithCurrent(); - private readonly IBindable host = new Bindable(); private readonly bool allowEdit; private Drawable? editButton; @@ -40,7 +39,6 @@ namespace osu.Game.Screens.OnlinePlay.Match this.allowEdit = allowEdit; base.SelectedItem.BindTo(SelectedItem); - host.BindTo(room.Host); } [BackgroundDependencyLoader] @@ -62,13 +60,31 @@ namespace osu.Game.Screens.OnlinePlay.Match { base.LoadComplete(); + Room.PropertyChanged += onRoomPropertyChanged; + updateRoomHost(); + } + + private void onRoomPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(Room.Host)) + updateRoomHost(); + } + + private void updateRoomHost() + { if (editButton != null) - host.BindValueChanged(h => editButton.Alpha = h.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0, true); + editButton.Alpha = Room.Host?.Equals(api.LocalUser.Value) == true ? 1 : 0; } protected override UpdateableBeatmapBackgroundSprite CreateBackground() => base.CreateBackground().With(d => { d.BackgroundLoadDelay = 0; }); + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + Room.PropertyChanged -= onRoomPropertyChanged; + } } } diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs index f642b9c989..4c614bba8f 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs @@ -16,9 +16,6 @@ namespace osu.Game.Screens.OnlinePlay /// public partial class OnlinePlayComposite : CompositeDrawable { - [Resolved(typeof(Room))] - protected Bindable Host { get; private set; } = null!; - [Resolved(typeof(Room))] protected Bindable Status { get; private set; } = null!; diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs index d8c110d12a..b0f91ca0b9 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay { RoomID = -currentRoomId, Name = $@"Room {currentRoomId}", - Host = { Value = new APIUser { Username = @"Host" } }, + Host = new APIUser { Username = @"Host" }, EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) }, Category = { Value = withSpotlightRooms && i % 2 == 0 ? RoomCategory.Spotlight : RoomCategory.Normal }, }; diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs index cc8bd27d91..271b036d8e 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs @@ -262,12 +262,12 @@ namespace osu.Game.Tests.Visual.OnlinePlay public void AddServerSideRoom(Room room, APIUser host) { room.RoomID ??= currentRoomId++; - room.Host.Value = host; + room.Host = host; for (int i = 0; i < room.Playlist.Count; i++) { room.Playlist[i].ID = currentPlaylistItemId++; - room.Playlist[i].OwnerID = room.Host.Value.OnlineID; + room.Playlist[i].OwnerID = room.Host.OnlineID; } serverSideRooms.Add(room);