1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-05 15:23:11 +08:00

Merge pull request #27754 from peppy/multi-binding-fix

Fix double binding causing game crash after API enters failing state
This commit is contained in:
Bartłomiej Dach 2024-03-29 10:21:33 +01:00 committed by GitHub
commit 5c7fdeca35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 7 deletions

View File

@ -15,6 +15,7 @@ using osu.Game.Online.API.Requests;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Login; using osu.Game.Overlays.Login;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Users;
using osu.Game.Users.Drawables; using osu.Game.Users.Drawables;
using osuTK.Input; using osuTK.Input;
@ -72,9 +73,24 @@ namespace osu.Game.Tests.Visual.Menus
return false; return false;
}); });
AddStep("enter code", () => loginOverlay.ChildrenOfType<OsuTextBox>().First().Text = "88800088"); AddStep("enter code", () => loginOverlay.ChildrenOfType<OsuTextBox>().First().Text = "88800088");
assertAPIState(APIState.Online); assertAPIState(APIState.Online);
assertDropdownState(UserAction.Online);
AddStep("set failing", () => { dummyAPI.SetState(APIState.Failing); });
AddStep("return to online", () => { dummyAPI.SetState(APIState.Online); });
AddStep("clear handler", () => dummyAPI.HandleRequest = null); AddStep("clear handler", () => dummyAPI.HandleRequest = null);
assertDropdownState(UserAction.Online);
AddStep("change user state", () => dummyAPI.LocalUser.Value.Status.Value = UserStatus.DoNotDisturb);
assertDropdownState(UserAction.DoNotDisturb);
}
private void assertDropdownState(UserAction state)
{
AddAssert($"dropdown state is {state}", () => loginOverlay.ChildrenOfType<UserDropdown>().First().Current.Value, () => Is.EqualTo(state));
} }
private void assertAPIState(APIState expected) => private void assertAPIState(APIState expected) =>

View File

@ -15,6 +15,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Users; using osu.Game.Users;
using osuTK; using osuTK;
@ -30,15 +31,17 @@ namespace osu.Game.Overlays.Login
[Resolved] [Resolved]
private OsuColour colours { get; set; } = null!; private OsuColour colours { get; set; } = null!;
private UserDropdown dropdown = null!; private UserDropdown? dropdown;
/// <summary> /// <summary>
/// Called to request a hide of a parent displaying this container. /// Called to request a hide of a parent displaying this container.
/// </summary> /// </summary>
public Action? RequestHide; public Action? RequestHide;
private IBindable<APIUser> user = null!;
private readonly Bindable<UserStatus?> status = new Bindable<UserStatus?>();
private readonly IBindable<APIState> apiState = new Bindable<APIState>(); private readonly IBindable<APIState> apiState = new Bindable<APIState>();
private readonly Bindable<UserStatus?> userStatus = new Bindable<UserStatus?>();
[Resolved] [Resolved]
private IAPIProvider api { get; set; } = null!; private IAPIProvider api { get; set; } = null!;
@ -61,11 +64,21 @@ namespace osu.Game.Overlays.Login
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
} }
[BackgroundDependencyLoader] protected override void LoadComplete()
private void load()
{ {
base.LoadComplete();
apiState.BindTo(api.State); apiState.BindTo(api.State);
apiState.BindValueChanged(onlineStateChanged, true); apiState.BindValueChanged(onlineStateChanged, true);
user = api.LocalUser.GetBoundCopy();
user.BindValueChanged(u =>
{
status.UnbindBindings();
status.BindTo(u.NewValue.Status);
}, true);
status.BindValueChanged(e => updateDropdownCurrent(e.NewValue), true);
} }
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() => private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
@ -144,9 +157,6 @@ namespace osu.Game.Overlays.Login
}, },
}; };
userStatus.BindTo(api.LocalUser.Value.Status);
userStatus.BindValueChanged(e => updateDropdownCurrent(e.NewValue), true);
dropdown.Current.BindValueChanged(action => dropdown.Current.BindValueChanged(action =>
{ {
switch (action.NewValue) switch (action.NewValue)
@ -171,6 +181,7 @@ namespace osu.Game.Overlays.Login
break; break;
} }
}, true); }, true);
break; break;
} }
@ -180,6 +191,9 @@ namespace osu.Game.Overlays.Login
private void updateDropdownCurrent(UserStatus? status) private void updateDropdownCurrent(UserStatus? status)
{ {
if (dropdown == null)
return;
switch (status) switch (status)
{ {
case UserStatus.Online: case UserStatus.Online: