From 3b6adeb5ff95aabb775b84d48931c5c41843e157 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sat, 30 Sep 2023 15:12:17 +1000 Subject: [PATCH] Reduce transform resolves in `RecursiveDeleteEntity()` (#4468) --- Robust.Shared/GameObjects/EntityManager.cs | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Robust.Shared/GameObjects/EntityManager.cs b/Robust.Shared/GameObjects/EntityManager.cs index 25095bc547a..70da74cd3a9 100644 --- a/Robust.Shared/GameObjects/EntityManager.cs +++ b/Robust.Shared/GameObjects/EntityManager.cs @@ -435,8 +435,13 @@ public virtual void DeleteEntity(EntityUid? uid) // Notify all entities they are being terminated prior to detaching & deleting RecursiveFlagEntityTermination(e, meta); + var xform = TransformQuery.GetComponent(e); + TransformComponent? parentXform = null; + if (xform.ParentUid.IsValid()) + TransformQuery.Resolve(xform.ParentUid, ref parentXform); + // Then actually delete them - RecursiveDeleteEntity(e, meta); + RecursiveDeleteEntity(e, meta, xform, parentXform); } private void RecursiveFlagEntityTermination( @@ -471,11 +476,14 @@ private void RecursiveFlagEntityTermination( private void RecursiveDeleteEntity( EntityUid uid, - MetaDataComponent metadata) + MetaDataComponent metadata, + TransformComponent transform, + TransformComponent? parentXform) { + DebugTools.Assert(transform.ParentUid.IsValid() == (parentXform != null)); + DebugTools.Assert(parentXform == null || parentXform.ChildEntities.Contains(uid)); + // Note about this method: #if EXCEPTION_TOLERANCE is not used here because we're gonna it in the future... - var netEntity = GetNetEntity(uid, metadata); - var transform = TransformQuery.GetComponent(uid); // Detach the base entity to null before iterating over children // This also ensures that the entity-lookup updates don't have to be re-run for every child (which recurses up the transform hierarchy). @@ -483,7 +491,7 @@ private void RecursiveDeleteEntity( { try { - _xforms.DetachParentToNull(uid, transform); + _xforms.DetachParentToNull(uid, transform, parentXform); } catch (Exception e) { @@ -495,7 +503,10 @@ private void RecursiveDeleteEntity( { try { - RecursiveDeleteEntity(child, MetaQuery.GetComponent(child)); + var childMeta = MetaQuery.GetComponent(child); + var childXform = TransformQuery.GetComponent(child); + DebugTools.AssertEqual(childXform.ParentUid, uid); + RecursiveDeleteEntity(child, childMeta, childXform, transform); } catch(Exception e) { @@ -538,7 +549,7 @@ private void RecursiveDeleteEntity( _eventBus.OnEntityDeleted(uid); Entities.Remove(uid); // Need to get the ID above before MetadataComponent shutdown but only remove it after everything else is done. - NetEntityLookup.Remove(netEntity); + NetEntityLookup.Remove(metadata.NetEntity); } public virtual void QueueDeleteEntity(EntityUid? uid)