1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-11 05:57:24 +08:00

Move room tracking to lounge subscreen

This commit is contained in:
Dan Balasescu 2025-02-12 18:35:35 +09:00
parent d3f6f0953a
commit 068a66e7d4
No known key found for this signature in database
8 changed files with 95 additions and 150 deletions

View File

@ -50,17 +50,17 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
AddStep("add rooms", () => RoomManager.AddRooms(5, withSpotlightRooms: true)); AddStep("add rooms", () => RoomManager.AddRooms(5, withSpotlightRooms: true));
AddAssert("has 5 rooms", () => container.Rooms.Count == 5); AddAssert("has 5 rooms", () => container.DrawableRooms.Count == 5);
AddAssert("all spotlights at top", () => container.Rooms AddAssert("all spotlights at top", () => container.DrawableRooms
.SkipWhile(r => r.Room.Category == RoomCategory.Spotlight) .SkipWhile(r => r.Room.Category == RoomCategory.Spotlight)
.All(r => r.Room.Category == RoomCategory.Normal)); .All(r => r.Room.Category == RoomCategory.Normal));
AddStep("remove first room", () => RoomManager.RemoveRoom(RoomManager.Rooms.First(r => r.RoomID == 0))); AddStep("remove first room", () => RoomManager.RemoveRoom(RoomManager.Rooms.First(r => r.RoomID == 0)));
AddAssert("has 4 rooms", () => container.Rooms.Count == 4); AddAssert("has 4 rooms", () => container.DrawableRooms.Count == 4);
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID != 0)); AddAssert("first room removed", () => container.DrawableRooms.All(r => r.Room.RoomID != 0));
AddStep("select first room", () => container.Rooms.First().TriggerClick()); AddStep("select first room", () => container.DrawableRooms.First().TriggerClick());
AddAssert("first spotlight selected", () => checkRoomSelected(RoomManager.Rooms.First(r => r.Category == RoomCategory.Spotlight))); AddAssert("first spotlight selected", () => checkRoomSelected(RoomManager.Rooms.First(r => r.Category == RoomCategory.Spotlight)));
AddStep("remove last room", () => RoomManager.RemoveRoom(RoomManager.Rooms.MinBy(r => r.RoomID)!)); AddStep("remove last room", () => RoomManager.RemoveRoom(RoomManager.Rooms.MinBy(r => r.RoomID)!));
@ -137,15 +137,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
AddStep("add rooms", () => RoomManager.AddRooms(4)); AddStep("add rooms", () => RoomManager.AddRooms(4));
AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); AddUntilStep("4 rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 4);
AddStep("filter one room", () => container.Filter.Value = new FilterCriteria { SearchString = "1" }); AddStep("filter one room", () => container.Filter.Value = new FilterCriteria { SearchString = "1" });
AddUntilStep("1 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 1); AddUntilStep("1 rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 1);
AddStep("remove filter", () => container.Filter.Value = null); AddStep("remove filter", () => container.Filter.Value = null);
AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); AddUntilStep("4 rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 4);
} }
[Test] [Test]
@ -156,13 +156,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
// Todo: What even is this case...? // Todo: What even is this case...?
AddStep("set empty filter criteria", () => container.Filter.Value = new FilterCriteria()); AddStep("set empty filter criteria", () => container.Filter.Value = new FilterCriteria());
AddUntilStep("5 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 5); AddUntilStep("5 rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 5);
AddStep("filter osu! rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo }); AddStep("filter osu! rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo });
AddUntilStep("2 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 2); AddUntilStep("2 rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 2);
AddStep("filter catch rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo }); AddStep("filter catch rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo });
AddUntilStep("3 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 3); AddUntilStep("3 rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 3);
} }
[Test] [Test]
@ -176,15 +176,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("apply default filter", () => container.Filter.SetDefault()); AddStep("apply default filter", () => container.Filter.SetDefault());
AddUntilStep("both rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 2); AddUntilStep("both rooms visible", () => container.DrawableRooms.Count(r => r.IsPresent) == 2);
AddStep("filter public rooms", () => container.Filter.Value = new FilterCriteria { Permissions = RoomPermissionsFilter.Public }); AddStep("filter public rooms", () => container.Filter.Value = new FilterCriteria { Permissions = RoomPermissionsFilter.Public });
AddUntilStep("private room hidden", () => container.Rooms.All(r => !r.Room.HasPassword)); AddUntilStep("private room hidden", () => container.DrawableRooms.All(r => !r.Room.HasPassword));
AddStep("filter private rooms", () => container.Filter.Value = new FilterCriteria { Permissions = RoomPermissionsFilter.Private }); AddStep("filter private rooms", () => container.Filter.Value = new FilterCriteria { Permissions = RoomPermissionsFilter.Private });
AddUntilStep("public room hidden", () => container.Rooms.All(r => r.Room.HasPassword)); AddUntilStep("public room hidden", () => container.DrawableRooms.All(r => r.Room.HasPassword));
} }
[Test] [Test]

