diff --git a/GFramework.Game.Abstractions/enums/CacheEvictionPolicy.cs b/GFramework.Game.Abstractions/enums/CacheEvictionPolicy.cs
new file mode 100644
index 0000000..481d943
--- /dev/null
+++ b/GFramework.Game.Abstractions/enums/CacheEvictionPolicy.cs
@@ -0,0 +1,17 @@
+namespace GFramework.Game.Abstractions.enums;
+
+///
+/// 缓存淘汰策略枚举
+///
+public enum CacheEvictionPolicy
+{
+ ///
+ /// 最近最少使用
+ ///
+ Lru,
+
+ ///
+ /// 最少使用频率
+ ///
+ Lfu,
+}
diff --git a/GFramework.Game.Abstractions/enums/UiTransitionAnimation.cs b/GFramework.Game.Abstractions/enums/UiTransitionAnimation.cs
deleted file mode 100644
index 15d2c08..0000000
--- a/GFramework.Game.Abstractions/enums/UiTransitionAnimation.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-namespace GFramework.Game.Abstractions.enums;
-
-///
-/// UI过渡动画类型枚举
-/// 定义UI切换时支持的动画效果
-///
-public enum UiTransitionAnimation
-{
- ///
- /// 无动画
- ///
- None,
-
- ///
- /// 淡入淡出动画
- ///
- Fade,
-
- ///
- /// 从右侧滑入
- ///
- SlideLeft,
-
- ///
- /// 从左侧滑入
- ///
- SlideRight,
-
- ///
- /// 从下方滑入
- ///
- SlideUp,
-
- ///
- /// 从上方滑入
- ///
- SlideDown,
-
- ///
- /// 缩放动画
- ///
- Scale,
-
- ///
- /// 自定义动画(需要提供自定义的 IUiTransition 实现)
- ///
- Custom
-}
diff --git a/GFramework.Game.Abstractions/ui/IUiCacheStatistics.cs b/GFramework.Game.Abstractions/ui/IUiCacheStatistics.cs
new file mode 100644
index 0000000..54190d3
--- /dev/null
+++ b/GFramework.Game.Abstractions/ui/IUiCacheStatistics.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace GFramework.Game.Abstractions.ui;
+
+///
+/// UI缓存统计信息接口
+///
+public interface IUiCacheStatistics
+{
+ ///
+ /// 缓存总数
+ ///
+ int CacheSize { get; }
+
+ ///
+ /// 缓存命中次数
+ ///
+ int HitCount { get; }
+
+ ///
+ /// 缓存未命中次数
+ ///
+ int MissCount { get; }
+
+ ///
+ /// 命中率
+ ///
+ double HitRate { get; }
+
+ ///
+ /// 最近访问时间
+ ///
+ DateTime? LastAccessTime { get; }
+}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/ui/IUiFactory.cs b/GFramework.Game.Abstractions/ui/IUiFactory.cs
index 70bcf56..20753dc 100644
--- a/GFramework.Game.Abstractions/ui/IUiFactory.cs
+++ b/GFramework.Game.Abstractions/ui/IUiFactory.cs
@@ -4,37 +4,6 @@ using GFramework.Core.Abstractions.utility;
namespace GFramework.Game.Abstractions.ui;
-///
-/// UI缓存统计信息接口
-///
-public interface IUiCacheStatistics
-{
- ///
- /// 缓存总数
- ///
- int CacheSize { get; }
-
- ///
- /// 缓存命中次数
- ///
- int HitCount { get; }
-
- ///
- /// 缓存未命中次数
- ///
- int MissCount { get; }
-
- ///
- /// 命中率
- ///
- double HitRate { get; }
-
- ///
- /// 最近访问时间
- ///
- DateTime? LastAccessTime { get; }
-}
-
///
/// UI工厂接口,用于创建UI页面实例
///
diff --git a/GFramework.Game.Abstractions/ui/IUiRouter.cs b/GFramework.Game.Abstractions/ui/IUiRouter.cs
index 08bd15d..5c3c250 100644
--- a/GFramework.Game.Abstractions/ui/IUiRouter.cs
+++ b/GFramework.Game.Abstractions/ui/IUiRouter.cs
@@ -26,9 +26,8 @@ public interface IUiRouter : ISystem
/// 进入界面的参数,可为空
/// 界面切换策略,默认为Exclusive(独占)
/// 实例管理策略,默认为Reuse(复用)
- /// 动画策略,可为空
void Push(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive,
- UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse, UiAnimationPolicy? animationPolicy = null);
+ UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse);
///
@@ -38,9 +37,8 @@ public interface IUiRouter : ISystem
/// 已创建的UI页面行为实例
/// 进入界面的参数,可为空
/// 界面切换策略,默认为Exclusive(独占)
- /// 动画策略,可为空
void Push(IUiPageBehavior page, IUiPageEnterParam? param = null,
- UiTransitionPolicy policy = UiTransitionPolicy.Exclusive, UiAnimationPolicy? animationPolicy = null);
+ UiTransitionPolicy policy = UiTransitionPolicy.Exclusive);
///
@@ -57,14 +55,12 @@ public interface IUiRouter : ISystem
/// 弹出页面时的销毁策略,默认为销毁
/// 推入页面时的过渡策略,默认为独占
/// 实例管理策略
- /// 动画策略,可为空
public void Replace(
string uiKey,
IUiPageEnterParam? param = null,
UiPopPolicy popPolicy = UiPopPolicy.Destroy,
UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive,
- UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse,
- UiAnimationPolicy? animationPolicy = null);
+ UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse);
///
/// 替换当前所有页面为已存在的页面(基于实例)
@@ -73,13 +69,11 @@ public interface IUiRouter : ISystem
/// 页面进入参数,可为空
/// 弹出页面时的销毁策略,默认为销毁
/// 推入页面时的过渡策略,默认为独占
- /// 动画策略,可为空
public void Replace(
IUiPageBehavior page,
IUiPageEnterParam? param = null,
UiPopPolicy popPolicy = UiPopPolicy.Destroy,
- UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive,
- UiAnimationPolicy? animationPolicy = null);
+ UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive);
///
/// 清空所有UI界面,重置路由状态
///
@@ -129,17 +123,16 @@ public interface IUiRouter : ISystem
/// 守卫实例
void AddGuard(IUiRouteGuard guard);
+ ///
+ /// 注册路由守卫(泛型方法)
+ ///
+ /// 守卫类型,必须实现 IUiRouteGuard 且有无参构造函数
+ void AddGuard() where T : IUiRouteGuard, new();
///
/// 移除路由守卫
///
/// 守卫实例
void RemoveGuard(IUiRouteGuard guard);
- ///
- /// 注册路由守卫(泛型方法)
- ///
- /// 守卫类型,必须实现 IUiRouteGuard 且有无参构造函数
- void AddGuard() where T : IUiRouteGuard, new();
-
#endregion
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/ui/UiAnimationPolicy.cs b/GFramework.Game.Abstractions/ui/UiAnimationPolicy.cs
deleted file mode 100644
index 3ce0713..0000000
--- a/GFramework.Game.Abstractions/ui/UiAnimationPolicy.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using GFramework.Game.Abstractions.enums;
-
-namespace GFramework.Game.Abstractions.ui;
-
-///
-/// UI动画策略配置
-/// 用于配置UI过渡动画的行为
-///
-public class UiAnimationPolicy
-{
- ///
- /// 动画类型
- ///
- public UiTransitionAnimation Animation { get; set; } = UiTransitionAnimation.None;
-
- ///
- /// 动画持续时间(秒)
- ///
- public float Duration { get; set; } = 0.3f;
-
- ///
- /// 是否阻塞UI切换(等待动画完成)
- ///
- public bool BlockTransition { get; set; } = false;
-
- ///
- /// 自定义动画实现(仅当 Animation 为 Custom 时使用)
- ///
- public IUiTransition? CustomTransition { get; set; }
-
- ///
- /// 缓动函数(可选,用于调整动画曲线)
- ///
- public EasingFunction Easing { get; set; } = EasingFunction.EaseInOut;
-
- ///
- /// 创建默认策略(无动画)
- ///
- public static UiAnimationPolicy None => new UiAnimationPolicy { Animation = UiTransitionAnimation.None };
-
- ///
- /// 创建淡入淡出策略
- ///
- /// 持续时间
- /// 是否阻塞
- public static UiAnimationPolicy Fade(float duration = 0.3f, bool block = false)
- => new UiAnimationPolicy { Animation = UiTransitionAnimation.Fade, Duration = duration, BlockTransition = block };
-
- ///
- /// 创建滑入策略
- ///
- /// 滑动方向
- /// 持续时间
- /// 是否阻塞
- public static UiAnimationPolicy Slide(UiTransitionAnimation direction, float duration = 0.3f, bool block = false)
- => new UiAnimationPolicy { Animation = direction, Duration = duration, BlockTransition = block };
-
- ///
- /// 创建缩放策略
- ///
- /// 持续时间
- /// 是否阻塞
- public static UiAnimationPolicy Scale(float duration = 0.3f, bool block = false)
- => new UiAnimationPolicy { Animation = UiTransitionAnimation.Scale, Duration = duration, BlockTransition = block };
-}
-
-///
-/// 缓动函数枚举
-///
-public enum EasingFunction
-{
- ///
- /// 线性
- ///
- Linear,
-
- ///
- /// 缓入
- ///
- EaseIn,
-
- ///
- /// 缓出
- ///
- EaseOut,
-
- ///
- /// 缓入缓出
- ///
- EaseInOut
-}
diff --git a/GFramework.Game.Abstractions/ui/UiCacheConfig.cs b/GFramework.Game.Abstractions/ui/UiCacheConfig.cs
index c5e14ca..e7d9687 100644
--- a/GFramework.Game.Abstractions/ui/UiCacheConfig.cs
+++ b/GFramework.Game.Abstractions/ui/UiCacheConfig.cs
@@ -1,4 +1,5 @@
using System;
+using GFramework.Game.Abstractions.enums;
namespace GFramework.Game.Abstractions.ui;
@@ -16,20 +17,20 @@ public class UiCacheConfig
///
/// 缓存淘汰策略
///
- public CacheEvictionPolicy EvictionPolicy { get; set; } = CacheEvictionPolicy.LRU;
+ public CacheEvictionPolicy EvictionPolicy { get; set; } = CacheEvictionPolicy.Lru;
///
/// 访问后过期时间(可选,null 表示不启用)
///
- public TimeSpan? ExpireAfterAccess { get; set; } = null;
+ public TimeSpan? ExpireAfterAccess { get; set; }
///
/// 创建默认配置(LRU 策略,最大 10 个实例)
///
- public static UiCacheConfig Default => new UiCacheConfig
+ public static UiCacheConfig Default => new()
{
MaxCacheSize = 10,
- EvictionPolicy = CacheEvictionPolicy.LRU,
+ EvictionPolicy = CacheEvictionPolicy.Lru,
ExpireAfterAccess = null
};
@@ -39,10 +40,10 @@ public class UiCacheConfig
/// 最大缓存数量
/// 访问后过期时间
public static UiCacheConfig Lru(int maxSize = 10, TimeSpan? expireAfter = null)
- => new UiCacheConfig
+ => new()
{
MaxCacheSize = maxSize,
- EvictionPolicy = CacheEvictionPolicy.LRU,
+ EvictionPolicy = CacheEvictionPolicy.Lru,
ExpireAfterAccess = expireAfter
};
@@ -52,26 +53,10 @@ public class UiCacheConfig
/// 最大缓存数量
/// 访问后过期时间
public static UiCacheConfig Lfu(int maxSize = 10, TimeSpan? expireAfter = null)
- => new UiCacheConfig
+ => new()
{
MaxCacheSize = maxSize,
- EvictionPolicy = CacheEvictionPolicy.LFU,
+ EvictionPolicy = CacheEvictionPolicy.Lfu,
ExpireAfterAccess = expireAfter
};
-}
-
-///
-/// 缓存淘汰策略枚举
-///
-public enum CacheEvictionPolicy
-{
- ///
- /// 最近最少使用
- ///
- LRU,
-
- ///
- /// 最少使用频率
- ///
- LFU
-}
+}
\ No newline at end of file
diff --git a/GFramework.Game/ui/UiRouterBase.cs b/GFramework.Game/ui/UiRouterBase.cs
index 70b5a79..a249ee7 100644
--- a/GFramework.Game/ui/UiRouterBase.cs
+++ b/GFramework.Game/ui/UiRouterBase.cs
@@ -4,7 +4,6 @@ using GFramework.Core.logging;
using GFramework.Core.system;
using GFramework.Game.Abstractions.enums;
using GFramework.Game.Abstractions.ui;
-using System.Linq;
namespace GFramework.Game.ui;
@@ -69,7 +68,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
_uiRoot = root;
Log.Debug("Bind UI Root: {0}", root.GetType().Name);
}
-
+
///
/// 将指定的UI界面压入路由栈,显示新的UI界面
@@ -78,9 +77,9 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
/// 进入界面的参数,可为空
/// 界面切换策略,默认为Exclusive(独占)
/// 实例管理策略,默认为Reuse(复用)
- /// 动画策略,可为空
- public void Push(string uiKey, IUiPageEnterParam? param = null, UiTransitionPolicy policy = UiTransitionPolicy.Exclusive,
- UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse, UiAnimationPolicy? animationPolicy = null)
+ public void Push(string uiKey, IUiPageEnterParam? param = null,
+ UiTransitionPolicy policy = UiTransitionPolicy.Exclusive,
+ UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse)
{
if (IsTop(uiKey))
{
@@ -89,7 +88,6 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
}
var @event = CreateEvent(uiKey, UiTransitionType.Push, policy, param);
- @event.Set("AnimationPolicy", animationPolicy);
Log.Debug(
"Push UI Page: key={0}, policy={1}, instancePolicy={2}, stackBefore={3}",
@@ -97,7 +95,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
);
BeforeChange(@event);
- DoPushPageInternal(uiKey, param, policy, instancePolicy, animationPolicy);
+ DoPushPageInternal(uiKey, param, policy, instancePolicy);
AfterChange(@event);
}
@@ -107,12 +105,10 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
/// 已创建的UI页面行为实例
/// 页面进入参数,可为空
/// 页面切换策略
- /// 动画策略,可为空
public void Push(
IUiPageBehavior page,
IUiPageEnterParam? param = null,
- UiTransitionPolicy policy = UiTransitionPolicy.Exclusive,
- UiAnimationPolicy? animationPolicy = null
+ UiTransitionPolicy policy = UiTransitionPolicy.Exclusive
)
{
var uiKey = page.View.GetType().Name;
@@ -124,7 +120,6 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
}
var @event = CreateEvent(uiKey, UiTransitionType.Push, policy, param);
- @event.Set("AnimationPolicy", animationPolicy);
Log.Debug(
"Push existing UI Page: key={0}, policy={1}, stackBefore={2}",
@@ -177,18 +172,14 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
/// 弹出页面时的销毁策略,默认为销毁
/// 推入页面时的过渡策略,默认为独占
/// 实例管理策略
- /// 动画策略,可为空
public void Replace(
string uiKey,
IUiPageEnterParam? param = null,
UiPopPolicy popPolicy = UiPopPolicy.Destroy,
UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive,
- UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse,
- UiAnimationPolicy? animationPolicy = null)
+ UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse)
{
var @event = CreateEvent(uiKey, UiTransitionType.Replace, pushPolicy, param);
- @event.Set("AnimationPolicy", animationPolicy);
-
Log.Debug(
"Replace UI Stack with page: key={0}, popPolicy={1}, pushPolicy={2}, instancePolicy={3}",
uiKey, popPolicy, pushPolicy, instancePolicy
@@ -207,6 +198,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
AfterChange(@event);
}
+
///
/// 替换当前所有页面为已存在的页面(基于实例)
///
@@ -214,17 +206,14 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
/// 页面进入参数,可为空
/// 弹出页面时的销毁策略,默认为销毁
/// 推入页面时的过渡策略,默认为独占
- /// 动画策略,可为空
public void Replace(
IUiPageBehavior page,
IUiPageEnterParam? param = null,
UiPopPolicy popPolicy = UiPopPolicy.Destroy,
- UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive,
- UiAnimationPolicy? animationPolicy = null)
+ UiTransitionPolicy pushPolicy = UiTransitionPolicy.Exclusive)
{
var uiKey = page.Key;
var @event = CreateEvent(uiKey, UiTransitionType.Replace, pushPolicy, param);
- @event.Set("AnimationPolicy", animationPolicy);
Log.Debug(
"Replace UI Stack with existing page: key={0}, popPolicy={1}, pushPolicy={2}",
@@ -373,7 +362,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
/// 执行Push页面的核心逻辑(基于 uiKey)
///
private void DoPushPageInternal(string uiKey, IUiPageEnterParam? param, UiTransitionPolicy policy,
- UiInstancePolicy instancePolicy, UiAnimationPolicy? animationPolicy)
+ UiInstancePolicy instancePolicy)
{
// 执行进入守卫
if (!ExecuteEnterGuardsAsync(uiKey, param).GetAwaiter().GetResult())
@@ -486,11 +475,11 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
///
public void Show(
string uiKey,
- Game.Abstractions.enums.UiLayer layer,
+ UiLayer layer,
IUiPageEnterParam? param = null,
UiInstancePolicy instancePolicy = UiInstancePolicy.Reuse)
{
- if (layer == Game.Abstractions.enums.UiLayer.Page)
+ if (layer == UiLayer.Page)
{
throw new ArgumentException("Use Push() for Page layer");
}
@@ -546,7 +535,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
///
/// 隐藏指定层级的UI
///
- public void Hide(string uiKey, Game.Abstractions.enums.UiLayer layer, bool destroy = false)
+ public void Hide(string uiKey, UiLayer layer, bool destroy = false)
{
if (!_layers.TryGetValue(layer, out var layerDict))
return;
@@ -575,7 +564,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
///
/// 清空指定层级的所有UI
///
- public void ClearLayer(Game.Abstractions.enums.UiLayer layer, bool destroy = false)
+ public void ClearLayer(UiLayer layer, bool destroy = false)
{
if (!_layers.TryGetValue(layer, out var layerDict))
return;
@@ -612,121 +601,120 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
#region 路由守卫
-
-///
-/// 注册路由守卫
-///
-public void AddGuard(IUiRouteGuard guard)
-{
- ArgumentNullException.ThrowIfNull(guard);
-
- if (_guards.Contains(guard))
+ ///
+ /// 注册路由守卫
+ ///
+ public void AddGuard(IUiRouteGuard guard)
{
- Log.Debug("Guard already registered: {0}", guard.GetType().Name);
- return;
- }
-
- _guards.Add(guard);
- // 按优先级排序
- _guards.Sort((a, b) => a.Priority.CompareTo(b.Priority));
- Log.Debug("Guard registered: {0}, Priority={1}", guard.GetType().Name, guard.Priority);
-}
+ ArgumentNullException.ThrowIfNull(guard);
-///
-/// 移除路由守卫
-///
-public void RemoveGuard(IUiRouteGuard guard)
-{
- ArgumentNullException.ThrowIfNull(guard);
-
- if (_guards.Remove(guard))
- {
- Log.Debug("Guard removed: {0}", guard.GetType().Name);
- }
-}
-
-///
-/// 注册路由守卫(泛型方法)
-///
-public void AddGuard() where T : IUiRouteGuard, new()
-{
- var guard = new T();
- AddGuard(guard);
-}
-
-///
-/// 执行进入守卫
-///
-private async Task ExecuteEnterGuardsAsync(string uiKey, IUiPageEnterParam? param)
-{
- foreach (var guard in _guards)
- {
- try
+ if (_guards.Contains(guard))
{
- Log.Debug("Executing enter guard: {0} for {1}", guard.GetType().Name, uiKey);
- var canEnter = await guard.CanEnterAsync(uiKey, param);
-
- if (!canEnter)
- {
- Log.Debug("Enter guard blocked: {0}", guard.GetType().Name);
- return false;
- }
-
- if (guard.CanInterrupt)
- {
- Log.Debug("Enter guard {0} passed, can interrupt = true", guard.GetType().Name);
- return true;
- }
+ Log.Debug("Guard already registered: {0}", guard.GetType().Name);
+ return;
}
- catch (Exception ex)
+
+ _guards.Add(guard);
+ // 按优先级排序
+ _guards.Sort((a, b) => a.Priority.CompareTo(b.Priority));
+ Log.Debug("Guard registered: {0}, Priority={1}", guard.GetType().Name, guard.Priority);
+ }
+
+ ///
+ /// 注册路由守卫(泛型方法)
+ ///
+ public void AddGuard() where T : IUiRouteGuard, new()
+ {
+ var guard = new T();
+ AddGuard(guard);
+ }
+
+ ///
+ /// 移除路由守卫
+ ///
+ public void RemoveGuard(IUiRouteGuard guard)
+ {
+ ArgumentNullException.ThrowIfNull(guard);
+
+ if (_guards.Remove(guard))
{
- Log.Error("Enter guard {0} failed: {1}", guard.GetType().Name, ex.Message);
- if (guard.CanInterrupt)
- {
- return false;
- }
+ Log.Debug("Guard removed: {0}", guard.GetType().Name);
}
}
-
- return true;
-}
-///
-/// 执行离开守卫
-///
-private async Task ExecuteLeaveGuardsAsync(string uiKey)
-{
- foreach (var guard in _guards)
+ ///
+ /// 执行进入守卫
+ ///
+ private async Task ExecuteEnterGuardsAsync(string uiKey, IUiPageEnterParam? param)
{
- try
+ foreach (var guard in _guards)
{
- Log.Debug("Executing leave guard: {0} for {1}", guard.GetType().Name, uiKey);
- var canLeave = await guard.CanLeaveAsync(uiKey);
-
- if (!canLeave)
+ try
{
- Log.Debug("Leave guard blocked: {0}", guard.GetType().Name);
- return false;
- }
-
- if (guard.CanInterrupt)
- {
- Log.Debug("Leave guard {0} passed, can interrupt = true", guard.GetType().Name);
- return true;
- }
- }
- catch (Exception ex)
- {
- Log.Error("Leave guard {0} failed: {1}", guard.GetType().Name, ex.Message);
- if (guard.CanInterrupt)
- {
- return false;
- }
- }
- }
-
- return true;
-}
+ Log.Debug("Executing enter guard: {0} for {1}", guard.GetType().Name, uiKey);
+ var canEnter = await guard.CanEnterAsync(uiKey, param);
-#endregion
+ if (!canEnter)
+ {
+ Log.Debug("Enter guard blocked: {0}", guard.GetType().Name);
+ return false;
+ }
+
+ if (guard.CanInterrupt)
+ {
+ Log.Debug("Enter guard {0} passed, can interrupt = true", guard.GetType().Name);
+ return true;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Enter guard {0} failed: {1}", guard.GetType().Name, ex.Message);
+ if (guard.CanInterrupt)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// 执行离开守卫
+ ///
+ private async Task ExecuteLeaveGuardsAsync(string uiKey)
+ {
+ foreach (var guard in _guards)
+ {
+ try
+ {
+ Log.Debug("Executing leave guard: {0} for {1}", guard.GetType().Name, uiKey);
+ var canLeave = await guard.CanLeaveAsync(uiKey);
+
+ if (!canLeave)
+ {
+ Log.Debug("Leave guard blocked: {0}", guard.GetType().Name);
+ return false;
+ }
+
+ if (guard.CanInterrupt)
+ {
+ Log.Debug("Leave guard {0} passed, can interrupt = true", guard.GetType().Name);
+ return true;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Leave guard {0} failed: {1}", guard.GetType().Name, ex.Message);
+ if (guard.CanInterrupt)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/GFramework.Godot/ui/GodotUiFactory.cs b/GFramework.Godot/ui/GodotUiFactory.cs
index db6c568..365daab 100644
--- a/GFramework.Godot/ui/GodotUiFactory.cs
+++ b/GFramework.Godot/ui/GodotUiFactory.cs
@@ -1,8 +1,8 @@
-using System;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.extensions;
using GFramework.Core.logging;
using GFramework.Core.utility;
+using GFramework.Game.Abstractions.enums;
using GFramework.Game.Abstractions.ui;
using GFramework.Godot.extensions;
using Godot;
@@ -18,7 +18,7 @@ public class GodotUiFactory : AbstractContextUtility, IUiFactory
///
/// 缓存统计信息实现类
///
- private class CacheStatisticsInfo : IUiCacheStatistics
+ private sealed class CacheStatisticsInfo : IUiCacheStatistics
{
public int CacheSize { get; set; }
public int HitCount { get; set; }
@@ -381,27 +381,25 @@ public class GodotUiFactory : AbstractContextUtility, IUiFactory
{
var config = GetCacheConfig(uiKey);
var currentSize = _cachedInstances.TryGetValue(uiKey, out var queue) ? queue.Count : 0;
-
- if (currentSize > config.MaxCacheSize)
+
+ if (currentSize <= config.MaxCacheSize) return;
+ var toEvict = currentSize - config.MaxCacheSize;
+
+ for (var i = 0; i < toEvict; i++)
{
- var toEvict = currentSize - config.MaxCacheSize;
-
- for (int i = 0; i < toEvict; i++)
- {
- if (config.EvictionPolicy == CacheEvictionPolicy.LRU)
- EvictLRU(uiKey);
- else
- EvictLFU(uiKey);
- }
-
- Log.Debug("Evicted {0} instances for UI: {1}", toEvict, uiKey);
+ if (config.EvictionPolicy == CacheEvictionPolicy.Lru)
+ EvictLru(uiKey);
+ else
+ EvictLfu(uiKey);
}
+
+ Log.Debug("Evicted {0} instances for UI: {1}", toEvict, uiKey);
}
///
/// LRU淘汰策略
///
- private void EvictLRU(string uiKey)
+ private void EvictLru(string uiKey)
{
if (!_accessTimeQueue.TryGetValue(uiKey, out var timeQueue) || timeQueue.Count == 0)
return;
@@ -437,7 +435,7 @@ public class GodotUiFactory : AbstractContextUtility, IUiFactory
///
/// LFU淘汰策略
///
- private void EvictLFU(string uiKey)
+ private void EvictLfu(string uiKey)
{
if (!_cachedInstances.TryGetValue(uiKey, out var queue) || queue.Count == 0)
return;
diff --git a/GFramework.Godot/ui/GodotUiTransition.cs b/GFramework.Godot/ui/GodotUiTransition.cs
deleted file mode 100644
index 85323cf..0000000
--- a/GFramework.Godot/ui/GodotUiTransition.cs
+++ /dev/null
@@ -1,171 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using GFramework.Game.Abstractions.enums;
-using GFramework.Game.Abstractions.ui;
-using Godot;
-
-namespace GFramework.Godot.ui;
-
-///
-/// Godot平台的UI过渡动画实现
-/// 支持多种预定义动画效果
-///
-public class GodotUiTransition : IUiTransition
-{
- private readonly UiTransitionAnimation _animation;
-
- ///
- /// 创建过渡动画实例
- ///
- /// 动画类型
- public GodotUiTransition(UiTransitionAnimation animation)
- {
- _animation = animation;
- }
-
- ///
- /// 播放进入动画
- ///
- public async Task PlayEnterAsync(IUiPageBehavior page)
- {
- var node = page.View as Node;
- if (node == null)
- return;
-
- switch (_animation)
- {
- case UiTransitionAnimation.Fade:
- await PlayFadeEnterAsync(node);
- break;
- case UiTransitionAnimation.Scale:
- await PlayScaleEnterAsync(node);
- break;
- case UiTransitionAnimation.SlideLeft:
- case UiTransitionAnimation.SlideRight:
- case UiTransitionAnimation.SlideUp:
- case UiTransitionAnimation.SlideDown:
- await PlaySlideEnterAsync(node, _animation);
- break;
- case UiTransitionAnimation.None:
- default:
- break;
- }
- }
-
- ///
- /// 播放退出动画
- ///
- public async Task PlayExitAsync(IUiPageBehavior page)
- {
- var node = page.View as Node;
- if (node == null)
- return;
-
- switch (_animation)
- {
- case UiTransitionAnimation.Fade:
- await PlayFadeExitAsync(node);
- break;
- case UiTransitionAnimation.Scale:
- await PlayScaleExitAsync(node);
- break;
- case UiTransitionAnimation.SlideLeft:
- case UiTransitionAnimation.SlideRight:
- case UiTransitionAnimation.SlideUp:
- case UiTransitionAnimation.SlideDown:
- await PlaySlideExitAsync(node, _animation);
- break;
- case UiTransitionAnimation.None:
- default:
- break;
- }
- }
-
- private static async Task PlayFadeEnterAsync(Node node)
- {
- if (node is CanvasItem canvasItem)
- {
- canvasItem.Modulate = new Color(1,1, 1, 0);
- canvasItem.Visible = true;
- await Task.Delay(300);
- canvasItem.Modulate = new Color(1,1, 1, 1);
- }
- }
-
- private static async Task PlayFadeExitAsync(Node node)
- {
- if (node is CanvasItem canvasItem)
- {
- await Task.Delay(300);
- canvasItem.Modulate = new Color(1,1, 1, 0);
- }
- }
-
- private static async Task PlayScaleEnterAsync(Node node)
- {
- if (node is Control control)
- {
- control.Scale = Vector2.Zero;
- control.PivotOffset = control.Size / 2;
- await Task.Delay(300);
- control.Scale = Vector2.One;
- }
- }
-
- private static async Task PlayScaleExitAsync(Node node)
- {
- if (node is Control control)
- {
- control.PivotOffset = control.Size / 2;
- await Task.Delay(300);
- control.Scale = Vector2.Zero;
- }
- }
-
- private static async Task PlaySlideEnterAsync(Node node, UiTransitionAnimation direction)
- {
- if (node is Control control)
- {
- var screenPos = control.GetViewportRect().Size;
- var offset = GetSlideOffset(direction, screenPos);
- control.Position += offset;
- await Task.Delay(300);
- control.Position -= offset;
- }
- }
-
- private static async Task PlaySlideExitAsync(Node node, UiTransitionAnimation direction)
- {
- if (node is Control control)
- {
- var screenPos = control.GetViewportRect().Size;
- var offset = GetSlideExitOffset(direction, screenPos);
- await Task.Delay(300);
- control.Position += offset;
- }
- }
-
- private static Vector2 GetSlideOffset(UiTransitionAnimation direction, Vector2 screenPos)
- {
- return direction switch
- {
- UiTransitionAnimation.SlideLeft => Vector2.Right * screenPos.X,
- UiTransitionAnimation.SlideRight => Vector2.Left * screenPos.X,
- UiTransitionAnimation.SlideUp => Vector2.Down * screenPos.Y,
- UiTransitionAnimation.SlideDown => Vector2.Up * screenPos.Y,
- _ => Vector2.Zero
- };
- }
-
- private static Vector2 GetSlideExitOffset(UiTransitionAnimation direction, Vector2 screenPos)
- {
- return direction switch
- {
- UiTransitionAnimation.SlideLeft => Vector2.Left * screenPos.X,
- UiTransitionAnimation.SlideRight => Vector2.Right * screenPos.X,
- UiTransitionAnimation.SlideUp => Vector2.Up * screenPos.Y,
- UiTransitionAnimation.SlideDown => Vector2.Down * screenPos.Y,
- _ => Vector2.Zero
- };
- }
-}