diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs
index ef3dc7aaf1..940025d002 100644
--- a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs
+++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs
@@ -19,14 +19,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
void CombineGroup(INodeGroup newGroup);
- void BeforeCombine();
-
- void AfterCombine();
-
- void BeforeRemakeSpread();
-
- void AfterRemakeSpread();
-
void RemakeGroup();
}
@@ -62,14 +54,10 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
newGroup.CombineGroup(this);
return;
}
- BeforeCombine();
- newGroup.BeforeCombine();
foreach (var node in Nodes)
{
node.NodeGroup = newGroup;
}
- AfterCombine();
- newGroup.AfterCombine();
}
///
@@ -78,7 +66,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
///
public void RemakeGroup()
{
- BeforeRemake();
foreach (var node in Nodes)
{
node.ClearNodeGroup();
@@ -87,7 +74,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
{
if (node.TryAssignGroupIfNeeded())
{
- node.StartSpreadingGroup();
+ node.SpreadGroup();
}
}
}
@@ -96,18 +83,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
protected virtual void OnRemoveNode(Node node) { }
- protected virtual void BeforeRemake() { }
-
- protected virtual void AfterRemake() { }
-
- public virtual void BeforeCombine() { }
-
- public virtual void AfterCombine() { }
-
- public virtual void BeforeRemakeSpread() { }
-
- public virtual void AfterRemakeSpread() { }
-
private class NullNodeGroup : INodeGroup
{
public IReadOnlyList Nodes => _nodes;
@@ -115,10 +90,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
public void AddNode(Node node) { }
public void CombineGroup(INodeGroup newGroup) { }
public void RemoveNode(Node node) { }
- public void BeforeCombine() { }
- public void AfterCombine() { }
- public void BeforeRemakeSpread() { }
- public void AfterRemakeSpread() { }
public void RemakeGroup() { }
}
}
diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs
index 0bcf076251..8ebcc7794b 100644
--- a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs
+++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/PowerNetNodeGroup.cs
@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.Power.PowerNetComponents;
+using Robust.Shared.IoC;
using Robust.Shared.ViewVariables;
using System;
using System.Collections.Generic;
@@ -21,6 +22,8 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate);
void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority);
+
+ void UpdateConsumerReceivedPower();
}
[NodeGroup(NodeGroupID.HVPower, NodeGroupID.MVPower)]
@@ -38,63 +41,33 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
[ViewVariables]
private readonly Dictionary _drawByPriority = new Dictionary();
- [ViewVariables]
- private bool _supressPowerRecalculation = false;
-
public static readonly IPowerNet NullNet = new NullPowerNet();
+#pragma warning disable 649
+ [Dependency] private readonly IPowerNetManager _powerNetManager;
+#pragma warning restore 649
+
public PowerNetNodeGroup()
{
- foreach(Priority priority in Enum.GetValues(typeof(Priority)))
+ foreach (Priority priority in Enum.GetValues(typeof(Priority)))
{
_consumersByPriority.Add(priority, new List());
_drawByPriority.Add(priority, 0);
}
}
- #region BaseNodeGroup Overrides
-
protected override void SetNetConnectorNet(BasePowerNetComponent netConnectorComponent)
{
netConnectorComponent.Net = this;
}
- public override void BeforeCombine()
- {
- _supressPowerRecalculation = true;
- }
-
- public override void AfterCombine()
- {
- _supressPowerRecalculation = false;
- UpdateConsumerReceivedPower();
- }
-
- protected override void BeforeRemake()
- {
- _supressPowerRecalculation = true;
- }
-
- public override void BeforeRemakeSpread()
- {
- _supressPowerRecalculation = true;
- }
-
- public override void AfterRemakeSpread()
- {
- _supressPowerRecalculation = false;
- UpdateConsumerReceivedPower();
- }
-
- #endregion
-
#region IPowerNet Methods
public void AddSupplier(PowerSupplierComponent supplier)
{
_suppliers.Add(supplier);
_totalSupply += supplier.SupplyRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
public void RemoveSupplier(PowerSupplierComponent supplier)
@@ -102,7 +75,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
Debug.Assert(_suppliers.Contains(supplier));
_suppliers.Remove(supplier);
_totalSupply -= supplier.SupplyRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
public void UpdateSupplierSupply(PowerSupplierComponent supplier, int oldSupplyRate, int newSupplyRate)
@@ -110,14 +83,14 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
Debug.Assert(_suppliers.Contains(supplier));
_totalSupply -= oldSupplyRate;
_totalSupply += newSupplyRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
public void AddConsumer(PowerConsumerComponent consumer)
{
_consumersByPriority[consumer.Priority].Add(consumer);
_drawByPriority[consumer.Priority] += consumer.DrawRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
public void RemoveConsumer(PowerConsumerComponent consumer)
@@ -126,7 +99,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
consumer.ReceivedPower = 0;
_consumersByPriority[consumer.Priority].Remove(consumer);
_drawByPriority[consumer.Priority] -= consumer.DrawRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate)
@@ -134,7 +107,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
Debug.Assert(_consumersByPriority[consumer.Priority].Contains(consumer));
_drawByPriority[consumer.Priority] -= oldDrawRate;
_drawByPriority[consumer.Priority] += newDrawRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority)
@@ -144,20 +117,16 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
_drawByPriority[oldPriority] -= consumer.DrawRate;
_consumersByPriority[newPriority].Add(consumer);
_drawByPriority[newPriority] += consumer.DrawRate;
- UpdateConsumerReceivedPower();
+ _powerNetManager.AddDirtyPowerNet(this);
}
- private void UpdateConsumerReceivedPower()
+ public void UpdateConsumerReceivedPower()
{
- if (_supressPowerRecalculation)
- {
- return;
- }
var remainingSupply = _totalSupply;
foreach (Priority priority in Enum.GetValues(typeof(Priority)))
{
var categoryPowerDemand = _drawByPriority[priority];
- if (remainingSupply - categoryPowerDemand >= 0) //can fully power all in category
+ if (remainingSupply >= categoryPowerDemand) //can fully power all in category
{
remainingSupply -= categoryPowerDemand;
foreach (var consumer in _consumersByPriority[priority])
@@ -165,7 +134,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
consumer.ReceivedPower = consumer.DrawRate;
}
}
- else if (remainingSupply - categoryPowerDemand < 0) //cannot fully power all, split power
+ else //cannot fully power all, split power
{
var availiablePowerFraction = (float) remainingSupply / categoryPowerDemand;
remainingSupply = 0;
@@ -188,6 +157,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
public void RemoveSupplier(PowerSupplierComponent supplier) { }
public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate) { }
public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority) { }
+ public void UpdateConsumerReceivedPower() { }
}
}
}
diff --git a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs
index 630d4ff80a..6013b90a3a 100644
--- a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs
+++ b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs
@@ -87,13 +87,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
return true;
}
- public void StartSpreadingGroup()
- {
- NodeGroup.BeforeRemakeSpread();
- SpreadGroup();
- NodeGroup.AfterRemakeSpread();
- }
-
public void SpreadGroup()
{
Debug.Assert(!_needsGroup);
diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs
index 7a7cd5311f..12b9cd4963 100644
--- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs
+++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs
@@ -56,7 +56,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
///
/// Amount of charge this needs from an APC per second to function.
///
- [ViewVariables]
+ [ViewVariables(VVAccess.ReadWrite)]
public int Load { get => _load; set => SetLoad(value); }
private int _load;
diff --git a/Content.Server/GameObjects/Components/Power/PowerNetComponents/IPowerNetManager.cs b/Content.Server/GameObjects/Components/Power/PowerNetComponents/IPowerNetManager.cs
new file mode 100644
index 0000000000..125695e582
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Power/PowerNetComponents/IPowerNetManager.cs
@@ -0,0 +1,38 @@
+using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
+using System.Collections.Generic;
+
+namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
+{
+ ///
+ /// Maintains a set of s that need to be updated with .
+ /// Defers updating to reduce recalculations when a group is altered multiple times in a frame.
+ ///
+ public interface IPowerNetManager
+ {
+ ///
+ /// Queue up an to be updated.
+ ///
+ void AddDirtyPowerNet(IPowerNet powerNet);
+
+ void Update(float frameTime);
+ }
+
+ public class PowerNetManager : IPowerNetManager
+ {
+ private readonly HashSet _dirtyPowerNets = new HashSet();
+
+ public void AddDirtyPowerNet(IPowerNet powerNet)
+ {
+ _dirtyPowerNets.Add(powerNet);
+ }
+
+ public void Update(float frameTime)
+ {
+ foreach (var powerNet in _dirtyPowerNets)
+ {
+ powerNet.UpdateConsumerReceivedPower();
+ }
+ _dirtyPowerNets.Clear();
+ }
+ }
+}
diff --git a/Content.Server/GameObjects/EntitySystems/PowerNetSystem.cs b/Content.Server/GameObjects/EntitySystems/PowerNetSystem.cs
new file mode 100644
index 0000000000..74297f8670
--- /dev/null
+++ b/Content.Server/GameObjects/EntitySystems/PowerNetSystem.cs
@@ -0,0 +1,19 @@
+using Content.Server.GameObjects.Components.Power.PowerNetComponents;
+using Robust.Shared.GameObjects.Systems;
+using Robust.Shared.IoC;
+
+namespace Content.Server.GameObjects.EntitySystems
+{
+ public class PowerNetSystem : EntitySystem
+ {
+#pragma warning disable 649
+ [Dependency] private readonly IPowerNetManager _powerNetManager;
+#pragma warning restore 649
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ _powerNetManager.Update(frameTime);
+ }
+ }
+}
diff --git a/Content.Server/ServerContentIoC.cs b/Content.Server/ServerContentIoC.cs
index fba59dfaf0..e61f5ba4a7 100644
--- a/Content.Server/ServerContentIoC.cs
+++ b/Content.Server/ServerContentIoC.cs
@@ -16,6 +16,7 @@ using Content.Shared.Kitchen;
using Robust.Shared.IoC;
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
using Content.Server.GameObjects.Components.NodeContainer.Nodes;
+using Content.Server.GameObjects.Components.Power.PowerNetComponents;
namespace Content.Server
{
@@ -36,6 +37,7 @@ namespace Content.Server
IoCManager.Register();
IoCManager.Register();
IoCManager.Register();
+ IoCManager.Register();
IoCManager.Register();
IoCManager.Register();
IoCManager.Register();