Exemple #1
0
        public void SetArchetype(ArchetypeManager typeMan, Entity entity, Archetype *archetype,
                                 int *sharedComponentDataIndices)
        {
            var chunk      = typeMan.GetChunkWithEmptySlots(archetype, sharedComponentDataIndices);
            var chunkIndex = typeMan.AllocateIntoChunk(chunk);

            var oldArchetype  = m_Entities[entity.Index].Archetype;
            var oldChunk      = m_Entities[entity.Index].Chunk;
            var oldChunkIndex = m_Entities[entity.Index].IndexInChunk;

            ChunkDataUtility.Convert(oldChunk, oldChunkIndex, chunk, chunkIndex);
            if (chunk->ManagedArrayIndex >= 0 && oldChunk->ManagedArrayIndex >= 0)
            {
                ChunkDataUtility.CopyManagedObjects(typeMan, oldChunk, oldChunkIndex, chunk, chunkIndex, 1);
            }

            m_Entities[entity.Index].Archetype    = archetype;
            m_Entities[entity.Index].Chunk        = chunk;
            m_Entities[entity.Index].IndexInChunk = chunkIndex;

            var lastIndex = oldChunk->Count - 1;

            // No need to replace with ourselves
            if (lastIndex != oldChunkIndex)
            {
                var lastEntity = (Entity *)ChunkDataUtility.GetComponentData(oldChunk, lastIndex, 0);
                m_Entities[lastEntity->Index].IndexInChunk = oldChunkIndex;

                ChunkDataUtility.Copy(oldChunk, lastIndex, oldChunk, oldChunkIndex, 1);
                if (oldChunk->ManagedArrayIndex >= 0)
                {
                    ChunkDataUtility.CopyManagedObjects(typeMan, oldChunk, lastIndex, oldChunk, oldChunkIndex, 1);
                }
            }

            if (oldChunk->ManagedArrayIndex >= 0)
            {
                ChunkDataUtility.ClearManagedObjects(typeMan, oldChunk, lastIndex, 1);
            }

            --oldArchetype->EntityCount;
            typeMan.SetChunkCount(oldChunk, lastIndex);
        }
Exemple #2
0
        // ----------------------------------------------------------------------------------------------------------
        // Core, self-contained functions to change chunks. No other functions should actually move data from
        // one Chunk to another, or otherwise change the structure of a Chunk after creation.
        // ----------------------------------------------------------------------------------------------------------

        /// <summary>
        /// Move subset of chunk data into another chunk.
        /// - Chunks can be of same archetype (but differ by shared component values)
        /// - Returns number moved. Caller handles if less than indicated in srcBatch.
        /// </summary>
        /// <returns></returns>
        int Move(EntityBatchInChunk srcBatch, Chunk *dstChunk)
        {
            var srcChunk      = srcBatch.Chunk;
            var srcChunkIndex = srcBatch.StartIndex;
            var srcCount      = srcBatch.Count;
            var srcArchetype  = srcChunk->Archetype;
            var dstArchetype  = dstChunk->Archetype;

            // Note (srcArchetype == dstArchetype) is valid
            // Archetypes can the the same, but chunks still differ because filter is different (e.g. shared component)

            int dstChunkIndex;
            var dstCount = AllocateIntoChunk(dstChunk, srcCount, out dstChunkIndex);

            // If can only move partial batch, move from the end so that remainder of batch isn't affected.
            srcChunkIndex = srcChunkIndex + srcCount - dstCount;

            ChunkDataUtility.Convert(srcChunk, srcChunkIndex, dstChunk, dstChunkIndex, dstCount);

            if (dstChunk->ManagedArrayIndex >= 0 && srcChunk->ManagedArrayIndex >= 0)
            {
                ManagedChangesTracker.CopyManagedObjects(srcChunk, srcChunkIndex, dstChunk, dstChunkIndex, dstCount);
            }

            var dstEntities = (Entity *)ChunkDataUtility.GetComponentDataRO(dstChunk, dstChunkIndex, 0);

            for (int i = 0; i < dstCount; i++)
            {
                var entity = dstEntities[i];

                SetArchetype(entity, dstArchetype);
                SetEntityInChunk(entity, new EntityInChunk {
                    Chunk = dstChunk, IndexInChunk = dstChunkIndex + i
                });
            }

            // Fill in moved component data from the end.
            var srcTailIndex = srcChunkIndex + dstCount;
            var srcTailCount = srcChunk->Count - srcTailIndex;
            var fillCount    = math.min(dstCount, srcTailCount);

            if (fillCount > 0)
            {
                var fillStartIndex = srcChunk->Count - fillCount;

                ChunkDataUtility.Copy(srcChunk, fillStartIndex, srcChunk, srcChunkIndex, fillCount);

                var fillEntities = (Entity *)ChunkDataUtility.GetComponentDataRO(srcChunk, srcChunkIndex, 0);
                for (int i = 0; i < fillCount; i++)
                {
                    var entity = fillEntities[i];
                    SetEntityInChunk(entity, new EntityInChunk {
                        Chunk = srcChunk, IndexInChunk = srcChunkIndex + i
                    });
                }

                if (srcChunk->ManagedArrayIndex >= 0)
                {
                    ManagedChangesTracker.CopyManagedObjects(srcChunk, fillStartIndex, srcChunk, srcChunkIndex, fillCount);
                }
            }

            if (srcChunk->ManagedArrayIndex >= 0)
            {
                ManagedChangesTracker.ClearManagedObjects(srcChunk, srcChunk->Count - dstCount, dstCount);
            }

            srcArchetype->EntityCount -= dstCount;

            dstChunk->SetAllChangeVersions(GlobalSystemVersion);
            srcChunk->SetAllChangeVersions(GlobalSystemVersion);

            ManagedChangesTracker.IncrementComponentOrderVersion(srcArchetype, srcChunk->SharedComponentValues);
            IncrementComponentTypeOrderVersion(srcArchetype);

            ManagedChangesTracker.IncrementComponentOrderVersion(dstArchetype, dstChunk->SharedComponentValues);
            IncrementComponentTypeOrderVersion(dstArchetype);

            SetChunkCount(srcChunk, srcChunk->Count - dstCount);

            // Cannot DestroyEntities unless SystemStateCleanupComplete on the entity chunk.
            if (dstChunk->Archetype->SystemStateCleanupComplete)
            {
                DestroyEntities(dstEntities, dstCount);
            }

            return(dstCount);
        }