修复 P2 前复审问题

This commit is contained in:
JSD\13999
2026-05-21 15:05:56 +08:00
parent 558bc919ef
commit 4c9eaff7d8
6 changed files with 734 additions and 47 deletions

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
@@ -80,6 +81,80 @@ namespace FlowScope.Tests.PlayMode.UI
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.True);
}
[UnityTest]
public IEnumerator PreloadAsync_WhenFirstWaiterCancels_SecondWaiterStillSucceeds()
{
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new GatedUITestResources("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
using var firstCancellation = new CancellationTokenSource();
var first = preload.PreloadAsync<ExplicitPathPanel>(firstCancellation.Token);
var second = preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None);
Assert.That(resources.LoadCalls, Is.EqualTo(1));
Assert.That(resources.LoadCancellationTokenCanBeCanceled, Is.False);
firstCancellation.Cancel();
yield return UITestAsync.AwaitExpected<OperationCanceledException>(first);
resources.Complete();
yield return UITestAsync.Await(second);
Assert.That(resources.LoadCalls, Is.EqualTo(1));
Assert.That(resources.Handle.IsDisposed, Is.False);
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.True);
}
[UnityTest]
public IEnumerator PreloadAsync_WhenSecondWaiterCancels_FirstWaiterStillSucceeds()
{
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new GatedUITestResources("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
using var secondCancellation = new CancellationTokenSource();
var first = preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None);
var second = preload.PreloadAsync<ExplicitPathPanel>(secondCancellation.Token);
Assert.That(resources.LoadCalls, Is.EqualTo(1));
secondCancellation.Cancel();
yield return UITestAsync.AwaitExpected<OperationCanceledException>(second);
resources.Complete();
yield return UITestAsync.Await(first);
Assert.That(resources.LoadCalls, Is.EqualTo(1));
Assert.That(resources.Handle.IsDisposed, Is.False);
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.True);
}
[UnityTest]
public IEnumerator PreloadAsync_WhenAllWaitersCancel_ReleasesLoadedHandleWithoutCaching()
{
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new GatedUITestResources("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
using var firstCancellation = new CancellationTokenSource();
using var secondCancellation = new CancellationTokenSource();
var first = preload.PreloadAsync<ExplicitPathPanel>(firstCancellation.Token);
var second = preload.PreloadAsync<ExplicitPathPanel>(secondCancellation.Token);
firstCancellation.Cancel();
secondCancellation.Cancel();
yield return UITestAsync.AwaitExpected<OperationCanceledException>(first);
yield return UITestAsync.AwaitExpected<OperationCanceledException>(second);
resources.Complete();
yield return null;
Assert.That(resources.LoadCalls, Is.EqualTo(1));
Assert.That(resources.Handle.IsDisposed, Is.True);
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.False);
}
[UnityTest]
public IEnumerator OpenAsync_WhenPanelIsPreloaded_ReusesPreloadedHandle()
{
@@ -150,6 +225,7 @@ namespace FlowScope.Tests.PlayMode.UI
public int LoadCalls { get; private set; }
public UITestResourceHandle<GameObject> Handle { get; }
public bool LoadCancellationTokenCanBeCanceled { get; private set; }
public Task<FlowScope.Resources.IResourceHandle<T>> LoadAsync<T>(
string key,
@@ -157,6 +233,12 @@ namespace FlowScope.Tests.PlayMode.UI
where T : class
{
cancellationToken.ThrowIfCancellationRequested();
LoadCancellationTokenCanBeCanceled = cancellationToken.CanBeCanceled;
if (cancellationToken.CanBeCanceled)
{
cancellationToken.Register(() => _gate.TrySetCanceled(cancellationToken));
}
LoadCalls++;
Assert.That(key, Is.EqualTo(_key));
return AwaitHandle<T>();
@@ -169,7 +251,7 @@ namespace FlowScope.Tests.PlayMode.UI
public void Complete()
{
_gate.SetResult(Handle);
_gate.TrySetResult(Handle);
}
private async Task<FlowScope.Resources.IResourceHandle<T>> AwaitHandle<T>()