Improve lathe queue performance (#38583)

* Use an actual Queue

* Store ProtoIds instead of prototypes

* Network as NetListAsArray

* Remove Serializable & NetSerializable from LatheRecipePrototype

* Convert CurrentlyProducing too

* No point using NetListAsArray<T> if you're going to .ToArray() it anyways.

---------

Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
This commit is contained in:
Tayrtahn
2025-06-26 18:08:01 -04:00
committed by GitHub
parent cc2a89ed86
commit 3a8974f574
5 changed files with 25 additions and 19 deletions

View File

@@ -223,13 +223,14 @@ public sealed partial class LatheMenu : DefaultWindow
/// Populates the build queue list with all queued items /// Populates the build queue list with all queued items
/// </summary> /// </summary>
/// <param name="queue"></param> /// <param name="queue"></param>
public void PopulateQueueList(List<LatheRecipePrototype> queue) public void PopulateQueueList(IReadOnlyCollection<ProtoId<LatheRecipePrototype>> queue)
{ {
QueueList.DisposeAllChildren(); QueueList.DisposeAllChildren();
var idx = 1; var idx = 1;
foreach (var recipe in queue) foreach (var recipeProto in queue)
{ {
var recipe = _prototypeManager.Index(recipeProto);
var queuedRecipeBox = new BoxContainer(); var queuedRecipeBox = new BoxContainer();
queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal; queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
@@ -243,12 +244,14 @@ public sealed partial class LatheMenu : DefaultWindow
} }
} }
public void SetQueueInfo(LatheRecipePrototype? recipe) public void SetQueueInfo(ProtoId<LatheRecipePrototype>? recipeProto)
{ {
FabricatingContainer.Visible = recipe != null; FabricatingContainer.Visible = recipeProto != null;
if (recipe == null) if (recipeProto == null)
return; return;
var recipe = _prototypeManager.Index(recipeProto.Value);
FabricatingDisplayContainer.Children.Clear(); FabricatingDisplayContainer.Children.Clear();
FabricatingDisplayContainer.AddChild(GetRecipeDisplayControl(recipe)); FabricatingDisplayContainer.AddChild(GetRecipeDisplayControl(recipe));

View File

@@ -183,7 +183,7 @@ namespace Content.Server.Lathe
_materialStorage.TryChangeMaterialAmount(uid, mat, adjustedAmount); _materialStorage.TryChangeMaterialAmount(uid, mat, adjustedAmount);
} }
component.Queue.Add(recipe); component.Queue.Enqueue(recipe);
return true; return true;
} }
@@ -195,8 +195,8 @@ namespace Content.Server.Lathe
if (component.CurrentRecipe != null || component.Queue.Count <= 0 || !this.IsPowered(uid, EntityManager)) if (component.CurrentRecipe != null || component.Queue.Count <= 0 || !this.IsPowered(uid, EntityManager))
return false; return false;
var recipe = component.Queue.First(); var recipeProto = component.Queue.Dequeue();
component.Queue.RemoveAt(0); var recipe = _proto.Index(recipeProto);
var time = _reagentSpeed.ApplySpeed(uid, recipe.CompleteTime) * component.TimeMultiplier; var time = _reagentSpeed.ApplySpeed(uid, recipe.CompleteTime) * component.TimeMultiplier;
@@ -226,13 +226,14 @@ namespace Content.Server.Lathe
if (comp.CurrentRecipe != null) if (comp.CurrentRecipe != null)
{ {
if (comp.CurrentRecipe.Result is { } resultProto) var currentRecipe = _proto.Index(comp.CurrentRecipe.Value);
if (currentRecipe.Result is { } resultProto)
{ {
var result = Spawn(resultProto, Transform(uid).Coordinates); var result = Spawn(resultProto, Transform(uid).Coordinates);
_stack.TryMergeToContacts(result); _stack.TryMergeToContacts(result);
} }
if (comp.CurrentRecipe.ResultReagents is { } resultReagents && if (currentRecipe.ResultReagents is { } resultReagents &&
comp.ReagentOutputSlotId is { } slotId) comp.ReagentOutputSlotId is { } slotId)
{ {
var toAdd = new Solution( var toAdd = new Solution(
@@ -269,9 +270,11 @@ namespace Content.Server.Lathe
if (!Resolve(uid, ref component)) if (!Resolve(uid, ref component))
return; return;
var producing = component.CurrentRecipe ?? component.Queue.FirstOrDefault(); var producing = component.CurrentRecipe;
if (producing == null && component.Queue.TryPeek(out var next))
producing = next;
var state = new LatheUpdateState(GetAvailableRecipes(uid, component), component.Queue, producing); var state = new LatheUpdateState(GetAvailableRecipes(uid, component), component.Queue.ToArray(), producing);
_uiSys.SetUiState(uid, LatheUiKey.Key, state); _uiSys.SetUiState(uid, LatheUiKey.Key, state);
} }

View File

@@ -29,7 +29,7 @@ namespace Content.Shared.Lathe
/// The lathe's construction queue /// The lathe's construction queue
/// </summary> /// </summary>
[DataField] [DataField]
public List<LatheRecipePrototype> Queue = new(); public Queue<ProtoId<LatheRecipePrototype>> Queue = new();
/// <summary> /// <summary>
/// The sound that plays when the lathe is producing an item, if any /// The sound that plays when the lathe is producing an item, if any
@@ -64,7 +64,7 @@ namespace Content.Shared.Lathe
/// The recipe the lathe is currently producing /// The recipe the lathe is currently producing
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
public LatheRecipePrototype? CurrentRecipe; public ProtoId<LatheRecipePrototype>? CurrentRecipe;
#region MachineUpgrading #region MachineUpgrading
/// <summary> /// <summary>

View File

@@ -1,4 +1,5 @@
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
using NetSerializer;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -9,11 +10,11 @@ public sealed class LatheUpdateState : BoundUserInterfaceState
{ {
public List<ProtoId<LatheRecipePrototype>> Recipes; public List<ProtoId<LatheRecipePrototype>> Recipes;
public List<LatheRecipePrototype> Queue; public ProtoId<LatheRecipePrototype>[] Queue;
public LatheRecipePrototype? CurrentlyProducing; public ProtoId<LatheRecipePrototype>? CurrentlyProducing;
public LatheUpdateState(List<ProtoId<LatheRecipePrototype>> recipes, List<LatheRecipePrototype> queue, LatheRecipePrototype? currentlyProducing = null) public LatheUpdateState(List<ProtoId<LatheRecipePrototype>> recipes, ProtoId<LatheRecipePrototype>[] queue, ProtoId<LatheRecipePrototype>? currentlyProducing = null)
{ {
Recipes = recipes; Recipes = recipes;
Queue = queue; Queue = queue;

View File

@@ -3,13 +3,12 @@ using Content.Shared.FixedPoint;
using Content.Shared.Lathe.Prototypes; using Content.Shared.Lathe.Prototypes;
using Content.Shared.Materials; using Content.Shared.Materials;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Shared.Research.Prototypes namespace Content.Shared.Research.Prototypes
{ {
[NetSerializable, Serializable, Prototype] [Prototype]
public sealed partial class LatheRecipePrototype : IPrototype, IInheritingPrototype public sealed partial class LatheRecipePrototype : IPrototype, IInheritingPrototype
{ {
[ViewVariables] [ViewVariables]