Powernet Recalculation simplification (#1427)

Co-authored-by: py01 <pyronetics01@gmail.com>
This commit is contained in:
py01
2020-07-26 04:14:03 -06:00
committed by GitHub
parent 96ec60adab
commit fbbe43fff8
7 changed files with 80 additions and 87 deletions

View File

@@ -19,14 +19,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
void CombineGroup(INodeGroup newGroup); void CombineGroup(INodeGroup newGroup);
void BeforeCombine();
void AfterCombine();
void BeforeRemakeSpread();
void AfterRemakeSpread();
void RemakeGroup(); void RemakeGroup();
} }
@@ -62,14 +54,10 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
newGroup.CombineGroup(this); newGroup.CombineGroup(this);
return; return;
} }
BeforeCombine();
newGroup.BeforeCombine();
foreach (var node in Nodes) foreach (var node in Nodes)
{ {
node.NodeGroup = newGroup; node.NodeGroup = newGroup;
} }
AfterCombine();
newGroup.AfterCombine();
} }
/// <summary> /// <summary>
@@ -78,7 +66,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
/// </summary> /// </summary>
public void RemakeGroup() public void RemakeGroup()
{ {
BeforeRemake();
foreach (var node in Nodes) foreach (var node in Nodes)
{ {
node.ClearNodeGroup(); node.ClearNodeGroup();
@@ -87,7 +74,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
{ {
if (node.TryAssignGroupIfNeeded()) 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 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 private class NullNodeGroup : INodeGroup
{ {
public IReadOnlyList<Node> Nodes => _nodes; public IReadOnlyList<Node> Nodes => _nodes;
@@ -115,10 +90,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
public void AddNode(Node node) { } public void AddNode(Node node) { }
public void CombineGroup(INodeGroup newGroup) { } public void CombineGroup(INodeGroup newGroup) { }
public void RemoveNode(Node node) { } public void RemoveNode(Node node) { }
public void BeforeCombine() { }
public void AfterCombine() { }
public void BeforeRemakeSpread() { }
public void AfterRemakeSpread() { }
public void RemakeGroup() { } public void RemakeGroup() { }
} }
} }

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.Power.PowerNetComponents; using Content.Server.GameObjects.Components.Power.PowerNetComponents;
using Robust.Shared.IoC;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -21,6 +22,8 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate); void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate);
void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority); void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority);
void UpdateConsumerReceivedPower();
} }
[NodeGroup(NodeGroupID.HVPower, NodeGroupID.MVPower)] [NodeGroup(NodeGroupID.HVPower, NodeGroupID.MVPower)]
@@ -38,63 +41,33 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
[ViewVariables] [ViewVariables]
private readonly Dictionary<Priority, int> _drawByPriority = new Dictionary<Priority, int>(); private readonly Dictionary<Priority, int> _drawByPriority = new Dictionary<Priority, int>();
[ViewVariables]
private bool _supressPowerRecalculation = false;
public static readonly IPowerNet NullNet = new NullPowerNet(); public static readonly IPowerNet NullNet = new NullPowerNet();
#pragma warning disable 649
[Dependency] private readonly IPowerNetManager _powerNetManager;
#pragma warning restore 649
public PowerNetNodeGroup() public PowerNetNodeGroup()
{ {
foreach(Priority priority in Enum.GetValues(typeof(Priority))) foreach (Priority priority in Enum.GetValues(typeof(Priority)))
{ {
_consumersByPriority.Add(priority, new List<PowerConsumerComponent>()); _consumersByPriority.Add(priority, new List<PowerConsumerComponent>());
_drawByPriority.Add(priority, 0); _drawByPriority.Add(priority, 0);
} }
} }
#region BaseNodeGroup Overrides
protected override void SetNetConnectorNet(BasePowerNetComponent netConnectorComponent) protected override void SetNetConnectorNet(BasePowerNetComponent netConnectorComponent)
{ {
netConnectorComponent.Net = this; 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 #region IPowerNet Methods
public void AddSupplier(PowerSupplierComponent supplier) public void AddSupplier(PowerSupplierComponent supplier)
{ {
_suppliers.Add(supplier); _suppliers.Add(supplier);
_totalSupply += supplier.SupplyRate; _totalSupply += supplier.SupplyRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
public void RemoveSupplier(PowerSupplierComponent supplier) public void RemoveSupplier(PowerSupplierComponent supplier)
@@ -102,7 +75,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
Debug.Assert(_suppliers.Contains(supplier)); Debug.Assert(_suppliers.Contains(supplier));
_suppliers.Remove(supplier); _suppliers.Remove(supplier);
_totalSupply -= supplier.SupplyRate; _totalSupply -= supplier.SupplyRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
public void UpdateSupplierSupply(PowerSupplierComponent supplier, int oldSupplyRate, int newSupplyRate) 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)); Debug.Assert(_suppliers.Contains(supplier));
_totalSupply -= oldSupplyRate; _totalSupply -= oldSupplyRate;
_totalSupply += newSupplyRate; _totalSupply += newSupplyRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
public void AddConsumer(PowerConsumerComponent consumer) public void AddConsumer(PowerConsumerComponent consumer)
{ {
_consumersByPriority[consumer.Priority].Add(consumer); _consumersByPriority[consumer.Priority].Add(consumer);
_drawByPriority[consumer.Priority] += consumer.DrawRate; _drawByPriority[consumer.Priority] += consumer.DrawRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
public void RemoveConsumer(PowerConsumerComponent consumer) public void RemoveConsumer(PowerConsumerComponent consumer)
@@ -126,7 +99,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
consumer.ReceivedPower = 0; consumer.ReceivedPower = 0;
_consumersByPriority[consumer.Priority].Remove(consumer); _consumersByPriority[consumer.Priority].Remove(consumer);
_drawByPriority[consumer.Priority] -= consumer.DrawRate; _drawByPriority[consumer.Priority] -= consumer.DrawRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate) 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)); Debug.Assert(_consumersByPriority[consumer.Priority].Contains(consumer));
_drawByPriority[consumer.Priority] -= oldDrawRate; _drawByPriority[consumer.Priority] -= oldDrawRate;
_drawByPriority[consumer.Priority] += newDrawRate; _drawByPriority[consumer.Priority] += newDrawRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority) public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority)
@@ -144,20 +117,16 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
_drawByPriority[oldPriority] -= consumer.DrawRate; _drawByPriority[oldPriority] -= consumer.DrawRate;
_consumersByPriority[newPriority].Add(consumer); _consumersByPriority[newPriority].Add(consumer);
_drawByPriority[newPriority] += consumer.DrawRate; _drawByPriority[newPriority] += consumer.DrawRate;
UpdateConsumerReceivedPower(); _powerNetManager.AddDirtyPowerNet(this);
} }
private void UpdateConsumerReceivedPower() public void UpdateConsumerReceivedPower()
{ {
if (_supressPowerRecalculation)
{
return;
}
var remainingSupply = _totalSupply; var remainingSupply = _totalSupply;
foreach (Priority priority in Enum.GetValues(typeof(Priority))) foreach (Priority priority in Enum.GetValues(typeof(Priority)))
{ {
var categoryPowerDemand = _drawByPriority[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; remainingSupply -= categoryPowerDemand;
foreach (var consumer in _consumersByPriority[priority]) foreach (var consumer in _consumersByPriority[priority])
@@ -165,7 +134,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
consumer.ReceivedPower = consumer.DrawRate; 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; var availiablePowerFraction = (float) remainingSupply / categoryPowerDemand;
remainingSupply = 0; remainingSupply = 0;
@@ -188,6 +157,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
public void RemoveSupplier(PowerSupplierComponent supplier) { } public void RemoveSupplier(PowerSupplierComponent supplier) { }
public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate) { } public void UpdateConsumerDraw(PowerConsumerComponent consumer, int oldDrawRate, int newDrawRate) { }
public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority) { } public void UpdateConsumerPriority(PowerConsumerComponent consumer, Priority oldPriority, Priority newPriority) { }
public void UpdateConsumerReceivedPower() { }
} }
} }
} }

