diff --git a/Runtime/ABase/ObjectPool/ObjectPoolBase.cs b/Runtime/ABase/ObjectPool/ObjectPoolBase.cs index 00df568..86df41f 100644 --- a/Runtime/ABase/ObjectPool/ObjectPoolBase.cs +++ b/Runtime/ABase/ObjectPool/ObjectPoolBase.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using AlicizaX; namespace AlicizaX.ObjectPool @@ -139,6 +140,8 @@ namespace AlicizaX.ObjectPool /// 所有对象信息。 public abstract ObjectInfo[] GetAllObjectInfos(); + public abstract void GetAllObjectInfos(List results); + internal abstract void Update(float elapseSeconds, float realElapseSeconds); internal abstract void Shutdown(); diff --git a/Runtime/ABase/ObjectPool/ObjectPoolService.Object.cs b/Runtime/ABase/ObjectPool/ObjectPoolService.Object.cs index 6ef9130..0c7edec 100644 --- a/Runtime/ABase/ObjectPool/ObjectPoolService.Object.cs +++ b/Runtime/ABase/ObjectPool/ObjectPoolService.Object.cs @@ -157,8 +157,8 @@ namespace AlicizaX.ObjectPool /// public void Unspawn() { - m_Object.OnUnspawn(); m_Object.LastUseTime = DateTime.UtcNow; + m_Object.OnUnspawn(); m_SpawnCount--; if (m_SpawnCount < 0) { diff --git a/Runtime/ABase/ObjectPool/ObjectPoolService.ObjectPool.cs b/Runtime/ABase/ObjectPool/ObjectPoolService.ObjectPool.cs index ce1e227..40e60c8 100644 --- a/Runtime/ABase/ObjectPool/ObjectPoolService.ObjectPool.cs +++ b/Runtime/ABase/ObjectPool/ObjectPoolService.ObjectPool.cs @@ -14,10 +14,8 @@ namespace AlicizaX.ObjectPool { private readonly GameFrameworkMultiDictionary> m_Objects; private readonly Dictionary> m_ObjectMap; - private readonly ReleaseObjectFilterCallback m_DefaultReleaseObjectFilterCallback; private readonly List> m_CachedCanReleaseObjects; private readonly List> m_CachedToReleaseObjects; - private readonly List m_CachedCanReleaseTargets; private readonly IComparer> m_ReleaseObjectComparer; private readonly bool m_AllowMultiSpawn; private float m_AutoReleaseInterval; @@ -40,10 +38,8 @@ namespace AlicizaX.ObjectPool { m_Objects = new GameFrameworkMultiDictionary>(); m_ObjectMap = new Dictionary>(); - m_DefaultReleaseObjectFilterCallback = DefaultReleaseObjectFilterCallback; m_CachedCanReleaseObjects = new List>(); m_CachedToReleaseObjects = new List>(); - m_CachedCanReleaseTargets = new List(); m_ReleaseObjectComparer = Comparer>.Create(ReleaseObjectComparer); m_AllowMultiSpawn = allowMultiSpawn; m_AutoReleaseInterval = autoReleaseInterval; @@ -76,8 +72,14 @@ namespace AlicizaX.ObjectPool { get { - GetCanReleaseObjects(m_CachedCanReleaseObjects); - return m_CachedCanReleaseObjects.Count; + int count = 0; + foreach (KeyValuePair> kv in m_ObjectMap) + { + Object obj = kv.Value; + if (!obj.IsInUse && !obj.Locked && obj.CustomCanReleaseFlag) + count++; + } + return count; } } @@ -405,7 +407,7 @@ namespace AlicizaX.ObjectPool /// public override void Release() { - Release(Count - m_Capacity, m_DefaultReleaseObjectFilterCallback); + ReleaseWithDefaultFilter(Count - m_Capacity); } /// @@ -414,7 +416,7 @@ namespace AlicizaX.ObjectPool /// 尝试释放对象数量。 public override void Release(int toReleaseCount) { - Release(toReleaseCount, m_DefaultReleaseObjectFilterCallback); + ReleaseWithDefaultFilter(toReleaseCount); } /// @@ -434,11 +436,6 @@ namespace AlicizaX.ObjectPool public void Release(int toReleaseCount, ReleaseObjectFilterCallback releaseObjectFilterCallback) { if (releaseObjectFilterCallback == null) - { - throw new GameFrameworkException("Release object filter callback is invalid."); - } - - if (releaseObjectFilterCallback == m_DefaultReleaseObjectFilterCallback) { ReleaseWithDefaultFilter(toReleaseCount); return; @@ -457,13 +454,13 @@ namespace AlicizaX.ObjectPool m_AutoReleaseTime = 0f; GetCanReleaseObjects(m_CachedCanReleaseObjects); - m_CachedCanReleaseTargets.Clear(); + List candidateTargets = new List(m_CachedCanReleaseObjects.Count); foreach (Object internalObject in m_CachedCanReleaseObjects) { - m_CachedCanReleaseTargets.Add(internalObject.Peek()); + candidateTargets.Add(internalObject.Peek()); } - List toReleaseObjects = releaseObjectFilterCallback(m_CachedCanReleaseTargets, toReleaseCount, expireTime); + List toReleaseObjects = releaseObjectFilterCallback(candidateTargets, toReleaseCount, expireTime); if (toReleaseObjects == null || toReleaseObjects.Count <= 0) { return; @@ -495,6 +492,18 @@ namespace AlicizaX.ObjectPool public override ObjectInfo[] GetAllObjectInfos() { List results = new List(); + GetAllObjectInfos(results); + return results.ToArray(); + } + + public override void GetAllObjectInfos(List results) + { + if (results == null) + { + throw new GameFrameworkException("Results is invalid."); + } + + results.Clear(); foreach (KeyValuePair>> objectRanges in m_Objects) { foreach (Object internalObject in objectRanges.Value) @@ -502,8 +511,6 @@ namespace AlicizaX.ObjectPool results.Add(new ObjectInfo(internalObject.Name, internalObject.Locked, internalObject.CustomCanReleaseFlag, internalObject.Priority, internalObject.LastUseTime, internalObject.SpawnCount)); } } - - return results.ToArray(); } internal override void Update(float elapseSeconds, float realElapseSeconds) @@ -529,7 +536,6 @@ namespace AlicizaX.ObjectPool m_ObjectMap.Clear(); m_CachedCanReleaseObjects.Clear(); m_CachedToReleaseObjects.Clear(); - m_CachedCanReleaseTargets.Clear(); } private Object GetObject(object target) @@ -566,10 +572,7 @@ namespace AlicizaX.ObjectPool return false; } - if (!m_Objects.Remove(internalObject.Name, internalObject.NameNode)) - { - m_Objects.Remove(internalObject.Name, internalObject); - } + m_Objects.Remove(internalObject.Name, internalObject.NameNode); internalObject.NameNode = null; m_ObjectMap.Remove(targetObject.Target); @@ -656,45 +659,6 @@ namespace AlicizaX.ObjectPool } } - private List DefaultReleaseObjectFilterCallback(List candidateObjects, int toReleaseCount, DateTime expireTime) - { - m_CachedCanReleaseTargets.Clear(); - - if (expireTime > DateTime.MinValue) - { - for (int i = candidateObjects.Count - 1; i >= 0; i--) - { - if (candidateObjects[i].LastUseTime <= expireTime) - { - m_CachedCanReleaseTargets.Add(candidateObjects[i]); - candidateObjects.RemoveAt(i); - continue; - } - } - - toReleaseCount -= m_CachedCanReleaseTargets.Count; - } - - for (int i = 0; toReleaseCount > 0 && i < candidateObjects.Count; i++) - { - for (int j = i + 1; j < candidateObjects.Count; j++) - { - if (candidateObjects[i].Priority > candidateObjects[j].Priority - || candidateObjects[i].Priority == candidateObjects[j].Priority && candidateObjects[i].LastUseTime > candidateObjects[j].LastUseTime) - { - T temp = candidateObjects[i]; - candidateObjects[i] = candidateObjects[j]; - candidateObjects[j] = temp; - } - } - - m_CachedCanReleaseTargets.Add(candidateObjects[i]); - toReleaseCount--; - } - - return m_CachedCanReleaseTargets; - } - private static int ReleaseObjectComparer(Object a, Object b) { int priorityCompare = a.Priority.CompareTo(b.Priority); diff --git a/Runtime/ABase/ObjectPool/ObjectPoolService.cs b/Runtime/ABase/ObjectPool/ObjectPoolService.cs index 26367e3..0d52bfa 100644 --- a/Runtime/ABase/ObjectPool/ObjectPoolService.cs +++ b/Runtime/ABase/ObjectPool/ObjectPoolService.cs @@ -16,6 +16,7 @@ namespace AlicizaX.ObjectPool private const int DefaultPriority = 0; private readonly Dictionary m_ObjectPools; + private readonly List m_ObjectPoolList; private readonly List m_CachedAllObjectPools; private readonly Comparison m_ObjectPoolComparer; @@ -25,6 +26,7 @@ namespace AlicizaX.ObjectPool public ObjectPoolService() { m_ObjectPools = new Dictionary(); + m_ObjectPoolList = new List(); m_CachedAllObjectPools = new List(); m_ObjectPoolComparer = ObjectPoolComparer; } @@ -50,9 +52,9 @@ namespace AlicizaX.ObjectPool /// 真实流逝时间,以秒为单位。 void IServiceTickable.Tick(float deltaTime) { - foreach (KeyValuePair objectPool in m_ObjectPools) + for (int i = 0; i < m_ObjectPoolList.Count; i++) { - objectPool.Value.Update(Time.deltaTime,Time.unscaledDeltaTime); + m_ObjectPoolList[i].Update(deltaTime, Time.unscaledDeltaTime); } } @@ -63,12 +65,13 @@ namespace AlicizaX.ObjectPool protected override void OnDestroyService() { - foreach (KeyValuePair objectPool in m_ObjectPools) + for (int i = 0; i < m_ObjectPoolList.Count; i++) { - objectPool.Value.Shutdown(); + m_ObjectPoolList[i].Shutdown(); } m_ObjectPools.Clear(); + m_ObjectPoolList.Clear(); m_CachedAllObjectPools.Clear(); } @@ -146,9 +149,9 @@ namespace AlicizaX.ObjectPool throw new GameFrameworkException("Condition is invalid."); } - foreach (KeyValuePair objectPool in m_ObjectPools) + for (int i = 0; i < m_ObjectPoolList.Count; i++) { - if (condition(objectPool.Value)) + if (condition(m_ObjectPoolList[i])) { return true; } @@ -231,11 +234,11 @@ namespace AlicizaX.ObjectPool throw new GameFrameworkException("Condition is invalid."); } - foreach (KeyValuePair objectPool in m_ObjectPools) + for (int i = 0; i < m_ObjectPoolList.Count; i++) { - if (condition(objectPool.Value)) + if (condition(m_ObjectPoolList[i])) { - return objectPool.Value; + return m_ObjectPoolList[i]; } } @@ -255,11 +258,11 @@ namespace AlicizaX.ObjectPool } List results = new List(); - foreach (KeyValuePair objectPool in m_ObjectPools) + for (int i = 0; i < m_ObjectPoolList.Count; i++) { - if (condition(objectPool.Value)) + if (condition(m_ObjectPoolList[i])) { - results.Add(objectPool.Value); + results.Add(m_ObjectPoolList[i]); } } @@ -284,11 +287,11 @@ namespace AlicizaX.ObjectPool } results.Clear(); - foreach (KeyValuePair objectPool in m_ObjectPools) + for (int i = 0; i < m_ObjectPoolList.Count; i++) { - if (condition(objectPool.Value)) + if (condition(m_ObjectPoolList[i])) { - results.Add(objectPool.Value); + results.Add(m_ObjectPoolList[i]); } } } @@ -320,25 +323,13 @@ namespace AlicizaX.ObjectPool { if (sort) { - List results = new List(); - foreach (KeyValuePair objectPool in m_ObjectPools) - { - results.Add(objectPool.Value); - } - + List results = new List(m_ObjectPoolList); results.Sort(m_ObjectPoolComparer); return results.ToArray(); } else { - int index = 0; - ObjectPoolBase[] results = new ObjectPoolBase[m_ObjectPools.Count]; - foreach (KeyValuePair objectPool in m_ObjectPools) - { - results[index++] = objectPool.Value; - } - - return results; + return m_ObjectPoolList.ToArray(); } } @@ -355,10 +346,7 @@ namespace AlicizaX.ObjectPool } results.Clear(); - foreach (KeyValuePair objectPool in m_ObjectPools) - { - results.Add(objectPool.Value); - } + results.AddRange(m_ObjectPoolList); if (sort) { @@ -1245,6 +1233,7 @@ namespace AlicizaX.ObjectPool ObjectPool objectPool = new ObjectPool(name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority); m_ObjectPools.Add(typeNamePair, objectPool); + m_ObjectPoolList.Add(objectPool); return objectPool; } @@ -1269,6 +1258,7 @@ namespace AlicizaX.ObjectPool Type objectPoolType = typeof(ObjectPool<>).MakeGenericType(objectType); ObjectPoolBase objectPool = (ObjectPoolBase)Activator.CreateInstance(objectPoolType, name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority); m_ObjectPools.Add(typeNamePair, objectPool); + m_ObjectPoolList.Add(objectPool); return objectPool; } @@ -1278,6 +1268,7 @@ namespace AlicizaX.ObjectPool if (m_ObjectPools.TryGetValue(typeNamePair, out objectPool)) { objectPool.Shutdown(); + m_ObjectPoolList.Remove(objectPool); return m_ObjectPools.Remove(typeNamePair); }