Пример #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
        ArchetypeChunkFilter GetArchetypeChunkFilterWithChangedArchetype(Chunk *srcChunk, Archetype *dstArchetype)
        {
            var srcArchetype = srcChunk->Archetype;

            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = dstArchetype;
            BuildSharedComponentIndicesWithChangedArchetype(srcArchetype, dstArchetype, srcChunk->SharedComponentValues, archetypeChunkFilter.SharedComponentValues);
            return(archetypeChunkFilter);
        }
        void DestroyBatch(Entity *entities, Chunk *chunk, int indexInChunk, int batchCount)
        {
            var archetype = chunk->Archetype;

            if (!archetype->SystemStateCleanupNeeded)
            {
                DeallocateDataEntitiesInChunk(entities, chunk, indexInChunk, batchCount);
                ManagedChangesTracker.IncrementComponentOrderVersion(archetype,
                                                                     chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(archetype);

                if (chunk->ManagedArrayIndex >= 0)
                {
                    // We can just chop-off the end, no need to copy anything
                    if (chunk->Count != indexInChunk + batchCount)
                    {
                        ManagedChangesTracker.CopyManagedObjects(chunk, chunk->Count - batchCount,
                                                                 chunk,
                                                                 indexInChunk, batchCount);
                    }

                    ManagedChangesTracker.ClearManagedObjects(chunk, chunk->Count - batchCount,
                                                              batchCount);
                }

                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount);
            }
            else
            {
                var dstArchetypeChunkFilter = new ArchetypeChunkFilter();
                dstArchetypeChunkFilter.Archetype = archetype->SystemStateResidueArchetype;

                if (RequiresBuildingResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype))
                {
                    BuildResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype, chunk->SharedComponentValues, dstArchetypeChunkFilter.SharedComponentValues);
                }

                if (batchCount == chunk->Count)
                {
                    Move(chunk, ref dstArchetypeChunkFilter);
                }
                else
                {
                    Move(new EntityBatchInChunk {
                        Chunk = chunk, StartIndex = indexInChunk, Count = batchCount
                    }, ref dstArchetypeChunkFilter);
                }
            }
        }
Пример #5
0
        Chunk *GetChunkWithEmptySlots(ref ArchetypeChunkFilter archetypeChunkFilter)
        {
            var archetype = archetypeChunkFilter.Archetype;

            fixed(int *sharedComponentValues = archetypeChunkFilter.SharedComponentValues)
            {
                var chunk = archetype->GetExistingChunkWithEmptySlots(sharedComponentValues);

                if (chunk == null)
                {
                    chunk = GetCleanChunk(archetype, sharedComponentValues);
                }
                return(chunk);
            }
        }
Пример #6
0
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------

        public void CreateEntities(Archetype *archetype, Entity *entities, int count)
        {
            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = archetype;

            while (count != 0)
            {
                var chunk         = GetChunkWithEmptySlots(ref archetypeChunkFilter);
                var allocateCount = math.min(count, chunk->UnusedCount);

                ChunkDataUtility.Allocate(chunk, entities, allocateCount);

                entities += allocateCount;
                count    -= allocateCount;
            }
        }
