Add primitive to invalidate samples cached by a sample store

The use case for this is in client, in the editor more specifically. I'm
working on better support for custom samples, and a lack of an
invalidation primitive in `SampleStore` meant that even after a sample
was replaced, the old sample would play in the editor until the editor
is exited and re-entered.

A possible client-side alternative of recycling the entire sample store
*is* probably possible, but I think it's excessive.
This commit is contained in:
Bartłomiej Dach
2025-10-20 12:06:25 +02:00
parent 611aeb6a3c
commit 2cfb06ab12
3 changed files with 28 additions and 0 deletions

View File

@@ -28,6 +28,20 @@ namespace osu.Framework.Audio
});
}
public void RemoveItem(T item)
{
EnqueueAction(() =>
{
if (!Items.Contains(item)) return;
if (item is IAdjustableAudioComponent adjustable)
adjustable.UnbindAdjustments(this);
Items.Remove(item);
ItemRemoved(item);
});
}
void IBassAudio.UpdateDevice(int deviceIndex) => UpdateDevice(deviceIndex);
internal virtual void UpdateDevice(int deviceIndex)

View File

@@ -14,5 +14,10 @@ namespace osu.Framework.Audio.Sample
/// Add a file extension to automatically append to any lookups on this store.
/// </summary>
void AddExtension(string extension);
/// <summary>
/// Invalidates the cache for the sample with the given <paramref name="name"/>.
/// </summary>
void Invalidate(string name);
}
}

View File

@@ -62,6 +62,15 @@ namespace osu.Framework.Audio.Sample
public Task<Sample> GetAsync(string name, CancellationToken cancellationToken = default) =>
Task.Run(() => Get(name), cancellationToken);
public void Invalidate(string name)
{
lock (factories)
{
if (factories.Remove(name, out var factory))
RemoveItem(factory);
}
}
protected override void UpdateState()
{
FrameStatistics.Add(StatisticsCounterType.Samples, factories.Count);