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 <pyronetics01@gmail.com>
This commit is contained in:
py01
2020-07-06 07:48:18 -06:00
committed by GitHub
parent 3bab2fd803
commit 137511d8b9
5 changed files with 64 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.GameObjects.Components.NodeContainer.Nodes;
using Robust.Shared.IoC;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
using System.Collections.Generic; using System.Collections.Generic;
@@ -10,7 +11,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
/// </summary> /// </summary>
public interface INodeGroup public interface INodeGroup
{ {
public IReadOnlyList<Node> Nodes { get; } IReadOnlyList<Node> Nodes { get; }
void AddNode(Node node); void AddNode(Node node);
@@ -25,6 +26,8 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
void BeforeRemakeSpread(); void BeforeRemakeSpread();
void AfterRemakeSpread(); void AfterRemakeSpread();
void RemakeGroup();
} }
[NodeGroup(NodeGroupID.Default)] [NodeGroup(NodeGroupID.Default)]
@@ -49,7 +52,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
{ {
_nodes.Remove(node); _nodes.Remove(node);
OnRemoveNode(node); OnRemoveNode(node);
RemakeGroup(); IoCManager.Resolve<INodeGroupManager>().AddDirtyNodeGroup(this);
} }
public void CombineGroup(INodeGroup newGroup) public void CombineGroup(INodeGroup newGroup)
@@ -73,7 +76,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
/// Causes all <see cref="Node"/>s to remake their groups. Called when a <see cref="Node"/> is removed /// Causes all <see cref="Node"/>s to remake their groups. Called when a <see cref="Node"/> is removed
/// and may have split a group in two, so multiple new groups may need to be formed. /// and may have split a group in two, so multiple new groups may need to be formed.
/// </summary> /// </summary>
private void RemakeGroup() public void RemakeGroup()
{ {
BeforeRemake(); BeforeRemake();
foreach (var node in Nodes) foreach (var node in Nodes)
@@ -116,6 +119,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
public void AfterCombine() { } public void AfterCombine() { }
public void BeforeRemakeSpread() { } public void BeforeRemakeSpread() { }
public void AfterRemakeSpread() { } public void AfterRemakeSpread() { }
public void RemakeGroup() { }
} }
} }
} }

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
{
/// <summary>
/// Maintains a set of <see cref="INodeGroup"/>s that need to be remade with <see cref="INodeGroup.RemakeGroup"/>.
/// Defers remaking to reduce recalculations when a group is altered multiple times in a frame.
/// </summary>
public interface INodeGroupManager
{
/// <summary>
/// Queue up an <see cref="INodeGroup"/> to be remade.
/// </summary>
void AddDirtyNodeGroup(INodeGroup nodeGroup);
void Update(float frameTime);
}
public class NodeGroupManager : INodeGroupManager
{
private readonly HashSet<INodeGroup> _dirtyNodeGroups = new HashSet<INodeGroup>();
public void AddDirtyNodeGroup(INodeGroup nodeGroup)
{
_dirtyNodeGroups.Add(nodeGroup);
}
public void Update(float frameTime)
{
foreach (var group in _dirtyNodeGroups)
{
group.RemakeGroup();
}
_dirtyNodeGroups.Clear();
}
}
}

View File

@@ -72,7 +72,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
_deleting = true; _deleting = true;
if (Owner.TryGetComponent<PhysicsComponent>(out var physics)) if (Owner.TryGetComponent<PhysicsComponent>(out var physics))
{ {
AnchorUpdate();
physics.AnchoredChanged -= AnchorUpdate; physics.AnchoredChanged -= AnchorUpdate;
} }
NodeGroup.RemoveNode(this); NodeGroup.RemoveNode(this);

View File

@@ -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);
}
}
}

View File

@@ -34,6 +34,7 @@ namespace Content.Server
IoCManager.Register<RecipeManager, RecipeManager>(); IoCManager.Register<RecipeManager, RecipeManager>();
IoCManager.Register<IPDAUplinkManager,PDAUplinkManager>(); IoCManager.Register<IPDAUplinkManager,PDAUplinkManager>();
IoCManager.Register<INodeGroupFactory, NodeGroupFactory>(); IoCManager.Register<INodeGroupFactory, NodeGroupFactory>();
IoCManager.Register<INodeGroupManager, NodeGroupManager>();
IoCManager.Register<INodeFactory, NodeFactory>(); IoCManager.Register<INodeFactory, NodeFactory>();
IoCManager.Register<BlackboardManager, BlackboardManager>(); IoCManager.Register<BlackboardManager, BlackboardManager>();
} }