mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Move entity prototype reload logic to entity system.
Removes dependency of IPrototypeManager -> IEntityManager.
This commit is contained in:
@@ -70,6 +70,7 @@ Template for new versions:
|
||||
* Word-wrapping logic has been split off from `RichTextEntry`, into a new helper struct `WordWrap`.
|
||||
* Some internal logic in `LineEdit` has been shared with `TextEdit` by moving it to a new `TextEditShared` file.
|
||||
* SDL2 backend now uses `[UnmanagedCallersOnly]` instead of `GetFunctionPointerForDelegate`-style P/Invoke marshalling.
|
||||
* Entity prototype reloading logic has been moved out of `PrototypeManager` and into a new `PrototypeReloadSystem`.
|
||||
|
||||
## 0.62.1.0
|
||||
|
||||
|
||||
88
Robust.Shared/GameObjects/Systems/PrototypeReloadSystem.cs
Normal file
88
Robust.Shared/GameObjects/Systems/PrototypeReloadSystem.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Robust.Shared.GameObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Responsible for applying relevant changes to active entities when prototypes are reloaded.
|
||||
/// </summary>
|
||||
internal sealed class PrototypeReloadSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
||||
[Dependency] private readonly IComponentFactory _componentFactory = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
_prototypes.PrototypesReloaded += OnPrototypesReloaded;
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
|
||||
_prototypes.PrototypesReloaded -= OnPrototypesReloaded;
|
||||
}
|
||||
|
||||
private void OnPrototypesReloaded(PrototypesReloadedEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.ByType.TryGetValue(typeof(EntityPrototype), out var set))
|
||||
return;
|
||||
|
||||
foreach (var metadata in EntityQuery<MetaDataComponent>())
|
||||
{
|
||||
var id = metadata.EntityPrototype?.ID;
|
||||
if (id == null || !set.Modified.ContainsKey(id))
|
||||
continue;
|
||||
|
||||
var proto = _prototypes.Index<EntityPrototype>(id);
|
||||
UpdateEntity(metadata.Owner, metadata, proto);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEntity(EntityUid entity, MetaDataComponent metaData, EntityPrototype newPrototype)
|
||||
{
|
||||
var oldPrototype = metaData.EntityPrototype;
|
||||
|
||||
var oldPrototypeComponents = oldPrototype?.Components.Keys
|
||||
.Where(n => n != "Transform" && n != "MetaData")
|
||||
.Select(name => (name, _componentFactory.GetRegistration(name).Type))
|
||||
.ToList() ?? new List<(string name, Type Type)>();
|
||||
|
||||
var newPrototypeComponents = newPrototype.Components.Keys
|
||||
.Where(n => n != "Transform" && n != "MetaData")
|
||||
.Select(name => (name, _componentFactory.GetRegistration(name).Type))
|
||||
.ToList();
|
||||
|
||||
var ignoredComponents = new List<string>();
|
||||
|
||||
// Find components to be removed, and remove them
|
||||
foreach (var (name, type) in oldPrototypeComponents.Except(newPrototypeComponents))
|
||||
{
|
||||
if (newPrototype.Components.ContainsKey(name))
|
||||
{
|
||||
ignoredComponents.Add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
RemComp(entity, type);
|
||||
}
|
||||
|
||||
EntityManager.CullRemovedComponents();
|
||||
|
||||
// Add new components
|
||||
foreach (var (name, _) in newPrototypeComponents.Where(t => !ignoredComponents.Contains(t.name))
|
||||
.Except(oldPrototypeComponents))
|
||||
{
|
||||
var data = newPrototype.Components[name];
|
||||
var component = (Component)_componentFactory.GetComponent(name);
|
||||
component.Owner = entity;
|
||||
EntityManager.AddComponent(entity, component);
|
||||
}
|
||||
|
||||
// Update entity metadata
|
||||
metaData.EntityPrototype = newPrototype;
|
||||
}
|
||||
}
|
||||
@@ -190,60 +190,6 @@ namespace Robust.Shared.Prototypes
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateEntity(EntityUid entity)
|
||||
{
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var metaData = entityManager.GetComponent<MetaDataComponent>(entity);
|
||||
if (ID != metaData.EntityPrototype?.ID)
|
||||
{
|
||||
Logger.Error(
|
||||
$"Reloaded prototype used to update entity did not match entity's existing prototype: Expected '{ID}', got '{entityManager.GetComponent<MetaDataComponent>(entity).EntityPrototype?.ID}'");
|
||||
return;
|
||||
}
|
||||
|
||||
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||
var oldPrototype = metaData.EntityPrototype;
|
||||
|
||||
var oldPrototypeComponents = oldPrototype?.Components.Keys
|
||||
.Where(n => n != "Transform" && n != "MetaData")
|
||||
.Select(name => (name, factory.GetRegistration(name).Type))
|
||||
.ToList() ?? new List<(string name, Type Type)>();
|
||||
var newPrototypeComponents = Components.Keys
|
||||
.Where(n => n != "Transform" && n != "MetaData")
|
||||
.Select(name => (name, factory.GetRegistration(name).Type))
|
||||
.ToList();
|
||||
|
||||
var ignoredComponents = new List<string>();
|
||||
|
||||
// Find components to be removed, and remove them
|
||||
foreach (var (name, type) in oldPrototypeComponents.Except(newPrototypeComponents))
|
||||
{
|
||||
if (Components.Keys.Contains(name))
|
||||
{
|
||||
ignoredComponents.Add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
entityManager.RemoveComponent(entity, type);
|
||||
}
|
||||
|
||||
entityManager.CullRemovedComponents();
|
||||
|
||||
|
||||
// Add new components
|
||||
foreach (var (name, type) in newPrototypeComponents.Where(t => !ignoredComponents.Contains(t.name))
|
||||
.Except(oldPrototypeComponents))
|
||||
{
|
||||
var data = Components[name];
|
||||
var component = (Component) factory.GetComponent(name);
|
||||
component.Owner = entity;
|
||||
entityManager.AddComponent(entity, component);
|
||||
}
|
||||
|
||||
// Update entity metadata
|
||||
metaData.EntityPrototype = this;
|
||||
}
|
||||
|
||||
internal static void LoadEntity(
|
||||
EntityPrototype? prototype,
|
||||
EntityUid entity,
|
||||
|
||||
@@ -8,7 +8,6 @@ using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Asynchronous;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.IoC.Exceptions;
|
||||
using Robust.Shared.Log;
|
||||
@@ -237,7 +236,6 @@ namespace Robust.Shared.Prototypes
|
||||
{
|
||||
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
|
||||
[Dependency] protected readonly IResourceManager Resources = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] protected readonly ITaskManager TaskManager = default!;
|
||||
[Dependency] private readonly ISerializationManager _serializationManager = default!;
|
||||
|
||||
@@ -480,23 +478,6 @@ namespace Robust.Shared.Prototypes
|
||||
g => g.Key,
|
||||
g => new PrototypesReloadedEventArgs.PrototypeChangeSet(
|
||||
g.Value.Where(x => _prototypes[g.Key].ContainsKey(x)).ToDictionary(a => a, a => _prototypes[g.Key][a])))));
|
||||
|
||||
// TODO filter by entity prototypes changed
|
||||
if (!pushed.ContainsKey(typeof(EntityPrototype))) return;
|
||||
|
||||
var entityPrototypes = _prototypes[typeof(EntityPrototype)];
|
||||
|
||||
foreach (var prototype in pushed[typeof(EntityPrototype)])
|
||||
{
|
||||
foreach (var entity in _entityManager.GetEntities())
|
||||
{
|
||||
var metaData = _entityManager.GetComponent<MetaDataComponent>(entity);
|
||||
if (metaData.EntityPrototype != null && metaData.EntityPrototype.ID == prototype)
|
||||
{
|
||||
((EntityPrototype) entityPrototypes[prototype]).UpdateEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user