From 81272b0bc85b91f4522caeb02a69db9e3ba27677 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 6 Jun 2021 22:50:31 +1000 Subject: [PATCH] Reduce rendertree allocs (#1806) --- .../EntitySystems/RenderingTreeSystem.cs | 55 ++++--------------- 1 file changed, 11 insertions(+), 44 deletions(-) diff --git a/Robust.Client/GameObjects/EntitySystems/RenderingTreeSystem.cs b/Robust.Client/GameObjects/EntitySystems/RenderingTreeSystem.cs index 33b5e2b328..74dc508dd4 100644 --- a/Robust.Client/GameObjects/EntitySystems/RenderingTreeSystem.cs +++ b/Robust.Client/GameObjects/EntitySystems/RenderingTreeSystem.cs @@ -27,6 +27,8 @@ namespace Robust.Client.GameObjects private readonly List _spriteQueue = new(); private readonly List _lightQueue = new(); + private HashSet _checkedChildren = new(); + internal DynamicTree GetSpriteTreeForMap(MapId map, GridId grid) { return _gridTrees[map][grid].SpriteTree; @@ -54,12 +56,10 @@ namespace Robust.Client.GameObjects SubscribeLocalEvent(AnythingMoved); SubscribeLocalEvent(SpriteMapChanged); - SubscribeLocalEvent(SpriteMoved); SubscribeLocalEvent(SpriteParentChanged); SubscribeLocalEvent(RemoveSprite); SubscribeLocalEvent(LightMapChanged); - SubscribeLocalEvent(LightMoved); SubscribeLocalEvent(LightParentChanged); SubscribeLocalEvent(PointLightRadiusChanged); SubscribeLocalEvent(RemoveLight); @@ -72,13 +72,20 @@ namespace Robust.Client.GameObjects private void AnythingMovedSubHandler(ITransformComponent sender) { + // To avoid doing redundant updates (and we don't need to update a grid's children ever) + if (!_checkedChildren.Add(sender.Owner.Uid) || + sender.Owner.HasComponent() || + sender.Owner.HasComponent()) return; + // This recursive search is needed, as MoveEvent is defined to not care about indirect events like children. // WHATEVER YOU DO, DON'T REPLACE THIS WITH SPAMMING EVENTS UNLESS YOU HAVE A GUARANTEE IT WON'T LAG THE GC. // (Struct-based events ok though) if (sender.Owner.TryGetComponent(out SpriteComponent? sprite)) QueueSpriteUpdate(sprite); + if (sender.Owner.TryGetComponent(out PointLightComponent? light)) QueueLightUpdate(light); + foreach (ITransformComponent child in sender.Children) { AnythingMovedSubHandler(child); @@ -96,11 +103,6 @@ namespace Robust.Client.GameObjects QueueSpriteUpdate(component); } - private void SpriteMoved(EntityUid uid, SpriteComponent component, MoveEvent args) - { - QueueSpriteUpdate(component); - } - private void SpriteParentChanged(EntityUid uid, SpriteComponent component, EntParentChangedMessage args) { QueueSpriteUpdate(component); @@ -131,22 +133,6 @@ namespace Robust.Client.GameObjects component.TreeUpdateQueued = true; _spriteQueue.Add(component); - - foreach (var child in component.Owner.Transform.Children) - { - QueueSpriteUpdate(child.Owner); - } - } - - private void QueueSpriteUpdate(IEntity entity) - { - if (!entity.TryGetComponent(out SpriteComponent? spriteComponent)) return; - QueueSpriteUpdate(spriteComponent); - - foreach (var child in entity.Transform.Children) - { - QueueSpriteUpdate(child.Owner); - } } #endregion @@ -156,11 +142,6 @@ namespace Robust.Client.GameObjects QueueLightUpdate(component); } - private void LightMoved(EntityUid uid, PointLightComponent component, MoveEvent args) - { - QueueLightUpdate(component); - } - private void LightParentChanged(EntityUid uid, PointLightComponent component, EntParentChangedMessage args) { QueueLightUpdate(component); @@ -196,22 +177,6 @@ namespace Robust.Client.GameObjects component.TreeUpdateQueued = true; _lightQueue.Add(component); - - foreach (var child in component.Owner.Transform.Children) - { - QueueLightUpdate(child.Owner); - } - } - - private void QueueLightUpdate(IEntity entity) - { - if (!entity.TryGetComponent(out PointLightComponent? lightComponent)) return; - QueueLightUpdate(lightComponent); - - foreach (var child in entity.Transform.Children) - { - QueueLightUpdate(child.Owner); - } } #endregion @@ -286,6 +251,8 @@ namespace Robust.Client.GameObjects public override void FrameUpdate(float frameTime) { + _checkedChildren.Clear(); + foreach (var sprite in _spriteQueue) { sprite.TreeUpdateQueued = false;