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 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();
}
/// <summary>
@@ -78,7 +66,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
/// </summary>
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<Node> 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() { }
}
}

View File

@@ -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<Priority, int> _drawByPriority = new Dictionary<Priority, int>();
[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<PowerConsumerComponent>());
_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() { }
}
}
}

View File

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

View File

@@ -56,7 +56,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
/// <summary>
/// Amount of charge this needs from an APC per second to function.
/// </summary>
[ViewVariables]
[ViewVariables(VVAccess.ReadWrite)]
public int Load { get => _load; set => SetLoad(value); }
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 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<IPDAUplinkManager,PDAUplinkManager>();
IoCManager.Register<INodeGroupFactory, NodeGroupFactory>();
IoCManager.Register<INodeGroupManager, NodeGroupManager>();
IoCManager.Register<IPowerNetManager, PowerNetManager>();
IoCManager.Register<INodeFactory, NodeFactory>();
IoCManager.Register<BlackboardManager, BlackboardManager>();
IoCManager.Register<ConsiderationsManager, ConsiderationsManager>();