From a91aed082f9799d9f88aafd70e0c7a71aeee6c81 Mon Sep 17 00:00:00 2001 From: wrexbe <81056464+wrexbe@users.noreply.github.com> Date: Mon, 16 May 2022 16:52:37 -0700 Subject: [PATCH] Cleaning device net system (#8153) --- .../Systems/DeviceNetworkSystem.cs | 232 ++++++++---------- 1 file changed, 102 insertions(+), 130 deletions(-) diff --git a/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs b/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs index ad1375e879..e497528179 100644 --- a/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs @@ -3,6 +3,8 @@ using Content.Shared.DeviceNetwork; using JetBrains.Annotations; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Utility; +using System.Buffers; using System.Diagnostics.CodeAnalysis; using static Content.Server.DeviceNetwork.Components.DeviceNetworkComponent; @@ -19,7 +21,7 @@ namespace Content.Server.DeviceNetwork.Systems [Dependency] private readonly IPrototypeManager _protoMan = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; - private readonly Dictionary _networks = new(); + private readonly DeviceNet[] _networks = new DeviceNet[4]; // Number of ConnectionType enum values private readonly Queue _packets = new(); public override void Initialize() @@ -28,16 +30,17 @@ namespace Content.Server.DeviceNetwork.Systems SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnNetworkShutdown); + + InitNetwork(ConnectionType.Private); + InitNetwork(ConnectionType.Wired); + InitNetwork(ConnectionType.Wireless); + InitNetwork(ConnectionType.Apc); } public override void Update(float frameTime) { - base.Update(frameTime); - - while (_packets.Count > 0) + while (_packets.TryDequeue(out var packet)) { - var packet = _packets.Dequeue(); - SendPacket(packet); } } @@ -64,6 +67,9 @@ namespace Content.Server.DeviceNetwork.Systems _packets.Enqueue(new DeviceNetworkPacketEvent(device.DeviceNetId, address, frequency.Value, device.Address, uid, data)); } + private void InitNetwork(ConnectionType connectionType) => + _networks[(int) connectionType] = new(connectionType, _random); + /// /// Automatically attempt to connect some devices when a map starts. /// @@ -87,12 +93,15 @@ namespace Content.Server.DeviceNetwork.Systems ConnectDevice(uid, device); } + private DeviceNet GetNetwork(ConnectionType connectionType) => + _networks[(int) connectionType]; + /// /// Automatically disconnect when an entity with a DeviceNetworkComponent shuts down. /// private void OnNetworkShutdown(EntityUid uid, DeviceNetworkComponent component, ComponentShutdown args) { - DisconnectDevice(uid, component, false); + GetNetwork(component.DeviceNetId).Remove(component); } /// @@ -104,13 +113,7 @@ namespace Content.Server.DeviceNetwork.Systems if (!Resolve(uid, ref device, false)) return false; - if (!_networks.TryGetValue(device.DeviceNetId, out var network)) - { - network = new(device.DeviceNetId, _random); - _networks[device.DeviceNetId] = network; - } - - return network.Add(device); + return GetNetwork(device.DeviceNetId).Add(device); } /// @@ -125,82 +128,115 @@ namespace Content.Server.DeviceNetwork.Systems if (preventAutoConnect) device.AutoConnect = false; - if (!_networks.TryGetValue(device.DeviceNetId, out var network)) - { - return false; - } - - if (!network.Remove(device)) - return false; - - if (network.Devices.Count == 0) - _networks.Remove(device.DeviceNetId); - - return true; + return GetNetwork(device.DeviceNetId).Remove(device); } - #region Get Device - /// - /// Get a list of devices listening on a given frequency on some network. - /// - private HashSet GetListeningDevices(ConnectionType netId, uint frequency) + public void SetReceiveFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null) { - if (_networks.TryGetValue(netId, out var network) && network.ListeningDevices.TryGetValue(frequency, out var devices)) - return devices; + if (!Resolve(uid, ref device, false)) + return; - return new(); + if (device.ReceiveFrequency == frequency) return; + + var deviceNet = GetNetwork(device.DeviceNetId); + deviceNet.Remove(device); + device.ReceiveFrequency = frequency; + deviceNet.Add(device); } - /// - /// Get a list of devices listening for ANY transmission on a given frequency, rather than just broadcast & addressed events. - /// - private HashSet GetRecieveAllDevices(ConnectionType netId, uint frequency) + public void SetTransmitFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null) { - if (_networks.TryGetValue(netId, out var network) && network.ReceiveAllDevices.TryGetValue(frequency, out var devices)) - return devices; + if (Resolve(uid, ref device, false)) + device.TransmitFrequency = frequency; + } - return new(); + public void SetReceiveAll(EntityUid uid, bool receiveAll, DeviceNetworkComponent? device = null) + { + if (!Resolve(uid, ref device, false)) + return; + + if (device.ReceiveAll == receiveAll) return; + + var deviceNet = GetNetwork(device.DeviceNetId); + deviceNet.Remove(device); + device.ReceiveAll = receiveAll; + deviceNet.Add(device); + } + + public void SetAddress(EntityUid uid, string address, DeviceNetworkComponent? device = null) + { + if (!Resolve(uid, ref device, false)) + return; + + if (device.Address == address && device.CustomAddress == true) return; + + var deviceNet = GetNetwork(device.DeviceNetId); + deviceNet.Remove(device); + device.CustomAddress = true; + device.Address = address; + deviceNet.Add(device); + } + + public void RandomizeAddress(EntityUid uid, DeviceNetworkComponent? device = null) + { + if (!Resolve(uid, ref device, false)) + return; + var deviceNet = GetNetwork(device.DeviceNetId); + deviceNet.Remove(device); + device.CustomAddress = false; + device.Address = ""; + deviceNet.Add(device); } /// /// Try to find a device on a network using its address. /// - private bool TryGetDevice(ConnectionType netId, string address, [NotNullWhen(true)] out DeviceNetworkComponent? device) - { - if (!_networks.TryGetValue(netId, out var network)) - { - device = null; - return false; - } + private bool TryGetDevice(ConnectionType netId, string address, [NotNullWhen(true)] out DeviceNetworkComponent? device) => + GetNetwork(netId).Devices.TryGetValue(address, out device); - return network.Devices.TryGetValue(address, out device); - } - #endregion - - #region Packet Sending private void SendPacket(DeviceNetworkPacketEvent packet) { - HashSet recipients; - + var network = GetNetwork(packet.NetId); if (packet.Address == null) { - // Broadcast to all listening devices - recipients = GetListeningDevices(packet.NetId, packet.Frequency); + if (network.ListeningDevices.TryGetValue(packet.Frequency, out var devices)) + { + var deviceCopy = ArrayPool.Shared.Rent(devices.Count); + devices.CopyTo(deviceCopy); + SendToConnections(deviceCopy.AsSpan(0, devices.Count), packet); + ArrayPool.Shared.Return(deviceCopy); + } } else { - // Add devices listening to all messages - recipients = new(GetRecieveAllDevices(packet.NetId, packet.Frequency)); - - // add the intended recipient (if they are even listening). - if (TryGetDevice(packet.NetId, packet.Address, out var device) && device.ReceiveFrequency == packet.Frequency) - recipients.Add(device); + var totalDevices = 0; + var hasTargetedDevice = false; + if (network.ReceiveAllDevices.TryGetValue(packet.Frequency, out var devices)) + { + totalDevices += devices.Count; + } + if (TryGetDevice(packet.NetId, packet.Address, out var device) && + !device.ReceiveAll && + device.ReceiveFrequency == packet.Frequency) + { + totalDevices += 1; + hasTargetedDevice = true; + } + var deviceCopy = ArrayPool.Shared.Rent(totalDevices); + if (devices != null) + { + devices.CopyTo(deviceCopy); + } + if (hasTargetedDevice) + { + deviceCopy[totalDevices - 1] = device!; + } + SendToConnections(deviceCopy.AsSpan(0, totalDevices), packet); + ArrayPool.Shared.Return(deviceCopy); } - - SendToConnections(recipients, packet); } - private void SendToConnections(HashSet connections, DeviceNetworkPacketEvent packet) + private void SendToConnections(ReadOnlySpan connections, DeviceNetworkPacketEvent packet) { var xform = Transform(packet.Sender); @@ -219,70 +255,6 @@ namespace Content.Server.DeviceNetwork.Systems beforeEv.Uncancel(); } } - #endregion - - #region Component Setter Functions - public void SetReceiveFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null) - { - if (!Resolve(uid, ref device, false)) - return; - - if (device.ReceiveFrequency == frequency) - return; - - if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.UpdateReceiveFrequency(device.Address, frequency)) - device.ReceiveFrequency = frequency; - } - - public void SetTransmitFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null) - { - if (Resolve(uid, ref device, false)) - device.TransmitFrequency = frequency; - } - - public void SetReceiveAll(EntityUid uid, bool receiveAll, DeviceNetworkComponent? device = null) - { - if (!Resolve(uid, ref device, false)) - return; - - if (device.ReceiveAll == receiveAll) - return; - - if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.UpdateReceiveAll(device.Address, receiveAll)) - device.ReceiveAll = receiveAll; - } - - public void SetAddress(EntityUid uid, string address, DeviceNetworkComponent? device = null) - { - if (!Resolve(uid, ref device, false)) - return; - - if (device.Address == address) - { - device.CustomAddress = true; - return; - } - - if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.UpdateAddress(device.Address, address)) - { - device.Address = address; - device.CustomAddress = true; - } - } - - public void RandomizeAddress(EntityUid uid, string address, DeviceNetworkComponent? device = null) - { - if (!Resolve(uid, ref device, false)) - return; - - if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.RandomizeAddress(device.Address, address)) - { - var prefix = string.IsNullOrWhiteSpace(device.Prefix) ? null : Loc.GetString(device.Prefix); - device.Address = $"{prefix}{_random.Next():x}"; - device.CustomAddress = false; - } - } - #endregion } ///