Example #1
0
        private static unsafe void ApplySetComponents(
            EntityManager entityManager,
            NativeArray <PackedComponentDataChange> changes,
            NativeArray <byte> payload,
            NativeArray <EntityGuid> packedEntityGuids,
            NativeMultiHashMap <int, Entity> packedEntities,
            NativeArray <ComponentType> packedTypes,
            NativeMultiHashMap <EntityGuid, Entity> entityGuidToEntity,
            NativeHashMap <Entity, EntityGuid> entityToEntityGuid)
        {
            var entityGuidTypeIndex = TypeManager.GetTypeIndex <EntityGuid>();

            var offset = 0L;

            for (var i = 0; i < changes.Length; i++)
            {
                var packedComponentDataChange = changes[i];
                var packedComponent           = packedComponentDataChange.Component;
                var component = packedTypes[packedComponent.PackedTypeIndex];
                var size      = packedComponentDataChange.Size;
                var data      = (byte *)payload.GetUnsafeReadOnlyPtr() + offset;
                var componentTypeInArchetype = new ComponentTypeInArchetype(component);

                if (packedEntities.TryGetFirstValue(packedComponent.PackedEntityIndex, out var entity, out var iterator))
                {
                    do
                    {
                        if (!entityManager.Exists(entity))
                        {
                            Debug.LogWarning($"SetComponent<{component}>({packedEntityGuids[packedComponent.PackedEntityIndex]}) but entity does not exist.");
                        }
                        else if (!entityManager.HasComponent(entity, component))
                        {
                            Debug.LogWarning($"SetComponent<{component}>({packedEntityGuids[packedComponent.PackedEntityIndex]}) but component does not exist.");
                        }
                        else
                        {
                            if (componentTypeInArchetype.IsZeroSized)
                            {
                                // Nothing to set.
                            }
                            else if (componentTypeInArchetype.IsBuffer)
                            {
                                var typeInfo         = TypeManager.GetTypeInfo(componentTypeInArchetype.TypeIndex);
                                var elementSize      = typeInfo.ElementSize;
                                var lengthInElements = size / elementSize;
                                var header           = (BufferHeader *)entityManager.GetComponentDataRawRW(entity, component.TypeIndex);
                                BufferHeader.Assign(header, data, lengthInElements, elementSize, 16);
                            }
                            else
                            {
                                var target = (byte *)entityManager.GetComponentDataRawRW(entity, component.TypeIndex);

                                // Perform incremental updates on the entityGuidToEntity map to avoid a full rebuild.
                                if (componentTypeInArchetype.TypeIndex == entityGuidTypeIndex)
                                {
                                    EntityGuid entityGuid;
                                    UnsafeUtility.MemCpy(&entityGuid, target, sizeof(EntityGuid));

                                    if (!entityGuid.Equals(default))
        public static void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count)
        {
            var srcArchetype        = srcChunk->Archetype;
            var srcBuffer           = srcChunk->Buffer;
            var dstBuffer           = dstChunk->Buffer;
            var dstArchetype        = dstChunk->Archetype;
            var srcOffsets          = srcArchetype->Offsets;
            var srcSizeOfs          = srcArchetype->SizeOfs;
            var srcBufferCapacities = srcArchetype->BufferCapacities;
            var srcTypesCount       = srcArchetype->TypesCount;
            var srcTypes            = srcArchetype->Types;
            var dstTypes            = dstArchetype->Types;
            var dstOffsets          = dstArchetype->Offsets;
            var dstTypeIndex        = 1;

            // type[0] is always Entity, and will be patched up later, so just skip
            for (var srcTypeIndex = 1; srcTypeIndex != srcTypesCount; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];

                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }

                var srcOffset = srcOffsets[srcTypeIndex];
                var srcSizeOf = srcSizeOfs[srcTypeIndex];

                var dstOffset = dstOffsets[dstTypeIndex];

                var src = srcBuffer + (srcOffset + srcSizeOf * srcIndex);
                var dst = dstBuffer + (dstOffset + srcSizeOf * dstBaseIndex);

                if (!srcType.IsBuffer)
                {
                    UnsafeUtility.MemCpyReplicate(dst, src, srcSizeOf, count);
                }
                else
                {
                    var srcBufferCapacity = srcBufferCapacities[srcTypeIndex];
                    var alignment         = 8; // TODO: Need a way to compute proper alignment for arbitrary non-generic types in TypeManager
                    var elementSize       = TypeManager.GetTypeInfo(srcType.TypeIndex).ElementSize;
                    for (int i = 0; i < count; ++i)
                    {
                        BufferHeader *srcHdr = (BufferHeader *)src;
                        BufferHeader *dstHdr = (BufferHeader *)dst;
                        BufferHeader.Initialize(dstHdr, srcBufferCapacity);
                        BufferHeader.Assign(dstHdr, BufferHeader.GetElementPointer(srcHdr), srcHdr->Length, elementSize, alignment);

                        dst += srcSizeOf;
                    }
                }

                dstTypeIndex++;
            }
        }
        public static unsafe void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count)
        {
            Archetype *archetypePtr                 = srcChunk.Archetype;
            byte *     numPtr                       = &srcChunk.Buffer.FixedElementField;
            byte *     numPtr2                      = &dstChunk.Buffer.FixedElementField;
            Archetype *archetypePtr2                = dstChunk.Archetype;
            int *      offsets                      = archetypePtr->Offsets;
            int *      sizeOfs                      = archetypePtr->SizeOfs;
            int        typesCount                   = archetypePtr->TypesCount;
            ComponentTypeInArchetype *types         = archetypePtr->Types;
            ComponentTypeInArchetype *archetypePtr4 = archetypePtr2->Types;
            int *numPtr5 = archetypePtr2->Offsets;
            int  index   = 1;

            for (int i = 1; i != typesCount; i++)
            {
                ComponentTypeInArchetype archetype  = types[i];
                ComponentTypeInArchetype archetype2 = archetypePtr4[index];
                if (archetype.TypeIndex == archetype2.TypeIndex)
                {
                    int   size    = sizeOfs[i];
                    byte *numPtr6 = numPtr + (offsets[i] + (size * srcIndex));
                    byte *numPtr7 = numPtr2 + (numPtr5[index] + (size * dstBaseIndex));
                    if (!archetype.IsBuffer)
                    {
                        UnsafeUtility.MemCpyReplicate((void *)numPtr7, (void *)numPtr6, size, count);
                    }
                    else
                    {
                        int alignment   = 8;
                        int elementSize = TypeManager.GetTypeInfo(archetype.TypeIndex).ElementSize;
                        int num9        = 0;
                        while (true)
                        {
                            if (num9 >= count)
                            {
                                break;
                            }
                            BufferHeader *header     = (BufferHeader *)numPtr6;
                            BufferHeader *headerPtr2 = (BufferHeader *)numPtr7;
                            BufferHeader.Initialize(headerPtr2, archetype.BufferCapacity);
                            BufferHeader.Assign(headerPtr2, BufferHeader.GetElementPointer(header), header->Length, elementSize, alignment);
                            numPtr7 += size;
                            num9++;
                        }
                    }
                    index++;
                }
            }
        }
        public static void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex,
                                               int count)
        {
            Assert.IsTrue(srcChunk->Archetype == dstChunk->Archetype);

            var arch       = srcChunk->Archetype;
            var srcBuffer  = srcChunk->Buffer;
            var dstBuffer  = dstChunk->Buffer;
            var offsets    = arch->Offsets;
            var sizeOfs    = arch->SizeOfs;
            var typesCount = arch->TypesCount;
            var types      = arch->Types;

            // type[0] is always Entity, and will be patched up later, so just skip
            for (var t = 1; t != typesCount; t++)
            {
                var type   = types[t];
                var offset = offsets[t];
                var sizeOf = sizeOfs[t];
                var src    = srcBuffer + (offset + sizeOf * srcIndex);
                var dst    = dstBuffer + (offset + sizeOf * dstBaseIndex);

                if (!type.IsBuffer)
                {
                    UnsafeUtility.MemCpyReplicate(dst, src, sizeOf, count);
                }
                else
                {
                    var alignment = 8; // TODO: Need a way to compute proper alignment for arbitrary non-generic types in TypeManager
                    for (int i = 0; i < count; ++i)
                    {
                        BufferHeader *srcHdr = (BufferHeader *)src;
                        BufferHeader *dstHdr = (BufferHeader *)dst;
                        BufferHeader.Initialize(dstHdr, type.BufferCapacity);
                        BufferHeader.Assign(dstHdr, BufferHeader.GetElementPointer(srcHdr), srcHdr->Length, sizeOf, alignment);

                        src += sizeOf;
                        dst += sizeOf;
                    }
                }
            }
        }
        public static void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore)
        {
            var srcArchetype        = srcChunk->Archetype;
            var srcBuffer           = srcChunk->Buffer;
            var dstBuffer           = dstChunk->Buffer;
            var dstArchetype        = dstChunk->Archetype;
            var srcOffsets          = srcArchetype->Offsets;
            var srcSizeOfs          = srcArchetype->SizeOfs;
            var srcBufferCapacities = srcArchetype->BufferCapacities;
            var srcTypes            = srcArchetype->Types;
            var dstTypes            = dstArchetype->Types;
            var dstOffsets          = dstArchetype->Offsets;
            var dstTypeIndex        = 1;

            var nativeComponentsEnd = srcArchetype->NativeComponentsEnd;

            for (var srcTypeIndex = 1; srcTypeIndex != nativeComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                var srcSizeOf = srcSizeOfs[srcTypeIndex];
                var src       = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex);
                var dst       = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex);

                UnsafeUtility.MemCpyReplicate(dst, src, srcSizeOf, count);
                dstTypeIndex++;
            }

            dstTypeIndex = dstArchetype->FirstBufferComponent;
            var bufferComponentsEnd = srcArchetype->BufferComponentsEnd;

            for (var srcTypeIndex = srcArchetype->FirstBufferComponent; srcTypeIndex != bufferComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                var srcSizeOf = srcSizeOfs[srcTypeIndex];
                var src       = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex);
                var dst       = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex);

                var srcBufferCapacity = srcBufferCapacities[srcTypeIndex];
                var alignment         = 8; // TODO: Need a way to compute proper alignment for arbitrary non-generic types in TypeManager
                var elementSize       = TypeManager.GetTypeInfo(srcType.TypeIndex).ElementSize;
                for (int i = 0; i < count; ++i)
                {
                    BufferHeader *srcHdr = (BufferHeader *)src;
                    BufferHeader *dstHdr = (BufferHeader *)dst;
                    BufferHeader.Initialize(dstHdr, srcBufferCapacity);
                    BufferHeader.Assign(dstHdr, BufferHeader.GetElementPointer(srcHdr), srcHdr->Length, elementSize, alignment, false, 0);

                    dst += srcSizeOf;
                }

                dstTypeIndex++;
            }

            if (dstArchetype->NumManagedComponents > 0)
            {
                ReplicateManagedComponents(srcChunk, srcIndex, dstChunk, dstBaseIndex, count, ref entityComponentStore);
            }
        }