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
/// </summary>
/// <param name="queue"></param>
public void PopulateQueueList(List<LatheRecipePrototype> queue)
public void PopulateQueueList(IReadOnlyCollection<ProtoId<LatheRecipePrototype>> queue)
{
QueueList.DisposeAllChildren();
var idx = 1;
foreach (var recipe in queue)
foreach (var recipeProto in queue)
{
var recipe = _prototypeManager.Index(recipeProto);
var queuedRecipeBox = new BoxContainer();
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;
if (recipe == null)
FabricatingContainer.Visible = recipeProto != null;
if (recipeProto == null)
return;
var recipe = _prototypeManager.Index(recipeProto.Value);
FabricatingDisplayContainer.Children.Clear();
FabricatingDisplayContainer.AddChild(GetRecipeDisplayControl(recipe));

View File

@@ -183,7 +183,7 @@ namespace Content.Server.Lathe
_materialStorage.TryChangeMaterialAmount(uid, mat, adjustedAmount);
}
component.Queue.Add(recipe);
component.Queue.Enqueue(recipe);
return true;
}
@@ -195,8 +195,8 @@ namespace Content.Server.Lathe
if (component.CurrentRecipe != null || component.Queue.Count <= 0 || !this.IsPowered(uid, EntityManager))
return false;
var recipe = component.Queue.First();
component.Queue.RemoveAt(0);
var recipeProto = component.Queue.Dequeue();
var recipe = _proto.Index(recipeProto);
var time = _reagentSpeed.ApplySpeed(uid, recipe.CompleteTime) * component.TimeMultiplier;
@@ -226,13 +226,14 @@ namespace Content.Server.Lathe
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);
_stack.TryMergeToContacts(result);
}
if (comp.CurrentRecipe.ResultReagents is { } resultReagents &&
if (currentRecipe.ResultReagents is { } resultReagents &&
comp.ReagentOutputSlotId is { } slotId)
{
var toAdd = new Solution(
@@ -269,9 +270,11 @@ namespace Content.Server.Lathe
if (!Resolve(uid, ref component))
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);
}

View File

@@ -29,7 +29,7 @@ namespace Content.Shared.Lathe
/// The lathe's construction queue
/// </summary>
[DataField]
public List<LatheRecipePrototype> Queue = new();
public Queue<ProtoId<LatheRecipePrototype>> Queue = new();
/// <summary>
/// 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
/// </summary>
[ViewVariables]
public LatheRecipePrototype? CurrentRecipe;
public ProtoId<LatheRecipePrototype>? CurrentRecipe;
#region MachineUpgrading
/// <summary>

View File

@@ -1,4 +1,5 @@
using Content.Shared.Research.Prototypes;
using NetSerializer;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
@@ -9,11 +10,11 @@ public sealed class LatheUpdateState : BoundUserInterfaceState
{
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;
Queue = queue;

View File

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