View File

@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual.Playlists
public void TestManyRooms() public void TestManyRooms()
{ {
AddStep("add rooms", () => RoomManager.AddRooms(500)); AddStep("add rooms", () => RoomManager.AddRooms(500));
AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 500); AddUntilStep("wait for rooms", () => roomsContainer.DrawableRooms.Count == 500);
} }
[Test] [Test]
@ -45,45 +45,45 @@ namespace osu.Game.Tests.Visual.Playlists
AddStep("reset mouse", () => InputManager.ReleaseButton(MouseButton.Left)); AddStep("reset mouse", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("add rooms", () => RoomManager.AddRooms(30)); AddStep("add rooms", () => RoomManager.AddRooms(30));
AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 30); AddUntilStep("wait for rooms", () => roomsContainer.DrawableRooms.Count == 30);
AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0])); AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.DrawableRooms[0]));
AddStep("move mouse to third room", () => InputManager.MoveMouseTo(roomsContainer.Rooms[2])); AddStep("move mouse to third room", () => InputManager.MoveMouseTo(roomsContainer.DrawableRooms[2]));
AddStep("hold down", () => InputManager.PressButton(MouseButton.Left)); AddStep("hold down", () => InputManager.PressButton(MouseButton.Left));
AddStep("drag to top", () => InputManager.MoveMouseTo(roomsContainer.Rooms[0])); AddStep("drag to top", () => InputManager.MoveMouseTo(roomsContainer.DrawableRooms[0]));
AddAssert("first and second room masked", () AddAssert("first and second room masked", ()
=> !checkRoomVisible(roomsContainer.Rooms[0]) && => !checkRoomVisible(roomsContainer.DrawableRooms[0]) &&
!checkRoomVisible(roomsContainer.Rooms[1])); !checkRoomVisible(roomsContainer.DrawableRooms[1]));
} }
[Test] [Test]
public void TestScrollSelectedIntoView() public void TestScrollSelectedIntoView()
{ {
AddStep("add rooms", () => RoomManager.AddRooms(30)); AddStep("add rooms", () => RoomManager.AddRooms(30));
AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 30); AddUntilStep("wait for rooms", () => roomsContainer.DrawableRooms.Count == 30);
AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0])); AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.DrawableRooms[0]));
AddStep("select last room", () => roomsContainer.Rooms[^1].TriggerClick()); AddStep("select last room", () => roomsContainer.DrawableRooms[^1].TriggerClick());
AddUntilStep("first room is masked", () => !checkRoomVisible(roomsContainer.Rooms[0])); AddUntilStep("first room is masked", () => !checkRoomVisible(roomsContainer.DrawableRooms[0]));
AddUntilStep("last room is not masked", () => checkRoomVisible(roomsContainer.Rooms[^1])); AddUntilStep("last room is not masked", () => checkRoomVisible(roomsContainer.DrawableRooms[^1]));
} }
[Test] [Test]
public void TestEnteringRoomTakesLeaseOnSelection() public void TestEnteringRoomTakesLeaseOnSelection()
{ {
AddStep("add rooms", () => RoomManager.AddRooms(1)); AddStep("add rooms", () => RoomManager.AddRooms(1));
AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 1); AddUntilStep("wait for rooms", () => roomsContainer.DrawableRooms.Count == 1);
AddAssert("selected room is not disabled", () => !loungeScreen.SelectedRoom.Disabled); AddAssert("selected room is not disabled", () => !loungeScreen.SelectedRoom.Disabled);
AddStep("select room", () => roomsContainer.Rooms[0].TriggerClick()); AddStep("select room", () => roomsContainer.DrawableRooms[0].TriggerClick());
AddAssert("selected room is non-null", () => loungeScreen.SelectedRoom.Value != null); AddAssert("selected room is non-null", () => loungeScreen.SelectedRoom.Value != null);
AddStep("enter room", () => roomsContainer.Rooms[0].TriggerClick()); AddStep("enter room", () => roomsContainer.DrawableRooms[0].TriggerClick());
AddUntilStep("wait for match load", () => Stack.CurrentScreen is PlaylistsRoomSubScreen); AddUntilStep("wait for match load", () => Stack.CurrentScreen is PlaylistsRoomSubScreen);

View File

@ -1,9 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Lounge.Components;
@ -15,23 +15,8 @@ namespace osu.Game.Screens.OnlinePlay.Components
/// </summary> /// </summary>
public partial class ListingPollingComponent : RoomPollingComponent public partial class ListingPollingComponent : RoomPollingComponent
{ {
public IBindable<bool> InitialRoomsReceived => initialRoomsReceived; public required Action<Room[]> RoomsReceived { get; init; }
private readonly Bindable<bool> initialRoomsReceived = new Bindable<bool>(); public readonly IBindable<FilterCriteria?> Filter = new Bindable<FilterCriteria?>();
public readonly Bindable<FilterCriteria?> Filter = new Bindable<FilterCriteria?>();
[BackgroundDependencyLoader]
private void load()
{
Filter.BindValueChanged(_ =>
{
RoomManager.ClearRooms();
initialRoomsReceived.Value = false;
if (IsLoaded)
PollImmediately();
});
}
private GetRoomsRequest? lastPollRequest; private GetRoomsRequest? lastPollRequest;
@ -43,26 +28,14 @@ namespace osu.Game.Screens.OnlinePlay.Components
if (Filter.Value == null) if (Filter.Value == null)
return base.Poll(); return base.Poll();
var tcs = new TaskCompletionSource<bool>();
lastPollRequest?.Cancel(); lastPollRequest?.Cancel();
var tcs = new TaskCompletionSource<bool>();
var req = new GetRoomsRequest(Filter.Value); var req = new GetRoomsRequest(Filter.Value);
req.Success += result => req.Success += result =>
{ {
result = result.Where(r => r.Category != RoomCategory.DailyChallenge).ToList(); RoomsReceived(result.Where(r => r.Category != RoomCategory.DailyChallenge).ToArray());
foreach (var existing in RoomManager.Rooms.ToArray())
{
if (result.All(r => r.RoomID != existing.RoomID))
RoomManager.RemoveRoom(existing);
}
foreach (var incoming in result)
RoomManager.AddOrUpdateRoom(incoming);
initialRoomsReceived.Value = true;
tcs.SetResult(true); tcs.SetResult(true);
}; };
@ -71,6 +44,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
API.Queue(req); API.Queue(req);
lastPollRequest = req; lastPollRequest = req;
return tcs.Task; return tcs.Task;
} }
} }

