mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Cleanup, refactoring, and restart sample on skin change
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
@ -13,27 +14,48 @@ using osu.Game.Audio;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A sample corresponding to an <see cref="ISampleInfo"/> that supports being pooled and responding to skin changes.
|
||||||
|
/// </summary>
|
||||||
public class PoolableSkinnableSample : SkinReloadableDrawable, IAggregateAudioAdjustment, IAdjustableAudioComponent
|
public class PoolableSkinnableSample : SkinReloadableDrawable, IAggregateAudioAdjustment, IAdjustableAudioComponent
|
||||||
{
|
{
|
||||||
private readonly AudioContainer<DrawableSample> sampleContainer;
|
/// <summary>
|
||||||
|
/// The currently-loaded <see cref="DrawableSample"/>.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public DrawableSample Sample { get; private set; }
|
||||||
|
|
||||||
|
private readonly AudioContainer<DrawableSample> sampleContainer;
|
||||||
private ISampleInfo sampleInfo;
|
private ISampleInfo sampleInfo;
|
||||||
private DrawableSample sample;
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private ISampleStore sampleStore { get; set; }
|
private ISampleStore sampleStore { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="PoolableSkinnableSample"/> with no applied <see cref="ISampleInfo"/>.
|
||||||
|
/// An <see cref="ISampleInfo"/> can be applied later via <see cref="Apply"/>.
|
||||||
|
/// </summary>
|
||||||
public PoolableSkinnableSample()
|
public PoolableSkinnableSample()
|
||||||
{
|
{
|
||||||
InternalChild = sampleContainer = new AudioContainer<DrawableSample> { RelativeSizeAxes = Axes.Both };
|
InternalChild = sampleContainer = new AudioContainer<DrawableSample> { RelativeSizeAxes = Axes.Both };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="PoolableSkinnableSample"/> with an applied <see cref="ISampleInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sampleInfo">The <see cref="ISampleInfo"/> to attach.</param>
|
||||||
public PoolableSkinnableSample(ISampleInfo sampleInfo)
|
public PoolableSkinnableSample(ISampleInfo sampleInfo)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
Apply(sampleInfo);
|
Apply(sampleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies an <see cref="ISampleInfo"/> that describes the sample to retrieve.
|
||||||
|
/// Only one <see cref="ISampleInfo"/> can ever be applied to a <see cref="PoolableSkinnableSample"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sampleInfo">The <see cref="ISampleInfo"/> to apply.</param>
|
||||||
|
/// <exception cref="InvalidOperationException">If an <see cref="ISampleInfo"/> has already been applied to this <see cref="PoolableSkinnableSample"/>.</exception>
|
||||||
public void Apply(ISampleInfo sampleInfo)
|
public void Apply(ISampleInfo sampleInfo)
|
||||||
{
|
{
|
||||||
if (this.sampleInfo != null)
|
if (this.sampleInfo != null)
|
||||||
@ -55,6 +77,11 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private void updateSample()
|
private void updateSample()
|
||||||
{
|
{
|
||||||
|
if (sampleInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool wasPlaying = Playing;
|
||||||
|
|
||||||
sampleContainer.Clear();
|
sampleContainer.Clear();
|
||||||
|
|
||||||
var ch = CurrentSkin.GetSample(sampleInfo);
|
var ch = CurrentSkin.GetSample(sampleInfo);
|
||||||
@ -71,17 +98,34 @@ namespace osu.Game.Skinning
|
|||||||
if (ch == null)
|
if (ch == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sampleContainer.Add(sample = new DrawableSample(ch) { Looping = Looping });
|
sampleContainer.Add(Sample = new DrawableSample(ch) { Looping = Looping });
|
||||||
|
|
||||||
|
// Start playback internally for the new sample if the previous one was playing beforehand.
|
||||||
|
if (wasPlaying)
|
||||||
|
Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Play(bool restart = true) => sample?.Play(restart);
|
/// <summary>
|
||||||
|
/// Plays the sample.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="restart">Whether to play the sample from the beginning.</param>
|
||||||
|
public void Play(bool restart = true) => Sample?.Play(restart);
|
||||||
|
|
||||||
public void Stop() => sample?.Stop();
|
/// <summary>
|
||||||
|
/// Stops the sample.
|
||||||
|
/// </summary>
|
||||||
|
public void Stop() => Sample?.Stop();
|
||||||
|
|
||||||
public bool Playing => sample?.Playing ?? false;
|
/// <summary>
|
||||||
|
/// Whether the sample is currently playing.
|
||||||
|
/// </summary>
|
||||||
|
public bool Playing => Sample?.Playing ?? false;
|
||||||
|
|
||||||
private bool looping;
|
private bool looping;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether the sample should loop on completion.
|
||||||
|
/// </summary>
|
||||||
public bool Looping
|
public bool Looping
|
||||||
{
|
{
|
||||||
get => looping;
|
get => looping;
|
||||||
@ -89,29 +133,17 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
looping = value;
|
looping = value;
|
||||||
|
|
||||||
if (sample != null)
|
if (Sample != null)
|
||||||
sample.Looping = value;
|
Sample.Looping = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The volume of this component.
|
|
||||||
/// </summary>
|
|
||||||
public BindableNumber<double> Volume => sampleContainer.Volume;
|
public BindableNumber<double> Volume => sampleContainer.Volume;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The playback balance of this sample (-1 .. 1 where 0 is centered)
|
|
||||||
/// </summary>
|
|
||||||
public BindableNumber<double> Balance => sampleContainer.Balance;
|
public BindableNumber<double> Balance => sampleContainer.Balance;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency.
|
|
||||||
/// </summary>
|
|
||||||
public BindableNumber<double> Frequency => sampleContainer.Frequency;
|
public BindableNumber<double> Frequency => sampleContainer.Frequency;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed.
|
|
||||||
/// </summary>
|
|
||||||
public BindableNumber<double> Tempo => sampleContainer.Tempo;
|
public BindableNumber<double> Tempo => sampleContainer.Tempo;
|
||||||
|
|
||||||
public void AddAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable) => sampleContainer.AddAdjustment(type, adjustBindable);
|
public void AddAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable) => sampleContainer.AddAdjustment(type, adjustBindable);
|
||||||
|
@ -103,13 +103,6 @@ namespace osu.Game.Skinning
|
|||||||
SamplesContainer.ForEach(c => c.Stop());
|
SamplesContainer.ForEach(c => c.Stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
|
||||||
{
|
|
||||||
// Start playback internally for the new samples if the previous ones were playing beforehand.
|
|
||||||
if (IsPlaying)
|
|
||||||
Play();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSamples()
|
private void updateSamples()
|
||||||
{
|
{
|
||||||
bool wasPlaying = IsPlaying;
|
bool wasPlaying = IsPlaying;
|
||||||
|
Reference in New Issue
Block a user