internal void AddSharedComponent <T>(NativeArray <ArchetypeChunk> chunks, T componentData) where T : struct, ISharedComponentData { ManagedComponentStore mcs = GetCheckedEntityDataAccess()->ManagedComponentStore; var componentType = ComponentType.ReadWrite <T>(); int sharedComponentIndex = mcs.InsertSharedComponent(componentData); m_EntityDataAccess->AddSharedComponentData(chunks, sharedComponentIndex, componentType); mcs.RemoveReference(sharedComponentIndex); }
/// <summary> /// Sets the shared component of an entity. /// </summary> /// <remarks> /// Changing a shared component value of an entity results in the entity being moved to a /// different chunk. The entity moves to a chunk with other entities that have the same shared component values. /// A new chunk is created if no chunk with the same archetype and shared component values currently exists. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before setting the component and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// </remarks> /// <param name="entity">The entity</param> /// <param name="componentData">A shared component object containing the values to set.</param> /// <typeparam name="T">The shared component type.</typeparam> public void SetSharedComponentData <T>(Entity entity, T componentData) where T : struct, ISharedComponentData { BeforeStructuralChange(); var typeIndex = TypeManager.GetTypeIndex <T>(); EntityComponentStore->AssertEntityHasComponent(entity, typeIndex); var newSharedComponentDataIndex = m_ManagedComponentStore.InsertSharedComponent(componentData); EntityComponentStore->SetSharedComponentDataIndex(entity, typeIndex, newSharedComponentDataIndex); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); ManagedComponentStore.RemoveReference(newSharedComponentDataIndex); }
public static Chunk *CloneChunkForDiffing(Chunk *chunk, ManagedComponentStore srcManagedManager, EntityComponentStore *dstEntityComponentStore, ManagedComponentStore dstManagedComponentStore, EntityGroupManager dstEntityGroupManager) { int *sharedIndices = stackalloc int[chunk->Archetype->NumSharedComponents]; chunk->SharedComponentValues.CopyTo(sharedIndices, 0, chunk->Archetype->NumSharedComponents); dstManagedComponentStore.CopySharedComponents(srcManagedManager, sharedIndices, chunk->Archetype->NumSharedComponents); // Allocate a new chunk Archetype *arch = EntityManagerCreateArchetypeUtility.GetOrCreateArchetype(chunk->Archetype->Types, chunk->Archetype->TypesCount, dstEntityComponentStore, dstEntityGroupManager); Chunk *targetChunk = EntityManagerCreateDestroyEntitiesUtility.GetCleanChunk(arch, sharedIndices, dstEntityComponentStore, dstManagedComponentStore, dstEntityGroupManager); // GetCleanChunk & CopySharedComponents both acquire a ref, once chunk owns, release CopySharedComponents ref for (int i = 0; i < chunk->Archetype->NumSharedComponents; ++i) { dstManagedComponentStore.RemoveReference(sharedIndices[i]); } UnityEngine.Assertions.Assert.AreEqual(0, targetChunk->Count); UnityEngine.Assertions.Assert.IsTrue(targetChunk->Capacity >= chunk->Count); int copySize = Chunk.GetChunkBufferSize(); UnsafeUtility.MemCpy(targetChunk->Buffer, chunk->Buffer, copySize); EntityManagerCreateDestroyEntitiesUtility.SetChunkCount(targetChunk, chunk->Count, dstEntityComponentStore, dstManagedComponentStore, dstEntityGroupManager); targetChunk->Archetype->EntityCount += chunk->Count; BufferHeader.PatchAfterCloningChunk(targetChunk); var tempEntities = new NativeArray <Entity>(targetChunk->Count, Allocator.Temp); dstEntityComponentStore->AllocateEntities(targetChunk->Archetype, targetChunk, 0, targetChunk->Count, (Entity *)tempEntities.GetUnsafePtr()); tempEntities.Dispose(); return(targetChunk); }
public NativeArray <int> MoveSharedComponents(ManagedComponentStore srcManagedComponents, NativeArray <ArchetypeChunk> chunks, Allocator allocator) { var remap = new NativeArray <int>(srcManagedComponents.GetSharedComponentCount(), allocator); var remapPtr = (int *)remap.GetUnsafePtr(); // Build a map of all shared component values that will be moved // remap will have a refcount of how many chunks reference the shared component after this loop for (int i = 0; i < chunks.Length; ++i) { var chunk = chunks[i].m_Chunk; var archetype = chunk->Archetype; var sharedComponentValues = chunk->SharedComponentValues; for (int sharedComponentIndex = 0; sharedComponentIndex < archetype->NumSharedComponents; ++sharedComponentIndex) { remapPtr[sharedComponentValues[sharedComponentIndex]]++; } } remap[0] = 0; // Move all shared components that are being referenced // remap will have a remap table of src SharedComponentDataIndex -> dst SharedComponentDataIndex var srcInfos = srcManagedComponents.SharedComponentInfoPtr; for (int srcIndex = 1; srcIndex < remap.Length; ++srcIndex) { if (remapPtr[srcIndex] == 0) { continue; } var srcData = srcManagedComponents.m_SharedComponentData[srcIndex]; var typeIndex = srcInfos[srcIndex].ComponentType; var hashCode = srcInfos[srcIndex].HashCode; var dstIndex = InsertSharedComponentAssumeNonDefault(typeIndex, hashCode, srcData); // * remove refcount based on refcount table // * -1 because InsertSharedComponentAssumeNonDefault above adds 1 refcount int srcRefCount = remapPtr[srcIndex]; SharedComponentInfoPtr[dstIndex].RefCount += srcRefCount - 1; srcManagedComponents.RemoveReference(srcIndex, srcRefCount); SharedComponentInfoPtr[dstIndex].Version++; remapPtr[srcIndex] = dstIndex; } return(remap); }
internal void SetSharedComponentDataBoxedDefaultMustBeNull(Entity entity, int typeIndex, int hashCode, object componentData) { BeforeStructuralChange(); EntityComponentStore->AssertEntityHasComponent(entity, typeIndex); var newSharedComponentDataIndex = 0; if (componentData != null) // null means default { newSharedComponentDataIndex = m_ManagedComponentStore.InsertSharedComponentAssumeNonDefault(typeIndex, hashCode, componentData); } EntityComponentStore->SetSharedComponentDataIndex(entity, typeIndex, newSharedComponentDataIndex); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); ManagedComponentStore.RemoveReference(newSharedComponentDataIndex); }
public unsafe NativeArray <int> MoveSharedComponents(ManagedComponentStore srcManagedComponents, NativeArray <ArchetypeChunk> chunks, NativeArray <EntityRemapUtility.EntityRemapInfo> remapInfos, Allocator allocator) { var remap = new NativeArray <int>(srcManagedComponents.GetSharedComponentCount(), allocator); for (int i = 0; i < chunks.Length; ++i) { var chunk = chunks[i].m_Chunk; var archetype = chunk->Archetype; var sharedComponentValues = chunk->SharedComponentValues; for (int sharedComponentIndex = 0; sharedComponentIndex < archetype->NumSharedComponents; ++sharedComponentIndex) { remap[sharedComponentValues[sharedComponentIndex]]++; } } remap[0] = 0; for (int srcIndex = 1; srcIndex < remap.Length; ++srcIndex) { if (remap[srcIndex] == 0) { continue; } var srcData = srcManagedComponents.m_SharedComponentData[srcIndex]; var typeIndex = srcManagedComponents.m_SharedComponentType[srcIndex]; var hashCode = TypeManager.GetHashCode(srcData, typeIndex); var dstIndex = InsertSharedComponentAssumeNonDefault(typeIndex, hashCode, srcData); m_SharedComponentRefCount[dstIndex] += remap[srcIndex] - 1; srcManagedComponents.RemoveReference(srcIndex, remap[srcIndex]); remap[srcIndex] = dstIndex; } return(remap); }
/// <summary> /// Sets the shared component of all entities in the query. /// </summary> /// <remarks> /// The component data stays in the same chunk, the internal shared component data indices will be adjusted. /// /// **Important:** This function creates a sync point, which means that the EntityManager waits for all /// currently running Jobs to complete before setting the component and no additional Jobs can start before /// the function is finished. A sync point can cause a drop in performance because the ECS framework may not /// be able to make use of the processing power of all available cores. /// </remarks> /// <param name="entity">The entity</param> /// <param name="componentData">A shared component object containing the values to set.</param> /// <typeparam name="T">The shared component type.</typeparam> public void SetSharedComponentData <T>(EntityQuery query, T componentData) where T : struct, ISharedComponentData { using (var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob)) { if (chunks.Length == 0) { return; } BeforeStructuralChange(); var type = ComponentType.ReadWrite <T>(); m_EntityDataAccess.RemoveComponent(chunks, type); int sharedComponentIndex = ManagedComponentStore.InsertSharedComponent(componentData); m_EntityDataAccess.AddSharedComponentData(chunks, sharedComponentIndex, type); ManagedComponentStore.RemoveReference(sharedComponentIndex); } }
internal void AddSharedComponentData(NativeArray <ArchetypeChunk> chunks, int sharedComponentIndex, ComponentType componentType) { if (chunks.Length == 0) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->AssertCanAddComponent(chunks, componentType); EntityComponentStore->AddSharedComponent(chunks, componentType, sharedComponentIndex); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityQueryManager.AddAdditionalArchetypes(changedArchetypes); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); ManagedComponentStore.RemoveReference(sharedComponentIndex); }
public unsafe void MoveSharedComponents(ManagedComponentStore srcManagedComponents, int *sharedComponentIndices, int sharedComponentIndicesCount) { for (var i = 0; i != sharedComponentIndicesCount; i++) { var srcIndex = sharedComponentIndices[i]; if (srcIndex == 0) { continue; } var srcData = srcManagedComponents.m_SharedComponentData[srcIndex]; var typeIndex = srcManagedComponents.m_SharedComponentType[srcIndex]; var hashCode = TypeManager.GetHashCode(srcData, typeIndex); var dstIndex = InsertSharedComponentAssumeNonDefault(typeIndex, hashCode, srcData); srcManagedComponents.RemoveReference(srcIndex); sharedComponentIndices[i] = dstIndex; } }
internal void AddSharedComponentData(MatchingArchetypeList archetypeList, EntityQueryFilter filter, int sharedComponentIndex, ComponentType componentType) { var jobHandle = new JobHandle(); using (var chunks = ComponentChunkIterator.CreateArchetypeChunkArray(archetypeList, Allocator.TempJob, out jobHandle, ref filter)) { jobHandle.Complete(); if (chunks.Length == 0) { return; } BeforeStructuralChange(); var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking(); EntityComponentStore->AssertCanAddComponent(chunks, componentType); EntityManagerChangeArchetypeUtility.AddSharedComponent(chunks, componentType, sharedComponentIndex, EntityComponentStore, ManagedComponentStore); ManagedComponentStore.RemoveReference(sharedComponentIndex); var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges); EntityGroupManager.AddAdditionalArchetypes(changedArchetypes); } }
static void ReleaseChunk(Chunk *chunk, EntityComponentStore *entityComponentStore, ManagedComponentStore managedComponentStore, EntityGroupManager entityGroupManager) { // 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, entityGroupManager); } // 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); }