示例#1
0
        //cm
        internal void AddBufferRaw(Entity entity, int componentTypeIndex, BufferHeader *tempBuffer)
        {
            EntityComponentStore->AssertEntityHasComponent(entity, componentTypeIndex);

            ComponentJobSafetyManager->CompleteReadAndWriteDependency(componentTypeIndex);

            var bufferHeader = (BufferHeader *)EntityComponentStore->GetComponentDataWithTypeRW(entity, componentTypeIndex,
                                                                                                EntityComponentStore->GlobalSystemVersion);

            var typeInfo    = TypeManager.GetTypeInfo(componentTypeIndex);
            var elementSize = typeInfo.ElementSize;
            var alignment   = typeInfo.AlignmentInBytes;

            var total = bufferHeader->Length + tempBuffer->Length;

            if (total > bufferHeader->Capacity)
            {
                BufferHeader.EnsureCapacity(bufferHeader, total, elementSize, alignment, BufferHeader.TrashMode.RetainOldData);
            }

            UnsafeUtility.MemCpy(
                BufferHeader.GetElementPointer(bufferHeader) + bufferHeader->Length * elementSize,
                BufferHeader.GetElementPointer(tempBuffer),
                tempBuffer->Length * elementSize);

            bufferHeader->Length = total;
        }
        /// <summary>
        /// Copies all the elements from an array.
        /// </summary>
        /// <example>
        /// <code source="../../DocCodeSamples.Tests/DynamicBufferExamples.cs" language="csharp" region="dynamicbuffer.copyfrom.array"/>
        /// </example>
        /// <param name="v">A C# array containing the elements to copy.</param>
        /// <exception cref="ArgumentNullException"></exception>
        public void CopyFrom(T[] v)
        {
            if (v == null)
            {
                throw new ArgumentNullException(nameof(v));
            }

#if NET_DOTS
            Clear();
            foreach (var d in v)
            {
                Add(d);
            }
#else
            ResizeUninitialized(v.Length);
            CheckWriteAccess();

            GCHandle gcHandle = GCHandle.Alloc((object)v, GCHandleType.Pinned);
            IntPtr   num      = gcHandle.AddrOfPinnedObject();

            UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(m_Buffer),
                                 (void *)num, Length * UnsafeUtility.SizeOf <T>());
            gcHandle.Free();
#endif
        }
示例#3
0
        void AddToDestroyList(Chunk *chunk, int indexInChunk, int batchCount, int inputDestroyCount,
                              ref UnsafeList entitiesList, ref int minBufferLength, ref int maxBufferLength)
        {
            int indexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, m_LinkedGroupType);

            if (indexInArchetype != -1)
            {
                var baseHeader = ChunkDataUtility.GetComponentDataWithTypeRO(chunk, indexInChunk, m_LinkedGroupType);
                var stride     = chunk->Archetype->SizeOfs[indexInArchetype];
                for (int i = 0; i != batchCount; i++)
                {
                    var header = (BufferHeader *)(baseHeader + stride * i);

                    var entityGroupCount = header->Length - 1;
                    if (entityGroupCount <= 0)
                    {
                        continue;
                    }

                    var entityGroupArray = (Entity *)BufferHeader.GetElementPointer(header) + 1;

                    if (entitiesList.Capacity == 0)
                    {
                        entitiesList.SetCapacity <Entity>(inputDestroyCount * entityGroupCount /*, Allocator.TempJob*/);
                    }
                    entitiesList.AddRange <Entity>(entityGroupArray, entityGroupCount /*, Allocator.TempJob*/);

                    minBufferLength = math.min(minBufferLength, entityGroupCount);
                    maxBufferLength = math.max(maxBufferLength, entityGroupCount);
                }
            }
        }
 public TElement this[int index]
 {
     get
     {
         CheckBounds(index);
         return(UnsafeUtility.ReadArrayElement <TElement>(BufferHeader.GetElementPointer(m_Buffer), index));
     }
     set
     {
         // @FIXME
         //
         // In C# despite being `readonly` a list can have it's elements mutated, however for ECS data we have strict access writes.
         // For now we opt to silently skip until a proper fix is implemented.
         //
         // In order to properly fix this we need either:
         //
         // 1) A custom property bag for DynamicBufferContainer`1 which correctly sets IsReadOnly per element property.
         //    * While this is a more elegant solution we lose the built in machinery around ListPropertyBag`1. e.g. UI would not be quite right.
         //
         // 2) A fix directly in ListPropertyBag`1 to allow controlling IsReadOnly per element.
         //    * This is a best place to fix it but requires a package update of properties.
         //
         if (!m_IsReadOnly)
         {
             CheckBounds(index);
             UnsafeUtility.WriteArrayElement(BufferHeader.GetElementPointer(m_Buffer), index, value);
         }
     }
 }
