From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Wed, 27 Dec 2023 22:50:49 +0000 (-0500) Subject: Cache ItemSizePrototype in StorageSystem (#22611) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=364ecae94f66dc0a4e87760def5203cca4745cee;p=space-station-14.git Cache ItemSizePrototype in StorageSystem (#22611) --- diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index 43939b29f9..9092bdc741 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.ActionBlocker; @@ -51,8 +52,13 @@ public abstract class SharedStorageSystem : EntitySystem [ValidatePrototypeId] public const string DefaultStorageMaxItemSize = "Normal"; + private ItemSizePrototype _defaultStorageMaxItemSize = default!; + public bool CheckingCanInsert; + private readonly List _sortedSizes = new(); + private FrozenDictionary _nextSmallest = FrozenDictionary.Empty; + /// public override void Initialize() { @@ -61,6 +67,7 @@ public abstract class SharedStorageSystem : EntitySystem _itemQuery = GetEntityQuery(); _stackQuery = GetEntityQuery(); _xformQuery = GetEntityQuery(); + _prototype.PrototypesReloaded += OnPrototypesReloaded; SubscribeLocalEvent(OnComponentInit, before: new[] { typeof(SharedContainerSystem) }); SubscribeLocalEvent>(AddTransferVerbs); @@ -82,6 +89,39 @@ public abstract class SharedStorageSystem : EntitySystem SubscribeAllEvent(OnSetItemLocation); SubscribeAllEvent(OnInsertItemIntoLocation); SubscribeAllEvent(OnRemoveItem); + UpdatePrototypeCache(); + } + + public override void Shutdown() + { + _prototype.PrototypesReloaded -= OnPrototypesReloaded; + } + + private void OnPrototypesReloaded(PrototypesReloadedEventArgs args) + { + if (args.ByType.ContainsKey(typeof(ItemSizePrototype)) + || (args.Removed?.ContainsKey(typeof(ItemSizePrototype)) ?? false)) + { + UpdatePrototypeCache(); + } + } + + private void UpdatePrototypeCache() + { + _defaultStorageMaxItemSize = _prototype.Index(DefaultStorageMaxItemSize); + _sortedSizes.Clear(); + _sortedSizes.AddRange(_prototype.EnumeratePrototypes()); + _sortedSizes.Sort(); + + var nextSmallest = new KeyValuePair[_sortedSizes.Count]; + for (var i = 0; i < _sortedSizes.Count; i++) + { + var k = _sortedSizes[i].ID; + var v = _sortedSizes[Math.Max(i - 1, 0)]; + nextSmallest[i] = new(k, v); + } + + _nextSmallest = nextSmallest.ToFrozenDictionary(); } private void OnComponentInit(EntityUid uid, StorageComponent storageComp, ComponentInit args) @@ -601,7 +641,7 @@ public abstract class SharedStorageSystem : EntitySystem return true; } - var maxSize = ItemSystem.GetSizePrototype(GetMaxItemSize((uid, storageComp))); + var maxSize = GetMaxItemSize((uid, storageComp)); if (ItemSystem.GetSizePrototype(item.Size) > maxSize) { reason = "comp-storage-too-big"; @@ -609,7 +649,7 @@ public abstract class SharedStorageSystem : EntitySystem } if (TryComp(insertEnt, out var insertStorage) - && ItemSystem.GetSizePrototype(GetMaxItemSize((insertEnt, insertStorage))) >= maxSize) + && GetMaxItemSize((insertEnt, insertStorage)) >= maxSize) { reason = "comp-storage-too-big"; return false; @@ -1009,25 +1049,21 @@ public abstract class SharedStorageSystem : EntitySystem return sum; } - public ProtoId GetMaxItemSize(Entity uid) + public ItemSizePrototype GetMaxItemSize(Entity uid) { if (!Resolve(uid, ref uid.Comp)) - return DefaultStorageMaxItemSize; + return _defaultStorageMaxItemSize; // If we specify a max item size, use that if (uid.Comp.MaxItemSize != null) - return uid.Comp.MaxItemSize.Value; + return _prototype.Index(uid.Comp.MaxItemSize.Value); if (!_itemQuery.TryGetComponent(uid, out var item)) - return DefaultStorageMaxItemSize; - var size = ItemSystem.GetSizePrototype(item.Size); + return _defaultStorageMaxItemSize; // if there is no max item size specified, the value used - // is one below the item size of the storage entity, clamped at ItemSize.Tiny - var sizes = _prototype.EnumeratePrototypes().ToList(); - sizes.Sort(); - var currentSizeIndex = sizes.IndexOf(size); - return sizes[Math.Max(currentSizeIndex - 1, 0)].ID; + // is one below the item size of the storage entity. + return _nextSmallest[item.Size]; } private void OnStackCountChanged(EntityUid uid, MetaDataComponent component, StackCountChangedEvent args)