using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Robust.Shared.IoC; using Robust.Shared.ViewVariables; using System.Collections.Generic; namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups { /// /// Maintains a collection of s, and performs operations requiring a list of /// all connected s. /// public interface INodeGroup { IReadOnlyList Nodes { get; } void AddNode(Node node); void RemoveNode(Node node); void CombineGroup(INodeGroup newGroup); void RemakeGroup(); } [NodeGroup(NodeGroupID.Default)] public class BaseNodeGroup : INodeGroup { [ViewVariables] public IReadOnlyList Nodes => _nodes; private readonly List _nodes = new List(); [ViewVariables] public int NodeCount => Nodes.Count; public static readonly INodeGroup NullGroup = new NullNodeGroup(); public void AddNode(Node node) { _nodes.Add(node); OnAddNode(node); } public void RemoveNode(Node node) { _nodes.Remove(node); OnRemoveNode(node); IoCManager.Resolve().AddDirtyNodeGroup(this); } public void CombineGroup(INodeGroup newGroup) { if (newGroup.Nodes.Count < Nodes.Count) { newGroup.CombineGroup(this); return; } foreach (var node in Nodes) { node.NodeGroup = newGroup; } } /// /// Causes all s to remake their groups. Called when a is removed /// and may have split a group in two, so multiple new groups may need to be formed. /// public void RemakeGroup() { foreach (var node in Nodes) { node.ClearNodeGroup(); } foreach (var node in Nodes) { if (node.TryAssignGroupIfNeeded()) { node.SpreadGroup(); } } } protected virtual void OnAddNode(Node node) { } protected virtual void OnRemoveNode(Node node) { } private class NullNodeGroup : INodeGroup { public IReadOnlyList Nodes => _nodes; private readonly List _nodes = new List(); public void AddNode(Node node) { } public void CombineGroup(INodeGroup newGroup) { } public void RemoveNode(Node node) { } public void RemakeGroup() { } } } }