コード例 #1
0
        void Move(Chunk *srcChunk, ref ArchetypeChunkFilter archetypeChunkFilter)
        {
            if (archetypeChunkFilter.Archetype->SystemStateCleanupComplete)
            {
                ChunkDataUtility.Deallocate(srcChunk);
                return;
            }

            var srcArchetype = srcChunk->Archetype;

            if (ChunkDataUtility.AreLayoutCompatible(srcArchetype, archetypeChunkFilter.Archetype))
            {
                fixed(int *sharedComponentValues = archetypeChunkFilter.SharedComponentValues)
                {
                    ChunkDataUtility.ChangeArchetypeInPlace(srcChunk, archetypeChunkFilter.Archetype, sharedComponentValues);
                }

                return;
            }

            var entityBatch = new EntityBatchInChunk {
                Chunk = srcChunk, Count = srcChunk->Count, StartIndex = 0
            };

            Move(entityBatch, ref archetypeChunkFilter);
        }
コード例 #2
0
        void Move(Entity entity, ref ArchetypeChunkFilter archetypeChunkFilter)
        {
            var srcEntityInChunk = GetEntityInChunk(entity);
            var entityBatch      = new EntityBatchInChunk {
                Chunk = srcEntityInChunk.Chunk, Count = 1, StartIndex = srcEntityInChunk.IndexInChunk
            };

            Move(entityBatch, ref archetypeChunkFilter);
        }
コード例 #3
0
        // ----------------------------------------------------------------------------------------------------------
        // INTERNAL
        // ----------------------------------------------------------------------------------------------------------

        void Move(Entity entity, Chunk *dstChunk)
        {
            var srcEntityInChunk = GetEntityInChunk(entity);
            var srcChunk         = srcEntityInChunk.Chunk;
            var srcChunkIndex    = srcEntityInChunk.IndexInChunk;
            var entityBatch      = new EntityBatchInChunk {
                Chunk = srcChunk, Count = 1, StartIndex = srcChunkIndex
            };

            Move(entityBatch, dstChunk);
        }
コード例 #4
0
        bool AddComponent(EntityBatchInChunk entityBatchInChunk, ComponentType componentType, int sharedComponentIndex = 0)
        {
            var srcChunk             = entityBatchInChunk.Chunk;
            var archetypeChunkFilter = GetArchetypeChunkFilterWithAddedComponent(srcChunk, componentType, sharedComponentIndex);

            if (archetypeChunkFilter.Archetype == null)
            {
                return(false);
            }

            Move(entityBatchInChunk, ref archetypeChunkFilter);
            return(true);
        }
コード例 #5
0
        bool RemoveComponent(EntityBatchInChunk entityBatchInChunk, ComponentType componentType)
        {
            var srcChunk             = entityBatchInChunk.Chunk;
            var archetypeChunkFilter = GetArchetypeChunkFilterWithRemovedComponent(srcChunk, componentType);

            if (archetypeChunkFilter.Archetype == null)
            {
                return(false);
            }

            Move(entityBatchInChunk, ref archetypeChunkFilter);
            return(true);
        }
コード例 #6
0
        bool AddComponents(EntityBatchInChunk entityBatchInChunk, ComponentTypes componentTypes)
        {
            var srcChunk = entityBatchInChunk.Chunk;

            var dstArchetype = GetArchetypeWithAddedComponents(srcChunk->Archetype, componentTypes);

            if (dstArchetype == srcChunk->Archetype)  // none were added
            {
                return(false);
            }

            var archetypeChunkFilter = GetArchetypeChunkFilterWithAddedComponents(srcChunk, dstArchetype);

            if (archetypeChunkFilter.Archetype == null)
            {
                return(false);
            }

            Move(entityBatchInChunk, ref archetypeChunkFilter);
            return(true);
        }
コード例 #7
0
        void Move(Chunk *srcChunk, ref ArchetypeChunkFilter archetypeChunkFilter)
        {
            if (archetypeChunkFilter.Archetype->SystemStateCleanupComplete)
            {
                DeleteChunk(srcChunk);
                return;
            }

            var srcArchetype = srcChunk->Archetype;

            if (ChunkDataUtility.AreLayoutCompatible(srcArchetype, archetypeChunkFilter.Archetype))
            {
                ChangeArchetypeInPlace(srcChunk, ref archetypeChunkFilter);
                return;
            }

            var entityBatch = new EntityBatchInChunk {
                Chunk = srcChunk, Count = srcChunk->Count, StartIndex = 0
            };

            Move(entityBatch, ref archetypeChunkFilter);
        }
コード例 #8
0
        void Move(EntityBatchInChunk entityBatchInChunk, ref ArchetypeChunkFilter archetypeChunkFilter)
        {
            var systemStateCleanupComplete = archetypeChunkFilter.Archetype->SystemStateCleanupComplete;

            var srcChunk          = entityBatchInChunk.Chunk;
            var srcRemainingCount = entityBatchInChunk.Count;
            var startIndex        = entityBatchInChunk.StartIndex;

            if ((srcRemainingCount == srcChunk->Count) && systemStateCleanupComplete)
            {
                ChunkDataUtility.Deallocate(srcChunk);
                return;
            }

            while (srcRemainingCount > 0)
            {
                var dstChunk = GetChunkWithEmptySlots(ref archetypeChunkFilter);
                var dstCount = Move(new EntityBatchInChunk {
                    Chunk = srcChunk, Count = srcRemainingCount, StartIndex = startIndex
                }, dstChunk);
                srcRemainingCount -= dstCount;
            }
        }
コード例 #9
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);
        }