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);
        }
예제 #2
0
        /// <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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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;
            }
        }
예제 #10
0
        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);
        }