diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 49713b58c42..1834bc39166 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -51,7 +51,7 @@ END TEMPLATE--> ### Other -*None yet* +* If `EntityManager.FlushEntities()` fails to delete all entities, it will now attempt to do so a second time before throwing an exception. ### Internal diff --git a/Robust.Server/GameStates/PvsSystem.DataStorage.cs b/Robust.Server/GameStates/PvsSystem.DataStorage.cs index f34f747d5b9..b9927938b68 100644 --- a/Robust.Server/GameStates/PvsSystem.DataStorage.cs +++ b/Robust.Server/GameStates/PvsSystem.DataStorage.cs @@ -300,7 +300,8 @@ private void OnEntityDeleted(Entity entity) /// private void AfterEntityFlush() { - DebugTools.Assert(EntityManager.EntityCount == 0); + if (EntityManager.EntityCount > 0) + throw new Exception("Cannot reset PVS data without first deleting all entities."); ClearPvsData(); ShrinkDataMemory(); diff --git a/Robust.Shared/GameObjects/EntityManager.cs b/Robust.Shared/GameObjects/EntityManager.cs index 7ba519b7eae..b3abee1daac 100644 --- a/Robust.Shared/GameObjects/EntityManager.cs +++ b/Robust.Shared/GameObjects/EntityManager.cs @@ -693,6 +693,25 @@ public bool Deleted([NotNullWhen(false)] EntityUid? uid) public virtual void FlushEntities() { BeforeEntityFlush?.Invoke(); + FlushEntitiesInternal(); + + if (Entities.Count != 0) + _sawmill.Error("Failed to flush all entities"); + +#if EXCEPTION_TOLERANCE + // Attempt to flush entities a second time, just in case something somehow caused an entity to be spawned + // while flushing entities + FlushEntitiesInternal(); +#endif + + if (Entities.Count != 0) + throw new Exception("Failed to flush all entities"); + + AfterEntityFlush?.Invoke(); + } + + private void FlushEntitiesInternal() + { QueuedDeletions.Clear(); QueuedDeletionsSet.Clear(); @@ -738,11 +757,6 @@ public virtual void FlushEntities() #endif } } - - if (Entities.Count != 0) - _sawmill.Error("Entities were spawned while flushing entities."); - - AfterEntityFlush?.Invoke(); } ///