// 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; var dstArchetype = remapArchetypes[index].dstArchetype; UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkList.End, &srcArchetype->ChunkList); if (srcArchetype->NumSharedComponents == 0) { if (!srcArchetype->ChunkListWithEmptySlots.IsEmpty) { UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkListWithEmptySlots.End, &srcArchetype->ChunkListWithEmptySlots); } } else { remapArchetypes[index].dstArchetype->FreeChunksBySharedComponents.AppendFrom(&remapArchetypes[index].srcArchetype->FreeChunksBySharedComponents); } dstArchetype->EntityCount += srcArchetype->EntityCount; dstArchetype->ChunkCount += srcArchetype->ChunkCount; srcArchetype->EntityCount = 0; srcArchetype->ChunkCount = 0; }
void AddMultiple(UnsafeLinkedListNode *list) { var firstChunk = ArchetypeManager.GetChunkFromEmptySlotNode(list->Begin); UInt32 hash = GetHashCode(firstChunk->SharedComponentValueArray, firstChunk->Archetype->NumSharedComponents); int * sharedComponentDataIndices = firstChunk->SharedComponentValueArray; int numSharedComponents = firstChunk->Archetype->NumSharedComponents; Node *node = &buckets[hash & hashMask]; Node *lastNode = &buckets[hashMask]; Node *freeNode = null; while (!node->IsFree()) { if (!node->IsDeleted()) { if (node->CheckEqual(hash, sharedComponentDataIndices, numSharedComponents)) { UnsafeLinkedListNode.InsertListBefore(node->list.End, list); return; } } else { if (freeNode == null) { freeNode = node; } } node = node + 1; if (node > lastNode) { node = buckets; } } if (freeNode == null) { freeNode = node; --emptyNodes; } freeNode->hash = hash; UnsafeLinkedListNode.InitializeList(&freeNode->list); UnsafeLinkedListNode.InsertListBefore(freeNode->list.End, list); if (ShouldGrow(emptyNodes)) { Grow(); } }
private unsafe void AddMultiple(UnsafeLinkedListNode *list) { Chunk *chunkPtr = ref ArchetypeManager.GetChunkFromEmptySlotNode(list.Begin); uint hashCode = this.GetHashCode(chunkPtr->SharedComponentValueArray, chunkPtr->Archetype.NumSharedComponents); int * sharedComponentValueArray = chunkPtr->SharedComponentValueArray; int numSharedComponents = chunkPtr->Archetype.NumSharedComponents; Node * buckets = this.buckets + ((hashCode & this.hashMask) * sizeof(Node)); Node * nodePtr2 = this.buckets + (this.hashMask * sizeof(Node)); Node * nodePtr3 = null; while (true) { if (buckets.IsFree()) { if (nodePtr3 == null) { nodePtr3 = buckets; this.emptyNodes--; } nodePtr3->hash = hashCode; UnsafeLinkedListNode.InitializeList(&nodePtr3->list); UnsafeLinkedListNode.InsertListBefore(nodePtr3->list.End, list); if (this.ShouldGrow(this.emptyNodes)) { this.Grow(); } break; } if (!buckets.IsDeleted()) { if (buckets.CheckEqual(hashCode, sharedComponentValueArray, numSharedComponents)) { UnsafeLinkedListNode.InsertListBefore(buckets->list.End, list); break; } } else if (nodePtr3 == null) { nodePtr3 = buckets; } buckets++; if (buckets > nodePtr2) { buckets = this.buckets; } } }
public static void MoveChunks(ArchetypeManager srcArchetypeManager, EntityDataManager *srcEntityDataManager, SharedComponentDataManager srcSharedComponents, ArchetypeManager dstArchetypeManager, EntityGroupManager dstGroupManager, SharedComponentDataManager dstSharedComponentDataManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents) { var entitiesArray = new NativeArray <Entity>(Chunk.kMaximumEntitiesPerChunk, Allocator.Temp); var entitiesPtr = (Entity *)entitiesArray.GetUnsafePtr(); var srcArchetype = srcArchetypeManager.m_LastArchetype; while (srcArchetype != null) { if (srcArchetype->EntityCount != 0) { if (srcArchetype->NumManagedArrays != 0) { throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays"); } var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount, dstGroupManager); for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next) { Chunk *chunk = (Chunk *)c; EntityDataManager.FreeDataEntitiesInChunk(srcEntityDataManager, chunk, chunk->Count); dstEntityDataManager->AllocateEntities(dstArchetype, chunk, 0, chunk->Count, entitiesPtr); chunk->Archetype = dstArchetype; if (dstArchetype->NumSharedComponents > 0) { dstSharedComponents.MoveSharedComponents(srcSharedComponents, chunk->SharedComponentValueArray, dstArchetype->NumSharedComponents); } } //@TODO: Patch Entity references in IComponentData... UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkList.End, &srcArchetype->ChunkList); UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkListWithEmptySlots.End, &srcArchetype->ChunkListWithEmptySlots); dstArchetype->EntityCount += srcArchetype->EntityCount; srcArchetype->EntityCount = 0; } srcArchetype = srcArchetype->PrevArchetype; } entitiesArray.Dispose(); }
public static void MoveChunks(ArchetypeManager srcArchetypeManager, EntityDataManager *srcEntityDataManager, SharedComponentDataManager srcSharedComponents, ArchetypeManager dstArchetypeManager, EntityGroupManager dstGroupManager, SharedComponentDataManager dstSharedComponentDataManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents) { var entityRemapping = new NativeArray <EntityRemapUtility.EntityRemapInfo>(srcEntityDataManager->Capacity, Allocator.Temp); var entityPatches = new NativeList <EntityRemapUtility.EntityPatchInfo>(128, Allocator.Temp); dstEntityDataManager->AllocateEntitiesForRemapping(srcEntityDataManager, ref entityRemapping); var srcArchetype = srcArchetypeManager.m_LastArchetype; while (srcArchetype != null) { if (srcArchetype->EntityCount != 0) { if (srcArchetype->NumManagedArrays != 0) { throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays"); } var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount, dstGroupManager); entityPatches.Clear(); for (var i = 1; i != dstArchetype->TypesCount; i++) { EntityRemapUtility.AppendEntityPatches(ref entityPatches, TypeManager.GetComponentType(dstArchetype->Types[i].TypeIndex).EntityOffsets, dstArchetype->Offsets[i], dstArchetype->SizeOfs[i]); } for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next) { var chunk = (Chunk *)c; dstEntityDataManager->RemapChunk(dstArchetype, chunk, 0, chunk->Count, ref entityRemapping); EntityRemapUtility.PatchEntities(ref entityPatches, chunk->Buffer, chunk->Count, ref entityRemapping); chunk->Archetype = dstArchetype; if (dstArchetype->NumSharedComponents > 0) { dstSharedComponents.MoveSharedComponents(srcSharedComponents, chunk->SharedComponentValueArray, dstArchetype->NumSharedComponents); } } UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkList.End, &srcArchetype->ChunkList); if (!srcArchetype->ChunkListWithEmptySlots.IsEmpty) { UnsafeLinkedListNode.InsertListBefore(dstArchetype->ChunkListWithEmptySlots.End, &srcArchetype->ChunkListWithEmptySlots); } dstArchetype->EntityCount += srcArchetype->EntityCount; dstArchetype->ChunkCount += srcArchetype->ChunkCount; srcArchetype->EntityCount = 0; srcArchetype->ChunkCount = 0; } srcArchetype = srcArchetype->PrevArchetype; } srcEntityDataManager->FreeAllEntities(); entityRemapping.Dispose(); entityPatches.Dispose(); }