From 37c1f5a8242fdb2ffe904a77ec5cd1db07326ec1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 5 Feb 2019 15:38:19 +0900 Subject: [PATCH] Split polling logic from RoomManager, now a container --- osu.Game/Screens/Multi/IRoomManager.cs | 7 -- .../Multi/Lounge/Components/FilterControl.cs | 33 ++++++++-- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 10 +-- osu.Game/Screens/Multi/Multiplayer.cs | 18 +++-- osu.Game/Screens/Multi/RoomManager.cs | 64 +++++------------- .../Screens/Multi/RoomPollingComponent.cs | 66 +++++++++++++++++++ 6 files changed, 125 insertions(+), 73 deletions(-) create mode 100644 osu.Game/Screens/Multi/RoomPollingComponent.cs diff --git a/osu.Game/Screens/Multi/IRoomManager.cs b/osu.Game/Screens/Multi/IRoomManager.cs index 944bcf7ce7..980879d79a 100644 --- a/osu.Game/Screens/Multi/IRoomManager.cs +++ b/osu.Game/Screens/Multi/IRoomManager.cs @@ -4,7 +4,6 @@ using System; using osu.Framework.Configuration; using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Lounge.Components; namespace osu.Game.Screens.Multi { @@ -40,11 +39,5 @@ namespace osu.Game.Screens.Multi /// Parts the currently-joined . /// void PartRoom(); - - /// - /// Queries for s matching a new . - /// - /// The to match. - void Filter(FilterCriteria criteria); } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index a027125bb5..950d475a30 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System.ComponentModel; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Game.Graphics; using osu.Game.Overlays.SearchableList; using osuTK.Graphics; @@ -15,17 +17,38 @@ namespace osu.Game.Screens.Multi.Lounge.Components protected override float ContentHorizontalPadding => base.ContentHorizontalPadding + OsuScreen.HORIZONTAL_OVERFLOW_PADDING; + [Resolved(CanBeNull = true)] + private Bindable filter { get; set; } + public FilterControl() { DisplayStyleControl.Hide(); } - public FilterCriteria CreateCriteria() => new FilterCriteria + [BackgroundDependencyLoader] + private void load() { - SearchString = Search.Current.Value ?? string.Empty, - PrimaryFilter = Tabs.Current, - SecondaryFilter = DisplayStyleControl.Dropdown.Current - }; + if (filter == null) + filter = new Bindable(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Search.Current.BindValueChanged(_ => updateFilter()); + Tabs.Current.BindValueChanged(_ => updateFilter(), true); + } + + private void updateFilter() + { + filter.Value = new FilterCriteria + { + SearchString = Search.Current.Value ?? string.Empty, + PrimaryFilter = Tabs.Current, + SecondaryFilter = DisplayStyleControl.Dropdown.Current + }; + } } public enum PrimaryFilter diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index a56d2892a4..5bc36090d5 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -21,7 +21,6 @@ namespace osu.Game.Screens.Multi.Lounge protected readonly FilterControl Filter; private readonly Container content; - private readonly RoomsContainer rooms; private readonly Action pushGameplayScreen; private readonly ProcessingOverlay processingOverlay; @@ -30,6 +29,7 @@ namespace osu.Game.Screens.Multi.Lounge this.pushGameplayScreen = pushGameplayScreen; RoomInspector inspector; + RoomsContainer rooms; InternalChildren = new Drawable[] { @@ -73,8 +73,6 @@ namespace osu.Game.Screens.Multi.Lounge inspector.Room.BindTo(rooms.SelectedRoom); - Filter.Search.Current.ValueChanged += s => filterRooms(); - Filter.Tabs.Current.ValueChanged += t => filterRooms(); Filter.Search.Exit += this.Exit; } @@ -113,12 +111,6 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.HoldFocus = false; } - private void filterRooms() - { - rooms.Filter(Filter.CreateCriteria()); - Manager?.Filter(Filter.CreateCriteria()); - } - private void joinRequested(Room room) { processingOverlay.Show(); diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 1741ac0b7b..be9650019d 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -20,6 +20,7 @@ using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Menu; using osu.Game.Screens.Multi.Lounge; +using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; using osuTK; @@ -47,6 +48,10 @@ namespace osu.Game.Screens.Multi private readonly OsuButton createButton; private readonly LoungeSubScreen loungeSubScreen; private readonly ScreenStack screenStack; + private readonly RoomPollingComponent pollingComponent; + + [Cached] + private readonly Bindable filter = new Bindable(); [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -99,7 +104,7 @@ namespace osu.Game.Screens.Multi }, }, }, - new Container + roomManager = new RoomManager { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, @@ -123,9 +128,12 @@ namespace osu.Game.Screens.Multi Name = { Value = $"{api.LocalUser}'s awesome room" } }), }, - roomManager = new RoomManager() + pollingComponent = new RoomPollingComponent() }); + pollingComponent.Filter.BindTo(filter); + pollingComponent.RoomsRetrieved += roomManager.UpdateRooms; + screenStack.ScreenPushed += screenPushed; screenStack.ScreenExited += screenExited; } @@ -149,8 +157,8 @@ namespace osu.Game.Screens.Multi private void updatePollingRate(bool idle) { - roomManager.TimeBetweenPolls = !this.IsCurrentScreen() || !(screenStack.CurrentScreen is LoungeSubScreen) ? 0 : (idle ? 120000 : 15000); - Logger.Log($"Polling adjusted to {roomManager.TimeBetweenPolls}"); + pollingComponent.TimeBetweenPolls = !this.IsCurrentScreen() || !(screenStack.CurrentScreen is LoungeSubScreen) ? 0 : (idle ? 120000 : 15000); + Logger.Log($"Polling adjusted to {pollingComponent.TimeBetweenPolls}"); } public void APIStateChanged(APIAccess api, APIState state) @@ -213,7 +221,7 @@ namespace osu.Game.Screens.Multi this.FadeOut(250); cancelLooping(); - roomManager.TimeBetweenPolls = 0; + pollingComponent.TimeBetweenPolls = 0; } private void cancelLooping() diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index bb943b80c6..1457261770 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -2,22 +2,21 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Graphics.Containers; using osu.Framework.Logging; using osu.Game.Beatmaps; -using osu.Game.Online; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Lounge.Components; namespace osu.Game.Screens.Multi { - public class RoomManager : PollingComponent, IRoomManager + public class RoomManager : Container, IRoomManager { public event Action RoomsUpdated; @@ -26,8 +25,6 @@ namespace osu.Game.Screens.Multi private Room currentRoom; - private FilterCriteria currentFilter = new FilterCriteria(); - [Resolved] private APIAccess api { get; set; } @@ -102,52 +99,25 @@ namespace osu.Game.Screens.Multi currentRoom = null; } - public void Filter(FilterCriteria criteria) + public void UpdateRooms(List newRooms) { - currentFilter = criteria; - PollImmediately(); - } - - private GetRoomsRequest pollReq; - - protected override Task Poll() - { - if (!api.IsLoggedIn) - return base.Poll(); - - var tcs = new TaskCompletionSource(); - - pollReq?.Cancel(); - pollReq = new GetRoomsRequest(currentFilter.PrimaryFilter); - - pollReq.Success += result => + // Remove past matches + foreach (var r in rooms.ToList()) { - // Remove past matches - foreach (var r in rooms.ToList()) - { - if (result.All(e => e.RoomID.Value != r.RoomID.Value)) - rooms.Remove(r); - } + if (newRooms.All(e => e.RoomID.Value != r.RoomID.Value)) + rooms.Remove(r); + } - for (int i = 0; i < result.Count; i++) - { - var r = result[i]; - r.Position = i; + for (int i = 0; i < newRooms.Count; i++) + { + var r = newRooms[i]; + r.Position = i; - update(r, r); - addRoom(r); - } + update(r, r); + addRoom(r); + } - RoomsUpdated?.Invoke(); - - tcs.SetResult(true); - }; - - pollReq.Failure += _ => tcs.SetResult(false); - - api.Queue(pollReq); - - return tcs.Task; + RoomsUpdated?.Invoke(); } /// diff --git a/osu.Game/Screens/Multi/RoomPollingComponent.cs b/osu.Game/Screens/Multi/RoomPollingComponent.cs new file mode 100644 index 0000000000..53c90d4d61 --- /dev/null +++ b/osu.Game/Screens/Multi/RoomPollingComponent.cs @@ -0,0 +1,66 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Game.Online; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Lounge.Components; + +namespace osu.Game.Screens.Multi +{ + public class RoomPollingComponent : PollingComponent + { + /// + /// Invoked when s have been retrieved from the API. + /// + public Action> RoomsRetrieved; + + /// + /// The to use when polling for s. + /// + public readonly Bindable Filter = new Bindable(); + + [Resolved] + private APIAccess api { get; set; } + + public RoomPollingComponent() + { + Filter.BindValueChanged(_ => + { + if (IsLoaded) + PollImmediately(); + }); + } + + private GetRoomsRequest pollReq; + + protected override Task Poll() + { + if (!api.IsLoggedIn) + return base.Poll(); + + var tcs = new TaskCompletionSource(); + + pollReq?.Cancel(); + pollReq = new GetRoomsRequest(Filter.Value.PrimaryFilter); + + pollReq.Success += result => + { + RoomsRetrieved?.Invoke(result); + tcs.SetResult(true); + }; + + pollReq.Failure += _ => tcs.SetResult(false); + + api.Queue(pollReq); + + return tcs.Task; + } + } +}