mirror of
https://github.com/SK-la/osu-framework.git
synced 2026-03-13 11:20:31 +00:00
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.
98 lines
2.7 KiB
C#
98 lines
2.7 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace osu.Framework.Audio
|
|
{
|
|
/// <summary>
|
|
/// A collection of audio components which need central property control.
|
|
/// </summary>
|
|
public class AudioCollectionManager<T> : AdjustableAudioComponent, IBassAudio
|
|
where T : AudioComponent
|
|
{
|
|
internal List<T> Items = new List<T>();
|
|
|
|
public void AddItem(T item)
|
|
{
|
|
EnqueueAction(delegate
|
|
{
|
|
if (Items.Contains(item)) return;
|
|
|
|
if (item is IAdjustableAudioComponent adjustable)
|
|
adjustable.BindAdjustments(this);
|
|
|
|
Items.Add(item);
|
|
ItemAdded(item);
|
|
});
|
|
}
|
|
|
|
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)
|
|
{
|
|
foreach (var item in Items.OfType<IBassAudio>())
|
|
item.UpdateDevice(deviceIndex);
|
|
}
|
|
|
|
protected override void UpdateChildren()
|
|
{
|
|
base.UpdateChildren();
|
|
|
|
for (int i = 0; i < Items.Count; i++)
|
|
{
|
|
var item = Items[i];
|
|
|
|
if (!item.IsAlive)
|
|
{
|
|
Items.RemoveAt(i--);
|
|
ItemRemoved(item);
|
|
continue;
|
|
}
|
|
|
|
item.Update();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An item has been added to <see cref="Items"/>.
|
|
/// </summary>
|
|
/// <param name="item">The item which was added.</param>
|
|
protected virtual void ItemAdded(T item)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// An item has been removed from <see cref="Items"/>. Implementations should dispose the removed item if required.
|
|
/// </summary>
|
|
/// <param name="item">The item which was removed.</param>
|
|
protected virtual void ItemRemoved(T item)
|
|
{
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
// make the items queue their disposal, so they get disposed when UpdateChildren updates them.
|
|
foreach (var i in Items)
|
|
i.Dispose();
|
|
|
|
base.Dispose(disposing);
|
|
}
|
|
}
|
|
}
|