修正音频异步取消语义
This commit is contained in:
@@ -211,6 +211,10 @@ namespace FlowScope.Audio
|
||||
var handle = await _resources.LoadAsync<AudioClip>(key, cancellationToken);
|
||||
return ValidateLoadedClip(key, handle);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to load audio clip '{key}'.", exception);
|
||||
|
||||
@@ -209,6 +209,34 @@ namespace FlowScope.Tests.PlayMode.Audio
|
||||
Assert.That(handle.IsPlaying, Is.True);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public System.Collections.IEnumerator PlayBgmAsync_WhenCanceled_ThrowsOperationCanceledException()
|
||||
{
|
||||
var service = CreateService();
|
||||
using var cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
var sourceCountBeforePlay = Object.FindObjectsOfType<AudioSource>().Length;
|
||||
|
||||
yield return ThrowsAsync<OperationCanceledException>(
|
||||
service.PlayBgmAsync("bgm-a", cancellationToken: cts.Token));
|
||||
|
||||
Assert.That(Object.FindObjectsOfType<AudioSource>().Length, Is.EqualTo(sourceCountBeforePlay));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public System.Collections.IEnumerator PlaySfxAsync_WhenCanceled_ThrowsOperationCanceledException()
|
||||
{
|
||||
var service = CreateService();
|
||||
using var cts = new CancellationTokenSource();
|
||||
cts.Cancel();
|
||||
var sourceCountBeforePlay = Object.FindObjectsOfType<AudioSource>().Length;
|
||||
|
||||
yield return ThrowsAsync<OperationCanceledException>(
|
||||
service.PlaySfxAsync("sfx", cts.Token));
|
||||
|
||||
Assert.That(Object.FindObjectsOfType<AudioSource>().Length, Is.EqualTo(sourceCountBeforePlay));
|
||||
}
|
||||
|
||||
private AudioService CreateService(AudioServiceConfig config = null)
|
||||
{
|
||||
var gameObject = new GameObject("AudioServiceTest");
|
||||
@@ -249,6 +277,27 @@ namespace FlowScope.Tests.PlayMode.Audio
|
||||
onCompleted(task.Result);
|
||||
}
|
||||
|
||||
private static System.Collections.IEnumerator ThrowsAsync<TException>(Task task)
|
||||
where TException : Exception
|
||||
{
|
||||
while (!task.IsCompleted)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (task.IsFaulted && task.Exception?.GetBaseException() is TException)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (task.IsCanceled && typeof(TException) == typeof(OperationCanceledException))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
Assert.Fail($"Expected {typeof(TException).Name}.");
|
||||
}
|
||||
|
||||
private static AudioClip CreateClip(string name, float lengthSeconds)
|
||||
{
|
||||
var sampleCount = Mathf.CeilToInt(44100 * lengthSeconds);
|
||||
@@ -285,6 +334,7 @@ namespace FlowScope.Tests.PlayMode.Audio
|
||||
where T : class
|
||||
{
|
||||
LoadRequests++;
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (typeof(T) != typeof(AudioClip))
|
||||
{
|
||||
throw new InvalidOperationException($"missing resource: {key}");
|
||||
|
||||
Reference in New Issue
Block a user