Rework entity storage to remove CullDeletedEntities.

Now we only use the dictionary for storing entities, similar to components.

This means creating/deleting entities while enumerating them will throw, but that's probably fine since GetEntities() is barely used nowadays, and we have QueueDelete().
This commit is contained in:
Pieter-Jan Briers
2021-08-25 22:47:17 +02:00
parent 310aebaee2
commit 6a0cb6a5af
2 changed files with 3 additions and 47 deletions

View File

@@ -127,7 +127,7 @@ namespace Robust.Server.GameObjects
base.TickUpdate(frameTime, histogram);
EntitiesCount.Set(AllEntities.Count);
EntitiesCount.Set(Entities.Count);
}
public uint GetLastMessageSequence(IPlayerSession session)

View File

@@ -48,8 +48,6 @@ namespace Robust.Shared.GameObjects
/// </summary>
protected readonly Dictionary<EntityUid, Entity> Entities = new();
protected readonly List<Entity> AllEntities = new();
private EntityEventBus _eventBus = null!;
protected virtual int NextEntityUid { get; set; } = (int)EntityUid.FirstUid;
@@ -124,11 +122,6 @@ namespace Robust.Shared.GameObjects
{
_componentManager.CullRemovedComponents();
}
using (histogram?.WithLabels("EntityCull").NewTimer())
{
CullDeletedEntities();
}
}
public virtual void FrameUpdate(float frameTime)
@@ -225,21 +218,7 @@ namespace Robust.Shared.GameObjects
}
/// <inheritdoc />
public IEnumerable<IEntity> GetEntities()
{
// Need to do an iterator loop to avoid issues with concurrent access.
// ReSharper disable once ForCanBeConvertedToForeach
for (var i = 0; i < AllEntities.Count; i++)
{
var entity = AllEntities[i];
if (entity.Deleted)
{
continue;
}
yield return entity;
}
}
public IEnumerable<IEntity> GetEntities() => Entities.Values;
/// <summary>
/// Shuts-down and removes given Entity. This is also broadcast to all clients.
@@ -293,6 +272,7 @@ namespace Robust.Shared.GameObjects
entity.LifeStage = EntityLifeStage.Deleted;
EntityDeleted?.Invoke(this, entity.Uid);
EventBus.RaiseEvent(EventSource.Local, new EntityDeletedMessage(entity));
Entities.Remove(entity.Uid);
}
public void QueueDeleteEntity(IEntity entity)
@@ -333,8 +313,6 @@ namespace Robust.Shared.GameObjects
{
DeleteEntity(e);
}
CullDeletedEntities();
}
/// <summary>
@@ -379,7 +357,6 @@ namespace Robust.Shared.GameObjects
// We do this after the event, so if the event throws we have not committed
Entities[entity.Uid] = entity;
AllEntities.Add(entity);
// allocate the required MetaDataComponent
_componentManager.AddComponent<MetaDataComponent>(entity);
@@ -445,27 +422,6 @@ namespace Robust.Shared.GameObjects
EntityStarted?.Invoke(this, entity.Uid);
}
private void CullDeletedEntities()
{
// Culling happens in updates.
// It doesn't matter because to-be culled entities can't be accessed.
// This should prevent most cases of "somebody is iterating while we're removing things"
for (var i = 0; i < AllEntities.Count; i++)
{
var entity = AllEntities[i];
if (!entity.Deleted)
{
continue;
}
AllEntities.RemoveSwap(i);
Entities.Remove(entity.Uid);
// Process the one we just swapped next.
i--;
}
}
#endregion Entity Management
protected void DispatchComponentMessage(NetworkComponentMessage netMsg)