diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs index dcb184b308..a5c3008436 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs @@ -3,6 +3,7 @@ using Robust.Client.AutoGenerated; using Robust.Client.UserInterface; using Robust.Client.UserInterface.XAML; using Robust.Shared.Map.Components; +using Robust.Shared.Timing; namespace Content.Client.Administration.UI.Tabs.ObjectsTab; @@ -10,12 +11,20 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab; public sealed partial class ObjectsTab : Control { [Dependency] private readonly EntityManager _entityManager = default!; + [Dependency] private readonly IGameTiming _timing = default!; private readonly List _objects = new(); private List _selections = new(); public event Action? OnEntryKeyBindDown; + // Listen I could either have like 4 different event subscribers (for map / grid / station changes) and manage their lifetimes in AdminUIController + // OR + // I can do this. + private TimeSpan _updateFrequency = TimeSpan.FromSeconds(2); + + private TimeSpan _nextUpdate = TimeSpan.FromSeconds(2); + public ObjectsTab() { RobustXamlLoader.Load(this); @@ -33,12 +42,17 @@ public sealed partial class ObjectsTab : Control ObjectTypeOptions.AddItem(Enum.GetName((ObjectsTabSelection)type)!); } + RefreshObjectList(); + } + + private void RefreshObjectList() + { RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]); } private void RefreshObjectList(ObjectsTabSelection selection) { - var entities = new List(); + var entities = new List<(string Name, NetEntity Entity)>(); switch (selection) { case ObjectsTabSelection.Stations: @@ -46,20 +60,20 @@ public sealed partial class ObjectsTab : Control break; case ObjectsTabSelection.Grids: { - var query = _entityManager.AllEntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _)) + var query = _entityManager.AllEntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var metadata)) { - entities.Add(uid); + entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid))); } break; } case ObjectsTabSelection.Maps: { - var query = _entityManager.AllEntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _)) + var query = _entityManager.AllEntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var metadata)) { - entities.Add(uid); + entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid))); } break; } @@ -74,17 +88,28 @@ public sealed partial class ObjectsTab : Control _objects.Clear(); - foreach (var entity in entities) + foreach (var (name, nent) in entities) { - // TODO the server eitehr needs to send the entity's name, or it needs to ensure the client knows about the entity. - var name = _entityManager.GetComponentOrNull(entity)?.EntityName ?? "Unknown Entity"; // this should be fixed, so I CBF localizing. - var ctrl = new ObjectsTabEntry(name, entity); + var ctrl = new ObjectsTabEntry(name, nent); _objects.Add(ctrl); ObjectList.AddChild(ctrl); ctrl.OnKeyBindDown += args => OnEntryKeyBindDown?.Invoke(ctrl, args); } } + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + if (_timing.CurTime < _nextUpdate) + return; + + // I do not care for precision. + _nextUpdate = _timing.CurTime + _updateFrequency; + + RefreshObjectList(); + } + private enum ObjectsTabSelection { Grids, diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs index 98cfe53af1..c9b2cd8b57 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml.cs @@ -7,13 +7,13 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab; [GenerateTypedNameReferences] public sealed partial class ObjectsTabEntry : ContainerButton { - public EntityUid AssocEntity; + public NetEntity AssocEntity; - public ObjectsTabEntry(string name, EntityUid euid) + public ObjectsTabEntry(string name, NetEntity nent) { RobustXamlLoader.Load(this); - AssocEntity = euid; - EIDLabel.Text = euid.ToString(); + AssocEntity = nent; + EIDLabel.Text = nent.ToString(); NameLabel.Text = name; } } diff --git a/Content.Client/Station/StationSystem.cs b/Content.Client/Station/StationSystem.cs index 737a12aa60..2a3e4850cf 100644 --- a/Content.Client/Station/StationSystem.cs +++ b/Content.Client/Station/StationSystem.cs @@ -7,8 +7,7 @@ namespace Content.Client.Station; /// public sealed class StationSystem : EntitySystem { - - private readonly HashSet _stations = new(); + private readonly List<(string Name, NetEntity Entity)> _stations = new(); /// /// All stations that currently exist. @@ -16,7 +15,7 @@ public sealed class StationSystem : EntitySystem /// /// I'd have this just invoke an entity query, but we're on the client and the client barely knows about stations. /// - public IReadOnlySet Stations => _stations; + public IReadOnlyList<(string Name, NetEntity Entity)> Stations => _stations; /// public override void Initialize() @@ -27,7 +26,7 @@ public sealed class StationSystem : EntitySystem private void StationsUpdated(StationsUpdatedEvent ev) { _stations.Clear(); - // TODO this needs to be dona in component states and with the Ensure() methods - _stations.UnionWith(GetEntitySet(ev.Stations)); + // TODO this needs to be done in component states and with the Ensure() methods + _stations.AddRange(ev.Stations); } } diff --git a/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs b/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs index 0969a62940..cccd9201a2 100644 --- a/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs +++ b/Content.Client/UserInterface/Systems/Admin/AdminUIController.cs @@ -23,7 +23,10 @@ using static Robust.Client.UserInterface.Controls.BaseButton; namespace Content.Client.UserInterface.Systems.Admin; [UsedImplicitly] -public sealed class AdminUIController : UIController, IOnStateEntered, IOnStateEntered, IOnSystemChanged +public sealed class AdminUIController : UIController, + IOnStateEntered, + IOnStateEntered, + IOnSystemChanged { [Dependency] private readonly IClientAdminManager _admin = default!; [Dependency] private readonly IClientConGroupController _conGroups = default!; diff --git a/Content.Server/Station/Systems/StationSystem.cs b/Content.Server/Station/Systems/StationSystem.cs index 7aa29551b2..a0adeb2243 100644 --- a/Content.Server/Station/Systems/StationSystem.cs +++ b/Content.Server/Station/Systems/StationSystem.cs @@ -85,7 +85,7 @@ public sealed class StationSystem : EntitySystem { if (e.NewStatus == SessionStatus.Connected) { - RaiseNetworkEvent(new StationsUpdatedEvent(GetNetEntitySet(GetStationsSet())), e.Session); + RaiseNetworkEvent(new StationsUpdatedEvent(GetStationNames()), e.Session); } } @@ -93,7 +93,7 @@ public sealed class StationSystem : EntitySystem private void OnStationAdd(EntityUid uid, StationDataComponent component, ComponentStartup args) { - RaiseNetworkEvent(new StationsUpdatedEvent(GetNetEntitySet(GetStationsSet())), Filter.Broadcast()); + RaiseNetworkEvent(new StationsUpdatedEvent(GetStationNames()), Filter.Broadcast()); var metaData = MetaData(uid); RaiseLocalEvent(new StationInitializedEvent(uid)); @@ -108,7 +108,7 @@ public sealed class StationSystem : EntitySystem RemComp(grid); } - RaiseNetworkEvent(new StationsUpdatedEvent(GetNetEntitySet(GetStationsSet())), Filter.Broadcast()); + RaiseNetworkEvent(new StationsUpdatedEvent(GetStationNames()), Filter.Broadcast()); } private void OnPreGameMapLoad(PreGameMapLoad ev) @@ -468,6 +468,19 @@ public sealed class StationSystem : EntitySystem return stations; } + public List<(string Name, NetEntity Entity)> GetStationNames() + { + var stations = GetStationsSet(); + var stats = new List<(string Name, NetEntity Station)>(); + + foreach (var weh in stations) + { + stats.Add((MetaData(weh).EntityName, GetNetEntity(weh))); + } + + return stats; + } + /// /// Returns the first station that has a grid in a certain map. /// If the map has no stations, null is returned instead. diff --git a/Content.Shared/Station/StationsUpdatedEvent.cs b/Content.Shared/Station/StationsUpdatedEvent.cs index ff782b7650..488e2b8e20 100644 --- a/Content.Shared/Station/StationsUpdatedEvent.cs +++ b/Content.Shared/Station/StationsUpdatedEvent.cs @@ -5,9 +5,9 @@ namespace Content.Shared.Station; [NetSerializable, Serializable] public sealed class StationsUpdatedEvent : EntityEventArgs { - public readonly HashSet Stations; + public readonly List<(string Name, NetEntity Entity)> Stations; - public StationsUpdatedEvent(HashSet stations) + public StationsUpdatedEvent(List<(string Name, NetEntity Entity)> stations) { Stations = stations; }