1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 10:23:20 +08:00

Compare commits

...

14 Commits

Author SHA1 Message Date
Dean Herbert
feade4a2b8
Merge c14fe21219 into f09d8f097a 2024-12-03 23:25:09 +09:00
Dan Balasescu
f09d8f097a
Merge pull request #30953 from peppy/notification-while-chedcking-for-updates
Show an ongoing operation when checking for updates
2024-12-03 17:27:10 +09:00
Dean Herbert
457957d3b8
Refactor check-update flow to better handle unobserved exceptions 2024-12-03 14:23:10 +09:00
Dean Herbert
2ceb3f6f85
Show an ongoing operation when checking for updates
Addresses https://github.com/ppy/osu/discussions/30950.
2024-12-03 13:43:20 +09:00
Bartłomiej Dach
c14fe21219
Fix LCA call crashing in actual usage
It's not allowed to call `LoadComponentsAsync()` on a background thread:

	fd64f2f0d4/osu.Framework/Graphics/Containers/CompositeDrawable.cs (L147)

and in this case the event that causes the LCA call is dispatched from a
websocket client, which is not on the update thread, so scheduling is
required.
2024-11-28 11:19:00 +01:00
Bartłomiej Dach
b0958c8d41
Attempt to fix test failures 2024-11-28 10:29:53 +01:00
Dean Herbert
bf29e3ae71
Simplify hide code by moving to common method 2024-11-26 18:00:32 +09:00
Dean Herbert
71294c312b
Change point of queueing to avoid loading-from-in-queue 2024-11-26 17:58:50 +09:00
Dean Herbert
98044c108e
Revert "Ensure DrawableMedal loading doesn't ever block on online resources"
This reverts commit 8585327858.
2024-11-26 17:41:12 +09:00
Dean Herbert
1e6c04e98b
Remove debug logging 2024-11-26 16:11:06 +09:00
Dean Herbert
e8fae85e8d
Fix hidden dissmissing logic 2024-11-26 14:45:40 +09:00
Dean Herbert
672dbe6e03
Better control of show/hide of overlay 2024-11-26 14:42:30 +09:00
Dean Herbert
d057dc9a95
Refactor MedalOverlay to be more readable
Shouldn't really have any functionality changes, just fixing some old
code that I can't easily parse these days.
2024-11-26 14:19:39 +09:00
Dean Herbert
8585327858
Ensure DrawableMedal loading doesn't ever block on online resources 2024-11-26 14:08:53 +09:00
4 changed files with 102 additions and 52 deletions

View File

@ -44,6 +44,11 @@ namespace osu.Game.Localisation
/// </summary> /// </summary>
public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates"); public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates");
/// <summary>
/// "Checking for updates"
/// </summary>
public static LocalisableString CheckingForUpdates => new TranslatableString(getKey(@"checking_for_updates"), @"Checking for updates");
/// <summary> /// <summary>
/// "Open osu! folder" /// "Open osu! folder"
/// </summary> /// </summary>

View File

@ -245,18 +245,19 @@ namespace osu.Game.Overlays
this.FadeOut(200); this.FadeOut(200);
} }
public void Dismiss() public bool Dismiss()
{ {
if (drawableMedal != null && drawableMedal.State != DisplayState.Full) if (drawableMedal != null && drawableMedal.State != DisplayState.Full)
{ {
// if we haven't yet, play out the animation fully // if we haven't yet, play out the animation fully
drawableMedal.State = DisplayState.Full; drawableMedal.State = DisplayState.Full;
FinishTransforms(true); FinishTransforms(true);
return; return false;
} }
Hide(); Hide();
Expire(); Expire();
return true;
} }
private partial class BackgroundStrip : Container private partial class BackgroundStrip : Container

View File