View File

@ -28,15 +28,14 @@ namespace osu.Game.Screens.OnlinePlay.Components
if (room.RoomID == null) if (room.RoomID == null)
return base.Poll(); return base.Poll();
var tcs = new TaskCompletionSource<bool>();
lastPollRequest?.Cancel(); lastPollRequest?.Cancel();
var tcs = new TaskCompletionSource<bool>();
var req = new GetRoomRequest(room.RoomID.Value); var req = new GetRoomRequest(room.RoomID.Value);
req.Success += result => req.Success += result =>
{ {
RoomManager.AddOrUpdateRoom(result); room.CopyFrom(result);
tcs.SetResult(true); tcs.SetResult(true);
}; };

View File

@ -7,10 +7,8 @@ using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
@ -24,17 +22,14 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
{ {
public partial class RoomsContainer : CompositeDrawable, IKeyBindingHandler<GlobalAction> public partial class RoomsContainer : CompositeDrawable, IKeyBindingHandler<GlobalAction>
{ {
public readonly BindableList<Room> Rooms = new BindableList<Room>();
public readonly Bindable<Room?> SelectedRoom = new Bindable<Room?>(); public readonly Bindable<Room?> SelectedRoom = new Bindable<Room?>();
public readonly Bindable<FilterCriteria?> Filter = new Bindable<FilterCriteria?>(); public readonly Bindable<FilterCriteria?> Filter = new Bindable<FilterCriteria?>();
public IReadOnlyList<DrawableRoom> Rooms => roomFlow.FlowingChildren.Cast<DrawableRoom>().ToArray(); public IReadOnlyList<DrawableRoom> DrawableRooms => roomFlow.FlowingChildren.Cast<DrawableRoom>().ToArray();
private readonly IBindableList<Room> rooms = new BindableList<Room>();
private readonly FillFlowContainer<DrawableLoungeRoom> roomFlow; private readonly FillFlowContainer<DrawableLoungeRoom> roomFlow;
[Resolved]
private IRoomManager roomManager { get; set; } = null!;
// handle deselection // handle deselection
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
@ -62,11 +57,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
protected override void LoadComplete() protected override void LoadComplete()
{ {
rooms.CollectionChanged += roomsChanged; Rooms.BindCollectionChanged(roomsChanged, true);
roomManager.RoomsUpdated += updateSorting;
rooms.BindTo(roomManager.Rooms);
Filter.BindValueChanged(criteria => applyFilterCriteria(criteria.NewValue), true); Filter.BindValueChanged(criteria => applyFilterCriteria(criteria.NewValue), true);
} }
@ -155,7 +146,14 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
private void addRooms(IEnumerable<Room> rooms) private void addRooms(IEnumerable<Room> rooms)
{ {
foreach (var room in rooms) foreach (var room in rooms)
roomFlow.Add(new DrawableLoungeRoom(room) { SelectedRoom = SelectedRoom }); {
var drawableRoom = new DrawableLoungeRoom(room) { SelectedRoom = SelectedRoom };
roomFlow.Add(drawableRoom);
// Always show spotlight playlists at the top of the listing.
roomFlow.SetLayoutPosition(drawableRoom, room.Category > RoomCategory.Normal ? float.MinValue : -(room.RoomID ?? 0));
}
applyFilterCriteria(Filter.Value); applyFilterCriteria(Filter.Value);
} }
@ -181,17 +179,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
SelectedRoom.Value = null; SelectedRoom.Value = null;
} }
private void updateSorting()
{
foreach (var room in roomFlow)
{
roomFlow.SetLayoutPosition(room, room.Room.Category > RoomCategory.Normal
// Always show spotlight playlists at the top of the listing.
? float.MinValue
: -(room.Room.RoomID ?? 0));
}
}
protected override bool OnClick(ClickEvent e) protected override bool OnClick(ClickEvent e)
{ {
if (!SelectedRoom.Disabled) if (!SelectedRoom.Disabled)
@ -226,7 +213,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
if (SelectedRoom.Disabled) if (SelectedRoom.Disabled)
return; return;
var visibleRooms = Rooms.AsEnumerable().Where(r => r.IsPresent); var visibleRooms = DrawableRooms.AsEnumerable().Where(r => r.IsPresent);
Room? room; Room? room;
@ -246,13 +233,5 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
} }
#endregion #endregion
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (roomManager.IsNotNull())
roomManager.RoomsUpdated -= updateSorting;
}
} }
} }

