Skip to content

Commit acbbd61

Browse files
frozone
1 parent 2e8407f commit acbbd61

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

Robust.Server.Testing/RobustServerSimulation.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ public ISimulation InitializeInstance()
251251
container.Register<ISerializationManager, SerializationManager>();
252252
container.Register<IRobustRandom, RobustRandom>();
253253
container.Register<IPrototypeManager, ServerPrototypeManager>();
254+
container.Register<IPrototypeManagerInternal, ServerPrototypeManager>();
254255
container.Register<IComponentFactory, ComponentFactory>();
255256
container.Register<IEntitySystemManager, EntitySystemManager>();
256257
container.Register<IManifoldManager, CollisionManager>();

Robust.Shared/Prototypes/PrototypeManager.EntityLoad.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Frozen;
23
using System.Collections.Generic;
34
using Robust.Shared.EntitySerialization;
45
using Robust.Shared.GameObjects;
@@ -8,7 +9,8 @@ namespace Robust.Shared.Prototypes;
89

910
public abstract partial class PrototypeManager
1011
{
11-
private readonly Dictionary<string, PrototypeComponentRegistration[]> _entityComponentRegistrations = new();
12+
private FrozenDictionary<string, PrototypeComponentRegistration[]> _entityComponentRegistrations
13+
= FrozenDictionary<string, PrototypeComponentRegistration[]>.Empty;
1214

1315
void IPrototypeManagerInternal.LoadEntity(Entity<MetaDataComponent> ent, IEntityLoadContext? context)
1416
{
@@ -34,6 +36,34 @@ private PrototypeComponentRegistration[] GetComponentRegistrations(EntityPrototy
3436
if (_entityComponentRegistrations.TryGetValue(prototype.ID, out var cached))
3537
return cached;
3638

39+
// This should only happen if an entity is being loaded before prototype resolution has rebuilt the cache.
40+
return BuildComponentRegistrations(prototype);
41+
}
42+
43+
private void RebuildEntityComponentRegistrationCache()
44+
{
45+
if (!TryGetInstances<EntityPrototype>(out var prototypes))
46+
{
47+
ClearEntityComponentRegistrationCache();
48+
return;
49+
}
50+
51+
var registrations = new Dictionary<string, PrototypeComponentRegistration[]>(prototypes.Count);
52+
foreach (var (id, prototype) in prototypes)
53+
{
54+
registrations[id] = BuildComponentRegistrations(prototype);
55+
}
56+
57+
_entityComponentRegistrations = registrations.ToFrozenDictionary();
58+
}
59+
60+
private void ClearEntityComponentRegistrationCache()
61+
{
62+
_entityComponentRegistrations = FrozenDictionary<string, PrototypeComponentRegistration[]>.Empty;
63+
}
64+
65+
private PrototypeComponentRegistration[] BuildComponentRegistrations(EntityPrototype prototype)
66+
{
3767
var registrations = new PrototypeComponentRegistration[prototype.Components.Count];
3868
var i = 0;
3969

@@ -42,7 +72,6 @@ private PrototypeComponentRegistration[] GetComponentRegistrations(EntityPrototy
4272
registrations[i++] = new PrototypeComponentRegistration(name, entry, _factory.GetRegistration(name));
4373
}
4474

45-
_entityComponentRegistrations[prototype.ID] = registrations;
4675
return registrations;
4776
}
4877

Robust.Shared/Prototypes/PrototypeManager.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ public void Clear()
295295
{
296296
_kindNames.Clear();
297297
_kinds = FrozenDictionary<Type, KindData>.Empty;
298+
ClearEntityComponentRegistrationCache();
298299
}
299300

300301
/// <inheritdoc />
@@ -478,11 +479,16 @@ void AddToQueue(string id)
478479
private void Freeze(IEnumerable<KindData> kinds)
479480
{
480481
var st = RStopwatch.StartNew();
482+
var frozeEntityPrototypes = false;
481483
foreach (var kind in kinds)
482484
{
483485
kind.Freeze();
486+
frozeEntityPrototypes |= kind.Type == typeof(EntityPrototype);
484487
}
485488

489+
if (frozeEntityPrototypes)
490+
RebuildEntityComponentRegistrationCache();
491+
486492
// fun fact: Sawmill can be null in tests????
487493
Sawmill?.Verbose($"Freezing prototype instances took {st.Elapsed.TotalMilliseconds:f2}ms");
488494
}
@@ -1170,7 +1176,6 @@ private void OnReload(PrototypesReloadedEventArgs args)
11701176
foreach (var id in modified.Modified.Keys)
11711177
{
11721178
_prototypeDataCache.Remove(id);
1173-
_entityComponentRegistrations.Remove(id);
11741179
}
11751180
}
11761181

@@ -1180,7 +1185,6 @@ private void OnReload(PrototypesReloadedEventArgs args)
11801185
foreach (var id in removed)
11811186
{
11821187
_prototypeDataCache.Remove(id);
1183-
_entityComponentRegistrations.Remove(id);
11841188
}
11851189
}
11861190

0 commit comments

Comments
 (0)