Boat Attack使用了Universal RP的许多新图形功能,可以用于探索 Universal RP 的使用方式和技巧。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

675 行
31 KiB

using System;
using Unity.Assertions;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Mathematics;
namespace Unity.Entities
{
/// <summary>
/// Utilities which work on EntityManager data (for CreateDestroyEntities)
/// Which require more than one of of these, in this order, as last parameters:
/// EntityComponentStore* entityComponentStore
/// SharedComponentDataManager sharedComponentDataManager
/// </summary>
internal static unsafe class EntityManagerCreateDestroyEntitiesUtility
{
// ----------------------------------------------------------------------------------------------------------
// PUBLIC
// ----------------------------------------------------------------------------------------------------------
public static void CreateMetaEntityForChunk(Chunk* chunk,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
CreateEntities(chunk->Archetype->MetaChunkArchetype, &chunk->metaChunkEntity, 1,
entityComponentStore, managedComponentStore);
var typeIndex = TypeManager.GetTypeIndex<ChunkHeader>();
var chunkHeader =
(ChunkHeader*) entityComponentStore->GetComponentDataWithTypeRW(chunk->metaChunkEntity, typeIndex,
entityComponentStore->GlobalSystemVersion);
chunkHeader->ArchetypeChunk = new ArchetypeChunk(chunk, entityComponentStore);
}
public static void CreateEntities(Archetype* archetype, Entity* entities, int count,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var sharedComponentValues = stackalloc int[archetype->NumSharedComponents];
UnsafeUtility.MemClear(sharedComponentValues, archetype->NumSharedComponents * sizeof(int));
while (count != 0)
{
var chunk = GetChunkWithEmptySlots(archetype, sharedComponentValues,
entityComponentStore, managedComponentStore);
int allocatedIndex;
var allocatedCount = AllocateIntoChunk(chunk, count, out allocatedIndex,
entityComponentStore, managedComponentStore);
entityComponentStore->AllocateEntities(archetype, chunk, allocatedIndex, allocatedCount, entities);
ChunkDataUtility.InitializeComponents(chunk, allocatedIndex, allocatedCount);
chunk->SetAllChangeVersions(entityComponentStore->GlobalSystemVersion);
entities += allocatedCount;
count -= allocatedCount;
}
entityComponentStore->IncrementComponentTypeOrderVersion(archetype);
}
public static void DestroyEntities(NativeArray<ArchetypeChunk> chunkArray,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var chunks = (ArchetypeChunk*) chunkArray.GetUnsafeReadOnlyPtr();
for (int i = 0; i != chunkArray.Length; i++)
{
var chunk = chunks[i].m_Chunk;
DestroyBatch((Entity*) chunk->Buffer, chunk, 0, chunk->Count,
entityComponentStore, managedComponentStore);
}
}
public static void DestroyEntities(Entity* entities, int count,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var entityIndex = 0;
var additionalDestroyList = new UnsafeList();
int minDestroyStride = int.MaxValue;
int maxDestroyStride = 0;
while (entityIndex != count)
{
var entityBatchInChunk =
entityComponentStore->GetFirstEntityBatchInChunk(entities + entityIndex, count - entityIndex);
var chunk = entityBatchInChunk.Chunk;
var batchCount = entityBatchInChunk.Count;
var indexInChunk = entityBatchInChunk.StartIndex;
if (chunk == null)
{
entityIndex += batchCount;
continue;
}
AddToDestroyList(chunk, indexInChunk, batchCount, count, ref additionalDestroyList,
ref minDestroyStride, ref maxDestroyStride);
DestroyBatch(entities + entityIndex, chunk, indexInChunk, batchCount,
entityComponentStore, managedComponentStore);
entityIndex += batchCount;
}
// Apply additional destroys from any LinkedEntityGroup
if (additionalDestroyList.m_pointer != null)
{
var additionalDestroyPtr = (Entity*) additionalDestroyList.m_pointer;
// Optimal for destruction speed is if entities with same archetype/chunk are followed one after another.
// So we lay out the to be destroyed objects assuming that the destroyed entities are "similar":
// Reorder destruction by index in entityGroupArray...
//@TODO: This is a very specialized fastpath that is likely only going to give benefits in the stress test.
/// Figure out how to make this more general purpose.
if (minDestroyStride == maxDestroyStride)
{
var reordered = (Entity*) UnsafeUtility.Malloc(additionalDestroyList.m_size * sizeof(Entity), 16,
Allocator.TempJob);
int batchCount = additionalDestroyList.m_size / minDestroyStride;
for (int i = 0; i != batchCount; i++)
{
for (int j = 0; j != minDestroyStride; j++)
reordered[j * batchCount + i] = additionalDestroyPtr[i * minDestroyStride + j];
}
DestroyEntities(reordered, additionalDestroyList.m_size,
entityComponentStore, managedComponentStore);
UnsafeUtility.Free(reordered, Allocator.TempJob);
}
else
{
DestroyEntities(additionalDestroyPtr, additionalDestroyList.m_size,
entityComponentStore, managedComponentStore);
}
UnsafeUtility.Free(additionalDestroyPtr, Allocator.TempJob);
}
}
public static void DeleteChunk(Chunk* chunk,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var entityCount = chunk->Count;
entityComponentStore->DeallocateDataEntitiesInChunk((Entity*) chunk->Buffer, chunk, 0, chunk->Count);
managedComponentStore.IncrementComponentOrderVersion(chunk->Archetype, chunk->SharedComponentValues);
entityComponentStore->IncrementComponentTypeOrderVersion(chunk->Archetype);
chunk->Archetype->EntityCount -= entityCount;
SetChunkCount(chunk, 0, entityComponentStore, managedComponentStore);
}
public static void DestroyMetaChunkEntity(Entity entity,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
EntityManagerChangeArchetypeUtility.RemoveComponent(entity, ComponentType.ReadWrite<ChunkHeader>(),
entityComponentStore, managedComponentStore);
DestroyEntities(&entity, 1, entityComponentStore, managedComponentStore);
}
public static void SetChunkCount(Chunk* chunk, int newCount,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
Assert.AreNotEqual(newCount, chunk->Count);
Assert.IsFalse(chunk->Locked);
Assert.IsTrue(!chunk->LockedEntityOrder || newCount == 0);
// Chunk released to empty chunk pool
if (newCount == 0)
{
ReleaseChunk(chunk, entityComponentStore, managedComponentStore);
return;
}
var capacity = chunk->Capacity;
// Chunk is now full
if (newCount == capacity)
{
// this chunk no longer has empty slots, so it shouldn't be in the empty slot list.
chunk->Archetype->EmptySlotTrackingRemoveChunk(chunk);
}
// Chunk is no longer full
else if (chunk->Count == capacity)
{
Assert.IsTrue(newCount < chunk->Count);
chunk->Archetype->EmptySlotTrackingAddChunk(chunk);
}
chunk->Count = newCount;
chunk->Archetype->Chunks.SetChunkEntityCount(chunk->ListIndex, newCount);
}
public static void CreateChunks(Archetype* archetype, ArchetypeChunk* chunks, int entityCount,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
int* sharedComponentValues = stackalloc int[archetype->NumSharedComponents];
UnsafeUtility.MemClear(sharedComponentValues, archetype->NumSharedComponents * sizeof(int));
Chunk* lastChunk = null;
int chunkIndex = 0;
while (entityCount != 0)
{
var chunk = GetCleanChunk(archetype, sharedComponentValues,
entityComponentStore, managedComponentStore);
int allocatedIndex;
var allocatedCount = AllocateIntoChunk(chunk, entityCount, out allocatedIndex,
entityComponentStore, managedComponentStore);
entityComponentStore->AllocateEntities(archetype, chunk, allocatedIndex, allocatedCount, null);
ChunkDataUtility.InitializeComponents(chunk, allocatedIndex, allocatedCount);
chunk->SetAllChangeVersions(entityComponentStore->GlobalSystemVersion);
chunks[chunkIndex] = new ArchetypeChunk(chunk, entityComponentStore);
lastChunk = chunk;
entityCount -= allocatedCount;
chunkIndex++;
}
entityComponentStore->IncrementComponentTypeOrderVersion(archetype);
}
public static Chunk* GetChunkWithEmptySlots(Archetype* archetype, SharedComponentValues sharedComponentValues,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var chunk = archetype->GetExistingChunkWithEmptySlots(sharedComponentValues);
if (chunk == null)
{
chunk = GetCleanChunk(archetype, sharedComponentValues,
entityComponentStore, managedComponentStore);
}
return chunk;
}
public static Chunk* GetCleanChunk(Archetype* archetype, SharedComponentValues sharedComponentValues,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
Chunk* newChunk = entityComponentStore->AllocateChunk();
ConstructChunk(archetype, newChunk, sharedComponentValues,
entityComponentStore, managedComponentStore);
return newChunk;
}
public static void InstantiateEntities(Entity srcEntity, Entity* outputEntities, int instanceCount,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
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);
}
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);
}
}
public static int AllocateIntoChunk(Chunk* chunk,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
int outIndex;
var res = AllocateIntoChunk(chunk, 1, out outIndex,
entityComponentStore, managedComponentStore);
Assert.AreEqual(1, res);
return outIndex;
}
public static int AllocateIntoChunk(Chunk* chunk, int count, out int outIndex,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var allocatedCount = Math.Min(chunk->Capacity - chunk->Count, count);
outIndex = chunk->Count;
SetChunkCount(chunk, chunk->Count + allocatedCount,
entityComponentStore, managedComponentStore);
chunk->Archetype->EntityCount += allocatedCount;
return allocatedCount;
}
// ----------------------------------------------------------------------------------------------------------
// INTERNAL
// ----------------------------------------------------------------------------------------------------------
struct InstantiateRemapChunk
{
public Chunk* Chunk;
public int IndexInChunk;
public int AllocatedCount;
public int InstanceBeginIndex;
}
static void AddToDestroyList(Chunk* chunk, int indexInChunk, int batchCount, int inputDestroyCount,
ref UnsafeList entitiesList, ref int minBufferLength, ref int maxBufferLength)
{
var linkedGroupType = TypeManager.GetTypeIndex<LinkedEntityGroup>();
int indexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, linkedGroupType);
if (indexInArchetype != -1)
{
var baseHeader = ChunkDataUtility.GetComponentDataWithTypeRO(chunk, indexInChunk, 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.m_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);
}
}
}
static void DestroyBatch(Entity* entities, Chunk* chunk, int indexInChunk, int batchCount,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var archetype = chunk->Archetype;
if (!archetype->SystemStateCleanupNeeded)
{
entityComponentStore->DeallocateDataEntitiesInChunk(entities, chunk, indexInChunk, batchCount);
managedComponentStore.IncrementComponentOrderVersion(archetype, chunk->SharedComponentValues);
entityComponentStore->IncrementComponentTypeOrderVersion(archetype);
if (chunk->ManagedArrayIndex >= 0)
{
// We can just chop-off the end, no need to copy anything
if (chunk->Count != indexInChunk + batchCount)
managedComponentStore.CopyManagedObjects(chunk, chunk->Count - batchCount, chunk,
indexInChunk, batchCount);
managedComponentStore.ClearManagedObjects(chunk, chunk->Count - batchCount,
batchCount);
}
chunk->Archetype->EntityCount -= batchCount;
SetChunkCount(chunk, chunk->Count - batchCount, entityComponentStore, managedComponentStore);
}
else
{
var newType = archetype->SystemStateResidueArchetype;
var sharedComponentValues = chunk->SharedComponentValues;
if (RequiresBuildingResidueSharedComponentIndices(archetype, newType))
{
var tempAlloc = stackalloc int[newType->NumSharedComponents];
BuildResidueSharedComponentIndices(archetype, newType, sharedComponentValues, tempAlloc);
sharedComponentValues = tempAlloc;
}
// See: https://github.com/Unity-Technologies/dots/issues/1387
// For Locked Order Chunks specfically, need to make sure that structural changes are always done per-chunk.
// If trying to muutate structure in a way that is not per chunk, will hit an exception in the else clause anyway.
// This ultimately needs to be replaced by entity batch interface.
if (batchCount == chunk->Count)
{
managedComponentStore.IncrementComponentOrderVersion(archetype, chunk->SharedComponentValues);
entityComponentStore->IncrementComponentTypeOrderVersion(archetype);
EntityManagerChangeArchetypeUtility.SetArchetype(chunk, newType, sharedComponentValues,
entityComponentStore, managedComponentStore);
}
else
{
for (var i = 0; i < batchCount; i++)
{
var entity = entities[i];
managedComponentStore.IncrementComponentOrderVersion(archetype,
entityComponentStore->GetChunk(entity)->SharedComponentValues);
entityComponentStore->IncrementComponentTypeOrderVersion(archetype);
EntityManagerChangeArchetypeUtility.SetArchetype(entity, newType, sharedComponentValues,
entityComponentStore, managedComponentStore);
}
}
}
}
static bool RequiresBuildingResidueSharedComponentIndices(Archetype* srcArchetype,
Archetype* dstArchetype)
{
return dstArchetype->NumSharedComponents > 0 &&
dstArchetype->NumSharedComponents != srcArchetype->NumSharedComponents;
}
static void BuildResidueSharedComponentIndices(Archetype* srcArchetype, Archetype* dstArchetype,
SharedComponentValues srcSharedComponentValues, int* dstSharedComponentValues)
{
int oldFirstShared = srcArchetype->FirstSharedComponent;
int newFirstShared = dstArchetype->FirstSharedComponent;
int newCount = dstArchetype->NumSharedComponents;
for (int oldIndex = 0, newIndex = 0; newIndex < newCount; ++newIndex, ++oldIndex)
{
var t = dstArchetype->Types[newIndex + newFirstShared];
while (t != srcArchetype->Types[oldIndex + oldFirstShared])
++oldIndex;
dstSharedComponentValues[newIndex] = srcSharedComponentValues[oldIndex];
}
}
static void ReleaseChunk(Chunk* chunk,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
// Remove references to shared components
if (chunk->Archetype->NumSharedComponents > 0)
{
var sharedComponentValueArray = chunk->SharedComponentValues;
for (var i = 0; i < chunk->Archetype->NumSharedComponents; ++i)
managedComponentStore.RemoveReference(sharedComponentValueArray[i]);
}
if (chunk->ManagedArrayIndex != -1)
{
managedComponentStore.DeallocateManagedArrayStorage(chunk->ManagedArrayIndex);
chunk->ManagedArrayIndex = -1;
}
if (chunk->metaChunkEntity != Entity.Null)
DestroyMetaChunkEntity(chunk->metaChunkEntity,
entityComponentStore, managedComponentStore);
// this chunk is going away, so it shouldn't be in the empty slot list.
if (chunk->Count < chunk->Capacity)
chunk->Archetype->EmptySlotTrackingRemoveChunk(chunk);
chunk->Archetype->RemoveFromChunkList(chunk);
chunk->Archetype = null;
entityComponentStore->FreeChunk(chunk);
}
static int InstantiateEntitiesOne(Entity srcEntity, Entity* outputEntities,
int instanceCount, InstantiateRemapChunk* remapChunks, int remapChunksCount,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
var src = entityComponentStore->GetEntityInChunk(srcEntity);
var srcArchetype = src.Chunk->Archetype;
var dstArchetype = srcArchetype->InstantiableArchetype;
var temp = stackalloc int[dstArchetype->NumSharedComponents];
if (RequiresBuildingResidueSharedComponentIndices(srcArchetype, dstArchetype))
{
BuildResidueSharedComponentIndices(srcArchetype, dstArchetype,
src.Chunk->SharedComponentValues, temp);
}
else
{
// Always copy shared component indices since GetChunkWithEmptySlots might reallocate the storage of SharedComponentValues
src.Chunk->SharedComponentValues.CopyTo(temp, 0, dstArchetype->NumSharedComponents);
}
SharedComponentValues sharedComponentValues = temp;
Chunk* chunk = null;
int instanceBeginIndex = 0;
while (instanceBeginIndex != instanceCount)
{
chunk = GetChunkWithEmptySlots(dstArchetype, sharedComponentValues,
entityComponentStore, managedComponentStore);
int indexInChunk;
var allocatedCount = AllocateIntoChunk(chunk, instanceCount - instanceBeginIndex, out indexInChunk,
entityComponentStore, managedComponentStore);
ChunkDataUtility.ReplicateComponents(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount);
entityComponentStore->AllocateEntities(dstArchetype, chunk, indexInChunk, allocatedCount,
outputEntities + instanceBeginIndex);
chunk->SetAllChangeVersions(entityComponentStore->GlobalSystemVersion);
#if UNITY_EDITOR
for (var i = 0; i < allocatedCount; ++i)
entityComponentStore->SetName(outputEntities[i + instanceBeginIndex], entityComponentStore->GetName(srcEntity));
#endif
if (remapChunks != null)
{
remapChunks[remapChunksCount].Chunk = chunk;
remapChunks[remapChunksCount].IndexInChunk = indexInChunk;
remapChunks[remapChunksCount].AllocatedCount = allocatedCount;
remapChunks[remapChunksCount].InstanceBeginIndex = instanceBeginIndex;
remapChunksCount++;
}
instanceBeginIndex += allocatedCount;
}
if (chunk != null)
{
managedComponentStore.IncrementComponentOrderVersion(dstArchetype, chunk->SharedComponentValues);
entityComponentStore->IncrementComponentTypeOrderVersion(dstArchetype);
}
return remapChunksCount;
}
static void InstantiateEntitiesGroup(Entity* srcEntities, int srcEntityCount,
Entity* outputRootEntities, int instanceCount,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
int totalCount = srcEntityCount * instanceCount;
var tempAllocSize = sizeof(EntityRemapUtility.SparseEntityRemapInfo) * totalCount +
sizeof(InstantiateRemapChunk) * totalCount + sizeof(Entity) * instanceCount;
byte* allocation;
const int kMaxStackAllocSize = 16 * 1024;
if (tempAllocSize > kMaxStackAllocSize)
{
allocation = (byte*) UnsafeUtility.Malloc(tempAllocSize, 16, Allocator.Temp);
}
else
{
var temp = stackalloc byte[tempAllocSize];
allocation = temp;
}
var entityRemap = (EntityRemapUtility.SparseEntityRemapInfo*) allocation;
var remapChunks = (InstantiateRemapChunk*) (entityRemap + totalCount);
var outputEntities = (Entity*) (remapChunks + totalCount);
var remapChunksCount = 0;
for (int i = 0; i != srcEntityCount; i++)
{
var srcEntity = srcEntities[i];
remapChunksCount = InstantiateEntitiesOne(srcEntity,
outputEntities, instanceCount, remapChunks, remapChunksCount,
entityComponentStore, managedComponentStore);
for (int r = 0; r != instanceCount; r++)
{
var ptr = entityRemap + (r * srcEntityCount + i);
ptr->Src = srcEntity;
ptr->Target = outputEntities[r];
}
if (i == 0)
{
for (int r = 0; r != instanceCount; r++)
outputRootEntities[r] = outputEntities[r];
}
}
for (int i = 0; i != remapChunksCount; i++)
{
var chunk = remapChunks[i].Chunk;
var dstArchetype = chunk->Archetype;
var allocatedCount = remapChunks[i].AllocatedCount;
var indexInChunk = remapChunks[i].IndexInChunk;
var instanceBeginIndex = remapChunks[i].InstanceBeginIndex;
var localRemap = entityRemap + instanceBeginIndex * srcEntityCount;
EntityRemapUtility.PatchEntitiesForPrefab(dstArchetype->ScalarEntityPatches + 1,
dstArchetype->ScalarEntityPatchCount - 1, dstArchetype->BufferEntityPatches,
dstArchetype->BufferEntityPatchCount, chunk->Buffer, indexInChunk, allocatedCount, localRemap,
srcEntityCount);
}
if (tempAllocSize > kMaxStackAllocSize)
UnsafeUtility.Free(allocation, Allocator.Temp);
}
static void ConstructChunk(Archetype* archetype, Chunk* chunk,
SharedComponentValues sharedComponentValues,
EntityComponentStore* entityComponentStore,
ManagedComponentStore managedComponentStore)
{
chunk->Archetype = archetype;
chunk->Count = 0;
chunk->Capacity = archetype->ChunkCapacity;
chunk->SequenceNumber = entityComponentStore->AssignSequenceNumber(chunk);
chunk->metaChunkEntity = Entity.Null;
var numSharedComponents = archetype->NumSharedComponents;
if (numSharedComponents > 0)
{
for (var i = 0; i < archetype->NumSharedComponents; ++i)
{
var sharedComponentIndex = sharedComponentValues[i];
managedComponentStore.AddReference(sharedComponentIndex);
}
}
archetype->AddToChunkList(chunk, sharedComponentValues, entityComponentStore->GlobalSystemVersion);
Assert.IsTrue(archetype->Chunks.Count != 0);
// Chunk can't be locked at at construction time
archetype->EmptySlotTrackingAddChunk(chunk);
if (numSharedComponents == 0)
{
Assert.IsTrue(archetype->ChunksWithEmptySlots.Count != 0);
}
else
{
Assert.IsTrue(archetype->FreeChunksBySharedComponents.TryGet(chunk->SharedComponentValues,
archetype->NumSharedComponents) != null);
}
if (archetype->NumManagedArrays > 0)
chunk->ManagedArrayIndex =
managedComponentStore.AllocateManagedArrayStorage(archetype->NumManagedArrays * chunk->Capacity);
else
chunk->ManagedArrayIndex = -1;
chunk->Flags = 0;
if (archetype->MetaChunkArchetype != null)
{
CreateMetaEntityForChunk(chunk, entityComponentStore, managedComponentStore);
}
}
}
}