示例#5
0
        public static void PatchEntitiesForPrefab(EntityPatchInfo *scalarPatches, int scalarPatchCount, BufferEntityPatchInfo *bufferPatches, int bufferPatchCount, byte *data, int indexInChunk, int entityCount, SparseEntityRemapInfo *remapping, int remappingCount)
        {
            // Patch scalars (single components) with entity references.
            for (int p = 0; p < scalarPatchCount; p++)
            {
                byte *entityData = data + scalarPatches[p].Offset;
                for (int e = 0; e != entityCount; e++)
                {
                    Entity *entity = (Entity *)(entityData + scalarPatches[p].Stride * (e + indexInChunk));
                    *       entity = RemapEntityForPrefab(remapping + e * remappingCount, remappingCount, *entity);
                }
            }

            // Patch buffers that contain entity references
            for (int p = 0; p < bufferPatchCount; ++p)
            {
                byte *bufferData = data + bufferPatches[p].BufferOffset;

                for (int e = 0; e != entityCount; e++)
                {
                    BufferHeader *header = (BufferHeader *)(bufferData + bufferPatches[p].BufferStride * (e + indexInChunk));

                    byte *elemsBase = BufferHeader.GetElementPointer(header) + bufferPatches[p].ElementOffset;
                    int   elemCount = header->Length;

                    for (int k = 0; k != elemCount; ++k)
                    {
                        Entity *entityPtr = (Entity *)elemsBase;
                        *       entityPtr = RemapEntityForPrefab(remapping + e * remappingCount, remappingCount, *entityPtr);
                        elemsBase += bufferPatches[p].ElementStride;
                    }
                }
            }
        }
示例#6
0
        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++;
            }
        }