Пример #7
0
        void DestroyBatch(Chunk *chunk, int indexInChunk, int batchCount)
        {
            var archetype = chunk->Archetype;

            if (!archetype->SystemStateCleanupNeeded)
            {
                DeallocateDataEntitiesInChunk(chunk, indexInChunk, batchCount);
                ManagedChangesTracker.IncrementComponentOrderVersion(archetype, chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(archetype);
                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount);
            }
            else
            {
                var systemStateResidueArchetype = archetype->SystemStateResidueArchetype;
                if (archetype == systemStateResidueArchetype)
                {
                    return;
                }

                var dstArchetypeChunkFilter = new ArchetypeChunkFilter();
                dstArchetypeChunkFilter.Archetype = systemStateResidueArchetype;

                if (RequiresBuildingResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype))
                {
                    BuildResidueSharedComponentIndices(archetype, dstArchetypeChunkFilter.Archetype, chunk->SharedComponentValues, dstArchetypeChunkFilter.SharedComponentValues);
                }
                else
                {
                    chunk->SharedComponentValues.CopyTo(dstArchetypeChunkFilter.SharedComponentValues, 0, archetype->NumSharedComponents);
                }

                if (batchCount == chunk->Count)
                {
                    Move(chunk, ref dstArchetypeChunkFilter);
                }
                else
                {
                    Move(new EntityBatchInChunk {
                        Chunk = chunk, StartIndex = indexInChunk, Count = batchCount
                    }, ref dstArchetypeChunkFilter);
                }
            }
        }
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------

        public void CreateEntities(Archetype *archetype, Entity *entities, int count)
        {
            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = archetype;

            while (count != 0)
            {
                var chunk = GetChunkWithEmptySlots(ref archetypeChunkFilter);

                int allocatedIndex;
                var allocatedCount = AllocateIntoChunk(chunk, count, out allocatedIndex);
                AllocateEntities(archetype, chunk, allocatedIndex, allocatedCount, entities);
                ChunkDataUtility.InitializeComponents(chunk, allocatedIndex, allocatedCount);
                chunk->SetAllChangeVersions(GlobalSystemVersion);
                entities += allocatedCount;
                count    -= allocatedCount;
            }

            IncrementComponentTypeOrderVersion(archetype);
        }
Пример #9
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);
        }
Пример #10
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;
            }
        }
Пример #11
0
        public void RemoveComponents(ArchetypeChunk *chunks, int chunkCount, ComponentTypes types)
        {
            Archetype *          prevArchetype        = null;
            ArchetypeChunkFilter archetypeChunkFilter = default(ArchetypeChunkFilter);

            for (int i = 0; i < chunkCount; i++)
            {
                var chunk     = chunks[i].m_Chunk;
                var archetype = chunk->Archetype;

                if (archetype != prevArchetype)
                {
                    // returns default if no types removed
                    archetypeChunkFilter = GetArchetypeChunkFilterWithRemovedComponents(chunk, types);
                    prevArchetype        = archetype;
                }

                if (archetypeChunkFilter.Archetype != null)
                {
                    Move(chunk, ref archetypeChunkFilter);
                }
            }
        }