View File

@@ -87,13 +87,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
return true; return true;
} }
public void StartSpreadingGroup()
{
NodeGroup.BeforeRemakeSpread();
SpreadGroup();
NodeGroup.AfterRemakeSpread();
}
public void SpreadGroup() public void SpreadGroup()
{ {
Debug.Assert(!_needsGroup); Debug.Assert(!_needsGroup);

View File

@@ -56,7 +56,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
/// <summary> /// <summary>
/// Amount of charge this needs from an APC per second to function. /// Amount of charge this needs from an APC per second to function.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables(VVAccess.ReadWrite)]
public int Load { get => _load; set => SetLoad(value); } public int Load { get => _load; set => SetLoad(value); }
private int _load; private int _load;

View File

@@ -0,0 +1,38 @@
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
using System.Collections.Generic;
namespace Content.Server.GameObjects.Components.Power.PowerNetComponents
{
/// <summary>
/// Maintains a set of <see cref="IPowerNet"/>s that need to be updated with <see cref="IPowerNet.UpdateConsumerReceivedPower"/>.
/// Defers updating to reduce recalculations when a group is altered multiple times in a frame.
/// </summary>
public interface IPowerNetManager
{
/// <summary>
/// Queue up an <see cref="IPowerNet"/> to be updated.
/// </summary>
void AddDirtyPowerNet(IPowerNet powerNet);
void Update(float frameTime);
}
public class PowerNetManager : IPowerNetManager
{
private readonly HashSet<IPowerNet> _dirtyPowerNets = new HashSet<IPowerNet>();
public void AddDirtyPowerNet(IPowerNet powerNet)
{
_dirtyPowerNets.Add(powerNet);
}
public void Update(float frameTime)
{
foreach (var powerNet in _dirtyPowerNets)
{
powerNet.UpdateConsumerReceivedPower();
}
_dirtyPowerNets.Clear();
}
}
}

View File

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

View File

@@ -16,6 +16,7 @@ using Content.Shared.Kitchen;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.GameObjects.Components.NodeContainer.Nodes;
using Content.Server.GameObjects.Components.Power.PowerNetComponents;
namespace Content.Server namespace Content.Server
{ {
@@ -36,6 +37,7 @@ namespace Content.Server
IoCManager.Register<IPDAUplinkManager,PDAUplinkManager>(); IoCManager.Register<IPDAUplinkManager,PDAUplinkManager>();
IoCManager.Register<INodeGroupFactory, NodeGroupFactory>(); IoCManager.Register<INodeGroupFactory, NodeGroupFactory>();
IoCManager.Register<INodeGroupManager, NodeGroupManager>(); IoCManager.Register<INodeGroupManager, NodeGroupManager>();
IoCManager.Register<IPowerNetManager, PowerNetManager>();
IoCManager.Register<INodeFactory, NodeFactory>(); IoCManager.Register<INodeFactory, NodeFactory>();
IoCManager.Register<BlackboardManager, BlackboardManager>(); IoCManager.Register<BlackboardManager, BlackboardManager>();
IoCManager.Register<ConsiderationsManager, ConsiderationsManager>(); IoCManager.Register<ConsiderationsManager, ConsiderationsManager>();