protected override VisitStatus BeginContainer <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref TValue value, ref ChangeTracker changeTracker) { if (typeof(IComponentData).IsAssignableFrom(typeof(TValue))) { var index = TypeManager.GetTypeIndex(typeof(TValue)); if (!TypeManager.GetTypeInfo(index).IsZeroSized) { Unsafe.Copy(m_EntityManager.GetComponentDataRawRW(m_TargetEntity, index), ref value); } } if (typeof(ISharedComponentData).IsAssignableFrom(typeof(TValue))) { var index = TypeManager.GetTypeIndex(typeof(TValue)); m_EntityManager.SetSharedComponentDataBoxed(m_TargetEntity, index, value); } if (typeof(IDynamicBufferContainer).IsAssignableFrom(typeof(TValue)) && value is IDynamicBufferContainer buffer) { var index = TypeManager.GetTypeIndex(buffer.ElementType); var componentType = TypeManager.GetTypeInfo(index); var srcBuffer = (BufferHeader *)m_EntityManager.GetComponentDataRawRW(m_SourceEntity, componentType.TypeIndex); var dstBuffer = (BufferHeader *)m_EntityManager.GetComponentDataRawRW(m_TargetEntity, componentType.TypeIndex); dstBuffer->Length = srcBuffer->Length; BufferHeader.EnsureCapacity(dstBuffer, srcBuffer->Length, componentType.ElementSize, 4, BufferHeader.TrashMode.RetainOldData); // Copy all blittable data UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(dstBuffer), BufferHeader.GetElementPointer(srcBuffer), componentType.ElementSize * srcBuffer->Length); } return(VisitStatus.Override); }
public void EnsureCapacity(int length) { BufferHeader.EnsureCapacity(m_Buffer, length, UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), BufferHeader.TrashMode.RetainOldData, false, 0); }
private static unsafe Entity CopyEntity(Entity srcEntity, World srcWorld, World dstWorld) { Assert.AreNotEqual(Entity.Null, srcEntity); using (var entityReferences = new NativeList <EntityReferenceRemap>(8, Allocator.Temp)) using (var componentTypes = srcWorld.EntityManager.GetComponentTypes(srcEntity)) { var archetype = dstWorld.EntityManager.CreateArchetype(componentTypes.ToArray()); var dstEntity = dstWorld.EntityManager.CreateEntity(archetype); if (componentTypes.Any(x => x.HasEntityReferences) && !dstWorld.EntityManager.HasComponent <EntityReferenceRemap>(dstEntity)) { dstWorld.EntityManager.AddBuffer <EntityReferenceRemap>(dstEntity); } foreach (var componentType in componentTypes) { var typeInfo = TypeManager.GetTypeInfo(componentType.TypeIndex); if (typeInfo.SizeInChunk == 0) { continue; } if (componentType.IsSharedComponent) { // @TODO For now we assume that all shared component data is blittable var srcComponent = srcWorld.EntityManager.GetSharedComponentData(srcEntity, componentType.TypeIndex); var ptr = Unsafe.AsPointer(ref srcComponent); // Pull out all references into the `entityReferences` list ExtractEntityReferences(entityReferences, typeInfo, srcWorld.EntityManager, ptr); // Zero out entity references ClearEntityReferences(typeInfo, ptr); dstWorld.EntityManager.SetSharedComponentDataBoxed(dstEntity, componentType.TypeIndex, srcComponent); continue; } if (componentType.IsBuffer) { var srcBuffer = (BufferHeader *)srcWorld.EntityManager.GetComponentDataRawRW(srcEntity, componentType.TypeIndex); var dstBuffer = (BufferHeader *)dstWorld.EntityManager.GetComponentDataRawRW(dstEntity, componentType.TypeIndex); dstBuffer->Length = srcBuffer->Length; BufferHeader.EnsureCapacity(dstBuffer, srcBuffer->Length, typeInfo.ElementSize, 4, BufferHeader.TrashMode.RetainOldData); // Copy all blittable data UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(dstBuffer), BufferHeader.GetElementPointer(srcBuffer), typeInfo.ElementSize * srcBuffer->Length); for (var i = 0; i < srcBuffer->Length; i++) { var baseOffset = i * typeInfo.ElementSize; // Pull out all references into the `entityReferences` list ExtractEntityReferences(entityReferences, typeInfo, srcWorld.EntityManager, BufferHeader.GetElementPointer(dstBuffer), baseOffset); // Zero out entity references ClearEntityReferences(typeInfo, BufferHeader.GetElementPointer(dstBuffer), baseOffset); } continue; } var componentData = srcWorld.EntityManager.GetComponentDataRawRW(srcEntity, componentType.TypeIndex); // Copy all blittable data dstWorld.EntityManager.SetComponentDataRaw(dstEntity, componentType.TypeIndex, componentData, typeInfo.SizeInChunk); // Pull out all references into the `entityReferences` list ExtractEntityReferences(entityReferences, typeInfo, srcWorld.EntityManager, componentData); // Zero out entity references ClearEntityReferences(typeInfo, dstWorld.EntityManager.GetComponentDataRawRW(dstEntity, componentType.TypeIndex)); } if (entityReferences.Length > 0) { dstWorld.EntityManager.GetBuffer <EntityReferenceRemap>(dstEntity).AddRange(entityReferences); } return(dstEntity); } }