示例#7
0
        public unsafe void AddRange(NativeArray <T> newElems)
        {
            this.CheckWriteAccess();
            int num    = UnsafeUtility.SizeOf <T>();
            int length = this.Length;

            this.ResizeUninitialized(length + newElems.Length);
            UnsafeUtility.MemCpy((void *)(BufferHeader.GetElementPointer(this.m_Buffer) + (length * num)), newElems.GetUnsafeReadOnlyPtr <T>(), (long)(num * newElems.Length));
        }
        public static unsafe void PatchEntities(EntityPatchInfo *scalarPatches, int scalarPatchCount, BufferEntityPatchInfo *bufferPatches, int bufferPatchCount, byte *data, int count, ref NativeArray <EntityRemapInfo> remapping)
        {
            int index = 0;

            while (true)
            {
                if (index >= scalarPatchCount)
                {
                    int num3 = 0;
                    while (num3 < bufferPatchCount)
                    {
                        byte *numPtr2 = data + bufferPatches[num3].BufferOffset;
                        int   num4    = 0;
                        while (true)
                        {
                            if (num4 == count)
                            {
                                num3++;
                                break;
                            }
                            BufferHeader *header  = (BufferHeader *)numPtr2;
                            byte *        numPtr3 = BufferHeader.GetElementPointer(header) + bufferPatches[num3].ElementOffset;
                            int           length  = header->Length;
                            int           num6    = 0;
                            while (true)
                            {
                                if (num6 == length)
                                {
                                    numPtr2 += bufferPatches[num3].BufferStride;
                                    num4++;
                                    break;
                                }
                                Entity *entityPtr2 = (Entity *)numPtr3;
                                entityPtr2[0] = RemapEntity(ref remapping, entityPtr2[0]);
                                numPtr3      += bufferPatches[num3].ElementStride;
                                num6++;
                            }
                        }
                    }
                    return;
                }
                byte *numPtr = data + scalarPatches[index].Offset;
                int   num2   = 0;
                while (true)
                {
                    if (num2 == count)
                    {
                        index++;
                        break;
                    }
                    Entity *entityPtr = (Entity *)numPtr;
                    entityPtr[0] = RemapEntity(ref remapping, entityPtr[0]);
                    numPtr      += scalarPatches[index].Stride;
                    num2++;
                }
            }
        }
        public static void InstantiateEntities(Entity srcEntity, Entity *outputEntities, int instanceCount,
                                               EntityComponentStore *entityComponentStore,
                                               ManagedComponentStore managedComponentStore,
                                               EntityGroupManager entityGroupManager)
        {
            var linkedType = TypeManager.GetTypeIndex <LinkedEntityGroup>();

            if (entityComponentStore->HasComponent(srcEntity, linkedType))
            {
                var header      = (BufferHeader *)entityComponentStore->GetComponentDataWithTypeRO(srcEntity, linkedType);
                var entityPtr   = (Entity *)BufferHeader.GetElementPointer(header);
                var entityCount = header->Length;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (entityCount == 0 || entityPtr[0] != srcEntity)
                {
                    throw new ArgumentException("LinkedEntityGroup[0] must always be the Entity itself.");
                }
                for (int i = 0; i < entityCount; i++)
                {
                    if (!entityComponentStore->Exists(entityPtr[i]))
                    {
                        throw new ArgumentException(
                                  "The srcEntity's LinkedEntityGroup references an entity that is invalid. (Entity at index {i} on the LinkedEntityGroup.)");
                    }

                    var archetype = entityComponentStore->GetArchetype(entityPtr[i]);
                    if (archetype->InstantiableArchetype == null)
                    {
                        throw new ArgumentException(
                                  "The srcEntity's LinkedEntityGroup references an entity that has already been destroyed. (Entity at index {i} on the LinkedEntityGroup. Only system state components are left on the entity)");
                    }
                }
#endif
                InstantiateEntitiesGroup(entityPtr, entityCount, outputEntities, instanceCount,
                                         entityComponentStore, managedComponentStore, entityGroupManager);
            }
            else
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (!entityComponentStore->Exists(srcEntity))
                {
                    throw new ArgumentException("srcEntity is not a valid entity");
                }

                var srcArchetype = entityComponentStore->GetArchetype(srcEntity);
                if (srcArchetype->InstantiableArchetype == null)
                {
                    throw new ArgumentException(
                              "srcEntity is not instantiable because it has already been destroyed. (Only system state components are left on it)");
                }
#endif
                InstantiateEntitiesOne(srcEntity, outputEntities, instanceCount, null, 0,
                                       entityComponentStore, managedComponentStore, entityGroupManager);
            }
        }
示例#10
0
        internal void *GetBufferRawRO(Entity entity, int typeIndex)
        {
            EntityComponentStore->AssertEntityHasComponent(entity, typeIndex);

            ComponentJobSafetyManager->CompleteReadAndWriteDependency(typeIndex);

            BufferHeader *header = (BufferHeader *)EntityComponentStore->GetComponentDataWithTypeRO(entity, typeIndex);

            return(BufferHeader.GetElementPointer(header));
        }
        public void AddRange(NativeArray<T> newElems)
        {
            CheckWriteAccess();
            int elemSize = UnsafeUtility.SizeOf<T>();
            int oldLength = Length;
            ResizeUninitialized(oldLength + newElems.Length);

            byte* basePtr = BufferHeader.GetElementPointer(m_Buffer);
            UnsafeUtility.MemCpy(basePtr + oldLength * elemSize, newElems.GetUnsafeReadOnlyPtr<T>(), elemSize * newElems.Length);
        }
        /// <summary>
        /// Copies all the elements from another dynamic buffer.
        /// </summary>
        /// <example>
        /// <code source="../../DocCodeSamples.Tests/DynamicBufferExamples.cs" language="csharp" region="dynamicbuffer.copyfrom.dynamicbuffer"/>
        /// </example>
        /// <param name="v">The dynamic buffer containing the elements to copy.</param>
        public void CopyFrom(DynamicBuffer <T> v)
        {
            ResizeUninitialized(v.Length);

            v.CheckReadAccess();
            CheckWriteAccess();

            UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(m_Buffer),
                                 BufferHeader.GetElementPointer(v.m_Buffer), Length * UnsafeUtility.SizeOf <T>());
        }
