1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-23 16:47:26 +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.Login;
using osu.Game.Overlays.Settings;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK.Input;
@ -72,9 +73,24 @@ namespace osu.Game.Tests.Visual.Menus
return false;
});
AddStep("enter code", () => loginOverlay.ChildrenOfType<OsuTextBox>().First().Text = "88800088");
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);
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) =>

View File

@ -15,6 +15,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Settings;
using osu.Game.Users;
using osuTK;
@ -30,15 +31,17 @@ namespace osu.Game.Overlays.Login
[Resolved]
private OsuColour colours { get; set; } = null!;
private UserDropdown dropdown = null!;
private UserDropdown? dropdown;
/// <summary>
/// Called to request a hide of a parent displaying this container.
/// </summary>
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 Bindable<UserStatus?> userStatus = new Bindable<UserStatus?>();
[Resolved]
private IAPIProvider api { get; set; } = null!;
@ -61,11 +64,21 @@ namespace osu.Game.Overlays.Login
AutoSizeAxes = Axes.Y;
}
[BackgroundDependencyLoader]
private void load()
protected override void LoadComplete()
{
base.LoadComplete();
apiState.BindTo(api.State);
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(() =>
@ -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 =>
{
switch (action.NewValue)
@ -171,6 +181,7 @@ namespace osu.Game.Overlays.Login
break;
}
}, true);
break;
}
@ -180,6 +191,9 @@ namespace osu.Game.Overlays.Login
private void updateDropdownCurrent(UserStatus? status)
{
if (dropdown == null)
return;
switch (status)
{
case UserStatus.Online: