Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions GFramework.Game.Abstractions/ui/IUiRouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public interface IUiRouter : ISystem
/// <param name="uiKey">UI界面的唯一标识符</param>
/// <param name="param">进入界面的参数,可为空</param>
/// <param name="policy">界面切换策略,默认为Exclusive(独占)</param>
void Push(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive);
ValueTask PushAsync(string uiKey, IUiPageEnterParam? param = null,
UiTransitionPolicy policy = UiTransitionPolicy.Exclusive);


/// <summary>
Expand All @@ -35,15 +36,15 @@ public interface IUiRouter : ISystem
/// <param name="page">已创建的UI页面行为实例</param>
/// <param name="param">进入界面的参数,可为空</param>
/// <param name="policy">界面切换策略,默认为Exclusive(独占)</param>
void Push(IUiPageBehavior page, IUiPageEnterParam? param = null,
ValueTask PushAsync(IUiPageBehavior page, IUiPageEnterParam? param = null,
UiTransitionPolicy policy = UiTransitionPolicy.Exclusive);


/// <summary>
/// 弹出路由栈顶的UI界面,返回到上一个界面
/// </summary>
/// <param name="policy">界面弹出策略,默认为Destroy(销毁)</param>
void Pop(UiPopPolicy policy = UiPopPolicy.Destroy);
ValueTask PopAsync(UiPopPolicy policy = UiPopPolicy.Destroy);

/// <summary>
/// 替换当前所有页面为新页面(基于uiKey)
Expand All @@ -52,7 +53,7 @@ void Push(IUiPageBehavior page, IUiPageEnterParam? param = null,
/// <param name="param">页面进入参数,可为空</param>
/// <param name="popPolicy">弹出页面时的销毁策略,默认为销毁</param>
/// <param name="pushPolicy">推入页面时的过渡策略,默认为独占</param>
public void Replace(
public ValueTask ReplaceAsync(
string uiKey,
IUiPageEnterParam? param = null,
UiPopPolicy popPolicy = UiPopPolicy.Destroy,
Expand All @@ -65,7 +66,7 @@ public void Replace(
/// <param name="param">页面进入参数,可为空</param>
/// <param name="popPolicy">弹出页面时的销毁策略,默认为销毁</param>
/// <param name="pushPolicy">推入页面时的过渡策略,默认为独占</param>
public void Replace(
public ValueTask ReplaceAsync(
IUiPageBehavior page,
IUiPageEnterParam? param = null,
UiPopPolicy popPolicy = UiPopPolicy.Destroy,
Expand All @@ -74,7 +75,7 @@ public void Replace(
/// <summary>
/// 清空所有UI界面,重置路由状态
/// </summary>
void Clear();
ValueTask ClearAsync();

/// <summary>
/// 注册UI切换处理器
Expand Down
26 changes: 7 additions & 19 deletions GFramework.Game/scene/SceneRouterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ await _pipeline.ExecuteAroundAsync(@event, async () =>
await BeforeChangeAsync(@event);
await ClearInternalAsync();
await PushInternalAsync(sceneKey, param);
AfterChange(@event);
await AfterChangeAsync(@event);
});
}
finally
Expand Down Expand Up @@ -237,7 +237,7 @@ await _pipeline.ExecuteAroundAsync(@event, async () =>
{
await BeforeChangeAsync(@event);
await PushInternalAsync(sceneKey, param);
AfterChange(@event);
await AfterChangeAsync(@event);
});
}
finally
Expand Down Expand Up @@ -318,7 +318,7 @@ await _pipeline.ExecuteAroundAsync(@event, async () =>
{
await BeforeChangeAsync(@event);
await PopInternalAsync();
AfterChange(@event);
await AfterChangeAsync(@event);
});
}
finally
Expand Down Expand Up @@ -389,7 +389,7 @@ await _pipeline.ExecuteAroundAsync(@event, async () =>
{
await BeforeChangeAsync(@event);
await ClearInternalAsync();
AfterChange(@event);
await AfterChangeAsync(@event);
});
}
finally
Expand Down Expand Up @@ -451,25 +451,13 @@ private async Task BeforeChangeAsync(SceneTransitionEvent @event)

/// <summary>
/// 执行转换后阶段的处理逻辑。
/// 在后台线程中异步执行,避免阻塞主线程。
/// </summary>
/// <param name="event">场景转换事件。</param>
private void AfterChange(SceneTransitionEvent @event)
private async Task AfterChangeAsync(SceneTransitionEvent @event)
{
Log.Debug("AfterChange phases started: {0}", @event.TransitionType);
_ = Task.Run(async () =>
{
try
{
await _pipeline.ExecuteAsync(@event, SceneTransitionPhases.AfterChange);
Log.Debug("AfterChange phases completed: {0}", @event.TransitionType);
}
catch (Exception ex)
{
Log.Error("AfterChange phases failed: {0}, Error: {1}",
@event.TransitionType, ex.Message);
}
});
await _pipeline.ExecuteAsync(@event, SceneTransitionPhases.AfterChange);
Log.Debug("AfterChange phases completed: {0}", @event.TransitionType);
}

/// <summary>
Comment on lines +456 to 463

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (bug_risk): Scene AfterChangeAsync now runs synchronously in the transition flow rather than fire-and-forget, which may affect latency and error handling.

Previously, AfterChange ran via Task.Run and isolated failures (log + swallow). Now AfterChangeAsync is awaited, so scene transitions won’t complete until all handlers finish, and any exception will surface to the caller and can fail/cancel the transition. Please confirm if this change in behavior is intentional. If you don’t want AfterChange failures to abort navigation, consider adding isolation around the pipeline execution (while avoiding Task.Run if possible), so errors remain logged but non-fatal.

Expand Down
17 changes: 8 additions & 9 deletions GFramework.Game/scene/SceneTransitionPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,14 @@ public async Task ExecuteAsync(
{
@event.Set("Phases", phases.ToString());

if (@event.FromSceneKey != null)
Log.Debug(
"Execute pipeline: Phases={0}, From={1}, To={2}, Type={3}, HandlerCount={4}",
phases,
@event.FromSceneKey,
@event.ToSceneKey ?? "None",
@event.TransitionType,
_handlers.Count
);
Log.Debug(
"Execute pipeline: Phases={0}, From={1}, To={2}, Type={3}, HandlerCount={4}",
phases,
@event.FromSceneKey ?? "None",
@event.ToSceneKey ?? "None",
@event.TransitionType,
_handlers.Count
);

var sortedHandlers = FilterAndSortHandlers(@event, phases);

Expand Down
Loading
Loading