public void AssertCanRemoveComponent(NativeArray <ArchetypeChunk> chunkArray, ComponentType componentType)
        {
            var chunks = (ArchetypeChunk *)chunkArray.GetUnsafeReadOnlyPtr();

            for (int i = 0; i < chunkArray.Length; ++i)
            {
                var chunk = chunks[i].m_Chunk;
                if (ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, componentType.TypeIndex) != -1)
                {
                    if (chunk->Locked)
                    {
                        throw new InvalidOperationException(
                                  "Cannot remove components from locked Chunks. Unlock Chunk first.");
                    }
                }
            }
        }
        public void GetCacheForType(int componentType, out ComponentChunkCache cache, out int typeIndexInArchetype)
        {
            var archetype = m_CurrentMatchingArchetype->Archetype;

            typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, componentType);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (typeIndexInArchetype == -1)
            {
                throw new System.ArgumentException("componentType does not exist in the iterated archetype");
            }
#endif

            cache.CachedBeginIndex = m_CurrentChunkIndex + m_CurrentArchetypeIndex;
            cache.CachedEndIndex   = cache.CachedBeginIndex + m_CurrentChunk->Count;
            cache.CachedSizeOf     = archetype->SizeOfs[typeIndexInArchetype];
            cache.CachedPtr        = m_CurrentChunk->Buffer + archetype->Offsets[typeIndexInArchetype] - cache.CachedBeginIndex * cache.CachedSizeOf;
        }
        public unsafe int GetSharedComponentIndex <T>(ArchetypeChunkSharedComponentType <T> chunkSharedComponentData) where T : struct, ISharedComponentData
        {
            int num4;

            Unity.Entities.Archetype *archetype = this.m_Chunk.Archetype;
            int indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, chunkSharedComponentData.m_TypeIndex);

            if (indexInTypeArray == -1)
            {
                num4 = -1;
            }
            else
            {
                int index = archetype->SharedComponentOffset[indexInTypeArray];
                num4 = this.m_Chunk.SharedComponentValueArray[index];
            }
            return(num4);
        }
            public unsafe void Execute(int index)
            {
                var chunk            = Chunks[index].m_Chunk;
                var chunkChangeFlags = ChunkChangeFlags[index];
                var baseIndex        = Offsets[index];

                var archetype = chunk->Archetype;
                var componentIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, ComponentTypeIndex);
                var componentBuffer           = (TComponent *)(ChunkUtility.GetBuffer(chunk) + archetype->Offsets[componentIndexInArchetype]);

                for (var i = 0; i < chunk->Count; ++i)
                {
                    Entities[baseIndex + i] = new EntityInChunkWithComponent <TComponent>
                    {
                        EntityInChunk = new EntityInChunk {
                            Chunk = chunk, IndexInChunk = i
                        },
                        Component        = componentBuffer[i],
                        ChunkChangeFlags = chunkChangeFlags
                    };
                }
            }
Пример #5
0
        public bool HasComponent(Entity entity, ComponentType type)
        {
            if (!Exists(entity))
            {
                return(false);
            }

            var archetype = m_Entities[entity.Index].Archetype;

            if (!type.IsFixedArray)
            {
                return(ChunkDataUtility.GetIndexInTypeArray(archetype, type.TypeIndex) != -1);
            }

            var idx = ChunkDataUtility.GetIndexInTypeArray(archetype, type.TypeIndex);

            if (idx == -1)
            {
                return(false);
            }

            return(archetype->Types[idx].FixedArrayLength == type.FixedArrayLength);
        }