Пример #12
0
        public void Move(Entity entity, Archetype *archetype, SharedComponentValues sharedComponentValues)
        {
            var archetypeChunkFilter = new ArchetypeChunkFilter(archetype, sharedComponentValues);

            Move(entity, ref archetypeChunkFilter);
        }
        int InstantiateEntitiesOne(Entity srcEntity, Entity *outputEntities, int instanceCount, InstantiateRemapChunk *remapChunks, int remapChunksCount)
        {
            var src          = GetEntityInChunk(srcEntity);
            var srcArchetype = src.Chunk->Archetype;
            var dstArchetype = srcArchetype->InstantiableArchetype;

            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = dstArchetype;

            if (RequiresBuildingResidueSharedComponentIndices(srcArchetype, dstArchetype))
            {
                BuildResidueSharedComponentIndices(srcArchetype, dstArchetype, src.Chunk->SharedComponentValues, archetypeChunkFilter.SharedComponentValues);
            }
            else
            {
                // Always copy shared component indices since GetChunkWithEmptySlots might reallocate the storage of SharedComponentValues
                src.Chunk->SharedComponentValues.CopyTo(archetypeChunkFilter.SharedComponentValues, 0, dstArchetype->NumSharedComponents);
            }

            Chunk *chunk = null;

            int instanceBeginIndex = 0;

            while (instanceBeginIndex != instanceCount)
            {
                chunk = GetChunkWithEmptySlots(ref archetypeChunkFilter);

                int indexInChunk;
                var allocatedCount = AllocateIntoChunk(chunk, instanceCount - instanceBeginIndex, out indexInChunk);

                ChunkDataUtility.ReplicateComponents(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount);
                AllocateEntities(dstArchetype, chunk, indexInChunk, allocatedCount,
                                 outputEntities + instanceBeginIndex);

                if (srcArchetype->NumManagedArrays > 0)
                {
                    ManagedChangesTracker.ReplicateManagedObjects(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount, srcEntity, outputEntities + instanceBeginIndex);
                }

                chunk->SetAllChangeVersions(GlobalSystemVersion);

#if UNITY_EDITOR
                for (var i = 0; i < allocatedCount; ++i)
                {
                    CopyName(outputEntities[i + instanceBeginIndex], srcEntity);
                }
#endif

                if (remapChunks != null)
                {
                    remapChunks[remapChunksCount].Chunk              = chunk;
                    remapChunks[remapChunksCount].IndexInChunk       = indexInChunk;
                    remapChunks[remapChunksCount].AllocatedCount     = allocatedCount;
                    remapChunks[remapChunksCount].InstanceBeginIndex = instanceBeginIndex;
                    remapChunksCount++;
                }


                instanceBeginIndex += allocatedCount;
            }

            if (chunk != null)
            {
                ManagedChangesTracker.IncrementComponentOrderVersion(dstArchetype,
                                                                     chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(dstArchetype);
            }

            return(remapChunksCount);
        }
Пример #14
0
        /// <summary>
        /// Fix-up the chunk to refer to a different (but layout compatible) archetype.
        /// - Should only be called by Move(chunk)
        /// </summary>
        void ChangeArchetypeInPlace(Chunk *srcChunk, ref ArchetypeChunkFilter dstArchetypeChunkFilter)
        {
            var dstArchetype = dstArchetypeChunkFilter.Archetype;

            fixed(int *sharedComponentValues = dstArchetypeChunkFilter.SharedComponentValues)
            {
                var srcArchetype = srcChunk->Archetype;

                ChunkDataUtility.AssertAreLayoutCompatible(srcArchetype, dstArchetype);

                var fixupSharedComponentReferences = (srcArchetype->NumSharedComponents > 0) || (dstArchetype->NumSharedComponents > 0);

                if (fixupSharedComponentReferences)
                {
                    int srcFirstShared = srcArchetype->FirstSharedComponent;
                    int dstFirstShared = dstArchetype->FirstSharedComponent;
                    int srcCount       = srcArchetype->NumSharedComponents;
                    int dstCount       = dstArchetype->NumSharedComponents;

                    int o = 0;
                    int n = 0;

                    for (; n < dstCount && o < srcCount;)
                    {
                        int srcType = srcArchetype->Types[o + srcFirstShared].TypeIndex;
                        int dstType = dstArchetype->Types[n + dstFirstShared].TypeIndex;
                        if (srcType == dstType)
                        {
                            var srcSharedComponentDataIndex = srcChunk->SharedComponentValues[o];
                            var dstSharedComponentDataIndex = sharedComponentValues[n];
                            if (srcSharedComponentDataIndex != dstSharedComponentDataIndex)
                            {
                                ManagedChangesTracker.RemoveReference(srcSharedComponentDataIndex);
                                ManagedChangesTracker.AddReference(dstSharedComponentDataIndex);
                            }

                            n++;
                            o++;
                        }
                        else if (dstType > srcType) // removed from dstArchetype
                        {
                            var sharedComponentDataIndex = srcChunk->SharedComponentValues[o];
                            ManagedChangesTracker.RemoveReference(sharedComponentDataIndex);
                            o++;
                        }
                        else // added to dstArchetype
                        {
                            var sharedComponentDataIndex = sharedComponentValues[n];
                            ManagedChangesTracker.AddReference(sharedComponentDataIndex);
                            n++;
                        }
                    }

                    for (; n < dstCount; n++) // added to dstArchetype
                    {
                        var sharedComponentDataIndex = sharedComponentValues[n];
                        ManagedChangesTracker.AddReference(sharedComponentDataIndex);
                    }

                    for (; o < srcCount; o++) // removed from dstArchetype
                    {
                        var sharedComponentDataIndex = srcChunk->SharedComponentValues[o];
                        ManagedChangesTracker.RemoveReference(sharedComponentDataIndex);
                    }
                }

                var fixupManagedComponents = (srcArchetype->NumManagedArrays > 0) || (dstArchetype->NumManagedArrays > 0);

                if (fixupManagedComponents)
                {
                    if (dstArchetype->NumManagedArrays == 0) // removed all
                    {
                        ManagedChangesTracker.DeallocateManagedArrayStorage(srcChunk->ManagedArrayIndex);
                        m_ManagedArrayFreeIndex.Add(srcChunk->ManagedArrayIndex);
                        srcChunk->ManagedArrayIndex = -1;
                    }
                    else
                    {
                        // We have changed the managed array order + size so allocate a new managed array
                        // copy the unchanged values into it
                        int dstManagedArrayIndex;
                        if (!m_ManagedArrayFreeIndex.IsEmpty)
                        {
                            dstManagedArrayIndex = m_ManagedArrayFreeIndex.Pop <int>();
                        }
                        else
                        {
                            dstManagedArrayIndex = m_ManagedArrayIndex;
                            m_ManagedArrayIndex++;
                        }

                        ManagedChangesTracker.AllocateManagedArrayStorage(dstManagedArrayIndex, dstArchetype->NumManagedArrays * srcChunk->Capacity);

                        int srcManagedArrayIndex = srcChunk->ManagedArrayIndex;
                        srcChunk->ManagedArrayIndex = dstManagedArrayIndex;

                        if (srcManagedArrayIndex != -1)
                        {
                            ManagedChangesTracker.MoveChunksManagedObjects(srcArchetype, srcManagedArrayIndex, dstArchetype, dstManagedArrayIndex, srcChunk->Capacity, srcChunk->Count);

                            ManagedChangesTracker.DeallocateManagedArrayStorage(srcManagedArrayIndex);
                            m_ManagedArrayFreeIndex.Add(srcManagedArrayIndex);
                        }
                    }
                }

                var  count         = srcChunk->Count;
                bool hasEmptySlots = count < srcChunk->Capacity;

                if (hasEmptySlots)
                {
                    srcArchetype->EmptySlotTrackingRemoveChunk(srcChunk);
                }

                int chunkIndexInSrcArchetype = srcChunk->ListIndex;

                var dstTypes = dstArchetype->Types;
                var srcTypes = srcArchetype->Types;

                //Change version is overriden below
                dstArchetype->AddToChunkList(srcChunk, sharedComponentValues, 0);
                int chunkIndexInDstArchetype = srcChunk->ListIndex;

                //Copy change versions from src to dst archetype
                for (int isrcType = srcArchetype->TypesCount - 1, idstType = dstArchetype->TypesCount - 1;
                     idstType >= 0;
                     --idstType)
                {
                    var dstType = dstTypes[idstType];
                    while (srcTypes[isrcType] > dstType)
                    {
                        --isrcType;
                    }
                    var version = srcTypes[isrcType] == dstType
                        ? srcArchetype->Chunks.GetChangeVersion(isrcType, chunkIndexInSrcArchetype)
                        : GlobalSystemVersion;

                    dstArchetype->Chunks.SetChangeVersion(idstType, chunkIndexInDstArchetype, version);
                }

                srcChunk->ListIndex = chunkIndexInSrcArchetype;
                srcArchetype->RemoveFromChunkList(srcChunk);
                srcChunk->ListIndex = chunkIndexInDstArchetype;

                if (hasEmptySlots)
                {
                    dstArchetype->EmptySlotTrackingAddChunk(srcChunk);
                }

                SetArchetype(srcChunk, dstArchetype);

                srcArchetype->EntityCount -= count;
                dstArchetype->EntityCount += count;

                if (srcArchetype->MetaChunkArchetype != dstArchetype->MetaChunkArchetype)
                {
                    if (srcArchetype->MetaChunkArchetype == null)
                    {
                        CreateMetaEntityForChunk(srcChunk);
                    }
                    else if (dstArchetype->MetaChunkArchetype == null)
                    {
                        DestroyMetaChunkEntity(srcChunk->metaChunkEntity);
                        srcChunk->metaChunkEntity = Entity.Null;
                    }
                    else
                    {
                        var metaChunk            = GetChunk(srcChunk->metaChunkEntity);
                        var archetypeChunkFilter = new ArchetypeChunkFilter(dstArchetype->MetaChunkArchetype, metaChunk->SharedComponentValues);
                        Move(srcChunk->metaChunkEntity, ref archetypeChunkFilter);
                    }
                }
            }
        }