1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 02:32:55 +08:00

Cache any skin changes in SkinReloadableDrawable to ScheduledDelegate

This commit is contained in:
Terochi 2023-03-15 09:00:34 +01:00
parent 390ad335d0
commit a9c349fa6d
2 changed files with 20 additions and 5 deletions

View File

@ -5,6 +5,7 @@ using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Threading;
namespace osu.Game.Skinning
{
@ -14,6 +15,8 @@ namespace osu.Game.Skinning
/// </summary>
public abstract partial class SkinReloadableDrawable : PoolableDrawable
{
private ScheduledDelegate? pendingSkinChange;
/// <summary>
/// Invoked when <see cref="CurrentSkin"/> has changed.
/// </summary>
@ -31,10 +34,22 @@ namespace osu.Game.Skinning
CurrentSkin.SourceChanged += onChange;
}
private void onChange() =>
private void onChange()
{
// schedule required to avoid calls after disposed.
// note that this has the side-effect of components only performing a skin change when they are alive.
Scheduler.AddOnce(skinChanged);
pendingSkinChange?.Cancel();
pendingSkinChange = Scheduler.Add(skinChanged);
}
public void FlushPendingSkinChanges()
{
if (pendingSkinChange == null)
return;
pendingSkinChange.RunTask();
pendingSkinChange = null;
}
protected override void LoadAsyncComplete()
{

View File

@ -115,12 +115,12 @@ namespace osu.Game.Skinning
/// </summary>
public virtual void Play()
{
if (Scheduler.HasPendingTasks)
// update samples queued due to skin change before playing them
UpdateSubTree();
FlushPendingSkinChanges();
samplesContainer.ForEach(c =>
{
c.FlushPendingSkinChanges();
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
{
c.Stop();