Пример #6
0
        public void AssertCanAddComponent(NativeArray <ArchetypeChunk> chunkArray, ComponentType componentType)
        {
            var chunks = (ArchetypeChunk *)chunkArray.GetUnsafeReadOnlyPtr();

            for (int i = 0; i < chunkArray.Length; ++i)
            {
                var chunk = chunks[i].m_Chunk;
                if (ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, componentType.TypeIndex) != -1)
                {
                    throw new ArgumentException(
                              $"A component with type:{componentType} has already been added to the chunk.");
                }
                if (chunk->Locked)
                {
                    throw new InvalidOperationException("Cannot add components to locked Chunks. Unlock Chunk first.");
                }
                if (chunk->LockedEntityOrder && !componentType.IsZeroSized)
                {
                    throw new InvalidOperationException(
                              "Cannot add non-zero sized components to LockedEntityOrder Chunks. Unlock Chunk first.");
                }
            }
        }
        public unsafe BufferAccessor <T> GetBufferAccessor <T>(ArchetypeChunkBufferType <T> bufferComponentType) where T : struct, IBufferElementData
        {
            BufferAccessor <T> accessor;

            AtomicSafetyHandle.CheckReadAndThrow(bufferComponentType.m_Safety);
            Unity.Entities.Archetype *archetype = this.m_Chunk.Archetype;
            int indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, bufferComponentType.m_TypeIndex);

            if (indexInTypeArray == -1)
            {
                accessor = new BufferAccessor <T>(null, 0, 0, true, bufferComponentType.m_Safety, bufferComponentType.m_ArrayInvalidationSafety);
            }
            else
            {
                if (!bufferComponentType.IsReadOnly)
                {
                    this.m_Chunk.ChangeVersion[indexInTypeArray] = bufferComponentType.GlobalSystemVersion;
                }
                int count = this.m_Chunk.Count;
                accessor = new BufferAccessor <T>(&this.m_Chunk.Buffer.FixedElementField + archetype->Offsets[indexInTypeArray], count, archetype->SizeOfs[indexInTypeArray], bufferComponentType.IsReadOnly, bufferComponentType.m_Safety, bufferComponentType.m_ArrayInvalidationSafety);
            }
            return(accessor);
        }
Пример #8
0
        public NativeArray <T> GetNativeArray <T>(ArchetypeChunkComponentType <T> chunkComponentType)
            where T : struct, IComponentData
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (chunkComponentType.m_IsZeroSized)
            {
                throw new ArgumentException($"ArchetypeChunk.GetNativeArray<{typeof(T)}> cannot be called on zero-sized IComponentData");
            }

            AtomicSafetyHandle.CheckReadAndThrow(chunkComponentType.m_Safety);
#endif
            var archetype            = m_Chunk->Archetype;
            var typeIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex);
            if (typeIndexInArchetype == -1)
            {
                var emptyResult =
                    NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(null, 0, 0);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref emptyResult, chunkComponentType.m_Safety);
#endif
                return(emptyResult);
            }

            var buffer      = m_Chunk->Buffer;
            var length      = m_Chunk->Count;
            var startOffset = archetype->Offsets[typeIndexInArchetype];
            var result      = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(buffer + startOffset, length, Allocator.None);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, chunkComponentType.m_Safety);
#endif
            if (!chunkComponentType.IsReadOnly)
            {
                m_Chunk->SetChangeVersion(typeIndexInArchetype, chunkComponentType.GlobalSystemVersion);
            }
            return(result);
        }
Пример #9
0
        public void AssertCanAddChunkComponent(NativeArray <ArchetypeChunk> chunkArray, ComponentType componentType)
        {
            var chunks = (ArchetypeChunk *)chunkArray.GetUnsafeReadOnlyPtr();

            for (int i = 0; i < chunkArray.Length; ++i)
            {
                var chunk = chunks[i].m_Chunk;
                if (ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, componentType.TypeIndex) != -1)
                {
                    throw new ArgumentException(
                              $"A chunk component with type:{componentType} has already been added to the chunk.");
                }
                if (chunk->Locked)
                {
                    throw new InvalidOperationException(
                              "Cannot add chunk components to locked Chunks. Unlock Chunk first.");
                }
                if ((chunk->metaChunkEntity != Entity.Null) && GetChunk(chunk->metaChunkEntity)->Locked)
                {
                    throw new InvalidOperationException(
                              "Cannot add chunk components if Meta Chunk is locked. Unlock Meta Chunk first.");
                }
            }
        }
Пример #10
0
            public void Execute(int index)
            {
                var chunk      = Chunks[index].m_Chunk;
                var flags      = Flags[index];
                var startIndex = EntityCounts[index];

                var archetype = chunk->Archetype;
                var entityGuidIndexInArchetype = ChunkDataUtility.GetIndexInTypeArray(archetype, EntityGuidTypeIndex);
                var entityGuidBuffer           = (EntityGuid *)(ChunkDataUtility.GetChunkBuffer(chunk) + archetype->Offsets[entityGuidIndexInArchetype]);

                var entitiesIndex = startIndex;

                for (var i = 0; i < chunk->Count; ++i)
                {
                    Entities[entitiesIndex++] = new EntityInChunkWithGuid
                    {
                        EntityInChunk = new EntityInChunk {
                            Chunk = chunk, IndexInChunk = i
                        },
                        EntityGuid = entityGuidBuffer[i],
                        Flags      = flags
                    };
                }
            }
