Skip to content

Commit

Permalink
Raise ECS event on prototype-reload (#4724)
Browse files Browse the repository at this point in the history
* Raise system event on prototype-reload

* Oops
  • Loading branch information
ElectroJr authored Dec 16, 2023
1 parent 0150c5e commit 1bdd82b
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,13 @@ public RSI.State GetState(SpriteSpecifier.Rsi rsiSpecifier)
return GetFallbackState();
}

private void OnPrototypesReloaded(PrototypesReloadedEventArgs protoReloaded)
private void OnPrototypesReloaded(PrototypesReloadedEventArgs args)
{
// Check if any EntityPrototype has been changed.
if (!protoReloaded.ByType.TryGetValue(typeof(EntityPrototype), out var changedSet))
if (!args.TryGetModified<EntityPrototype>(out var modified))
return;

// Remove all changed prototypes from the cache, if they're there.
foreach (var (prototype, _) in changedSet.Modified)
foreach (var prototype in modified)
{
// Let's be lazy and not regenerate them until something needs them again.
_cachedPrototypeIcons.Remove(prototype);
Expand Down
3 changes: 1 addition & 2 deletions Robust.Client/GameObjects/EntitySystems/SpriteSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public override void Initialize()

UpdatesAfter.Add(typeof(SpriteTreeSystem));

_proto.PrototypesReloaded += OnPrototypesReloaded;
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
SubscribeLocalEvent<SpriteComponent, SpriteUpdateInertEvent>(QueueUpdateInert);
SubscribeLocalEvent<SpriteComponent, ComponentInit>(OnInit);

Expand All @@ -75,7 +75,6 @@ private void OnInit(EntityUid uid, SpriteComponent component, ComponentInit args
public override void Shutdown()
{
base.Shutdown();
_proto.PrototypesReloaded -= OnPrototypesReloaded;
_cfg.UnsubValueChanged(CVars.RenderSpriteDirectionBias, OnBiasChanged);
}

Expand Down
9 changes: 1 addition & 8 deletions Robust.Shared/GameObjects/Systems/PrototypeReloadSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ internal sealed class PrototypeReloadSystem : EntitySystem

public override void Initialize()
{
_prototypes.PrototypesReloaded += OnPrototypesReloaded;
}

public override void Shutdown()
{
base.Shutdown();

_prototypes.PrototypesReloaded -= OnPrototypesReloaded;
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
}

private void OnPrototypesReloaded(PrototypesReloadedEventArgs eventArgs)
Expand Down
6 changes: 2 additions & 4 deletions Robust.Shared/Localization/LocalizationManager.Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ private bool TryGetEntityLocAttrib(EntityUid entity, string attribute, [NotNullW
// Flush caches conservatively on prototype/localization changes.
private void OnPrototypesReloaded(PrototypesReloadedEventArgs args)
{
if (!args.ByType.ContainsKey(typeof(EntityPrototype)))
return;

FlushEntityCache();
if (args.WasModified<EntityPrototype>())
FlushEntityCache();
}

private EntityLocData CalcEntityLoc(string prototypeId)
Expand Down
33 changes: 32 additions & 1 deletion Robust.Shared/Prototypes/IPrototypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,40 @@ internal interface IPrototypeManagerInternal : IPrototypeManager
event Action<DataNodeDocument>? LoadedData;
}

public sealed record PrototypesReloadedEventArgs(
/// <summary>
/// This is event contains information about prototypes that have been modified. It is broadcast as a system event,
/// whenever <see cref="IPrototypeManager.PrototypesReloaded"/> gets invoked.
/// </summary>
public sealed record PrototypesReloadedEventArgs(HashSet<Type> Modified,
IReadOnlyDictionary<Type, PrototypesReloadedEventArgs.PrototypeChangeSet> ByType,
IReadOnlyDictionary<Type, HashSet<string>>? Removed = null)
{
public sealed record PrototypeChangeSet(IReadOnlyDictionary<string, IPrototype> Modified);

/// <summary>
/// Checks whether a given prototype kind was modified at all. This includes both changes and removals.
/// </summary>
public bool WasModified<T>() where T : IPrototype
{
return Modified.Contains(typeof(T));
}

/// <summary>
/// Returns a set of all modified prototype instances of a given kind. This includes both changes and removals.
/// </summary>
public bool TryGetModified<T>([NotNullWhen(true)] out HashSet<string>? modified) where T : IPrototype
{
modified = null;
if (!WasModified<T>())
return false;

modified = new();
if (ByType.TryGetValue(typeof(T), out var mod))
modified.UnionWith(mod.Modified.Keys);

if (Removed != null && Removed.TryGetValue(typeof(T), out var rem))
modified.UnionWith(rem);

return true;
}
}
24 changes: 15 additions & 9 deletions Robust.Shared/Prototypes/PrototypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public abstract partial class PrototypeManager : IPrototypeManagerInternal
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly ILocalizationManager _locMan = default!;
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IEntityManager _entMan = default!;

private readonly Dictionary<string, Dictionary<string, MappingDataNode>> _prototypeDataCache = new();
private EntityDiffContext _context = new();
Expand Down Expand Up @@ -354,15 +355,20 @@ public void ReloadPrototypes(Dictionary<Type, HashSet<string>> modified,
#endif

//todo paul i hate it but i am not opening that can of worms in this refactor
PrototypesReloaded?.Invoke(
new PrototypesReloadedEventArgs(
modified
.ToDictionary(
g => g.Key,
g => new PrototypesReloadedEventArgs.PrototypeChangeSet(
g.Value.Where(x => _kinds[g.Key].Instances.ContainsKey(x))
.ToDictionary(a => a, a => _kinds[g.Key].Instances[a]))),
removed));
var byType = modified
.ToDictionary(
g => g.Key,
g => new PrototypesReloadedEventArgs.PrototypeChangeSet(
g.Value.Where(x => _kinds[g.Key].Instances.ContainsKey(x))
.ToDictionary(a => a, a => _kinds[g.Key].Instances[a])));

var modifiedTypes = new HashSet<Type>(byType.Keys);
if (removed != null)
modifiedTypes.UnionWith(removed.Keys);

var ev = new PrototypesReloadedEventArgs(modifiedTypes, byType, removed);
PrototypesReloaded?.Invoke(ev);
_entMan.EventBus.RaiseEvent(EventSource.Local, ev);
}

private void Freeze(HashSet<KindData> kinds)
Expand Down

0 comments on commit 1bdd82b

Please sign in to comment.