View File

@ -53,8 +53,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
AutoSizeAxes = Axes.Both AutoSizeAxes = Axes.Both
}; };
protected ListingPollingComponent ListingPollingComponent { get; private set; } = null!;
protected readonly Bindable<Room?> SelectedRoom = new Bindable<Room?>(); protected readonly Bindable<Room?> SelectedRoom = new Bindable<Room?>();
[Resolved] [Resolved]
@ -75,12 +73,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
[Resolved] [Resolved]
protected OsuConfigManager Config { get; private set; } = null!; protected OsuConfigManager Config { get; private set; } = null!;
private IDisposable? joiningRoomOperation { get; set; } private IDisposable? joiningRoomOperation;
private LeasedBindable<Room?>? selectionLease; private LeasedBindable<Room?>? selectionLease;
private readonly BindableList<Room> rooms = new BindableList<Room>();
private readonly Bindable<FilterCriteria?> filter = new Bindable<FilterCriteria?>(); private readonly Bindable<FilterCriteria?> filter = new Bindable<FilterCriteria?>();
private readonly Bindable<bool> hasListingResults = new Bindable<bool>();
private readonly IBindable<bool> operationInProgress = new Bindable<bool>(); private readonly IBindable<bool> operationInProgress = new Bindable<bool>();
private readonly IBindable<bool> isIdle = new BindableBool(); private readonly IBindable<bool> isIdle = new BindableBool();
private ListingPollingComponent listingPollingComponent = null!;
private PopoverContainer popoverContainer = null!; private PopoverContainer popoverContainer = null!;
private LoadingLayer loadingLayer = null!; private LoadingLayer loadingLayer = null!;
private RoomsContainer roomsContainer = null!; private RoomsContainer roomsContainer = null!;
@ -100,7 +101,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
ListingPollingComponent = CreatePollingComponent().With(c => c.Filter.BindTarget = filter), listingPollingComponent = new ListingPollingComponent
{
RoomsReceived = onListingReceived,
Filter = { BindTarget = filter }
},
popoverContainer = new PopoverContainer popoverContainer = new PopoverContainer
{ {
Name = @"Rooms area", Name = @"Rooms area",
@ -116,8 +121,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
ScrollbarOverlapsContent = false, ScrollbarOverlapsContent = false,
Child = roomsContainer = new RoomsContainer Child = roomsContainer = new RoomsContainer
{ {
Rooms = { BindTarget = rooms },
SelectedRoom = { BindTarget = SelectedRoom },
Filter = { BindTarget = filter }, Filter = { BindTarget = filter },
SelectedRoom = { BindTarget = SelectedRoom }
} }
}, },
}, },
@ -178,7 +184,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
// scroll selected room into view on selection. // scroll selected room into view on selection.
SelectedRoom.BindValueChanged(val => SelectedRoom.BindValueChanged(val =>
{ {
var drawable = roomsContainer.Rooms.FirstOrDefault(r => r.Room == val.NewValue); var drawable = roomsContainer.DrawableRooms.FirstOrDefault(r => r.Room == val.NewValue);
if (drawable != null) if (drawable != null)
scrollContainer.ScrollIntoView(drawable); scrollContainer.ScrollIntoView(drawable);
}); });
@ -190,7 +196,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced()); searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced());
ruleset.BindValueChanged(_ => UpdateFilter()); ruleset.BindValueChanged(_ => UpdateFilter());
isIdle.BindValueChanged(_ => updatePollingRate(this.IsCurrentScreen()), true); isIdle.BindValueChanged(_ => updatePollingRate(this.IsCurrentScreen()), true);
if (ongoingOperationTracker != null) if (ongoingOperationTracker != null)
@ -199,11 +204,38 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
operationInProgress.BindValueChanged(_ => updateLoadingLayer()); operationInProgress.BindValueChanged(_ => updateLoadingLayer());
} }
ListingPollingComponent.InitialRoomsReceived.BindValueChanged(_ => updateLoadingLayer(), true); hasListingResults.BindValueChanged(_ => updateLoadingLayer());
filter.BindValueChanged(_ =>
{
rooms.Clear();
hasListingResults.Value = false;
listingPollingComponent.PollImmediately();
});
updateFilter(); updateFilter();
} }
private void onListingReceived(Room[] result)
{
Dictionary<long, Room> localRoomsById = rooms.ToDictionary(r => r.RoomID!.Value);
Dictionary<long, Room> resultRoomsById = result.ToDictionary(r => r.RoomID!.Value);
// Remove all local rooms no longer in the result set.
rooms.RemoveAll(r => !resultRoomsById.ContainsKey(r.RoomID!.Value));
// Add or update local rooms with the result set.
foreach (var r in result)
{
if (localRoomsById.TryGetValue(r.RoomID!.Value, out Room? existingRoom))
existingRoom.CopyFrom(r);
else
rooms.Add(r);
}
hasListingResults.Value = true;
}
#region Filtering #region Filtering
public void UpdateFilter() => Scheduler.AddOnce(updateFilter); public void UpdateFilter() => Scheduler.AddOnce(updateFilter);
@ -267,7 +299,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
onReturning(); onReturning();
// Poll for any newly-created rooms (including potentially the user's own). // Poll for any newly-created rooms (including potentially the user's own).
ListingPollingComponent.PollImmediately(); listingPollingComponent.PollImmediately();
} }
public override bool OnExiting(ScreenExitEvent e) public override bool OnExiting(ScreenExitEvent e)
@ -392,11 +424,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
this.Push(CreateRoomSubScreen(room)); this.Push(CreateRoomSubScreen(room));
} }
public void RefreshRooms() => ListingPollingComponent.PollImmediately(); public void RefreshRooms() => listingPollingComponent.PollImmediately();
private void updateLoadingLayer() private void updateLoadingLayer()
{ {
if (operationInProgress.Value || !ListingPollingComponent.InitialRoomsReceived.Value) if (operationInProgress.Value || !hasListingResults.Value)
loadingLayer.Show(); loadingLayer.Show();
else else
loadingLayer.Hide(); loadingLayer.Hide();
@ -405,11 +437,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
private void updatePollingRate(bool isCurrentScreen) private void updatePollingRate(bool isCurrentScreen)
{ {
if (!isCurrentScreen) if (!isCurrentScreen)
ListingPollingComponent.TimeBetweenPolls.Value = 0; listingPollingComponent.TimeBetweenPolls.Value = 0;
else else
ListingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; listingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000;
Logger.Log($"Polling adjusted (listing: {ListingPollingComponent.TimeBetweenPolls.Value})"); Logger.Log($"Polling adjusted (listing: {listingPollingComponent.TimeBetweenPolls.Value})");
} }
protected abstract OsuButton CreateNewRoomButton(); protected abstract OsuButton CreateNewRoomButton();
@ -421,7 +453,5 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
protected abstract Room CreateNewRoom(); protected abstract Room CreateNewRoom();
protected abstract RoomSubScreen CreateRoomSubScreen(Room room); protected abstract RoomSubScreen CreateRoomSubScreen(Room room);
protected abstract ListingPollingComponent CreatePollingComponent();
} }
} }