示例#13
0
        internal void *GetBufferRawRW(Entity entity, int typeIndex)
        {
            Entities->AssertEntityHasComponent(entity, typeIndex);

            ComponentJobSafetyManager.CompleteReadAndWriteDependency(typeIndex);

            BufferHeader *header = (BufferHeader *)Entities->GetComponentDataWithTypeRW(entity, typeIndex, Entities->GlobalSystemVersion);

            return(BufferHeader.GetElementPointer(header));
        }
 public void Insert(int index, T elem)
 {
     CheckWriteAccess();
     int length = Length;
     ResizeUninitialized(length + 1);
     CheckBounds(index); //CheckBounds after ResizeUninitialized since index == length is allowed
     int elemSize = UnsafeUtility.SizeOf<T>();
     byte* basePtr = BufferHeader.GetElementPointer(m_Buffer);
     UnsafeUtility.MemMove(basePtr + (index + 1) * elemSize, basePtr + index * elemSize, elemSize * (length - index));
     this[index] = elem;
 }
示例#15
0
        public unsafe void RemoveRange(int index, int count)
        {
            this.CheckWriteAccess();
            this.CheckBounds((index + count) - 1);
            int   num            = UnsafeUtility.SizeOf <T>();
            byte *elementPointer = BufferHeader.GetElementPointer(this.m_Buffer);

            UnsafeUtility.MemMove((void *)(elementPointer + (index * num)), (void *)(elementPointer + ((index + count) * num)), (long)(num * ((this.Length - count) - index)));
            int *numPtr1 = (int *)ref this.m_Buffer.Length;

            numPtr1[0] -= count;
        }
        /// <summary>
        /// Removes the specified number of elements, starting with the element at the specified index.
        /// </summary>
        /// <remarks>The buffer capacity remains unchanged.</remarks>
        /// <example>
        /// <code source="../../DocCodeSamples.Tests/DynamicBufferExamples.cs" language="csharp" region="dynamicbuffer.removerange"/>
        /// </example>
        /// <param name="index">The first element to remove.</param>
        /// <param name="count">How many elements tot remove.</param>
        public void RemoveRange(int index, int count)
        {
            CheckWriteAccess();
            CheckBounds(index + count - 1);

            int   elemSize = UnsafeUtility.SizeOf <T>();
            byte *basePtr  = BufferHeader.GetElementPointer(m_Buffer);

            UnsafeUtility.MemMove(basePtr + index * elemSize, basePtr + (index + count) * elemSize, (long)elemSize * (Length - count - index));

            m_Buffer->Length -= count;
        }
示例#17
0
            void GatherBlobAssetsMemoryOrdered(Archetype *archetype, Chunk *chunk, int typeIndexInArchetype, int entityCount)
            {
                var componentTypeInArchetype = archetype->Types[typeIndexInArchetype];

                if (componentTypeInArchetype.IsZeroSized || componentTypeInArchetype.IsSharedComponent)
                {
                    return;
                }

                var typeInfo          = TypeInfo[componentTypeInArchetype.TypeIndex & TypeManager.ClearFlagsMask];
                var blobAssetRefCount = typeInfo.BlobAssetRefOffsetCount;

                if (blobAssetRefCount == 0)
                {
                    return;
                }

                var blobAssetRefOffsets = BlobAssetRefOffsets + typeInfo.BlobAssetRefOffsetStartIndex;
                var chunkBuffer         = chunk->Buffer;
                var subArrayOffset      = archetype->Offsets[typeIndexInArchetype];
                var componentArrayStart = chunkBuffer + subArrayOffset;

                if (componentTypeInArchetype.IsBuffer)
                {
                    var header      = (BufferHeader *)componentArrayStart;
                    var strideSize  = archetype->SizeOfs[typeIndexInArchetype];
                    var elementSize = typeInfo.ElementSize;

                    for (var entityIndex = 0; entityIndex < entityCount; entityIndex++)
                    {
                        var bufferStart = BufferHeader.GetElementPointer(header);
                        var bufferEnd   = bufferStart + header->Length * elementSize;

                        for (var componentData = bufferStart; componentData < bufferEnd; componentData += elementSize)
                        {
                            AddBlobAssets(componentData, blobAssetRefOffsets, blobAssetRefCount);
                        }

                        header = (BufferHeader *)(((byte *)header) + strideSize);
                    }
                }
                else
                {
                    var componentSize = archetype->SizeOfs[typeIndexInArchetype];
                    var end           = componentArrayStart + componentSize * entityCount;

                    for (var componentData = componentArrayStart; componentData < end; componentData += componentSize)
                    {
                        AddBlobAssets(componentData, blobAssetRefOffsets, blobAssetRefCount);
                    }
                }
            }
        internal void *GetBufferRawRO(Entity entity, int typeIndex)
        {
            var access = GetCheckedEntityDataAccess();
            var ecs    = access->EntityComponentStore;

            ecs->AssertEntityHasComponent(entity, typeIndex);

            access->DependencyManager->CompleteReadAndWriteDependency(typeIndex);

            BufferHeader *header = (BufferHeader *)ecs->GetComponentDataWithTypeRO(entity, typeIndex);

            return(BufferHeader.GetElementPointer(header));
        }
