diff --git a/GFramework.Game.Abstractions/ui/IAssetRegistry.cs b/GFramework.Game.Abstractions/asset/IAssetRegistry.cs
similarity index 87%
rename from GFramework.Game.Abstractions/ui/IAssetRegistry.cs
rename to GFramework.Game.Abstractions/asset/IAssetRegistry.cs
index fcf3a7e..1c35089 100644
--- a/GFramework.Game.Abstractions/ui/IAssetRegistry.cs
+++ b/GFramework.Game.Abstractions/asset/IAssetRegistry.cs
@@ -1,7 +1,7 @@
using GFramework.Core.Abstractions.registries;
using GFramework.Core.Abstractions.utility;
-namespace GFramework.Game.Abstractions.ui;
+namespace GFramework.Game.Abstractions.asset;
///
/// 资源注册表接口,用于管理指定类型T的资源注册和查找
diff --git a/GFramework.Game.Abstractions/enums/CacheEvictionPolicy.cs b/GFramework.Game.Abstractions/enums/CacheEvictionPolicy.cs
deleted file mode 100644
index 030ebd5..0000000
--- a/GFramework.Game.Abstractions/enums/CacheEvictionPolicy.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace GFramework.Game.Abstractions.enums;
-
-///
-/// 缓存淘汰策略枚举
-///
-public enum CacheEvictionPolicy
-{
- ///
- /// 最近最少使用
- ///
- Lru,
-
- ///
- /// 最少使用频率
- ///
- Lfu
-}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/enums/UITransitionPhases.cs b/GFramework.Game.Abstractions/enums/UITransitionPhases.cs
index e35bfca..c87bf72 100644
--- a/GFramework.Game.Abstractions/enums/UITransitionPhases.cs
+++ b/GFramework.Game.Abstractions/enums/UITransitionPhases.cs
@@ -4,7 +4,7 @@ namespace GFramework.Game.Abstractions.enums;
/// UI切换阶段枚举,定义UI切换过程中的不同阶段
///
[Flags]
-public enum UITransitionPhases
+public enum UiTransitionPhases
{
///
/// UI切换前阶段,在此阶段执行的Handler可以阻塞UI切换流程
diff --git a/GFramework.Game.Abstractions/scene/IScene.cs b/GFramework.Game.Abstractions/scene/IScene.cs
new file mode 100644
index 0000000..887a403
--- /dev/null
+++ b/GFramework.Game.Abstractions/scene/IScene.cs
@@ -0,0 +1,64 @@
+// Copyright (c) 2026 GeWuYou
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace GFramework.Game.Abstractions.scene;
+
+///
+/// 场景接口,定义了场景生命周期管理的核心方法。
+/// 实现此接口的类需要处理场景从加载到卸载的完整生命周期。
+///
+public interface IScene
+{
+ ///
+ /// 异步加载场景所需资源。
+ /// 在场景正式进入前调用,负责预加载场景所需的各类资源。
+ ///
+ /// 场景进入参数,可能包含初始化数据或上下文信息。
+ /// 表示加载操作完成的ValueTask。
+ ValueTask OnLoadAsync(ISceneEnterParam? param);
+
+ ///
+ /// 异步处理场景正式进入逻辑。
+ /// 在资源加载完成后调用,启动场景的主要运行逻辑。
+ ///
+ /// 表示进入操作完成的ValueTask。
+ ValueTask OnEnterAsync();
+
+ ///
+ /// 异步处理场景暂停逻辑。
+ /// 当场景被其他场景覆盖或失去焦点时调用。
+ ///
+ /// 表示暂停操作完成的ValueTask。
+ ValueTask OnPauseAsync();
+
+ ///
+ /// 异步处理场景恢复逻辑。
+ /// 当场景重新获得焦点或从暂停状态恢复时调用。
+ ///
+ /// 表示恢复操作完成的ValueTask。
+ ValueTask OnResumeAsync();
+
+ ///
+ /// 异步处理场景退出逻辑。
+ /// 在场景即将被替换或关闭时调用,执行清理工作。
+ ///
+ /// 表示退出操作完成的ValueTask。
+ ValueTask OnExitAsync();
+
+ ///
+ /// 异步卸载场景资源。
+ /// 在场景完全退出后调用,释放占用的内存和资源。
+ ///
+ /// 表示卸载操作完成的ValueTask。
+ ValueTask OnUnloadAsync();
+}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/scene/ISceneBehavior.cs b/GFramework.Game.Abstractions/scene/ISceneBehavior.cs
new file mode 100644
index 0000000..820324f
--- /dev/null
+++ b/GFramework.Game.Abstractions/scene/ISceneBehavior.cs
@@ -0,0 +1,88 @@
+// Copyright (c) 2026 GeWuYou
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace GFramework.Game.Abstractions.scene;
+
+///
+/// 场景行为接口,定义了场景生命周期管理的标准方法。
+/// 实现此接口的类需要处理场景的加载、激活、暂停、恢复和卸载等核心操作。
+///
+public interface ISceneBehavior
+{
+ ///
+ /// 获取场景的唯一标识符。
+ /// 用于区分不同的场景实例。
+ ///
+ string Key { get; }
+
+ ///
+ /// 获取场景是否已加载完成的状态。
+ /// true表示场景资源已加载,false表示未加载或正在加载中。
+ ///
+ bool IsLoaded { get; }
+
+ ///
+ /// 获取场景是否处于活跃运行状态。
+ /// true表示场景正在前台运行,false表示场景已暂停或未激活。
+ ///
+ bool IsActive { get; }
+
+ ///
+ /// 获取场景是否正在进行切换操作。
+ /// true表示场景正在加载、卸载或过渡中,false表示场景状态稳定。
+ ///
+ bool IsTransitioning { get; }
+
+ ///
+ /// 异步加载场景所需资源。
+ /// 在场景正式进入前调用,负责预加载场景所需的各类资源。
+ ///
+ /// 场景进入参数,可能包含初始化数据或上下文信息。
+ /// 表示加载操作完成的ValueTask。
+ ValueTask OnLoadAsync(ISceneEnterParam? param);
+
+ ///
+ /// 异步处理场景正式进入逻辑。
+ /// 在资源加载完成后调用,启动场景的主要运行逻辑。
+ ///
+ /// 表示进入操作完成的ValueTask。
+ ValueTask OnEnterAsync();
+
+ ///
+ /// 异步处理场景暂停逻辑。
+ /// 当场景被其他场景覆盖或失去焦点时调用。
+ ///
+ /// 表示暂停操作完成的ValueTask。
+ ValueTask OnPauseAsync();
+
+ ///
+ /// 异步处理场景恢复逻辑。
+ /// 当场景重新获得焦点或从暂停状态恢复时调用。
+ ///
+ /// 表示恢复操作完成的ValueTask。
+ ValueTask OnResumeAsync();
+
+ ///
+ /// 异步处理场景退出逻辑。
+ /// 在场景即将被替换或关闭时调用,执行清理工作。
+ ///
+ /// 表示退出操作完成的ValueTask。
+ ValueTask OnExitAsync();
+
+ ///
+ /// 异步卸载场景资源。
+ /// 在场景完全退出后调用,释放占用的内存和资源。
+ ///
+ /// 表示卸载操作完成的ValueTask。
+ ValueTask OnUnloadAsync();
+}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/scene/ISceneBehaviorProvider.cs b/GFramework.Game.Abstractions/scene/ISceneBehaviorProvider.cs
new file mode 100644
index 0000000..121e11d
--- /dev/null
+++ b/GFramework.Game.Abstractions/scene/ISceneBehaviorProvider.cs
@@ -0,0 +1,27 @@
+// Copyright (c) 2026 GeWuYou
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace GFramework.Game.Abstractions.scene;
+
+///
+/// 场景行为提供者接口,用于获取场景行为实例。
+/// 实现此接口的类负责创建和提供具体的场景行为对象。
+///
+public interface ISceneBehaviorProvider
+{
+ ///
+ /// 获取场景行为实例。
+ ///
+ /// 场景行为对象,包含场景的具体实现逻辑。
+ ISceneBehavior GetScene();
+}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/scene/ISceneEnterParam.cs b/GFramework.Game.Abstractions/scene/ISceneEnterParam.cs
new file mode 100644
index 0000000..901facf
--- /dev/null
+++ b/GFramework.Game.Abstractions/scene/ISceneEnterParam.cs
@@ -0,0 +1,20 @@
+// Copyright (c) 2026 GeWuYou
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace GFramework.Game.Abstractions.scene;
+
+///
+/// 场景进入参数接口
+/// 该接口用于定义场景跳转时传递的参数数据结构
+///
+public interface ISceneEnterParam;
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/scene/ISceneFactory.cs b/GFramework.Game.Abstractions/scene/ISceneFactory.cs
new file mode 100644
index 0000000..b1d61e1
--- /dev/null
+++ b/GFramework.Game.Abstractions/scene/ISceneFactory.cs
@@ -0,0 +1,30 @@
+// Copyright (c) 2026 GeWuYou
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using GFramework.Core.Abstractions.utility;
+
+namespace GFramework.Game.Abstractions.scene;
+
+///
+/// 场景工厂接口,继承自上下文工具接口。
+/// 负责根据场景键值创建对应的场景行为实例,是场景管理系统的核心工厂模式实现。
+///
+public interface ISceneFactory : IContextUtility
+{
+ ///
+ /// 根据指定的场景键值创建场景行为实例。
+ ///
+ /// 场景的唯一标识符键值。
+ /// 创建的场景行为对象,如果无法创建则返回null。
+ ISceneBehavior Create(string sceneKy);
+}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/scene/ISceneRoot.cs b/GFramework.Game.Abstractions/scene/ISceneRoot.cs
index 4947608..22673b1 100644
--- a/GFramework.Game.Abstractions/scene/ISceneRoot.cs
+++ b/GFramework.Game.Abstractions/scene/ISceneRoot.cs
@@ -14,18 +14,74 @@
namespace GFramework.Game.Abstractions.scene;
///
-/// 定义场景根接口,用于管理场景的加载和卸载操作。
+/// 场景根接口,定义了场景管理系统的核心功能。
+/// 负责管理场景的生命周期、场景栈操作以及场景间的切换控制。
///
public interface ISceneRoot
{
///
- /// 替换当前场景为指定键对应的场景。
+ /// 获取当前活动的场景行为对象。
+ /// 返回null表示当前没有活动场景。
///
- /// 场景的唯一标识符,用于定位要加载的场景。
- void Replace(string key);
+ ISceneBehavior? Current { get; }
///
- /// 卸载当前场景。
+ /// 获取所有已加载场景的行为对象列表。
+ /// 列表采用栈式结构,索引0为栈底场景,最后一个元素为当前活动场景。
///
- void Unload();
+ IReadOnlyList Stack { get; }
+
+ ///
+ /// 获取场景系统是否正在进行切换操作。
+ /// true表示正在执行场景加载、卸载或切换,false表示系统空闲。
+ ///
+ bool IsTransitioning { get; }
+
+ ///
+ /// 异步替换当前场景,清空整个场景栈并加载新场景。
+ /// 此操作会卸载所有现有场景,然后加载指定的新场景。
+ ///
+ /// 要加载的场景唯一标识符。
+ /// 可选的场景进入参数,用于传递初始化数据。
+ /// 表示替换操作完成的ValueTask。
+ ValueTask ReplaceAsync(string key, ISceneEnterParam? param = null);
+
+ ///
+ /// 异步压入新场景到场景栈顶部。
+ /// 当前场景会被暂停,新场景成为活动场景。
+ ///
+ /// 要加载的场景唯一标识符。
+ /// 可选的场景进入参数,用于传递初始化数据。
+ /// 表示压入操作完成的ValueTask。
+ ValueTask PushAsync(string key, ISceneEnterParam? param = null);
+
+ ///
+ /// 异步弹出当前场景并恢复下一个场景。
+ /// 当前场景会被卸载,栈中的下一个场景变为活动场景。
+ ///
+ /// 表示弹出操作完成的ValueTask。
+ ValueTask PopAsync();
+
+ ///
+ /// 异步清空所有已加载的场景。
+ /// 卸载场景栈中的所有场景,使系统回到无场景状态。
+ ///
+ /// 表示清空操作完成的ValueTask。
+ ValueTask ClearAsync();
+
+ ///
+ /// 异步加载指定场景并返回场景行为实例。
+ /// 此方法仅加载场景资源但不激活场景,通常用于预加载或后台加载场景。
+ ///
+ /// 要加载的场景唯一标识符。
+ /// 表示加载操作完成的ValueTask,包含加载成功的场景行为对象。
+ ValueTask LoadAsync(string sceneKey);
+
+ ///
+ /// 异步卸载指定的场景行为实例。
+ /// 释放场景占用的资源并从系统中移除该场景实例。
+ ///
+ /// 要卸载的场景行为实例。
+ /// 表示卸载操作完成的ValueTask。
+ ValueTask UnloadAsync(ISceneBehavior scene);
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/scene/ISceneRouter.cs b/GFramework.Game.Abstractions/scene/ISceneRouter.cs
index ee896f0..d7708a5 100644
--- a/GFramework.Game.Abstractions/scene/ISceneRouter.cs
+++ b/GFramework.Game.Abstractions/scene/ISceneRouter.cs
@@ -16,30 +16,82 @@ using GFramework.Core.Abstractions.system;
namespace GFramework.Game.Abstractions.scene;
///
-/// 定义场景路由接口,用于管理场景的切换、卸载以及根节点绑定。
+/// 场景路由接口,继承自系统接口。
+/// 负责管理场景的导航、切换、生命周期控制以及与场景根节点的绑定操作。
+/// 提供完整的场景栈管理和路由功能。
///
public interface ISceneRouter : ISystem
{
///
- /// 获取当前场景的唯一标识符(键)。
+ /// 获取当前活动的场景行为对象。
+ /// 返回null表示当前没有活动场景。
+ ///
+ ISceneBehavior? Current { get; }
+
+ ///
+ /// 获取当前活动场景的唯一标识键值。
+ /// 返回null表示当前没有活动场景。
///
- /// 当前场景的键,如果未加载任何场景则返回 null。
string? CurrentKey { get; }
///
- /// 替换当前场景为指定键对应的场景。
+ /// 获取场景行为对象的只读列表,表示当前的场景栈结构。
+ /// 列表中第一个元素为栈底场景,最后一个元素为当前活动场景。
///
- /// 目标场景的唯一标识符(键)。
- void Replace(string sceneKey);
+ IReadOnlyList Stack { get; }
///
- /// 卸载当前场景。
+ /// 获取场景路由器是否正在进行场景切换操作。
+ /// true表示正在执行场景加载、卸载或切换,false表示系统空闲。
///
- void Unload();
+ bool IsTransitioning { get; }
///
- /// 将指定的场景根节点与当前路由进行绑定。
+ /// 绑定场景根节点,建立路由与场景管理器的连接。
///
- /// 需要绑定的场景根节点。
+ /// 要绑定的场景根节点实例。
void BindRoot(ISceneRoot root);
+
+ ///
+ /// 异步替换当前所有场景,清空整个场景栈并加载新的场景。
+ /// 此操作会卸载所有现有场景,然后加载指定的新场景。
+ ///
+ /// 要加载的场景唯一标识符。
+ /// 可选的场景进入参数,用于传递初始化数据。
+ /// 表示替换操作完成的ValueTask。
+ ValueTask ReplaceAsync(
+ string sceneKey,
+ ISceneEnterParam? param = null);
+
+ ///
+ /// 异步压入新场景到场景栈顶部。
+ /// 当前场景会被暂停,新场景成为活动场景。
+ ///
+ /// 要加载的场景唯一标识符。
+ /// 可选的场景进入参数,用于传递初始化数据。
+ /// 表示压入操作完成的ValueTask。
+ ValueTask PushAsync(
+ string sceneKey,
+ ISceneEnterParam? param = null);
+
+ ///
+ /// 异步弹出当前场景并恢复栈中的下一个场景。
+ /// 当前场景会被卸载,栈中的下一个场景变为活动场景。
+ ///
+ /// 表示弹出操作完成的ValueTask。
+ ValueTask PopAsync();
+
+ ///
+ /// 异步清空所有已加载的场景。
+ /// 卸载场景栈中的所有场景,使系统回到无场景状态。
+ ///
+ /// 表示清空操作完成的ValueTask。
+ ValueTask ClearAsync();
+
+ ///
+ /// 检查指定场景是否存在于当前场景栈中。
+ ///
+ /// 要检查的场景唯一标识符。
+ /// true表示场景在栈中存在,false表示不存在。
+ bool Contains(string sceneKey);
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/ui/IUiTransitionHandler.cs b/GFramework.Game.Abstractions/ui/IUiTransitionHandler.cs
index 69c0f3e..4177849 100644
--- a/GFramework.Game.Abstractions/ui/IUiTransitionHandler.cs
+++ b/GFramework.Game.Abstractions/ui/IUiTransitionHandler.cs
@@ -16,7 +16,7 @@ public interface IUiTransitionHandler
/// 处理器适用的阶段,默认为所有阶段
/// 可以使用Flags枚举指定多个阶段
///
- UITransitionPhases Phases { get; }
+ UiTransitionPhases Phases { get; }
///
/// 判断是否应该处理当前事件
@@ -25,7 +25,7 @@ public interface IUiTransitionHandler
/// UI切换事件
/// 当前阶段
/// 是否处理
- bool ShouldHandle(UiTransitionEvent @event, UITransitionPhases phases);
+ bool ShouldHandle(UiTransitionEvent @event, UiTransitionPhases phases);
///
/// 处理UI切换事件
diff --git a/GFramework.Game/scene/SceneRouterBase.cs b/GFramework.Game/scene/SceneRouterBase.cs
index 88af0c2..9b884a5 100644
--- a/GFramework.Game/scene/SceneRouterBase.cs
+++ b/GFramework.Game/scene/SceneRouterBase.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2026 GeWuYou
+// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -11,6 +11,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+using GFramework.Core.Abstractions.logging;
+using GFramework.Core.logging;
using GFramework.Core.system;
using GFramework.Game.Abstractions.scene;
@@ -23,70 +25,174 @@ namespace GFramework.Game.scene;
public abstract class SceneRouterBase
: AbstractSystem, ISceneRouter
{
- ///
- /// 当前绑定的场景根节点。
- ///
+ private static readonly ILogger Log =
+ LoggerFactoryResolver.Provider.CreateLogger(nameof(SceneRouterBase));
+
+ private readonly Stack _stack = new();
+ private readonly SemaphoreSlim _transitionLock = new(1, 1);
+
protected ISceneRoot? Root;
- ///
- /// 当前激活场景的键值。
- ///
- public string? CurrentKey { get; private set; }
+ public ISceneBehavior? Current => _stack.Count > 0 ? _stack.Peek() : null;
+
+ public string? CurrentKey => Current?.Key;
+
+ public IReadOnlyList Stack =>
+ _stack.Reverse().ToList();
+
+ public bool IsTransitioning { get; private set; }
- ///
- /// 绑定场景根节点。
- ///
- /// 要绑定的场景根节点。
public void BindRoot(ISceneRoot root)
{
Root = root;
+ Log.Debug("Bind Scene Root: {0}", root.GetType().Name);
}
- ///
- /// 替换当前场景为指定键值的新场景。
- /// 在替换前后会调用相应的虚方法以支持扩展逻辑。
- ///
- /// 目标场景的键值。
- public void Replace(string sceneKey)
+ #region Replace
+
+ public async ValueTask ReplaceAsync(
+ string sceneKey,
+ ISceneEnterParam? param = null)
{
- // 调用替换前的钩子方法
- OnBeforeReplace(sceneKey);
+ await _transitionLock.WaitAsync();
+ try
+ {
+ IsTransitioning = true;
- // 执行场景替换操作
- Root!.Replace(sceneKey);
+ Log.Debug("Replace Scene: {0}", sceneKey);
- // 更新当前场景键值
- CurrentKey = sceneKey;
-
- // 调用替换后的钩子方法
- OnAfterReplace(sceneKey);
+ await ClearInternalAsync();
+ await PushInternalAsync(sceneKey, param);
+ }
+ finally
+ {
+ IsTransitioning = false;
+ _transitionLock.Release();
+ }
}
- ///
- /// 卸载当前场景,并将当前场景键值置为空。
- ///
- public void Unload()
+ #endregion
+
+ #region Query
+
+ public bool Contains(string sceneKey)
{
- // 执行场景卸载操作
- Root!.Unload();
-
- // 清空当前场景键值
- CurrentKey = null;
+ return _stack.Any(s => s.Key == sceneKey);
}
- ///
- /// 场景替换前的虚方法,可在子类中重写以实现自定义逻辑。
- ///
- /// 即将被替换的场景键值。
- protected virtual void OnBeforeReplace(string key)
+ #endregion
+
+ #region Push
+
+ public async ValueTask PushAsync(
+ string sceneKey,
+ ISceneEnterParam? param = null)
{
+ await _transitionLock.WaitAsync();
+ try
+ {
+ IsTransitioning = true;
+ await PushInternalAsync(sceneKey, param);
+ }
+ finally
+ {
+ IsTransitioning = false;
+ _transitionLock.Release();
+ }
}
- ///
- /// 场景替换后的虚方法,可在子类中重写以实现自定义逻辑。
- ///
- /// 已替换的场景键值。
- protected virtual void OnAfterReplace(string key)
+ private async ValueTask PushInternalAsync(
+ string sceneKey,
+ ISceneEnterParam? param)
{
+ if (Contains(sceneKey))
+ {
+ Log.Warn("Scene already in stack: {0}", sceneKey);
+ return;
+ }
+
+ var scene = await Root!.LoadAsync(sceneKey);
+
+ if (_stack.Count > 0)
+ {
+ var current = _stack.Peek();
+ await current.OnPauseAsync();
+ }
+
+ _stack.Push(scene);
+
+ await scene.OnEnterAsync(param);
+ await scene.OnShowAsync();
+
+ Log.Debug("Push Scene: {0}, stackCount={1}",
+ sceneKey, _stack.Count);
}
+
+ #endregion
+
+ #region Pop
+
+ public async ValueTask PopAsync()
+ {
+ await _transitionLock.WaitAsync();
+ try
+ {
+ IsTransitioning = true;
+ await PopInternalAsync();
+ }
+ finally
+ {
+ IsTransitioning = false;
+ _transitionLock.Release();
+ }
+ }
+
+ private async ValueTask PopInternalAsync()
+ {
+ if (_stack.Count == 0)
+ return;
+
+ var top = _stack.Pop();
+
+ await top.OnExitAsync();
+ await Root!.UnloadAsync(top);
+
+ if (_stack.Count > 0)
+ {
+ var next = _stack.Peek();
+ await next.OnResumeAsync();
+ await next.OnShowAsync();
+ }
+
+ Log.Debug("Pop Scene, stackCount={0}", _stack.Count);
+ }
+
+ #endregion
+
+ #region Clear
+
+ public async ValueTask ClearAsync()
+ {
+ await _transitionLock.WaitAsync();
+ try
+ {
+ IsTransitioning = true;
+ await ClearInternalAsync();
+ }
+ finally
+ {
+ IsTransitioning = false;
+ _transitionLock.Release();
+ }
+ }
+
+ private async ValueTask ClearInternalAsync()
+ {
+ while (_stack.Count > 0)
+ {
+ await PopInternalAsync();
+ }
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/GFramework.Game/ui/UiRouterBase.cs b/GFramework.Game/ui/UiRouterBase.cs
index 6c0b794..7be98ee 100644
--- a/GFramework.Game/ui/UiRouterBase.cs
+++ b/GFramework.Game/ui/UiRouterBase.cs
@@ -12,7 +12,7 @@ namespace GFramework.Game.ui;
///
public abstract class UiRouterBase : AbstractSystem, IUiRouter
{
- private static readonly ILogger Log = LoggerFactoryResolver.Provider.CreateLogger("UiRouterBase");
+ private static readonly ILogger Log = LoggerFactoryResolver.Provider.CreateLogger(nameof(UiRouterBase));
///
/// 路由守卫列表
@@ -519,7 +519,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
private void BeforeChange(UiTransitionEvent @event)
{
Log.Debug("BeforeChange phases started: {0}", @event.TransitionType);
- _pipeline.ExecuteAsync(@event, UITransitionPhases.BeforeChange).GetAwaiter().GetResult();
+ _pipeline.ExecuteAsync(@event, UiTransitionPhases.BeforeChange).GetAwaiter().GetResult();
Log.Debug("BeforeChange phases completed: {0}", @event.TransitionType);
}
@@ -530,7 +530,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
{
try
{
- await _pipeline.ExecuteAsync(@event, UITransitionPhases.AfterChange).ConfigureAwait(false);
+ await _pipeline.ExecuteAsync(@event, UiTransitionPhases.AfterChange).ConfigureAwait(false);
Log.Debug("AfterChange phases completed: {0}", @event.TransitionType);
}
catch (Exception ex)
diff --git a/GFramework.Game/ui/UiTransitionPipeline.cs b/GFramework.Game/ui/UiTransitionPipeline.cs
index 2e2d459..c5bd9e4 100644
--- a/GFramework.Game/ui/UiTransitionPipeline.cs
+++ b/GFramework.Game/ui/UiTransitionPipeline.cs
@@ -62,7 +62,7 @@ public class UiTransitionPipeline
/// 异步任务
public async Task ExecuteAsync(
UiTransitionEvent @event,
- UITransitionPhases phases,
+ UiTransitionPhases phases,
CancellationToken cancellationToken = default
)
{
@@ -102,7 +102,7 @@ public class UiTransitionPipeline
private List FilterAndSortHandlers(
UiTransitionEvent @event,
- UITransitionPhases phases)
+ UiTransitionPhases phases)
{
return _handlers
.Where(h => h.Phases.HasFlag(phases) && h.ShouldHandle(@event, phases))
diff --git a/GFramework.Game/ui/handler/LoggingTransitionHandler.cs b/GFramework.Game/ui/handler/LoggingTransitionHandler.cs
index e3f799e..39d81fa 100644
--- a/GFramework.Game/ui/handler/LoggingTransitionHandler.cs
+++ b/GFramework.Game/ui/handler/LoggingTransitionHandler.cs
@@ -13,7 +13,7 @@ public sealed class LoggingTransitionHandler : UiTransitionHandlerBase
///
/// 日志记录器实例,用于记录UI切换相关信息
///
- private static readonly ILogger Log = LoggerFactoryResolver.Provider.CreateLogger("LoggingTransitionHandler");
+ private static readonly ILogger Log = LoggerFactoryResolver.Provider.CreateLogger(nameof(LoggingTransitionHandler));
///
/// 获取处理器优先级,数值越大优先级越高
@@ -23,7 +23,7 @@ public sealed class LoggingTransitionHandler : UiTransitionHandlerBase
///
/// 获取处理器处理的UI切换阶段,处理所有阶段
///
- public override UITransitionPhases Phases => UITransitionPhases.All;
+ public override UiTransitionPhases Phases => UiTransitionPhases.All;
///
/// 处理UI切换事件的异步方法
diff --git a/GFramework.Game/ui/handler/UiTransitionHandlerBase.cs b/GFramework.Game/ui/handler/UiTransitionHandlerBase.cs
index 98394af..b868996 100644
--- a/GFramework.Game/ui/handler/UiTransitionHandlerBase.cs
+++ b/GFramework.Game/ui/handler/UiTransitionHandlerBase.cs
@@ -11,7 +11,7 @@ public abstract class UiTransitionHandlerBase : IUiTransitionHandler
///
/// 处理器适用的阶段,默认为所有阶段
///
- public virtual UITransitionPhases Phases => UITransitionPhases.All;
+ public virtual UiTransitionPhases Phases => UiTransitionPhases.All;
///
/// 优先级,需要在子类中实现
@@ -21,7 +21,7 @@ public abstract class UiTransitionHandlerBase : IUiTransitionHandler
///
/// 判断是否应该处理当前事件,默认返回true
///
- public virtual bool ShouldHandle(UiTransitionEvent @event, UITransitionPhases phases)
+ public virtual bool ShouldHandle(UiTransitionEvent @event, UiTransitionPhases phases)
{
return true;
}
diff --git a/GFramework.Godot/scene/IGodotSceneRegistry.cs b/GFramework.Godot/scene/IGodotSceneRegistry.cs
index 760db28..b28ceed 100644
--- a/GFramework.Godot/scene/IGodotSceneRegistry.cs
+++ b/GFramework.Godot/scene/IGodotSceneRegistry.cs
@@ -1,4 +1,4 @@
-using GFramework.Game.Abstractions.ui;
+using GFramework.Game.Abstractions.asset;
using Godot;
namespace GFramework.Godot.scene;
diff --git a/GFramework.Godot/ui/IGodotUiRegistry.cs b/GFramework.Godot/ui/IGodotUiRegistry.cs
index 3b90918..a67b411 100644
--- a/GFramework.Godot/ui/IGodotUiRegistry.cs
+++ b/GFramework.Godot/ui/IGodotUiRegistry.cs
@@ -1,4 +1,4 @@
-using GFramework.Game.Abstractions.ui;
+using GFramework.Game.Abstractions.asset;
using Godot;
namespace GFramework.Godot.ui;