Improve forwarding flow to not use piling delegates

This commit is contained in:
Dean Herbert
2022-08-30 21:31:06 +09:00
parent 224ab29ef4
commit ed11b1ba6f
2 changed files with 52 additions and 40 deletions

View File

@ -68,6 +68,7 @@ namespace osu.Game.Overlays
{ {
toastTray = new NotificationOverlayToastTray toastTray = new NotificationOverlayToastTray
{ {
ForwardNotificationToPermanentStore = addPermanently,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}, },
mainContent = new Container mainContent = new Container
@ -157,27 +158,26 @@ namespace osu.Game.Overlays
if (notification is IHasCompletionTarget hasCompletionTarget) if (notification is IHasCompletionTarget hasCompletionTarget)
hasCompletionTarget.CompletionTarget = Post; hasCompletionTarget.CompletionTarget = Post;
var ourType = notification.GetType();
int depth = notification.DisplayOnTop ? -runningDepth : runningDepth;
playDebouncedSample(notification.PopInSampleName); playDebouncedSample(notification.PopInSampleName);
if (State.Value == Visibility.Hidden) if (State.Value == Visibility.Hidden)
toastTray.Post(notification, addPermanently); toastTray.Post(notification);
else else
addPermanently(); addPermanently(notification);
void addPermanently()
{
var section = sections.Children.First(s => s.AcceptedNotificationTypes.Any(accept => accept.IsAssignableFrom(ourType)));
section.Add(notification, depth);
updateCounts();
}
}); });
private void addPermanently(Notification notification)
{
var ourType = notification.GetType();
int depth = notification.DisplayOnTop ? -runningDepth : runningDepth;
var section = sections.Children.First(s => s.AcceptedNotificationTypes.Any(accept => accept.IsAssignableFrom(ourType)));
section.Add(notification, depth);
updateCounts();
}
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();

View File

@ -2,7 +2,7 @@
// 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;
using System.Collections.Generic; using System.Diagnostics;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
@ -11,7 +11,6 @@ using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Threading;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osuTK; using osuTK;
@ -25,13 +24,13 @@ namespace osu.Game.Overlays
{ {
public bool IsDisplayingToasts => toastFlow.Count > 0; public bool IsDisplayingToasts => toastFlow.Count > 0;
private FillFlowContainer toastFlow = null!; private FillFlowContainer<Notification> toastFlow = null!;
private BufferedContainer toastContentBackground = null!; private BufferedContainer toastContentBackground = null!;
[Resolved] [Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!; private OverlayColourProvider colourProvider { get; set; } = null!;
private readonly List<ScheduledDelegate> pendingToastOperations = new List<ScheduledDelegate>(); public Action<Notification>? ForwardNotificationToPermanentStore { get; set; }
private int runningDepth; private int runningDepth;
@ -63,7 +62,7 @@ namespace osu.Game.Overlays
postEffectDrawable.AutoSizeAxes = Axes.None; postEffectDrawable.AutoSizeAxes = Axes.None;
postEffectDrawable.RelativeSizeAxes = Axes.X; postEffectDrawable.RelativeSizeAxes = Axes.X;
})), })),
toastFlow = new FillFlowContainer toastFlow = new FillFlowContainer<Notification>
{ {
LayoutDuration = 150, LayoutDuration = 150,
LayoutEasing = Easing.OutQuart, LayoutEasing = Easing.OutQuart,
@ -76,13 +75,13 @@ namespace osu.Game.Overlays
public void FlushAllToasts() public void FlushAllToasts()
{ {
foreach (var d in pendingToastOperations.Where(d => !d.Completed)) foreach (var notification in toastFlow.ToArray())
d.RunTask(); {
forwardNotification(notification);
pendingToastOperations.Clear(); }
} }
public void Post(Notification notification, Action addPermanently) public void Post(Notification notification)
{ {
++runningDepth; ++runningDepth;
@ -90,34 +89,47 @@ namespace osu.Game.Overlays
toastFlow.Insert(depth, notification); toastFlow.Insert(depth, notification);
pendingToastOperations.Add(scheduleDismissal()); scheduleDismissal();
ScheduledDelegate scheduleDismissal() => Scheduler.AddDelayed(() => void scheduleDismissal() => Scheduler.AddDelayed(() =>
{ {
// add notification to permanent overlay unless it was already dismissed by the user. // Notification dismissed by user.
if (notification.WasClosed) if (notification.WasClosed)
return; return;
// Notification forwarded away.
if (notification.Parent != toastFlow)
return;
// Notification hovered; delay dismissal.
if (notification.IsHovered) if (notification.IsHovered)
{ {
pendingToastOperations.Add(scheduleDismissal()); scheduleDismissal();
return; return;
} }
toastFlow.Remove(notification); // All looks good, forward away!
AddInternal(notification); forwardNotification(notification);
notification.MoveToOffset(new Vector2(400, 0), NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint);
notification.FadeOut(NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint).OnComplete(_ =>
{
RemoveInternal(notification);
addPermanently();
notification.FadeIn(300, Easing.OutQuint);
});
}, notification.IsImportant ? 12000 : 2500); }, notification.IsImportant ? 12000 : 2500);
} }
private void forwardNotification(Notification notification)
{
Debug.Assert(notification.Parent == toastFlow);
toastFlow.Remove(notification);
AddInternal(notification);
notification.MoveToOffset(new Vector2(400, 0), NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint);
notification.FadeOut(NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint).OnComplete(_ =>
{
RemoveInternal(notification);
ForwardNotificationToPermanentStore?.Invoke(notification);
notification.FadeIn(300, Easing.OutQuint);
});
}
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();