Пример #11
0
            // This must be run after chunks have been remapped since FreeChunksBySharedComponents needs the shared component
            // indices in the chunks to be remapped
            public void Execute(int index)
            {
                var srcArchetype  = remapArchetypes[index].srcArchetype;
                int srcChunkCount = srcArchetype->Chunks.Count;

                var dstArchetype  = remapArchetypes[index].dstArchetype;
                int dstChunkCount = dstArchetype->Chunks.Count;

                if (dstArchetype->Chunks.Capacity < srcChunkCount + dstChunkCount)
                {
                    dstArchetype->Chunks.Grow(srcChunkCount + dstChunkCount);
                }

                UnsafeUtility.MemCpy(dstArchetype->Chunks.p + dstChunkCount, srcArchetype->Chunks.p,
                                     sizeof(Chunk *) * srcChunkCount);

                if (srcArchetype->NumSharedComponents == 0)
                {
                    if (srcArchetype->ChunksWithEmptySlots.Count != 0)
                    {
                        dstArchetype->ChunksWithEmptySlotsUnsafePtrList.SetCapacity(
                            srcArchetype->ChunksWithEmptySlots.Count + dstArchetype->ChunksWithEmptySlots.Count);
                        dstArchetype->ChunksWithEmptySlotsUnsafePtrList.Append(
                            srcArchetype->ChunksWithEmptySlotsUnsafePtrList);
                        srcArchetype->ChunksWithEmptySlotsUnsafePtrList.Resize(0);
                    }
                }
                else
                {
                    for (int i = 0; i < dstArchetype->NumSharedComponents; ++i)
                    {
                        var srcArray = srcArchetype->Chunks.GetSharedComponentValueArrayForType(i);
                        var dstArray = dstArchetype->Chunks.GetSharedComponentValueArrayForType(i) + dstChunkCount;
                        for (int j = 0; j < srcChunkCount; ++j)
                        {
                            int srcIndex = srcArray[j];
                            int remapped = remapShared[srcIndex];
                            dstArray[j] = remapped;
                        }
                    }

                    for (int i = 0; i < srcChunkCount; ++i)
                    {
                        var chunk = dstArchetype->Chunks.p[i + dstChunkCount];
                        if (chunk->Count < chunk->Capacity)
                        {
                            dstArchetype->FreeChunksBySharedComponents.Add(dstArchetype->Chunks.p[i + dstChunkCount]);
                        }
                    }

                    srcArchetype->FreeChunksBySharedComponents.Init(16);
                }

                var globalSystemVersion = dstEntityComponentStore->GlobalSystemVersion;

                // Set change versions to GlobalSystemVersion
                for (int iType = 0; iType < dstArchetype->TypesCount; ++iType)
                {
                    var dstArray = dstArchetype->Chunks.GetChangeVersionArrayForType(iType) + dstChunkCount;
                    for (int i = 0; i < srcChunkCount; ++i)
                    {
                        dstArray[i] = globalSystemVersion;
                    }
                }

                // Copy chunk count array
                var dstCountArray = dstArchetype->Chunks.GetChunkEntityCountArray() + dstChunkCount;

                UnsafeUtility.MemCpy(dstCountArray, srcArchetype->Chunks.GetChunkEntityCountArray(),
                                     sizeof(int) * srcChunkCount);

                // Fix up chunk pointers in ChunkHeaders
                if (dstArchetype->HasChunkComponents)
                {
                    var metaArchetype    = dstArchetype->MetaChunkArchetype;
                    var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(metaArchetype, chunkHeaderType);
                    var offset           = metaArchetype->Offsets[indexInTypeArray];
                    var sizeOf           = metaArchetype->SizeOfs[indexInTypeArray];

                    for (int i = 0; i < srcChunkCount; ++i)
                    {
                        // Set chunk header without bumping change versions since they are zeroed when processing meta chunk
                        // modifying them here would be a race condition
                        var chunk           = dstArchetype->Chunks.p[i + dstChunkCount];
                        var metaChunkEntity = chunk->metaChunkEntity;
                        dstEntityComponentStore->GetChunk(metaChunkEntity, out var metaChunk, out var indexInMetaChunk);
                        var chunkHeader = (ChunkHeader *)(metaChunk->Buffer + (offset + sizeOf * indexInMetaChunk));
                        chunkHeader->ArchetypeChunk = new ArchetypeChunk(chunk, dstEntityComponentStore);
                    }
                }

                dstArchetype->EntityCount  += srcArchetype->EntityCount;
                dstArchetype->Chunks.Count += srcChunkCount;
                srcArchetype->Chunks.Dispose();
                srcArchetype->EntityCount = 0;
            }
