Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a method for copying components #5654

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Robust.Shared/GameObjects/EntityManager.Components.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,54 @@ public bool TryGetComponent([NotNullWhen(true)] EntityUid? uid, ushort netId,
return TryGetComponent(uid.Value, netId, out component, meta);
}

/// <inheritdoc/>
public bool CopyComponent<T>(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? metadataTarget = null) where T : IComponent
{
component = default;

if (!MetaQuery.Resolve(target, ref metadataTarget, false))
throw new ArgumentException($"Entity {target} is not valid.", nameof(target));

if (!HasComponent<T>(source))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utilizing something like CopyComps(source, ent, null, typeof(VocalComponent), typeof(SpeechComponent)); causes a Unknown component: IComponent error

image

return false;

var sourceComp = GetComponent<T>(source);
var compReg = ComponentFactory.GetRegistration(typeof(T));
component = (T)ComponentFactory.GetComponent(compReg);

_serManager.CopyTo(sourceComp, ref component, notNullableOverride: true);

AddComponentInternal(target, component, compReg, true, false, metadataTarget);
return true;
}

/// <inheritdoc/>
public bool CopyComponent(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? metadataTarget = null)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type), $"Type {type} is not a component");

var success = CopyComponent<IComponent>(source, target, out var baseComponent, metadataTarget);
component = baseComponent;
return success;
}

/// <inheritdoc/>
public bool CopyComponents(EntityUid source, EntityUid target, MetaDataComponent? metadataTarget = null, params Type[] types)
{
if (!MetaQuery.Resolve(target, ref metadataTarget, false))
throw new ArgumentException($"Entity {target} is not valid.", nameof(target));

var allSuccessful = true;

foreach (var type in types)
{
if (!CopyComponent(source, target, type, out _, metadataTarget))
allSuccessful = false;
}

return allSuccessful;
}

public EntityQuery<TComp1> GetEntityQuery<TComp1>() where TComp1 : IComponent
{
var comps = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
Expand Down
25 changes: 25 additions & 0 deletions Robust.Shared/GameObjects/EntitySystem.Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,31 @@ protected bool TryGetEntityData(NetEntity nuid, [NotNullWhen(true)] out EntityUi

#endregion

#region Component Copy

/// <inheritdoc cref="IEntityManager.CopyComponent{T}"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool CopyComp<T>(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? metadataTarget = null) where T : IComponent
{
return EntityManager.CopyComponent(source, target, out component, metadataTarget);
}

/// <inheritdoc cref="IEntityManager.CopyComponent"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool CopyComp(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? metadataTarget = null)
{
return EntityManager.CopyComponent(source, target, type, out component, metadataTarget);
}

/// <inheritdoc cref="IEntityManager.CopyComponents"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool CopyComps(EntityUid source, EntityUid target, MetaDataComponent? metadataTarget = null, params Type[] types)
{
return EntityManager.CopyComponents(source, target, metadataTarget, types);
}

#endregion

#region Component Has

/// <summary>
Expand Down
33 changes: 33 additions & 0 deletions Robust.Shared/GameObjects/IEntityManager.Components.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,39 @@ public partial interface IEntityManager
/// <returns>If the component existed in the entity.</returns>
bool TryGetComponent([NotNullWhen(true)] EntityUid? uid, ushort netId, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? meta = null);


/// <summary>
/// Copy a typed component from source to target entity and return a reference to the copied component.
/// </summary>
/// <typeparam name="T">The type of component to copy</typeparam>
/// <param name="source">The source entity to copy from</param>
/// <param name="target">The target entity to copy to</param>
/// <param name="component">The copied component if successful</param>
/// <param name="metadataTarget">Optional metadata of the target entity</param>
/// <returns>Whether the component was successfully copied</returns>
bool CopyComponent<T>(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? metadataTarget = null) where T : IComponent;

/// <summary>
/// Copy a single component from source to target entity and return a reference to the copied component.
/// </summary>
/// <param name="source">The source entity to copy the component from</param>
/// <param name="target">The target entity to copy the component to</param>
/// <param name="type">The type of component to copy</param>
/// <param name="component">The copied component if successful</param>
/// <param name="metadataTarget">Optional metadata of the target entity</param>
/// <returns>Whether the component was successfully copied</returns>
bool CopyComponent(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? metadataTarget = null);

/// <summary>
/// Copy multiple components from source to target entity.
/// </summary>
/// <param name="source">The source entity to copy from</param>
/// <param name="target">The target entity to copy to</param>
/// <param name="metadataTarget">Optional metadata of the target entity</param>
/// <param name="types">Array of component types to copy</param>
/// <returns>Whether all components were successfully copied</returns>
bool CopyComponents(EntityUid source, EntityUid target, MetaDataComponent? metadataTarget = null, params Type[] types);

/// <summary>
/// Returns a cached struct enumerator with the specified component.
/// </summary>
Expand Down
Loading