1
0
mirror of https://github.com/ppy/osu synced 2025-02-18 19:36:58 +00:00

Merge pull request from peppy/fix-poolable-sample-disposal-skin-change

Clean up previous sample immediately on skin source change to avoid `Play` after disposal
This commit is contained in:
Dan Balasescu 2021-06-08 16:52:59 +09:00 committed by GitHub
commit e3cb6f45f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@ -70,22 +71,48 @@ namespace osu.Game.Skinning
updateSample();
}
protected override void LoadComplete()
{
base.LoadComplete();
CurrentSkin.SourceChanged += skinChangedImmediate;
}
private void skinChangedImmediate()
{
// Clean up the previous sample immediately on a source change.
// This avoids a potential call to Play() of an already disposed sample (samples are disposed along with the skin, but SkinChanged is scheduled).
clearPreviousSamples();
}
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
updateSample();
}
/// <summary>
/// Whether this sample was playing before a skin source change.
/// </summary>
private bool wasPlaying;
private void clearPreviousSamples()
{
// only run if the samples aren't already cleared.
// this ensures the "wasPlaying" state is stored correctly even if multiple clear calls are executed.
if (!sampleContainer.Any()) return;
wasPlaying = Playing;
sampleContainer.Clear();
Sample = null;
}
private void updateSample()
{
if (sampleInfo == null)
return;
bool wasPlaying = Playing;
sampleContainer.Clear();
Sample = null;
var sample = CurrentSkin.GetSample(sampleInfo);
if (sample == null && AllowDefaultFallback)
@ -155,6 +182,14 @@ namespace osu.Game.Skinning
}
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (CurrentSkin != null)
CurrentSkin.SourceChanged -= skinChangedImmediate;
}
#region Re-expose AudioContainer
public BindableNumber<double> Volume => sampleContainer.Volume;