Skip to content

Commit

Permalink
wehj
Browse files Browse the repository at this point in the history
  • Loading branch information
metalgearsloth committed Aug 19, 2024
1 parent efa3e01 commit ed55f3b
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 27 deletions.
3 changes: 2 additions & 1 deletion Robust.Server/GameObjects/ServerComponentFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization.Manager;

namespace Robust.Server.GameObjects;

internal sealed class ServerComponentFactory : ComponentFactory
{
public ServerComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, ILogManager logManager) : base(typeFactory, reflectionManager, logManager)
public ServerComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, ISerializationManager serManager, ILogManager logManager) : base(typeFactory, reflectionManager, serManager, logManager)
{
RegisterIgnore("Input");
RegisterIgnore("AnimationPlayer");
Expand Down
10 changes: 10 additions & 0 deletions Robust.Shared/GameObjects/ComponentFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Prototypes;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

Expand All @@ -18,6 +20,7 @@ namespace Robust.Shared.GameObjects
internal class ComponentFactory(
IDynamicTypeFactoryInternal _typeFactory,
IReflectionManager _reflectionManager,
ISerializationManager _serManager,
ILogManager logManager) : IComponentFactory
{
private readonly ISawmill _sawmill = logManager.GetSawmill("ent.componentFactory");
Expand Down Expand Up @@ -181,6 +184,13 @@ public void IgnoreMissingComponents(string postfix = "")
_ignoreMissingComponentPostfix = postfix ?? throw new ArgumentNullException(nameof(postfix));
}

public IComponent GetComponent(EntityPrototype.ComponentRegistryEntry entry)
{
var copy = GetComponent(entry.Component.GetType());
_serManager.CopyTo(entry.Component, ref copy, notNullableOverride: true);
return copy;
}

public void RegisterIgnore(params string[] names)
{
foreach (var name in names)
Expand Down
10 changes: 10 additions & 0 deletions Robust.Shared/GameObjects/EntityManager.Components.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,16 @@ public static implicit operator T(CompInitializeHandle<T> handle)
return new CompInitializeHandle<T>(this, uid, newComponent, reg.Idx);
}

public void AddComponent(
EntityUid uid,
EntityPrototype.ComponentRegistryEntry entry,
bool overwrite = false,
MetaDataComponent? metadata = null)
{
var copy = _componentFactory.GetComponent(entry);
AddComponent(uid, copy, overwrite, metadata);
}

/// <inheritdoc />
public void AddComponent<T>(EntityUid uid, T component, bool overwrite = false, MetaDataComponent? metadata = null) where T : IComponent
{
Expand Down
2 changes: 2 additions & 0 deletions Robust.Shared/GameObjects/IComponentFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ public interface IComponentFactory
/// <param name="postfix">If provided, will only ignore components ending with the postfix.</param>
void IgnoreMissingComponents(string postfix = "");

IComponent GetComponent(EntityPrototype.ComponentRegistryEntry entry);

/// <summary>
/// Gets a new component instantiated of the specified type.
/// </summary>
Expand Down
68 changes: 43 additions & 25 deletions Robust.Shared/GameObjects/Systems/PrototypeReloadSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Robust.Shared.GameObjects;
internal sealed class PrototypeReloadSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypes = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!;

public override void Initialize()
{
Expand All @@ -36,43 +35,62 @@ private void OnPrototypesReloaded(PrototypesReloadedEventArgs eventArgs)
}
}

private bool IsIgnored(EntityPrototype.ComponentRegistryEntry entry)
{
var compType = entry.Component.GetType();

if (compType == typeof(TransformComponent) || compType == typeof(MetaDataComponent))
return true;

return false;
}

private void UpdateEntity(EntityUid entity, MetaDataComponent metaData, EntityPrototype newPrototype)
{
var oldPrototype = metaData.EntityPrototype;
var modified = false;

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)>();
if (oldPrototype != null)
{
foreach (var oldComp in oldPrototype.Components)
{
if (IsIgnored(oldComp.Value))
continue;

var newPrototypeComponents = newPrototype.Components.Keys
.Where(n => n != "Transform" && n != "MetaData")
.Select(name => (name, _componentFactory.GetRegistration(name).Type))
.ToList();
// Removed
if (!newPrototype.Components.TryGetValue(oldComp.Key, out var newComp))
{
modified = true;
RemComp(entity, oldComp.Value.Component.GetType());
continue;
}

var ignoredComponents = new List<string>();
// Modified
if (!newComp.Mapping.Equals(oldComp.Value.Mapping))
{
modified = true;
EntityManager.AddComponent(entity, newComp, overwrite: true, metaData);
}
}
}

// Find components to be removed, and remove them
foreach (var (name, type) in oldPrototypeComponents.Except(newPrototypeComponents))
foreach (var newComp in newPrototype.Components)
{
if (newPrototype.Components.ContainsKey(name))
{
ignoredComponents.Add(name);
if (IsIgnored(newComp.Value))
continue;
}

RemComp(entity, type);
}
// Existing component, handled above
if (oldPrototype?.Components.ContainsKey(newComp.Key) == true)
continue;

EntityManager.CullRemovedComponents();
// Added
modified = true;
EntityManager.AddComponent(entity, newComp.Value, overwrite: true, metadata: metaData);
}

// Add new components
foreach (var (name, _) in newPrototypeComponents.Where(t => !ignoredComponents.Contains(t.name))
.Except(oldPrototypeComponents))
if (modified)
{
var data = newPrototype.Components[name];
var component = _componentFactory.GetComponent(name);
EntityManager.AddComponent(entity, component);
EntityManager.CullRemovedComponents();
}

// Update entity metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization.Manager;
using Robust.UnitTesting.Shared.Reflection;

namespace Robust.UnitTesting.Shared.GameObjects
Expand All @@ -14,7 +15,7 @@ public sealed partial class EntityEventBusTests
[Test]
public void SubscribeCompEvent()
{
var compFactory = new ComponentFactory(new DynamicTypeFactory(), new ReflectionManagerTest(), new LogManager());
var compFactory = new ComponentFactory(new DynamicTypeFactory(), new ReflectionManagerTest(), new SerializationManager(), new LogManager());

// Arrange
var entUid = new EntityUid(7);
Expand Down

0 comments on commit ed55f3b

Please sign in to comment.