Пример #12
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="chunkComponentType"></param>
 /// <returns></returns>
 public bool Has(ArchetypeChunkComponentTypeDynamic chunkComponentType)
 {
     ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex, ref chunkComponentType.m_TypeLookupCache);
     return(chunkComponentType.m_TypeLookupCache != -1);
 }
Пример #13
0
        private void AddArchetypeIfMatching(Archetype *archetype, EntityGroupData *group)
        {
            // If the group has more actually required types than the archetype it can never match, so early out as an optimization
            if (group->RequiredComponentsCount - group->SubtractiveComponentsCount > archetype->TypesCount)
            {
                return;
            }
            var typeI             = 0;
            var prevTypeI         = 0;
            var disabledIndex     = TypeManager.GetTypeIndex <Disabled>();
            var requestedDisabled = false;

            for (var i = 0; i < group->RequiredComponentsCount; ++i, ++typeI)
            {
                while (archetype->Types[typeI].TypeIndex < group->RequiredComponents[i].TypeIndex &&
                       typeI < archetype->TypesCount)
                {
                    ++typeI;
                }

                if (group->RequiredComponents[i].TypeIndex == disabledIndex)
                {
                    requestedDisabled = true;
                }

                var hasComponent = !(typeI >= archetype->TypesCount);

                // Type mismatch
                if (hasComponent && archetype->Types[typeI].TypeIndex != group->RequiredComponents[i].TypeIndex)
                {
                    hasComponent = false;
                }

                if (hasComponent && group->RequiredComponents[i].AccessModeType == ComponentType.AccessMode.Subtractive)
                {
                    return;
                }
                if (!hasComponent &&
                    group->RequiredComponents[i].AccessModeType != ComponentType.AccessMode.Subtractive)
                {
                    return;
                }
                if (hasComponent)
                {
                    prevTypeI = typeI;
                }
                else
                {
                    typeI = prevTypeI;
                }
            }

            if (archetype->Disabled && (!requestedDisabled))
            {
                return;
            }

            var match = (MatchingArchetypes *)m_GroupDataChunkAllocator.Allocate(
                MatchingArchetypes.GetAllocationSize(group->RequiredComponentsCount), 8);

            match->Archetype = archetype;
            var typeIndexInArchetypeArray = match->TypeIndexInArchetypeArray;

            if (group->LastMatchingArchetype == null)
            {
                group->LastMatchingArchetype = match;
            }

            match->Next = group->FirstMatchingArchetype;
            group->FirstMatchingArchetype = match;

            for (var component = 0; component < group->RequiredComponentsCount; ++component)
            {
                var typeComponentIndex = -1;
                if (group->RequiredComponents[component].AccessModeType != ComponentType.AccessMode.Subtractive)
                {
                    typeComponentIndex =
                        ChunkDataUtility.GetIndexInTypeArray(archetype, group->RequiredComponents[component].TypeIndex);
                    Assert.AreNotEqual(-1, typeComponentIndex);
                }

                typeIndexInArchetypeArray[component] = typeComponentIndex;
            }
        }
            public void Execute()
            {
                for (var i = 0; i < CreatedEntities.Length; ++i)
                {
                    var entityGuid      = CreatedEntities[i].Component;
                    var afterEntity     = CreatedEntities[i].EntityInChunk;
                    var afterChunk      = afterEntity.Chunk;
                    var afterArchetype  = afterChunk->Archetype;
                    var afterTypesCount = afterArchetype->TypesCount;

                    for (var afterIndexInTypeArray = 1; afterIndexInTypeArray < afterTypesCount; afterIndexInTypeArray++)
                    {
                        var typeInArchetype = afterArchetype->Types[afterIndexInTypeArray];

                        if (typeInArchetype.IsSystemStateComponent)
                        {
                            continue;
                        }

                        var typeIndex = typeInArchetype.TypeIndex;
                        var typeInfo  = TypeInfoStream.GetTypeInfo(typeIndex);

                        AddComponentData(
                            afterChunk,
                            afterArchetype,
                            typeInArchetype,
                            afterIndexInTypeArray,
                            afterEntity.IndexInChunk,
                            entityGuid,
                            typeIndex,
                            typeInfo
                            );
                    }
                }

                for (var i = 0; i < ModifiedEntities.Length; ++i)
                {
                    var modification = ModifiedEntities[i];
                    var entityGuid   = modification.EntityGuid;

                    var afterEntity     = modification.After;
                    var afterChunk      = afterEntity.Chunk;
                    var afterArchetype  = afterChunk->Archetype;
                    var afterTypesCount = afterArchetype->TypesCount;

                    var beforeEntity     = modification.Before;
                    var beforeChunk      = beforeEntity.Chunk;
                    var beforeArchetype  = beforeChunk->Archetype;
                    var beforeTypesCount = beforeArchetype->TypesCount;

                    for (var afterIndexInTypeArray = 1; afterIndexInTypeArray < afterTypesCount; afterIndexInTypeArray++)
                    {
                        var afterTypeInArchetype = afterArchetype->Types[afterIndexInTypeArray];

                        if (afterTypeInArchetype.IsSystemStateComponent || afterTypeInArchetype.IsChunkComponent)
                        {
                            continue;
                        }

                        var typeIndex = afterTypeInArchetype.TypeIndex;
                        var beforeIndexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(beforeArchetype, typeIndex);
                        var typeInfo = TypeInfoStream.GetTypeInfo(typeIndex);

                        // This type is missing in the before entity.
                        // This means we are dealing with a newly added component.
                        if (-1 == beforeIndexInTypeArray)
                        {
                            // This type does not exist on the before world. This was a newly added component.
                            AddComponentData(
                                afterChunk,
                                afterArchetype,
                                afterTypeInArchetype,
                                afterIndexInTypeArray,
                                afterEntity.IndexInChunk,
                                entityGuid,
                                typeIndex,
                                typeInfo
                                );

                            continue;
                        }

                        if (modification.CanCompareChunkVersions && afterChunk->GetChangeVersion(afterIndexInTypeArray) == beforeChunk->GetChangeVersion(beforeIndexInTypeArray))
                        {
                            continue;
                        }

                        SetComponentData(
                            afterChunk,
                            afterArchetype,
                            afterTypeInArchetype,
                            afterIndexInTypeArray,
                            afterEntity.IndexInChunk,
                            beforeChunk,
                            beforeArchetype,
                            beforeIndexInTypeArray,
                            beforeEntity.IndexInChunk,
                            entityGuid,
                            typeIndex,
                            typeInfo);
                    }

                    for (var beforeTypeIndexInArchetype = 1; beforeTypeIndexInArchetype < beforeTypesCount; beforeTypeIndexInArchetype++)
                    {
                        var beforeComponentTypeInArchetype = beforeArchetype->Types[beforeTypeIndexInArchetype];

                        if (beforeComponentTypeInArchetype.IsSystemStateComponent)
                        {
                            continue;
                        }

                        var beforeTypeIndex = beforeComponentTypeInArchetype.TypeIndex;

                        if (-1 == ChunkDataUtility.GetIndexInTypeArray(afterArchetype, beforeTypeIndex))
                        {
                            var packedComponent = PackComponent(entityGuid, beforeTypeIndex, TypeInfoStream.GetTypeInfo(beforeTypeIndex).StableTypeHash);
                            RemoveComponents.Add(packedComponent);
                        }
                    }
                }
            }
 public unsafe bool Has <T>(ArchetypeChunkComponentType <T> chunkComponentType) where T : struct, IComponentData =>
 (ChunkDataUtility.GetIndexInTypeArray(this.m_Chunk.Archetype, chunkComponentType.m_TypeIndex) != -1);