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();