diff --git a/GFramework.Game.Abstractions/ui/IUiRouter.cs b/GFramework.Game.Abstractions/ui/IUiRouter.cs index 08b68f3..9eedc53 100644 --- a/GFramework.Game.Abstractions/ui/IUiRouter.cs +++ b/GFramework.Game.Abstractions/ui/IUiRouter.cs @@ -25,7 +25,8 @@ public interface IUiRouter : ISystem /// UI界面的唯一标识符 /// 进入界面的参数,可为空 /// 界面切换策略,默认为Exclusive(独占) - void Push(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive); + ValueTask PushAsync(string uiKey, IUiPageEnterParam? param = null, + UiTransitionPolicy policy = UiTransitionPolicy.Exclusive); /// @@ -35,7 +36,7 @@ public interface IUiRouter : ISystem /// 已创建的UI页面行为实例 /// 进入界面的参数,可为空 /// 界面切换策略,默认为Exclusive(独占) - void Push(IUiPageBehavior page, IUiPageEnterParam? param = null, + ValueTask PushAsync(IUiPageBehavior page, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive); @@ -43,7 +44,7 @@ public interface IUiRouter : ISystem /// 弹出路由栈顶的UI界面,返回到上一个界面 /// /// 界面弹出策略,默认为Destroy(销毁) - void Pop(UiPopPolicy policy = UiPopPolicy.Destroy); + ValueTask PopAsync(UiPopPolicy policy = UiPopPolicy.Destroy); /// /// 替换当前所有页面为新页面(基于uiKey) @@ -52,7 +53,7 @@ public interface IUiRouter : ISystem /// 页面进入参数,可为空 /// 弹出页面时的销毁策略,默认为销毁 /// 推入页面时的过渡策略,默认为独占 - public void Replace( + public ValueTask ReplaceAsync( string uiKey, IUiPageEnterParam? param = null, UiPopPolicy popPolicy = UiPopPolicy.Destroy, @@ -65,7 +66,7 @@ public interface IUiRouter : ISystem /// 页面进入参数,可为空 /// 弹出页面时的销毁策略,默认为销毁 /// 推入页面时的过渡策略,默认为独占 - public void Replace( + public ValueTask ReplaceAsync( IUiPageBehavior page, IUiPageEnterParam? param = null, UiPopPolicy popPolicy = UiPopPolicy.Destroy, @@ -74,7 +75,7 @@ public interface IUiRouter : ISystem /// /// 清空所有UI界面,重置路由状态 /// - void Clear(); + ValueTask ClearAsync(); /// /// 注册UI切换处理器 diff --git a/GFramework.Game/scene/SceneRouterBase.cs b/GFramework.Game/scene/SceneRouterBase.cs index 063b26b..20cd400 100644 --- a/GFramework.Game/scene/SceneRouterBase.cs +++ b/GFramework.Game/scene/SceneRouterBase.cs @@ -96,7 +96,7 @@ public abstract class SceneRouterBase await BeforeChangeAsync(@event); await ClearInternalAsync(); await PushInternalAsync(sceneKey, param); - AfterChange(@event); + await AfterChangeAsync(@event); }); } finally @@ -237,7 +237,7 @@ public abstract class SceneRouterBase { await BeforeChangeAsync(@event); await PushInternalAsync(sceneKey, param); - AfterChange(@event); + await AfterChangeAsync(@event); }); } finally @@ -318,7 +318,7 @@ public abstract class SceneRouterBase { await BeforeChangeAsync(@event); await PopInternalAsync(); - AfterChange(@event); + await AfterChangeAsync(@event); }); } finally @@ -389,7 +389,7 @@ public abstract class SceneRouterBase { await BeforeChangeAsync(@event); await ClearInternalAsync(); - AfterChange(@event); + await AfterChangeAsync(@event); }); } finally @@ -451,25 +451,13 @@ public abstract class SceneRouterBase /// /// 执行转换后阶段的处理逻辑。 - /// 在后台线程中异步执行,避免阻塞主线程。 /// /// 场景转换事件。 - 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); } /// diff --git a/GFramework.Game/scene/SceneTransitionPipeline.cs b/GFramework.Game/scene/SceneTransitionPipeline.cs index 6332972..7f94684 100644 --- a/GFramework.Game/scene/SceneTransitionPipeline.cs +++ b/GFramework.Game/scene/SceneTransitionPipeline.cs @@ -122,15 +122,14 @@ public class SceneTransitionPipeline { @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); diff --git a/GFramework.Game/ui/UiRouterBase.cs b/GFramework.Game/ui/UiRouterBase.cs index b860cee..90717f6 100644 --- a/GFramework.Game/ui/UiRouterBase.cs +++ b/GFramework.Game/ui/UiRouterBase.cs @@ -8,64 +8,72 @@ using GFramework.Game.Abstractions.ui; namespace GFramework.Game.ui; /// -/// UI路由类,提供页面栈管理功能 +/// UI路由基类,提供页面栈管理和层级UI管理功能 +/// 负责UI页面的导航、显示、隐藏以及生命周期管理 /// public abstract class UiRouterBase : AbstractSystem, IUiRouter { private static readonly ILogger Log = LoggerFactoryResolver.Provider.CreateLogger(nameof(UiRouterBase)); /// - /// 路由守卫列表 + /// 路由守卫列表,用于控制UI页面的进入和离开 /// private readonly List _guards = new(); /// - /// 层级管理(非栈层级),用于Overlay、Modal、Toast等浮层 - /// Key: UiLayer, Value: Dictionary of InstanceId -> PageBehavior + /// 层级管理字典(非栈层级),用于管理Overlay、Modal、Toast等浮层UI + /// Key: UiLayer枚举值, Value: InstanceId到PageBehavior的映射字典 /// private readonly Dictionary> _layers = new(); /// - /// UI切换处理器管道 + /// UI切换处理器管道,用于执行UI过渡动画和逻辑 /// private readonly UiTransitionPipeline _pipeline = new(); /// - /// 页面栈,用于管理UI页面的显示顺序 + /// 页面栈,用于管理UI页面的显示顺序和导航历史 /// private readonly Stack _stack = new(); /// - /// UI工厂实例,用于创建UI相关的对象 + /// UI工厂实例,用于创建UI页面和相关对象 /// private IUiFactory _factory = null!; /// - /// 实例ID计数器,用于生成唯一ID + /// 实例ID计数器,用于生成唯一的UI实例标识符 /// private int _instanceCounter; + /// + /// UI根节点引用,用于添加和移除UI页面 + /// private IUiRoot _uiRoot = null!; /// - /// 注册UI切换处理器 + /// 注册UI切换处理器 /// + /// UI切换处理器实例 + /// 处理器选项配置 public void RegisterHandler(IUiTransitionHandler handler, UiTransitionHandlerOptions? options = null) { _pipeline.RegisterHandler(handler, options); } /// - /// 注销UI切换处理器 + /// 注销UI切换处理器 /// + /// 要注销的UI切换处理器实例 public void UnregisterHandler(IUiTransitionHandler handler) { _pipeline.UnregisterHandler(handler); } /// - /// 绑定UI根节点 + /// 绑定UI根节点 /// + /// UI根节点实例 public void BindRoot(IUiRoot root) { _uiRoot = root; @@ -75,9 +83,12 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter #region Page Stack Management /// - /// 将指定的UI界面压入路由栈 + /// 将指定的UI界面压入路由栈 /// - public void Push(string uiKey, IUiPageEnterParam? param = null, + /// UI页面的唯一标识键 + /// 页面进入参数 + /// UI过渡策略 + public async ValueTask PushAsync(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive) { if (IsTop(uiKey)) @@ -89,18 +100,21 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter var @event = CreateEvent(uiKey, UiTransitionType.Push, policy, param); Log.Debug("Push UI Page: key={0}, policy={1}, stackBefore={2}", uiKey, policy, _stack.Count); - _pipeline.ExecuteAroundAsync(@event, async () => + await _pipeline.ExecuteAroundAsync(@event, async () => { - BeforeChange(@event); - DoPushPageInternal(uiKey, param, policy); - AfterChange(@event); - }).GetAwaiter().GetResult(); + await BeforeChangeAsync(@event); + await DoPushPageInternalAsync(uiKey, param, policy); + await AfterChangeAsync(@event); + }); } /// - /// 将已存在的UI页面压入栈顶 + /// 将已存在的UI页面压入栈顶 /// - public void Push(IUiPageBehavior page, IUiPageEnterParam? param = null, + /// 已存在的UI页面行为实例 + /// 页面进入参数 + /// UI过渡策略 + public async ValueTask PushAsync(IUiPageBehavior page, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive) { var uiKey = page.Key; @@ -114,18 +128,19 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter var @event = CreateEvent(uiKey, UiTransitionType.Push, policy, param); Log.Debug("Push existing UI Page: key={0}, policy={1}, stackBefore={2}", uiKey, policy, _stack.Count); - _pipeline.ExecuteAroundAsync(@event, async () => + await _pipeline.ExecuteAroundAsync(@event, async () => { - BeforeChange(@event); + await BeforeChangeAsync(@event); DoPushPageInternal(page, param, policy); - AfterChange(@event); - }).GetAwaiter().GetResult(); + await AfterChangeAsync(@event); + }); } /// - /// 弹出栈顶页面 + /// 弹出栈顶页面 /// - public void Pop(UiPopPolicy policy = UiPopPolicy.Destroy) + /// 页面弹出策略 + public async ValueTask PopAsync(UiPopPolicy policy = UiPopPolicy.Destroy) { if (_stack.Count == 0) { @@ -135,7 +150,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter var leavingUiKey = _stack.Peek().Key; - if (!ExecuteLeaveGuardsAsync(leavingUiKey).GetAwaiter().GetResult()) + if (!await ExecuteLeaveGuardsAsync(leavingUiKey)) { Log.Warn("Pop blocked by guard: {0}", leavingUiKey); return; @@ -144,41 +159,49 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter var nextUiKey = _stack.Count > 1 ? _stack.ElementAt(1).Key : null; var @event = CreateEvent(nextUiKey, UiTransitionType.Pop); - _pipeline.ExecuteAroundAsync(@event, async () => + await _pipeline.ExecuteAroundAsync(@event, async () => { - BeforeChange(@event); + await BeforeChangeAsync(@event); DoPopInternal(policy); - AfterChange(@event); - }).GetAwaiter().GetResult(); + await AfterChangeAsync(@event); + }); } /// - /// 替换当前所有页面为新页面(基于uiKey) + /// 替换当前所有页面为新页面(基于uiKey) /// - public void Replace(string uiKey, IUiPageEnterParam? param = null, + /// 新UI页面的唯一标识键 + /// 页面进入参数 + /// 页面弹出策略 + /// 页面压入策略 + public async ValueTask ReplaceAsync(string uiKey, IUiPageEnterParam? param = null, UiPopPolicy popPolicy = UiPopPolicy.Destroy, UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive) { var @event = CreateEvent(uiKey, UiTransitionType.Replace, pushPolicy, param); Log.Debug("Replace UI Stack with page: key={0}, popPolicy={1}, pushPolicy={2}", uiKey, popPolicy, pushPolicy); - _pipeline.ExecuteAroundAsync(@event, async () => + await _pipeline.ExecuteAroundAsync(@event, async () => { - BeforeChange(@event); + await BeforeChangeAsync(@event); DoClearInternal(popPolicy); var page = _factory.Create(uiKey); Log.Debug("Get/Create UI Page instance for Replace: {0}", page.GetType().Name); DoPushPageInternal(page, param, pushPolicy); - AfterChange(@event); - }).GetAwaiter().GetResult(); + await AfterChangeAsync(@event); + }); } /// - /// 替换当前所有页面为已存在的页面 + /// 替换当前所有页面为已存在的页面 /// - public void Replace(IUiPageBehavior page, IUiPageEnterParam? param = null, + /// 已存在的UI页面行为实例 + /// 页面进入参数 + /// 页面弹出策略 + /// 页面压入策略 + public async ValueTask ReplaceAsync(IUiPageBehavior page, IUiPageEnterParam? param = null, UiPopPolicy popPolicy = UiPopPolicy.Destroy, UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive) { @@ -187,66 +210,72 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter Log.Debug("Replace UI Stack with existing page: key={0}, popPolicy={1}, pushPolicy={2}", uiKey, popPolicy, pushPolicy); - _pipeline.ExecuteAroundAsync(@event, async () => + await _pipeline.ExecuteAroundAsync(@event, async () => { - BeforeChange(@event); + await BeforeChangeAsync(@event); DoClearInternal(popPolicy); Log.Debug("Use existing UI Page instance for Replace: {0}", page.GetType().Name); DoPushPageInternal(page, param, pushPolicy); - AfterChange(@event); - }).GetAwaiter().GetResult(); + await AfterChangeAsync(@event); + }); } /// - /// 清空所有页面栈 + /// 清空所有页面栈 /// - public void Clear() + public async ValueTask ClearAsync() { var @event = CreateEvent(string.Empty, UiTransitionType.Clear); Log.Debug("Clear UI Stack, stackCount={0}", _stack.Count); - _pipeline.ExecuteAroundAsync(@event, async () => + await _pipeline.ExecuteAroundAsync(@event, async () => { - BeforeChange(@event); + await BeforeChangeAsync(@event); DoClearInternal(UiPopPolicy.Destroy); - AfterChange(@event); - }).GetAwaiter().GetResult(); + await AfterChangeAsync(@event); + }); } /// - /// 获取栈顶元素的键值 + /// 获取栈顶元素的键值 /// + /// 栈顶UI页面的键值,如果栈为空则返回空字符串 public string PeekKey() { return _stack.Count == 0 ? string.Empty : _stack.Peek().Key; } /// - /// 获取栈顶元素 + /// 获取栈顶元素 /// + /// 栈顶UI页面行为实例,如果栈为空则返回null public IUiPageBehavior? Peek() { return _stack.Count == 0 ? null : _stack.Peek(); } /// - /// 判断栈顶是否为指定UI + /// 判断栈顶是否为指定UI /// + /// 要检查的UI页面键值 + /// 如果栈顶是指定UI则返回true,否则返回false public bool IsTop(string uiKey) { return _stack.Count != 0 && _stack.Peek().Key.Equals(uiKey); } /// - /// 判断栈中是否包含指定UI + /// 判断栈中是否包含指定UI /// + /// 要检查的UI页面键值 + /// 如果栈中包含指定UI则返回true,否则返回false public bool Contains(string uiKey) { return _stack.Any(p => p.Key.Equals(uiKey)); } /// - /// 获取栈深度 + /// 获取栈深度 /// public int Count => _stack.Count; @@ -255,8 +284,13 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter #region Layer UI Management /// - /// 在指定层级显示UI(基于 uiKey) + /// 在指定层级显示UI(基于 uiKey) /// + /// UI页面的唯一标识键 + /// UI显示层级 + /// 页面进入参数 + /// UI句柄实例 + /// 当尝试在Page层级使用此方法时抛出 public UiHandle Show(string uiKey, UiLayer layer, IUiPageEnterParam? param = null) { if (layer == UiLayer.Page) @@ -269,8 +303,12 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 在指定层级显示UI(基于实例) + /// 在指定层级显示UI(基于实例) /// + /// UI页面行为实例 + /// UI显示层级 + /// UI句柄实例 + /// 当尝试在Page层级使用此方法时抛出 public UiHandle Show(IUiPageBehavior page, UiLayer layer) { if (layer == UiLayer.Page) @@ -280,8 +318,11 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 隐藏指定层级的UI + /// 隐藏指定层级的UI /// + /// UI句柄 + /// UI层级 + /// 是否销毁UI实例,默认为false public void Hide(UiHandle handle, UiLayer layer, bool destroy = false) { if (!_layers.TryGetValue(layer, out var layerDict)) @@ -305,8 +346,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 恢复指定UI的显示 + /// 恢复指定UI的显示 /// + /// UI句柄 + /// UI层级 public void Resume(UiHandle handle, UiLayer layer) { if (!_layers.TryGetValue(layer, out var layerDict)) @@ -321,8 +364,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 清空指定层级的所有UI + /// 清空指定层级的所有UI /// + /// 要清空的UI层级 + /// 是否销毁UI实例,默认为false public void ClearLayer(UiLayer layer, bool destroy = false) { if (!_layers.TryGetValue(layer, out var layerDict)) @@ -343,8 +388,11 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 获取指定层级的UI实例 + /// 获取指定层级的UI实例 /// + /// UI句柄 + /// UI层级 + /// 如果找到则返回UI句柄,否则返回null public UiHandle? GetFromLayer(UiHandle handle, UiLayer layer) { if (!_layers.TryGetValue(layer, out var layerDict)) @@ -354,8 +402,11 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 获取指定 uiKey 在指定层级的所有实例 + /// 获取指定 uiKey 在指定层级的所有实例 /// + /// UI页面的唯一标识键 + /// UI层级 + /// 指定UI在该层级的所有实例句柄列表 public IReadOnlyList GetAllFromLayer(string uiKey, UiLayer layer) { if (!_layers.TryGetValue(layer, out var layerDict)) @@ -368,8 +419,11 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 判断指定UI是否在层级中可见 + /// 判断指定UI是否在层级中可见 /// + /// UI句柄 + /// UI层级 + /// 如果UI在层级中且可见则返回true,否则返回false public bool HasVisibleInLayer(UiHandle handle, UiLayer layer) { if (!_layers.TryGetValue(layer, out var layerDict)) @@ -382,7 +436,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 根据UI键隐藏指定层级中的UI。 + /// 根据UI键隐藏指定层级中的UI。 /// /// UI的唯一标识键。 /// 要操作的UI层级。 @@ -407,8 +461,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter #region Route Guards /// - /// 注册路由守卫 + /// 注册路由守卫 /// + /// 路由守卫实例 + /// 当守卫实例为null时抛出 public void AddGuard(IUiRouteGuard guard) { ArgumentNullException.ThrowIfNull(guard); @@ -425,16 +481,19 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 注册路由守卫(泛型) + /// 注册路由守卫(泛型) /// + /// 路由守卫类型,必须实现IUiRouteGuard接口且有无参构造函数 public void AddGuard() where T : IUiRouteGuard, new() { AddGuard(new T()); } /// - /// 移除路由守卫 + /// 移除路由守卫 /// + /// 要移除的路由守卫实例 + /// 当守卫实例为null时抛出 public void RemoveGuard(IUiRouteGuard guard) { ArgumentNullException.ThrowIfNull(guard); @@ -473,7 +532,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter #region Internal Helpers /// - /// 生成唯一实例ID + /// 生成唯一实例ID /// /// 格式为"ui_000001"的唯一实例标识符 private string GenerateInstanceId() @@ -485,8 +544,13 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } /// - /// 内部Show实现,支持重入 + /// 内部Show实现,支持重入 /// + /// UI页面行为实例 + /// UI显示层级 + /// 页面进入参数 + /// UI句柄实例 + /// 当UI不支持重入且已在该层级存在时抛出 private UiHandle ShowInternal(IUiPageBehavior page, UiLayer layer, IUiPageEnterParam? param) { var instanceId = GenerateInstanceId(); @@ -521,6 +585,14 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter return handle; } + /// + /// 创建UI过渡事件 + /// + /// 目标UI键值 + /// 过渡类型 + /// 过渡策略 + /// 进入参数 + /// UI过渡事件实例 private UiTransitionEvent CreateEvent(string? toUiKey, UiTransitionType type, UiTransitionPolicy? policy = null, IUiPageEnterParam? param = null) { @@ -534,33 +606,37 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter }; } - private void BeforeChange(UiTransitionEvent @event) + /// + /// 执行过渡前阶段 + /// + /// UI过渡事件 + private async Task BeforeChangeAsync(UiTransitionEvent @event) { Log.Debug("BeforeChange phases started: {0}", @event.TransitionType); - _pipeline.ExecuteAsync(@event, UiTransitionPhases.BeforeChange).GetAwaiter().GetResult(); + await _pipeline.ExecuteAsync(@event, UiTransitionPhases.BeforeChange); Log.Debug("BeforeChange phases completed: {0}", @event.TransitionType); } - private void AfterChange(UiTransitionEvent @event) + /// + /// 执行过渡后阶段 + /// + /// UI过渡事件 + private async Task AfterChangeAsync(UiTransitionEvent @event) { Log.Debug("AfterChange phases started: {0}", @event.TransitionType); - _ = Task.Run(async () => - { - try - { - await _pipeline.ExecuteAsync(@event, UiTransitionPhases.AfterChange).ConfigureAwait(false); - 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, UiTransitionPhases.AfterChange); + Log.Debug("AfterChange phases completed: {0}", @event.TransitionType); } - private void DoPushPageInternal(string uiKey, IUiPageEnterParam? param, UiTransitionPolicy policy) + /// + /// 内部异步压入页面实现 + /// + /// UI页面键值 + /// 页面进入参数 + /// 过渡策略 + private async Task DoPushPageInternalAsync(string uiKey, IUiPageEnterParam? param, UiTransitionPolicy policy) { - if (!ExecuteEnterGuardsAsync(uiKey, param).GetAwaiter().GetResult()) + if (!await ExecuteEnterGuardsAsync(uiKey, param)) { Log.Warn("Push blocked by guard: {0}", uiKey); return; @@ -571,6 +647,12 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter DoPushPageInternal(page, param, policy); } + /// + /// 内部压入页面实现 + /// + /// UI页面行为实例 + /// 页面进入参数 + /// 过渡策略 private void DoPushPageInternal(IUiPageBehavior page, IUiPageEnterParam? param, UiTransitionPolicy policy) { if (_stack.Count > 0) @@ -596,6 +678,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter page.OnShow(); } + /// + /// 内部弹出页面实现 + /// + /// 页面弹出策略 private void DoPopInternal(UiPopPolicy policy) { if (_stack.Count == 0) @@ -623,6 +709,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter } } + /// + /// 内部清空页面实现 + /// + /// 页面弹出策略 private void DoClearInternal(UiPopPolicy policy) { Log.Debug("Clear UI Stack internal, count={0}", _stack.Count); @@ -630,6 +720,12 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter DoPopInternal(policy); } + /// + /// 执行进入守卫检查 + /// + /// UI页面键值 + /// 页面进入参数 + /// 如果允许进入则返回true,否则返回false private async Task ExecuteEnterGuardsAsync(string uiKey, IUiPageEnterParam? param) { foreach (var guard in _guards) @@ -662,6 +758,11 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter return true; } + /// + /// 执行离开守卫检查 + /// + /// UI页面键值 + /// 如果允许离开则返回true,否则返回false private async Task ExecuteLeaveGuardsAsync(string uiKey) { foreach (var guard in _guards)