diff --git a/My project/Assets/FlowScope/Runtime/Audio/AudioService.cs b/My project/Assets/FlowScope/Runtime/Audio/AudioService.cs index 884e467..f3ea89d 100644 --- a/My project/Assets/FlowScope/Runtime/Audio/AudioService.cs +++ b/My project/Assets/FlowScope/Runtime/Audio/AudioService.cs @@ -211,6 +211,10 @@ namespace FlowScope.Audio var handle = await _resources.LoadAsync(key, cancellationToken); return ValidateLoadedClip(key, handle); } + catch (OperationCanceledException) + { + throw; + } catch (Exception exception) { throw new InvalidOperationException($"Failed to load audio clip '{key}'.", exception); diff --git a/My project/Assets/FlowScope/Tests/PlayMode/Audio/AudioServiceTests.cs b/My project/Assets/FlowScope/Tests/PlayMode/Audio/AudioServiceTests.cs index 7ddc1b8..ba9bae4 100644 --- a/My project/Assets/FlowScope/Tests/PlayMode/Audio/AudioServiceTests.cs +++ b/My project/Assets/FlowScope/Tests/PlayMode/Audio/AudioServiceTests.cs @@ -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().Length; + + yield return ThrowsAsync( + service.PlayBgmAsync("bgm-a", cancellationToken: cts.Token)); + + Assert.That(Object.FindObjectsOfType().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().Length; + + yield return ThrowsAsync( + service.PlaySfxAsync("sfx", cts.Token)); + + Assert.That(Object.FindObjectsOfType().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(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}");