From 137511d8b972d25c16ac4d4f220fd4470fda632a Mon Sep 17 00:00:00 2001 From: py01 <60152240+collinlunn@users.noreply.github.com> Date: Mon, 6 Jul 2020 07:48:18 -0600 Subject: [PATCH] NodeGroup remake deferment (#1268) * Remove Unnecessary AnchorUpdate() call * NodeGroupManager * NodeGroupManager issues NodeGroup remake attempts * Code cleanup * NodeGroupManager only stores dirty groups, handles them on next frame * Removes unused NodeGroupManager dependency * Prevents OnRemoveNode from iterating over every connector after the first time * Revert "Prevents OnRemoveNode from iterating over every connector after the first time" This reverts commit c72af4b18d55192af789514f74bef893cf076fbc. * Dependancy warning fix Co-authored-by: py01 --- .../NodeContainer/NodeGroups/INodeGroup.cs | 10 +++-- .../NodeGroups/INodeGroupManager.cs | 37 +++++++++++++++++++ .../Components/NodeContainer/Nodes/Node.cs | 1 - .../EntitySystems/NodeGroupSystem.cs | 19 ++++++++++ Content.Server/ServerContentIoC.cs | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs create mode 100644 Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs index 00a1d32561..ef3dc7aaf1 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs @@ -1,4 +1,5 @@ using Content.Server.GameObjects.Components.NodeContainer.Nodes; +using Robust.Shared.IoC; using Robust.Shared.ViewVariables; using System.Collections.Generic; @@ -10,7 +11,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups /// public interface INodeGroup { - public IReadOnlyList Nodes { get; } + IReadOnlyList Nodes { get; } void AddNode(Node node); @@ -25,6 +26,8 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups void BeforeRemakeSpread(); void AfterRemakeSpread(); + + void RemakeGroup(); } [NodeGroup(NodeGroupID.Default)] @@ -49,7 +52,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups { _nodes.Remove(node); OnRemoveNode(node); - RemakeGroup(); + IoCManager.Resolve().AddDirtyNodeGroup(this); } public void CombineGroup(INodeGroup newGroup) @@ -73,7 +76,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups /// Causes all s to remake their groups. Called when a is removed /// and may have split a group in two, so multiple new groups may need to be formed. /// - private void RemakeGroup() + public void RemakeGroup() { BeforeRemake(); foreach (var node in Nodes) @@ -116,6 +119,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups public void AfterCombine() { } public void BeforeRemakeSpread() { } public void AfterRemakeSpread() { } + public void RemakeGroup() { } } } } diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs new file mode 100644 index 0000000000..762752fb78 --- /dev/null +++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups +{ + /// + /// Maintains a set of s that need to be remade with . + /// Defers remaking to reduce recalculations when a group is altered multiple times in a frame. + /// + public interface INodeGroupManager + { + /// + /// Queue up an to be remade. + /// + void AddDirtyNodeGroup(INodeGroup nodeGroup); + + void Update(float frameTime); + } + + public class NodeGroupManager : INodeGroupManager + { + private readonly HashSet _dirtyNodeGroups = new HashSet(); + + public void AddDirtyNodeGroup(INodeGroup nodeGroup) + { + _dirtyNodeGroups.Add(nodeGroup); + } + + public void Update(float frameTime) + { + foreach (var group in _dirtyNodeGroups) + { + group.RemakeGroup(); + } + _dirtyNodeGroups.Clear(); + } + } +} diff --git a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs index 82b1b25950..b0e6cefc40 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs @@ -72,7 +72,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes _deleting = true; if (Owner.TryGetComponent(out var physics)) { - AnchorUpdate(); physics.AnchoredChanged -= AnchorUpdate; } NodeGroup.RemoveNode(this); diff --git a/Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs b/Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs new file mode 100644 index 0000000000..c1c719ad22 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs @@ -0,0 +1,19 @@ +using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.IoC; + +namespace Content.Server.GameObjects.EntitySystems +{ + public class NodeGroupSystem : EntitySystem + { +#pragma warning disable 649 + [Dependency] private readonly INodeGroupManager _groupManager; +#pragma warning restore 649 + + public override void Update(float frameTime) + { + base.Update(frameTime); + _groupManager.Update(frameTime); + } + } +} diff --git a/Content.Server/ServerContentIoC.cs b/Content.Server/ServerContentIoC.cs index 4e58f6379e..5af7382d2c 100644 --- a/Content.Server/ServerContentIoC.cs +++ b/Content.Server/ServerContentIoC.cs @@ -34,6 +34,7 @@ namespace Content.Server IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); }