1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 01:02:56 +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.Allocation;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Pooling;
using osu.Framework.Threading;
namespace osu.Game.Skinning namespace osu.Game.Skinning
{ {
@ -14,6 +15,8 @@ namespace osu.Game.Skinning
/// </summary> /// </summary>
public abstract partial class SkinReloadableDrawable : PoolableDrawable public abstract partial class SkinReloadableDrawable : PoolableDrawable
{ {
private ScheduledDelegate? pendingSkinChange;
/// <summary> /// <summary>
/// Invoked when <see cref="CurrentSkin"/> has changed. /// Invoked when <see cref="CurrentSkin"/> has changed.
/// </summary> /// </summary>
@ -31,10 +34,22 @@ namespace osu.Game.Skinning
CurrentSkin.SourceChanged += onChange; CurrentSkin.SourceChanged += onChange;
} }
private void onChange() => private void onChange()
{
// schedule required to avoid calls after disposed. // 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. // 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() protected override void LoadAsyncComplete()
{ {

View File

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