diff --git a/Runtime/ABase/Structs/TypeNamePair.cs b/Runtime/ABase/Structs/TypeNamePair.cs
index 76aa787..4ec532e 100644
--- a/Runtime/ABase/Structs/TypeNamePair.cs
+++ b/Runtime/ABase/Structs/TypeNamePair.cs
@@ -28,11 +28,6 @@ namespace AlicizaX
/// 名称。
public TypeNamePair(Type type, string name)
{
- if (type == null)
- {
- throw new GameFrameworkException("Type is invalid.");
- }
-
m_Type = type;
m_Name = name ?? string.Empty;
}
@@ -61,11 +56,21 @@ namespace AlicizaX
{
if (m_Type == null)
{
- throw new GameFrameworkException("Type is invalid.");
+ return string.Empty;
}
string typeName = m_Type.FullName;
- return (string.IsNullOrEmpty(m_Name) ? typeName : Utility.Text.Format("{0}.{1}", typeName, m_Name)) ?? string.Empty;
+ if (string.IsNullOrEmpty(m_Name))
+ return typeName ?? string.Empty;
+
+ // 使用 ZString 避免字符串分配
+ using (var sb = Cysharp.Text.ZString.CreateStringBuilder())
+ {
+ sb.Append(typeName);
+ sb.Append('.');
+ sb.Append(m_Name);
+ return sb.ToString();
+ }
}
///
diff --git a/Runtime/ObjectPool/IObjectPoolService.cs b/Runtime/ObjectPool/IObjectPoolService.cs
index 8862518..7c75286 100644
--- a/Runtime/ObjectPool/IObjectPoolService.cs
+++ b/Runtime/ObjectPool/IObjectPoolService.cs
@@ -9,6 +9,7 @@ namespace AlicizaX.ObjectPool
public readonly int? Capacity;
public readonly float? ExpireTime;
public readonly int Priority;
+ public readonly ReleaseStrategy ReleaseStrategy;
public ObjectPoolCreateOptions(
string name = "",
@@ -16,7 +17,8 @@ namespace AlicizaX.ObjectPool
float? autoReleaseInterval = null,
int? capacity = null,
float? expireTime = null,
- int priority = 0)
+ int priority = 0,
+ ReleaseStrategy releaseStrategy = ReleaseStrategy.LRU)
{
Name = name ?? string.Empty;
AllowMultiSpawn = allowMultiSpawn;
@@ -24,10 +26,11 @@ namespace AlicizaX.ObjectPool
Capacity = capacity;
ExpireTime = expireTime;
Priority = priority;
+ ReleaseStrategy = releaseStrategy;
}
public ObjectPoolCreateOptions WithName(string name)
- => new ObjectPoolCreateOptions(name, AllowMultiSpawn, AutoReleaseInterval, Capacity, ExpireTime, Priority);
+ => new ObjectPoolCreateOptions(name, AllowMultiSpawn, AutoReleaseInterval, Capacity, ExpireTime, Priority, ReleaseStrategy);
public static ObjectPoolCreateOptions Single(string name = "")
=> new ObjectPoolCreateOptions(name: name);
diff --git a/Runtime/ObjectPool/IPoolableObject.cs b/Runtime/ObjectPool/IPoolableObject.cs
new file mode 100644
index 0000000..1aad388
--- /dev/null
+++ b/Runtime/ObjectPool/IPoolableObject.cs
@@ -0,0 +1,18 @@
+namespace AlicizaX.ObjectPool
+{
+ ///
+ /// 可池化对象接口,支持自定义回收和重用逻辑
+ ///
+ public interface IPoolableObject
+ {
+ ///
+ /// 对象被回收到池中时调用(重置状态)
+ ///
+ void OnRecycle();
+
+ ///
+ /// 对象从池中取出时调用(初始化状态)
+ ///
+ void OnReuse();
+ }
+}
diff --git a/Runtime/ObjectPool/IPoolableObject.cs.meta b/Runtime/ObjectPool/IPoolableObject.cs.meta
new file mode 100644
index 0000000..876e9d4
--- /dev/null
+++ b/Runtime/ObjectPool/IPoolableObject.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0c4c7354bf5820e408151d8ecbd1bab1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ObjectPool/ObjectBase.cs b/Runtime/ObjectPool/ObjectBase.cs
index 9ae0c1d..dd6704d 100644
--- a/Runtime/ObjectPool/ObjectBase.cs
+++ b/Runtime/ObjectPool/ObjectBase.cs
@@ -54,4 +54,71 @@ namespace AlicizaX.ObjectPool
m_LastUseTime = 0f;
}
}
+
+ ///
+ /// 泛型对象池基类,消除装箱开销
+ ///
+ public abstract class ObjectBase : IMemory where T : class
+ {
+ private string m_Name;
+ private T m_Target;
+ private bool m_Locked;
+ private float m_LastUseTime;
+
+ public string Name => m_Name;
+ public T Target => m_Target;
+
+ public bool Locked
+ {
+ get => m_Locked;
+ set => m_Locked = value;
+ }
+
+ public float LastUseTime
+ {
+ get => m_LastUseTime;
+ internal set => m_LastUseTime = value;
+ }
+
+ public virtual bool CustomCanReleaseFlag => true;
+
+ protected void Initialize(T target)
+ {
+ Initialize(string.Empty, target, false);
+ }
+
+ protected void Initialize(string name, T target)
+ {
+ Initialize(name, target, false);
+ }
+
+ protected void Initialize(string name, T target, bool locked)
+ {
+ m_Name = name ?? string.Empty;
+ m_Target = target;
+ m_Locked = locked;
+ m_LastUseTime = 0f;
+
+ if (target is IPoolableObject poolable)
+ poolable.OnReuse();
+ }
+
+ protected internal virtual void OnSpawn() { }
+
+ protected internal virtual void OnUnspawn()
+ {
+ if (m_Target is IPoolableObject poolable)
+ poolable.OnRecycle();
+ }
+
+ protected internal abstract void Release(bool isShutdown);
+
+ public virtual void Clear()
+ {
+ m_Name = null;
+ m_Target = null;
+ m_Locked = false;
+ m_LastUseTime = 0f;
+ }
+ }
}
diff --git a/Runtime/ObjectPool/ObjectPoolBase.cs b/Runtime/ObjectPool/ObjectPoolBase.cs
index 5e8cee1..c5352bc 100644
--- a/Runtime/ObjectPool/ObjectPoolBase.cs
+++ b/Runtime/ObjectPool/ObjectPoolBase.cs
@@ -21,7 +21,18 @@ namespace AlicizaX.ObjectPool
get
{
if (m_FullName == null)
- m_FullName = new TypeNamePair(ObjectType, m_Name).ToString();
+ {
+ using (var sb = Cysharp.Text.ZString.CreateStringBuilder())
+ {
+ sb.Append(ObjectType.FullName);
+ if (!string.IsNullOrEmpty(m_Name))
+ {
+ sb.Append('.');
+ sb.Append(m_Name);
+ }
+ m_FullName = sb.ToString();
+ }
+ }
return m_FullName;
}
}
diff --git a/Runtime/ObjectPool/ObjectPoolService.ObjectPool.cs b/Runtime/ObjectPool/ObjectPoolService.ObjectPool.cs
index f03b233..e6c00f1 100644
--- a/Runtime/ObjectPool/ObjectPoolService.ObjectPool.cs
+++ b/Runtime/ObjectPool/ObjectPoolService.ObjectPool.cs
@@ -36,19 +36,21 @@ namespace AlicizaX.ObjectPool
private ObjectSlot[] m_Slots;
private int m_SlotCount;
+ private int m_SlotCapacity;
private int[] m_FreeStack;
private int m_FreeTop;
- private readonly Dictionary