示例#19
0
        public unsafe void Insert(int index, T elem)
        {
            this.CheckWriteAccess();
            int length = this.Length;

            this.ResizeUninitialized(length + 1);
            this.CheckBounds(index);
            int   num2           = UnsafeUtility.SizeOf <T>();
            byte *elementPointer = BufferHeader.GetElementPointer(this.m_Buffer);

            UnsafeUtility.MemMove((void *)(elementPointer + ((index + 1) * num2)), (void *)(elementPointer + (index * num2)), (long)(num2 * (length - index)));
            this.set_Item(index, elem);
        }
        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++;
                }
            }
        }
示例#21
0
            public void Execute(int index)
            {
                var chunk     = Chunks[index].m_Chunk;
                var archetype = chunk->Archetype;

                for (var typeIndexInArchetype = 0; typeIndexInArchetype < archetype->TypesCount; typeIndexInArchetype++)
                {
                    var componentTypeInArchetype = archetype->Types[typeIndexInArchetype];
                    var typeInfo = TypeInfoStream.GetTypeInfo(componentTypeInArchetype.TypeIndex);

                    if (typeInfo.EntityOffsetCount == 0)
                    {
                        // This type has no entity references. Skip.
                        continue;
                    }

                    if (componentTypeInArchetype.IsSharedComponent || componentTypeInArchetype.IsZeroSized)
                    {
                        // @TODO Should we handle shared components with references? Is that a thing?
                        continue;
                    }

                    var typeInChunkPtr = ChunkUtility.GetBuffer(chunk) + archetype->Offsets[typeIndexInArchetype];
                    var typeSizeOf     = archetype->SizeOfs[typeIndexInArchetype];

                    var changed = false;

                    for (var entityIndexInChunk = 0; entityIndexInChunk < Chunks[index].Count; entityIndexInChunk++)
                    {
                        var componentDataPtr = typeInChunkPtr + typeSizeOf * entityIndexInChunk;

                        if (componentTypeInArchetype.IsBuffer)
                        {
                            var bufferHeader = (BufferHeader *)componentDataPtr;
                            var bufferLength = bufferHeader->Length;
                            var bufferPtr    = BufferHeader.GetElementPointer(bufferHeader);
                            changed |= SetMissingEntityReferencesToNullForComponent(typeInfo, bufferPtr, bufferLength);
                        }
                        else
                        {
                            changed |= SetMissingEntityReferencesToNullForComponent(typeInfo, componentDataPtr, 1);
                        }
                    }

                    if (changed)
                    {
                        chunk->SetChangeVersion(typeIndexInArchetype, GlobalSystemVersion);
                    }
                }
            }
 /// <summary>
 /// Array-like indexing operator.
 /// </summary>
 /// <example>
 /// <code source="../../DocCodeSamples.Tests/DynamicBufferExamples.cs" language="csharp" region="dynamicbuffer.indexoperator"/>
 /// </example>
 /// <param name="index">The zero-based index.</param>
 public T this [int index]
 {
     get
     {
         CheckReadAccess();
         CheckBounds(index);
         return(UnsafeUtility.ReadArrayElement <T>(BufferHeader.GetElementPointer(m_Buffer), index));
     }
     set
     {
         CheckWriteAccess();
         CheckBounds(index);
         UnsafeUtility.WriteArrayElement <T>(BufferHeader.GetElementPointer(m_Buffer), index, value);
     }
 }
