Fix solution editor UI (#24004)

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.
This commit is contained in:
Pieter-Jan Briers
2024-01-13 05:52:42 +01:00
committed by GitHub
parent 2375a6cd1d
commit 3a2cd95d7f
4 changed files with 35 additions and 5 deletions

View File

@@ -34,9 +34,7 @@ namespace Content.Client.Administration.UI.ManageSolutions
public override void HandleState(EuiStateBase baseState) public override void HandleState(EuiStateBase baseState)
{ {
var state = (EditSolutionsEuiState) baseState; var state = (EditSolutionsEuiState) baseState;
_window.SetTargetEntity(state.Target); _window.SetState(state);
_window.UpdateSolutions(state.Solutions);
_window.UpdateReagents();
} }
} }
} }

View File

@@ -1,10 +1,13 @@
using Content.Shared.Administration;
using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent; using Content.Shared.Chemistry.Reagent;
using Robust.Client.AutoGenerated; using Robust.Client.AutoGenerated;
using Robust.Client.Console; using Robust.Client.Console;
using Robust.Client.Timing;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
namespace Content.Client.Administration.UI.ManageSolutions 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 IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IClientGameTiming _timing = default!;
private NetEntity _target = NetEntity.Invalid; private NetEntity _target = NetEntity.Invalid;
private string? _selectedSolution; private string? _selectedSolution;
private AddReagentWindow? _addReagentWindow; private AddReagentWindow? _addReagentWindow;
private Dictionary<string, EntityUid>? _solutions; private Dictionary<string, EntityUid>? _solutions;
private EditSolutionsEuiState? _nextState;
public EditSolutionsWindow() public EditSolutionsWindow()
{ {
@@ -327,5 +332,27 @@ namespace Content.Client.Administration.UI.ManageSolutions
SolutionOption.Select(selectedIndex); SolutionOption.Select(selectedIndex);
_selectedSolution = (string?) SolutionOption.SelectedMetadata; _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;
}
} }
} }

View File

@@ -5,6 +5,7 @@ using Content.Shared.Administration;
using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Eui; using Content.Shared.Eui;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Timing;
namespace Content.Server.Administration.UI namespace Content.Server.Administration.UI
{ {
@@ -15,6 +16,7 @@ namespace Content.Server.Administration.UI
public sealed class EditSolutionsEui : BaseEui public sealed class EditSolutionsEui : BaseEui
{ {
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
private readonly SolutionContainerSystem _solutionContainerSystem = default!; private readonly SolutionContainerSystem _solutionContainerSystem = default!;
public readonly EntityUid Target; public readonly EntityUid Target;
@@ -55,7 +57,7 @@ namespace Content.Server.Administration.UI
else else
netSolutions = null; netSolutions = null;
return new EditSolutionsEuiState(_entityManager.GetNetEntity(Target), netSolutions); return new EditSolutionsEuiState(_entityManager.GetNetEntity(Target), netSolutions, _gameTiming.CurTick);
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using Content.Shared.Eui; using Content.Shared.Eui;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Timing;
namespace Content.Shared.Administration namespace Content.Shared.Administration
{ {
@@ -8,11 +9,13 @@ namespace Content.Shared.Administration
{ {
public readonly NetEntity Target; public readonly NetEntity Target;
public readonly List<(string, NetEntity)>? Solutions; 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; Target = target;
Solutions = solutions; Solutions = solutions;
Tick = tick;
} }
} }
} }