View File

@ -79,8 +79,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
protected override RoomSubScreen CreateRoomSubScreen(Room room) => new MultiplayerMatchSubScreen(room); protected override RoomSubScreen CreateRoomSubScreen(Room room) => new MultiplayerMatchSubScreen(room);
protected override ListingPollingComponent CreatePollingComponent() => new MultiplayerListingPollingComponent();
protected override void JoinInternal(Room room, string? password, Action<Room> onSuccess, Action<string> onFailure) protected override void JoinInternal(Room room, string? password, Action<Room> onSuccess, Action<string> onFailure)
{ {
client.JoinRoom(room, password).ContinueWith(result => client.JoinRoom(room, password).ContinueWith(result =>
@ -109,37 +107,5 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
base.OpenNewRoom(room); base.OpenNewRoom(room);
} }
private partial class MultiplayerListingPollingComponent : ListingPollingComponent
{
[Resolved]
private MultiplayerClient client { get; set; } = null!;
private readonly IBindable<bool> isConnected = new Bindable<bool>();
[BackgroundDependencyLoader]
private void load()
{
isConnected.BindTo(client.IsConnected);
isConnected.BindValueChanged(_ => Scheduler.AddOnce(poll), true);
}
private void poll()
{
if (isConnected.Value && IsLoaded)
PollImmediately();
}
protected override Task Poll()
{
if (!isConnected.Value)
return Task.CompletedTask;
if (client.Room != null)
return Task.CompletedTask;
return base.Poll();
}
}
} }
} }

View File

@ -11,7 +11,6 @@ using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Components;
using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge;
using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Lounge.Components;
using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match;
@ -87,8 +86,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
protected override RoomSubScreen CreateRoomSubScreen(Room room) => new PlaylistsRoomSubScreen(room); protected override RoomSubScreen CreateRoomSubScreen(Room room) => new PlaylistsRoomSubScreen(room);
protected override ListingPollingComponent CreatePollingComponent() => new ListingPollingComponent();
private enum PlaylistsCategory private enum PlaylistsCategory
{ {
Any, Any,