示例#23
0
        public void InstantiateEntities(Entity srcEntity, Entity *outputEntities, int instanceCount)
        {
            if (HasComponent(srcEntity, m_LinkedGroupType))
            {
                var header      = (BufferHeader *)GetComponentDataWithTypeRO(srcEntity, m_LinkedGroupType);
                var entityPtr   = (Entity *)BufferHeader.GetElementPointer(header);
                var entityCount = header->Length;

                InstantiateEntitiesGroup(entityPtr, entityCount, outputEntities, true, instanceCount, true);
            }
            else
            {
                InstantiateEntitiesOne(srcEntity, outputEntities, instanceCount, null, 0, true);
            }
        }
示例#24
0
            public void Execute(int index)
            {
                var chunk       = Chunks[index].m_Chunk;
                var archetype   = chunk->Archetype;
                var typesCount  = archetype->TypesCount;
                var entityCount = Chunks[index].Count;

                for (var typeIndexInArchetype = 1; typeIndexInArchetype < typesCount; typeIndexInArchetype++)
                {
                    var componentTypeInArchetype = archetype->Types[typeIndexInArchetype];

                    if (!componentTypeInArchetype.HasEntityReferences || componentTypeInArchetype.IsSharedComponent || componentTypeInArchetype.IsZeroSized)
                    {
                        continue;
                    }

                    var typeInfo       = TypeInfo[componentTypeInArchetype.TypeIndex & TypeManager.ClearFlagsMask];
                    var typeInChunkPtr = GetChunkBuffer(chunk) + archetype->Offsets[typeIndexInArchetype];
                    var typeSizeOf     = archetype->SizeOfs[typeIndexInArchetype];

                    var changed = false;

                    if (componentTypeInArchetype.IsBuffer)
                    {
                        for (var entityIndexInChunk = 0; entityIndexInChunk < entityCount; entityIndexInChunk++)
                        {
                            var componentDataPtr = typeInChunkPtr + typeSizeOf * entityIndexInChunk;
                            var bufferHeader     = (BufferHeader *)componentDataPtr;
                            var bufferLength     = bufferHeader->Length;
                            var bufferPtr        = BufferHeader.GetElementPointer(bufferHeader);
                            changed |= ClearEntityReferences(typeInfo, bufferPtr, bufferLength);
                        }
                    }
                    else
                    {
                        for (var entityIndexInChunk = 0; entityIndexInChunk < entityCount; entityIndexInChunk++)
                        {
                            var componentDataPtr = typeInChunkPtr + typeSizeOf * entityIndexInChunk;
                            changed |= ClearEntityReferences(typeInfo, componentDataPtr, 1);
                        }
                    }

                    if (changed)
                    {
                        chunk->SetChangeVersion(typeIndexInArchetype, GlobalSystemVersion);
                    }
                }
            }
示例#25
0
        public void AssertCanInstantiateEntities(Entity srcEntity, Entity *outputEntities, int instanceCount)
        {
            if (HasComponent(srcEntity, m_LinkedGroupType))
            {
                var header      = (BufferHeader *)GetComponentDataWithTypeRO(srcEntity, m_LinkedGroupType);
                var entityPtr   = (Entity *)BufferHeader.GetElementPointer(header);
                var entityCount = header->Length;

                if (entityCount == 0 || entityPtr[0] != srcEntity)
                {
                    throw new ArgumentException("LinkedEntityGroup[0] must always be the Entity itself.");
                }

                for (int i = 0; i < entityCount; i++)
                {
                    if (!Exists(entityPtr[i]))
                    {
                        throw new ArgumentException(
                                  "The srcEntity's LinkedEntityGroup references an entity that is invalid. (Entity at index {i} on the LinkedEntityGroup.)");
                    }

                    var archetype = GetArchetype(entityPtr[i]);
                    if (archetype->InstantiableArchetype == null)
                    {
                        throw new ArgumentException(
                                  "The srcEntity's LinkedEntityGroup references an entity that has already been destroyed. (Entity at index {i} on the LinkedEntityGroup. Only system state components are left on the entity)");
                    }
                }
            }
            else
            {
                if (!Exists(srcEntity))
                {
                    throw new ArgumentException("srcEntity is not a valid entity");
                }

                var srcArchetype = GetArchetype(srcEntity);
                if (srcArchetype->InstantiableArchetype == null)
                {
                    throw new ArgumentException(
                              "srcEntity is not instantiable because it has already been destroyed. (Only system state components are left on it)");
                }
            }
        }
        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;
                    }
                }
            }
        }
