using Content.Client.Station; 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; [GenerateTypedNameReferences] 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); IoCManager.InjectDependencies(this); ObjectTypeOptions.OnItemSelected += ev => { ObjectTypeOptions.SelectId(ev.Id); RefreshObjectList(_selections[ev.Id]); }; foreach (var type in Enum.GetValues(typeof(ObjectsTabSelection))) { _selections.Add((ObjectsTabSelection)type!); ObjectTypeOptions.AddItem(Enum.GetName((ObjectsTabSelection)type)!); } RefreshObjectList(); } private void RefreshObjectList() { RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]); } private void RefreshObjectList(ObjectsTabSelection selection) { var entities = new List<(string Name, NetEntity Entity)>(); switch (selection) { case ObjectsTabSelection.Stations: entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem().Stations); break; case ObjectsTabSelection.Grids: { var query = _entityManager.AllEntityQueryEnumerator(); while (query.MoveNext(out var uid, out _, out var metadata)) { entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid))); } break; } case ObjectsTabSelection.Maps: { var query = _entityManager.AllEntityQueryEnumerator(); while (query.MoveNext(out var uid, out _, out var metadata)) { entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid))); } break; } default: throw new ArgumentOutOfRangeException(nameof(selection), selection, null); } foreach (var control in _objects) { ObjectList.RemoveChild(control); } _objects.Clear(); foreach (var (name, nent) in entities) { 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, Maps, Stations, } }