refactor(EnemyManager): 性能优化与并发安全修复
- EnemyRegistry: 移除List冗余存储, Register/Remove从O(n)→O(1) - 增加PruneInvalidEntries显式清理接口, 消除TryGet副作用 - Remove增加不存在告警, 防重复减成负数 - 增加CTS取消飞行中的异步生成, 关卡切换时取消+重建 - ClearEnemies先快照再遍历, 防Hide回调修改集合抛异常 - entityId去掉取模复用, 直接自增保证唯一 - Enemy EntityGroup调优: Capacity→10000, ReleaseInterval→30, ExpireTime→120
This commit is contained in:
@@ -6,80 +6,58 @@ namespace SepCore.EnemyManager
|
||||
{
|
||||
public class EnemyRegistry
|
||||
{
|
||||
private readonly List<EntityBase> _enemies;
|
||||
private readonly Dictionary<int, EntityBase> _enemyById;
|
||||
|
||||
public int Count { get; private set; }
|
||||
public List<EntityBase> Enemies => _enemies;
|
||||
public int Count => _enemyById.Count;
|
||||
public IReadOnlyCollection<EntityBase> Enemies => _enemyById.Values;
|
||||
|
||||
public EnemyRegistry()
|
||||
{
|
||||
_enemies = new List<EntityBase>();
|
||||
_enemyById = new Dictionary<int, EntityBase>();
|
||||
}
|
||||
|
||||
public void Register(EnemyBase enemy)
|
||||
{
|
||||
if (enemy == null) return;
|
||||
|
||||
Count++;
|
||||
RemoveFromCache(enemy.Id);
|
||||
_enemies.Add(enemy);
|
||||
_enemyById[enemy.Id] = enemy;
|
||||
}
|
||||
|
||||
public void Remove(int entityId)
|
||||
{
|
||||
if (Count > 0)
|
||||
if (!_enemyById.ContainsKey(entityId))
|
||||
{
|
||||
Count--;
|
||||
Debug.LogWarning($"EnemyRegistry: Attempt to remove non-existent entity id={entityId}");
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveFromCache(entityId);
|
||||
_enemyById.Remove(entityId);
|
||||
}
|
||||
|
||||
public bool TryGet(int entityId, out EntityBase enemy)
|
||||
{
|
||||
enemy = null;
|
||||
if (!_enemyById.TryGetValue(entityId, out EntityBase cachedEnemy))
|
||||
return _enemyById.TryGetValue(entityId, out enemy);
|
||||
}
|
||||
|
||||
public void PruneInvalidEntries()
|
||||
{
|
||||
var invalidIds = new List<int>();
|
||||
foreach (var kvp in _enemyById)
|
||||
{
|
||||
return false;
|
||||
if (kvp.Value == null || !kvp.Value.Available)
|
||||
{
|
||||
invalidIds.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedEnemy == null || !cachedEnemy.Available)
|
||||
foreach (int id in invalidIds)
|
||||
{
|
||||
_enemyById.Remove(entityId);
|
||||
return false;
|
||||
_enemyById.Remove(id);
|
||||
}
|
||||
|
||||
enemy = cachedEnemy;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_enemies.Clear();
|
||||
_enemyById.Clear();
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
private void RemoveFromCache(int entityId)
|
||||
{
|
||||
_enemyById.Remove(entityId);
|
||||
|
||||
for (int i = _enemies.Count - 1; i >= 0; i--)
|
||||
{
|
||||
EntityBase cachedEnemy = _enemies[i];
|
||||
if (cachedEnemy == null || cachedEnemy.Id == entityId)
|
||||
{
|
||||
if (cachedEnemy != null)
|
||||
{
|
||||
_enemyById.Remove(cachedEnemy.Id);
|
||||
}
|
||||
|
||||
_enemies.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user