示例#27
0
 unsafe object GetObject(void *pointer, Type type)
 {
     if (typeof(IBufferElementData).IsAssignableFrom(type))
     {
         var           listType            = typeof(List <>);
         var           constructedListType = listType.MakeGenericType(type);
         var           instance            = (IList)Activator.CreateInstance(constructedListType);
         var           size   = Marshal.SizeOf(type);
         BufferHeader *header = (BufferHeader *)pointer;
         var           begin  = BufferHeader.GetElementPointer(header);
         for (var i = 0; i < header->Length; ++i)
         {
             var item = begin + (size * i);
             instance.Add(Marshal.PtrToStructure((IntPtr)item, type));
         }
         return(instance);
     }
     else
     {
         return(Marshal.PtrToStructure((IntPtr)pointer, type));
     }
 }
        public static void PatchEntities(EntityPatchInfo *scalarPatches, int scalarPatchCount,
                                         BufferEntityPatchInfo *bufferPatches, int bufferPatchCount,
                                         byte *chunkBuffer, int entityCount, ref NativeArray <EntityRemapInfo> remapping)
        {
            // Patch scalars (single components) with entity references.
            for (int p = 0; p < scalarPatchCount; p++)
            {
                byte *entityData = chunkBuffer + scalarPatches[p].Offset;
                for (int i = 0; i != entityCount; i++)
                {
                    Entity *entity = (Entity *)entityData;
                    *       entity = RemapEntity(ref remapping, *entity);
                    entityData += scalarPatches[p].Stride;
                }
            }

            // Patch buffers that contain entity references
            for (int p = 0; p < bufferPatchCount; ++p)
            {
                byte *bufferData = chunkBuffer + bufferPatches[p].BufferOffset;

                for (int i = 0; i != entityCount; ++i)
                {
                    BufferHeader *header = (BufferHeader *)bufferData;

                    byte *elemsBase = BufferHeader.GetElementPointer(header) + bufferPatches[p].ElementOffset;
                    int   elemCount = header->Length;

                    for (int k = 0; k != elemCount; ++k)
                    {
                        Entity *entityPtr = (Entity *)elemsBase;
                        *       entityPtr = RemapEntity(ref remapping, *entityPtr);
                        elemsBase += bufferPatches[p].ElementStride;
                    }

                    bufferData += bufferPatches[p].BufferStride;
                }
            }
        }
        /// <summary>
        /// Return a native array that aliases the original buffer contents.
        /// </summary>
        /// <remarks>You can only access the native array as long as the
        /// the buffer memory has not been reallocated. Several dynamic buffer operations,
        /// such as <see cref="Add"/> and <see cref="TrimExcess"/> can result in
        /// buffer reallocation.</remarks>
        /// <example>
        /// <code source="../../DocCodeSamples.Tests/DynamicBufferExamples.cs" language="csharp" region="dynamicbuffer.asnativearray"/>
        /// </example>
        public NativeArray <T> AsNativeArray()
        {
            CheckReadAccess();

            var shadow = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(BufferHeader.GetElementPointer(m_Buffer), Length, Allocator.Invalid);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var handle = m_Safety1;
            AtomicSafetyHandle.UseSecondaryVersion(ref handle);
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref shadow, handle);
#endif
            return(shadow);
        }
 /// <summary>
 /// Gets an <see langword="unsafe"/> pointer to the contents of the buffer.
 /// </summary>
 /// <remarks>This function can only be called in unsafe code contexts.</remarks>
 /// <returns>A typed, unsafe pointer to the first element in the buffer.</returns>
 public void *GetUnsafePtr()
 {
     CheckWriteAccess();
     return(BufferHeader.GetElementPointer(m_Buffer));
 }