]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix solution editor UI (#24004)
authorPieter-Jan Briers <pieterjan.briers+git@gmail.com>
Sat, 13 Jan 2024 04:52:42 +0000 (05:52 +0100)
committerGitHub <noreply@github.com>
Sat, 13 Jan 2024 04:52:42 +0000 (15:52 +1100)
Fixes #23645

The problem is that the solution editor UI is an EUI, so the UI updates before the game states are applied.

A correct fix would be to move it to a BUI in some way, but that's a little involved as we don't really have pre-existing code that uses BUIs in a manner good for this. I decided against this because I realized we'd want to have more tools similar to this and tbh I kinda figured integrating it with VV would be a better fix instead, so...

This is a bad workaround to manually synchronize the UI updates against game timing. It's not pretty but it works.

Content.Client/Administration/UI/ManageSolutions/EditSolutionsEui.cs
Content.Client/Administration/UI/ManageSolutions/EditSolutionsWindow.xaml.cs
Content.Server/Administration/UI/EditSolutionsEui.cs
Content.Shared/Administration/EditSolutionsEuiState.cs

index 4bee78fa090dd1d038802fac162014a6c98c5a6b..625dafa23bc8ac26ade196873c568f7c3a3e0655 100644 (file)
@@ -34,9 +34,7 @@ namespace Content.Client.Administration.UI.ManageSolutions
         public override void HandleState(EuiStateBase baseState)
         {
             var state = (EditSolutionsEuiState) baseState;
-            _window.SetTargetEntity(state.Target);
-            _window.UpdateSolutions(state.Solutions);
-            _window.UpdateReagents();
+            _window.SetState(state);
         }
     }
 }
index ecc26d60265c2fc13c4b1297763d14c785b0ef92..812f2de3a0456d38eb90802e6c7233a8edf18a1f 100644 (file)
@@ -1,10 +1,13 @@
+using Content.Shared.Administration;
 using Content.Shared.Chemistry.Components;
 using Content.Shared.Chemistry.Reagent;
 using Robust.Client.AutoGenerated;
 using Robust.Client.Console;
+using Robust.Client.Timing;
 using Robust.Client.UserInterface.Controls;
 using Robust.Client.UserInterface.CustomControls;
 using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Timing;
 
 namespace Content.Client.Administration.UI.ManageSolutions
 {
@@ -16,11 +19,13 @@ namespace Content.Client.Administration.UI.ManageSolutions
     {
         [Dependency] private readonly IClientConsoleHost _consoleHost = default!;
         [Dependency] private readonly IEntityManager _entityManager = default!;
+        [Dependency] private readonly IClientGameTiming _timing = default!;
 
         private NetEntity _target = NetEntity.Invalid;
         private string? _selectedSolution;
         private AddReagentWindow? _addReagentWindow;
         private Dictionary<string, EntityUid>? _solutions;
+        private EditSolutionsEuiState? _nextState;
 
         public EditSolutionsWindow()
         {
@@ -327,5 +332,27 @@ namespace Content.Client.Administration.UI.ManageSolutions
             SolutionOption.Select(selectedIndex);
             _selectedSolution = (string?) SolutionOption.SelectedMetadata;
         }
+
+        protected override void FrameUpdate(FrameEventArgs args)
+        {
+            // TODO: THIS IS FUCKING TERRIBLE.
+            // Ok so the problem is that this shouldn't be via an EUI at all. Why?
+            // The EUI update notification comes in *before* the game state it updates from.
+            // So the UI doesn't update properly. Heck.
+            // I didn't wanna completely rewrite this thing to work properly so instead you get terrible hacks.
+
+            if (_nextState != null && _timing.LastRealTick >= _nextState.Tick)
+            {
+                SetTargetEntity(_nextState.Target);
+                UpdateSolutions(_nextState.Solutions);
+                UpdateReagents();
+                _nextState = null;
+            }
+        }
+
+        public void SetState(EditSolutionsEuiState state)
+        {
+            _nextState = state;
+        }
     }
 }
index 228463d5ce89ae92cdfec426a701b04ae6722eaf..2a78a27bc03f9afa02f130e5198b8843ab324bab 100644 (file)
@@ -5,6 +5,7 @@ using Content.Shared.Administration;
 using Content.Shared.Chemistry.Components.SolutionManager;
 using Content.Shared.Eui;
 using JetBrains.Annotations;
+using Robust.Shared.Timing;
 
 namespace Content.Server.Administration.UI
 {
@@ -15,6 +16,7 @@ namespace Content.Server.Administration.UI
     public sealed class EditSolutionsEui : BaseEui
     {
         [Dependency] private readonly IEntityManager _entityManager = default!;
+        [Dependency] private readonly IGameTiming _gameTiming = default!;
         private readonly SolutionContainerSystem _solutionContainerSystem = default!;
         public readonly EntityUid Target;
 
@@ -55,7 +57,7 @@ namespace Content.Server.Administration.UI
             else
                 netSolutions = null;
 
-            return new EditSolutionsEuiState(_entityManager.GetNetEntity(Target), netSolutions);
+            return new EditSolutionsEuiState(_entityManager.GetNetEntity(Target), netSolutions, _gameTiming.CurTick);
         }
     }
 }
index 12fae34962103db66265d30abe3d11802d39922c..636a57c520c07e1fa41804ec25f29d4ec1cfb1cc 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Eui;
 using Robust.Shared.Serialization;
+using Robust.Shared.Timing;
 
 namespace Content.Shared.Administration
 {
@@ -8,11 +9,13 @@ namespace Content.Shared.Administration
     {
         public readonly NetEntity Target;
         public readonly List<(string, NetEntity)>? Solutions;
+        public readonly GameTick Tick;
 
-        public EditSolutionsEuiState(NetEntity target, List<(string, NetEntity)>? solutions)
+        public EditSolutionsEuiState(NetEntity target, List<(string, NetEntity)>? solutions, GameTick tick)
         {
             Target = target;
             Solutions = solutions;
+            Tick = tick;
         }
     }
 }