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 }; } }
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); }
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); }
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); }
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."); } } }
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 }; } }
// 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; }
/// <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); }
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);