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 void AddComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager, EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray) { var componentType = new ComponentTypeInArchetype(type); var archetype = GetArchetype(entity); var t = 0; while (t < archetype->TypesCount && archetype->Types[t] < componentType) { componentTypeInArchetypeArray[t] = archetype->Types[t]; ++t; } var indexInTypeArray = t; componentTypeInArchetypeArray[t] = componentType; while (t < archetype->TypesCount) { componentTypeInArchetypeArray[t + 1] = archetype->Types[t]; ++t; } var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, archetype->TypesCount + 1, groupManager); int *sharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray; if ((newType->NumSharedComponents > 0) && (newType->NumSharedComponents != archetype->NumSharedComponents)) { var oldSharedComponentDataIndices = sharedComponentDataIndices; int *stackAlloced = stackalloc int[newType->NumSharedComponents]; sharedComponentDataIndices = stackAlloced; int indexOfNewSharedComponent = newType->SharedComponentOffset[indexInTypeArray]; UnsafeUtility.MemCpy(sharedComponentDataIndices, oldSharedComponentDataIndices, indexOfNewSharedComponent * sizeof(int)); sharedComponentDataIndices[indexOfNewSharedComponent] = 0; UnsafeUtility.MemCpy(sharedComponentDataIndices + indexOfNewSharedComponent + 1, oldSharedComponentDataIndices + indexOfNewSharedComponent, (archetype->NumSharedComponents - indexOfNewSharedComponent) * sizeof(int)); } SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices); IncrementComponentOrderVersion(newType, GetComponentChunk(entity), sharedComponentDataManager); }
public void RemoveComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager, EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray) { var componentType = new ComponentTypeInArchetype(type); var archetype = GetArchetype(entity); var removedTypes = 0; int indexInOldTypeArray = -1; for (var t = 0; t < archetype->TypesCount; ++t) { if (archetype->Types[t].TypeIndex == componentType.TypeIndex) { indexInOldTypeArray = t; ++removedTypes; } else { componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t]; } } var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, archetype->TypesCount - removedTypes, groupManager); int *sharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray; if ((newType->NumSharedComponents > 0) && (newType->NumSharedComponents != archetype->NumSharedComponents)) { var oldSharedComponentDataIndices = sharedComponentDataIndices; int *tempAlloc = stackalloc int[newType->NumSharedComponents]; sharedComponentDataIndices = tempAlloc; int indexOfRemovedSharedComponent = archetype->SharedComponentOffset[indexInOldTypeArray]; UnsafeUtility.MemCpy(sharedComponentDataIndices, oldSharedComponentDataIndices, indexOfRemovedSharedComponent * sizeof(int)); UnsafeUtility.MemCpy(sharedComponentDataIndices + indexOfRemovedSharedComponent, oldSharedComponentDataIndices + indexOfRemovedSharedComponent + 1, (newType->NumSharedComponents - indexOfRemovedSharedComponent) * sizeof(int)); } IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager); SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices); }
internal EntityArchetype CreateArchetype(ComponentType *types, int count) { var cachedComponentCount = PopulatedCachedTypeInArchetypeArray(types, count); // Lookup existing archetype (cheap) EntityArchetype entityArchetype; entityArchetype.Archetype = m_ArchetypeManager.GetExistingArchetype(m_CachedComponentTypeInArchetypeArray, cachedComponentCount); if (entityArchetype.Archetype != null) { return(entityArchetype); } // Creating an archetype invalidates all iterators / jobs etc // because it affects the live iteration linked lists... BeforeStructuralChange(); entityArchetype.Archetype = m_ArchetypeManager.GetOrCreateArchetype(m_CachedComponentTypeInArchetypeArray, cachedComponentCount, m_GroupManager); return(entityArchetype); }
public void RemoveComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager, EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray) { var componentType = new ComponentTypeInArchetype(type); var archetype = GetArchetype(entity); var removedTypes = 0; for (var t = 0; t < archetype->TypesCount; ++t) { if (archetype->Types[t].TypeIndex == componentType.TypeIndex) { ++removedTypes; } else { componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t]; } } Assert.AreNotEqual(-1, removedTypes); var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, archetype->TypesCount - removedTypes, groupManager); int *sharedComponentDataIndices = null; if (newType->NumSharedComponents > 0) { var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray; var removedComponentIsShared = TypeManager.TypeCategory.ISharedComponentData == TypeManager.GetComponentType(type.TypeIndex).Category; removedTypes = 0; if (removedComponentIsShared) { int *tempAlloc = stackalloc int[newType->NumSharedComponents]; sharedComponentDataIndices = tempAlloc; int srcIndex = 0; int dstIndex = 0; for (var t = 0; t < archetype->TypesCount; ++t) { if (archetype->SharedComponentOffset[t] != -1) { if (archetype->Types[t].TypeIndex == componentType.TypeIndex) { srcIndex++; } else { sharedComponentDataIndices[dstIndex] = oldSharedComponentDataIndices[srcIndex]; srcIndex++; dstIndex++; } } } } else { // reuse old sharedComponentDataIndices sharedComponentDataIndices = oldSharedComponentDataIndices; } } IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager); SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices); }
public void AddComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager, EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray) { var componentType = new ComponentTypeInArchetype(type); var archetype = GetArchetype(entity); var t = 0; while (t < archetype->TypesCount && archetype->Types[t] < componentType) { componentTypeInArchetypeArray[t] = archetype->Types[t]; ++t; } componentTypeInArchetypeArray[t] = componentType; while (t < archetype->TypesCount) { componentTypeInArchetypeArray[t + 1] = archetype->Types[t]; ++t; } var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, archetype->TypesCount + 1, groupManager); int *sharedComponentDataIndices = null; if (newType->NumSharedComponents > 0) { var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray; var newComponentIsShared = (TypeManager.TypeCategory.ISharedComponentData == TypeManager.GetComponentType(type.TypeIndex).Category); if (newComponentIsShared) { int *stackAlloced = stackalloc int[newType->NumSharedComponents]; sharedComponentDataIndices = stackAlloced; if (archetype->SharedComponentOffset == null) { sharedComponentDataIndices[0] = 0; } else { t = 0; var sharedIndex = 0; while (t < archetype->TypesCount && archetype->Types[t] < componentType) { if (archetype->SharedComponentOffset[t] != -1) { sharedComponentDataIndices[sharedIndex] = oldSharedComponentDataIndices[sharedIndex]; ++sharedIndex; } ++t; } sharedComponentDataIndices[sharedIndex] = 0; while (t < archetype->TypesCount) { if (archetype->SharedComponentOffset[t] != -1) { sharedComponentDataIndices[sharedIndex + 1] = oldSharedComponentDataIndices[sharedIndex]; ++sharedIndex; } ++t; } } } else { // reuse old sharedComponentDataIndices sharedComponentDataIndices = oldSharedComponentDataIndices; } } SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices); IncrementComponentOrderVersion(newType, GetComponentChunk(entity), sharedComponentDataManager); }
public static void MoveChunks(EntityManager srcEntities, ArchetypeManager dstArchetypeManager, EntityGroupManager dstGroupManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents) { var srcArchetypeManager = srcEntities.ArchetypeManager; var srcEntityDataManager = srcEntities.Entities; var srcSharedComponents = srcEntities.m_SharedComponentManager; var entityRemapping = new NativeArray <EntityRemapUtility.EntityRemapInfo>(srcEntityDataManager->Capacity, Allocator.Temp); dstEntityDataManager->AllocateEntitiesForRemapping(srcEntityDataManager, ref entityRemapping); srcEntityDataManager->FreeAllEntities(); var samplerShared = CustomSampler.Create("MoveAllSharedComponents"); samplerShared.Begin(); var remapShared = dstSharedComponents.MoveAllSharedComponents(srcSharedComponents, Allocator.Temp); samplerShared.End(); Archetype *srcArchetype; int chunkCount = 0; int archetypeCount = 0; srcArchetype = srcArchetypeManager.m_LastArchetype; while (srcArchetype != null) { archetypeCount++; chunkCount += srcArchetype->ChunkCount; srcArchetype = srcArchetype->PrevArchetype; } var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.Temp); var remapArchetypes = new NativeArray <RemapArchetype>(archetypeCount, Allocator.Temp); int chunkIndex = 0; int archetypeIndex = 0; srcArchetype = srcArchetypeManager.m_LastArchetype; while (srcArchetype != null) { if (srcArchetype->ChunkCount != 0) { if (srcArchetype->NumManagedArrays != 0) { throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays"); } var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount, dstGroupManager); remapArchetypes[archetypeIndex] = new RemapArchetype { srcArchetype = srcArchetype, dstArchetype = dstArchetype }; for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next) { remapChunks[chunkIndex] = new RemapChunk { chunk = (Chunk *)c, dstArchetype = dstArchetype }; chunkIndex++; } archetypeIndex++; dstEntityDataManager->IncrementComponentTypeOrderVersion(dstArchetype); } srcArchetype = srcArchetype->PrevArchetype; } for (int j = 0; j < remapChunks.Length; j++) { ref RemapChunk remapChunk = ref UnsafeUtilityEx.ArrayElementAsRef <RemapChunk>(remapChunks.GetUnsafePtr(), j); ref Chunk * chunk = ref remapChunk.chunk;
public static void MoveChunks(EntityManager srcEntities, ArchetypeManager dstArchetypeManager, EntityGroupManager dstGroupManager, EntityDataManager *dstEntityDataManager, SharedComponentDataManager dstSharedComponents, ComponentTypeInArchetype *componentTypeInArchetypeArray) { var srcArchetypeManager = srcEntities.ArchetypeManager; var srcEntityDataManager = srcEntities.Entities; var srcSharedComponents = srcEntities.m_SharedComponentManager; var entityRemapping = new NativeArray <EntityRemapUtility.EntityRemapInfo>(srcEntityDataManager->Capacity, Allocator.TempJob); var moveChunksJob = new MoveChunksJob { srcEntityDataManager = srcEntityDataManager, dstEntityDataManager = dstEntityDataManager, entityRemapping = entityRemapping }.Schedule(); JobHandle.ScheduleBatchedJobs(); var samplerShared = CustomSampler.Create("MoveAllSharedComponents"); samplerShared.Begin(); var remapShared = dstSharedComponents.MoveAllSharedComponents(srcSharedComponents, Allocator.TempJob); samplerShared.End(); Archetype *srcArchetype; int chunkCount = 0; int archetypeCount = 0; srcArchetype = srcArchetypeManager.m_LastArchetype; while (srcArchetype != null) { archetypeCount++; chunkCount += srcArchetype->ChunkCount; srcArchetype = srcArchetype->PrevArchetype; } var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob); var remapArchetypes = new NativeArray <RemapArchetype>(archetypeCount, Allocator.TempJob); int chunkIndex = 0; int archetypeIndex = 0; srcArchetype = srcArchetypeManager.m_LastArchetype; while (srcArchetype != null) { if (srcArchetype->ChunkCount != 0) { if (srcArchetype->NumManagedArrays != 0) { throw new ArgumentException("MoveEntitiesFrom is not supported with managed arrays"); } // Make copy. GetOrCreateArchetype writes to type array. UnsafeUtility.MemCpy(componentTypeInArchetypeArray, srcArchetype->Types, UnsafeUtility.SizeOf <ComponentTypeInArchetype>() * srcArchetype->TypesCount); var dstArchetype = dstArchetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, srcArchetype->TypesCount, dstGroupManager); remapArchetypes[archetypeIndex] = new RemapArchetype { srcArchetype = srcArchetype, dstArchetype = dstArchetype }; for (var c = srcArchetype->ChunkList.Begin; c != srcArchetype->ChunkList.End; c = c->Next) { remapChunks[chunkIndex] = new RemapChunk { chunk = (Chunk *)c, dstArchetype = dstArchetype }; chunkIndex++; } archetypeIndex++; dstEntityDataManager->IncrementComponentTypeOrderVersion(dstArchetype); } srcArchetype = srcArchetype->PrevArchetype; } var remapChunksJob = new RemapChunksJob { dstEntityDataManager = dstEntityDataManager, remapChunks = remapChunks, remapShared = remapShared, entityRemapping = entityRemapping }.Schedule(remapChunks.Length, 1, moveChunksJob); var remapArchetypesJob = new RemapArchetypesJob { remapArchetypes = remapArchetypes }.Schedule(archetypeIndex, 1, remapChunksJob); remapArchetypesJob.Complete(); entityRemapping.Dispose(); remapShared.Dispose(); }
public void TryRemoveEntityId(Entity *entities, int count, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager, EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray) { var entityIndex = 0; while (entityIndex != count) { int indexInChunk; int batchCount; fixed(EntityDataManager *manager = &this) { var chunk = EntityChunkBatch(manager, entities + entityIndex, count - entityIndex, out indexInChunk, out batchCount); var archetype = GetArchetype(entities[entityIndex]); if (!archetype->SystemStateCleanupNeeded) { DeallocateDataEntitiesInChunk(manager, entities + entityIndex, chunk, indexInChunk, batchCount); IncrementComponentOrderVersion(chunk->Archetype, chunk, sharedComponentDataManager); if (chunk->ManagedArrayIndex >= 0) { // We can just chop-off the end, no need to copy anything if (chunk->Count != indexInChunk + batchCount) { ChunkDataUtility.CopyManagedObjects(archetypeManager, chunk, chunk->Count - batchCount, chunk, indexInChunk, batchCount); } ChunkDataUtility.ClearManagedObjects(archetypeManager, chunk, chunk->Count - batchCount, batchCount); } chunk->Archetype->EntityCount -= batchCount; archetypeManager.SetChunkCount(chunk, chunk->Count - batchCount); } else { for (var batchEntityIndex = 0; batchEntityIndex < batchCount; batchEntityIndex++) { var entity = entities[entityIndex + batchEntityIndex]; var removedTypes = 0; var removedComponentIsShared = false; for (var t = 1; t < archetype->TypesCount; ++t) { var type = archetype->Types[t]; if (!(type.IsSystemStateComponent || type.IsSystemStateSharedComponent)) { ++removedTypes; removedComponentIsShared |= type.IsSharedComponent; } else { componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t]; } } componentTypeInArchetypeArray[archetype->TypesCount - removedTypes] = new ComponentTypeInArchetype(ComponentType.Create <CleanupEntity>()); var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray, archetype->TypesCount - removedTypes + 1, groupManager); int *sharedComponentDataIndices = null; if (newType->NumSharedComponents > 0) { var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray; if (removedComponentIsShared) { int *tempAlloc = stackalloc int[newType->NumSharedComponents]; sharedComponentDataIndices = tempAlloc; var srcIndex = 0; var dstIndex = 0; for (var t = 0; t < archetype->TypesCount; ++t) { if (archetype->SharedComponentOffset[t] != -1) { var typeIndex = archetype->Types[t].TypeIndex; var systemStateType = typeof(ISystemStateComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex)); var systemStateSharedType = typeof(ISystemStateSharedComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex)); if (!(systemStateType || systemStateSharedType)) { srcIndex++; } else { sharedComponentDataIndices[dstIndex] = oldSharedComponentDataIndices[srcIndex]; srcIndex++; dstIndex++; } } } } else { // reuse old sharedComponentDataIndices sharedComponentDataIndices = oldSharedComponentDataIndices; } } IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager); SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices); } } } entityIndex += batchCount; } }
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(); }