@ -2,7 +2,6 @@
// 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.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -35,7 +34,7 @@ namespace osu.Game.Overlays
private IAPIProvider api { get; set; } = null!; private IAPIProvider api { get; set; } = null!;
private Container<Drawable> medalContainer = null!; private Container<Drawable> medalContainer = null!;
private MedalAnimation? lastAnimation; private MedalAnimation? currentMedalDisplay;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
@ -54,11 +53,12 @@ namespace osu.Game.Overlays
{ {
base.LoadComplete(); base.LoadComplete();
OverlayActivationMode.BindValueChanged(val => OverlayActivationMode.BindValueChanged(_ => showNextMedal(), true);
}
public override void Hide()
{ {
if (val.NewValue == OverlayActivation.All && (queuedMedals.Any() || medalContainer.Any() || lastAnimation?.IsLoaded == false)) // don't allow hiding the overlay via any method other than our own.
Show();
}, true);
} }
private void handleMedalMessages(SocketMessage obj) private void handleMedalMessages(SocketMessage obj)
@ -83,34 +83,18 @@ namespace osu.Game.Overlays
var medalAnimation = new MedalAnimation(medal); var medalAnimation = new MedalAnimation(medal);
queuedMedals.Enqueue(medalAnimation);
Logger.Log($"Queueing medal unlock for \"{medal.Name}\" ({queuedMedals.Count} to display)"); Logger.Log($"Queueing medal unlock for \"{medal.Name}\" ({queuedMedals.Count} to display)");
if (OverlayActivationMode.Value == OverlayActivation.All) Schedule(() => LoadComponentAsync(medalAnimation, m =>
Scheduler.AddOnce(Show);
}
protected override void Update()
{ {
base.Update(); queuedMedals.Enqueue(m);
showNextMedal();
if (medalContainer.Any() || lastAnimation?.IsLoaded == false) }));
return;
if (!queuedMedals.TryDequeue(out lastAnimation))
{
Logger.Log("All queued medals have been displayed!");
Hide();
return;
}
Logger.Log($"Preparing to display \"{lastAnimation.Medal.Name}\"");
LoadComponentAsync(lastAnimation, medalContainer.Add);
} }
protected override bool OnClick(ClickEvent e) protected override bool OnClick(ClickEvent e)
{ {
lastAnimation?.Dismiss(); progressDisplayByUser();
return true; return true;
} }
@ -118,19 +102,54 @@ namespace osu.Game.Overlays
{ {
if (e.Action == GlobalAction.Back) if (e.Action == GlobalAction.Back)
{ {
lastAnimation?.Dismiss(); progressDisplayByUser();
return true; return true;
} }
return base.OnPressed(e); return base.OnPressed(e);
} }
private void progressDisplayByUser()
{
// Dismissing may sometimes play out the medal animation rather than immediately dismissing.
if (currentMedalDisplay?.Dismiss() == false)
return;
currentMedalDisplay = null;
showNextMedal();
}
private void showNextMedal()
{
// If already displayed, keep displaying medals regardless of activation mode changes.
if (OverlayActivationMode.Value != OverlayActivation.All && State.Value == Visibility.Hidden)
return;
// A medal is already displaying.
if (currentMedalDisplay != null)
return;
if (queuedMedals.TryDequeue(out currentMedalDisplay))
{
Logger.Log($"Displaying \"{currentMedalDisplay.Medal.Name}\"");
medalContainer.Add(currentMedalDisplay);
Show();
}
else if (State.Value == Visibility.Visible)
{
Logger.Log("All queued medals have been displayed, hiding overlay!");
base.Hide();
}
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); // this event subscription fires async loads, which hard-fail if `CompositeDrawable.disposalCancellationSource` is canceled, which happens in the base call.
// therefore, unsubscribe from this event early to reduce the chances of a stray event firing at an inconvenient spot.
if (api.IsNotNull()) if (api.IsNotNull())
api.NotificationsClient.MessageReceived -= handleMedalMessages; api.NotificationsClient.MessageReceived -= handleMedalMessages;
base.Dispose(isDisposing);
} }
} }
} }

View File

@ -4,7 +4,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework; using osu.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Framework.Logging; using osu.Framework.Logging;
@ -13,6 +12,7 @@ using osu.Framework.Screens;
using osu.Framework.Statistics; using osu.Framework.Statistics;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Online.Multiplayer;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osu.Game.Overlays.Settings.Sections.Maintenance; using osu.Game.Overlays.Settings.Sections.Maintenance;
using osu.Game.Updater; using osu.Game.Updater;
@ -36,8 +36,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
[Resolved] [Resolved]
private Storage storage { get; set; } = null!; private Storage storage { get; set; } = null!;
[Resolved]
private OsuGame? game { get; set; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config, OsuGame? game) private void load(OsuConfigManager config)
{ {
Add(new SettingsEnumDropdown<ReleaseStream> Add(new SettingsEnumDropdown<ReleaseStream>
{ {
@ -50,23 +53,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
Add(checkForUpdatesButton = new SettingsButton Add(checkForUpdatesButton = new SettingsButton
{ {
Text = GeneralSettingsStrings.CheckUpdate, Text = GeneralSettingsStrings.CheckUpdate,
Action = () => Action = () => checkForUpdates().FireAndForget()
{
checkForUpdatesButton.Enabled.Value = false;
Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(task => Schedule(() =>
{
if (!task.GetResultSafely())
{
notifications?.Post(new SimpleNotification
{
Text = GeneralSettingsStrings.RunningLatestRelease(game!.Version),
Icon = FontAwesome.Solid.CheckCircle,
});
}
checkForUpdatesButton.Enabled.Value = true;
}));
}
}); });
} }
@ -94,6 +81,44 @@ namespace osu.Game.Overlays.Settings.Sections.General
} }
} }
private async Task checkForUpdates()
{
if (updateManager == null || game == null)
return;
checkForUpdatesButton.Enabled.Value = false;
var checkingNotification = new ProgressNotification
{
Text = GeneralSettingsStrings.CheckingForUpdates,
};
notifications?.Post(checkingNotification);
try
{
bool foundUpdate = await updateManager.CheckForUpdateAsync().ConfigureAwait(true);
if (!foundUpdate)
{
notifications?.Post(new SimpleNotification
{
Text = GeneralSettingsStrings.RunningLatestRelease(game.Version),
Icon = FontAwesome.Solid.CheckCircle,
});
}
}
catch
{
}
finally
{
// This sequence allows the notification to be immediately dismissed.
checkingNotification.State = ProgressNotificationState.Cancelled;
checkingNotification.Close(false);
checkForUpdatesButton.Enabled.Value = true;
}
}
private void exportLogs() private void exportLogs()
{ {
ProgressNotification notification = new ProgressNotification ProgressNotification notification = new ProgressNotification