Beispiel #1
0
        internal void AddComponent(MatchingArchetypeList archetypeList, EntityQueryFilter filter,
                                   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();
                EntityComponentStore->AssertCanAddComponent(chunks, componentType);

                using (var entityBatchList = m_EntityComponentStore->CreateEntityBatchList(chunks))
                {
                    EntityManagerChangeArchetypeUtility.AddComponent(entityBatchList, componentType, 0,
                                                                     EntityComponentStore,
                                                                     ManagedComponentStore,
                                                                     EntityGroupManager);
                }
            }
        }
        public void AddComponent(Entity entity, ComponentType componentType)
        {
            CheckAccess();

            m_EntityComponentStore->AssertCanAddComponent(entity, componentType);
            EntityManagerChangeArchetypeUtility.AddComponent(entity, componentType, EntityComponentStore, ManagedComponentStore, EntityGroupManager);
        }
Beispiel #3
0
        /// <summary>
        /// Adds a component to each of the chunks identified by a EntityQuery and set the component values.
        /// </summary>
        /// <remarks>
        /// This function finds all chunks whose archetype satisfies the EntityQuery and adds the specified
        /// component to them.
        ///
        /// A chunk component is common to all entities in a chunk. You can access a chunk <see cref="IComponentData"/>
        /// instance through either the chunk itself or through an entity stored in that chunk.
        ///
        /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
        /// currently running Jobs to complete before adding 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="entityQuery">The EntityQuery identifying the chunks to modify.</param>
        /// <param name="componentData">The data to set.</param>
        /// <typeparam name="T">The type of component, which must implement IComponentData.</typeparam>
        public void AddChunkComponentData <T>(EntityQuery entityQuery, T componentData) where T : struct, IComponentData
        {
            using (var chunks = entityQuery.CreateArchetypeChunkArray(Allocator.TempJob))
            {
                if (chunks.Length == 0)
                {
                    return;
                }
                BeforeStructuralChange();
                var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();

                EntityComponentStore->AssertCanAddChunkComponent(chunks, ComponentType.ChunkComponent <T>());

                var type      = ComponentType.ReadWrite <T>();
                var chunkType = ComponentType.FromTypeIndex(TypeManager.MakeChunkComponentTypeIndex(type.TypeIndex));

                using (var entityBatchList = m_EntityComponentStore->CreateEntityBatchList(chunks))
                {
                    EntityManagerChangeArchetypeUtility.AddComponentFromMainThread(entityBatchList, chunkType, 0,
                                                                                   EntityComponentStore, ManagedComponentStore);
                    m_EntityComponentStore->SetChunkComponent <T>(entityBatchList, componentData);
                }

                var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);
                EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
            }
        }
        public void RemoveComponent(Entity entity, ComponentType type)
        {
            CheckAccess();

            EntityManagerChangeArchetypeUtility.RemoveComponent(entity, type,
                                                                EntityComponentStore, ManagedComponentStore, EntityGroupManager);
        }
Beispiel #5
0
        internal void RemoveComponent(MatchingArchetypeList archetypeList, EntityQueryFilter filter,
                                      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->AssertCanRemoveComponent(chunks, componentType);
                EntityManagerChangeArchetypeUtility.RemoveComponent(chunks, componentType,
                                                                    EntityComponentStore,
                                                                    ManagedComponentStore);

                var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);
                EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
            }
        }
Beispiel #6
0
 public static void DestroyMetaChunkEntity(Entity entity,
                                           EntityComponentStore *entityComponentStore,
                                           ManagedComponentStore managedComponentStore)
 {
     EntityManagerChangeArchetypeUtility.RemoveComponent(entity, ComponentType.ReadWrite <ChunkHeader>(),
                                                         entityComponentStore, managedComponentStore);
     DestroyEntities(&entity, 1, entityComponentStore, managedComponentStore);
 }
Beispiel #7
0
 /// <summary>
 /// Adds a component to a set of entities.
 /// </summary>
 /// <remarks>
 /// Adding a component changes an entity's archetype and results in the entity being moved to a different
 /// chunk.
 ///
 /// The added components have the default values for the type.
 ///
 /// If an <see cref="Entity"/> object in the `entities` array refers to an entity that has been destroyed, this function
 /// throws an ArgumentError exception.
 ///
 /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
 /// currently running Jobs to complete before creating these chunks 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="entities">An array of Entity objects.</param>
 /// <param name="componentType">The type of component to add.</param>
 public void AddComponent(NativeArray <Entity> entities, ComponentType componentType)
 {
     BeforeStructuralChange();
     using (var entityBatchList = m_EntityComponentStore->CreateEntityBatchList(entities))
     {
         EntityManagerChangeArchetypeUtility.AddComponent(entityBatchList, componentType, 0, EntityComponentStore, ManagedComponentStore, EntityGroupManager);
     }
 }
Beispiel #8
0
        /// <summary>
        /// Removes a component from an entity.
        /// </summary>
        /// <remarks>
        /// Removing a component changes an entity's archetype and results in the entity being moved to a different
        /// chunk.
        ///
        /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
        /// currently running Jobs to complete before removing 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 to modify.</param>
        /// <param name="type">The type of component to remove.</param>
        public void RemoveComponent(Entity entity, ComponentType type)
        {
            BeforeStructuralChange();
            var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();

            EntityManagerChangeArchetypeUtility.RemoveComponent(entity, type, EntityComponentStore, ManagedComponentStore);

            var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);

            EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
        }
Beispiel #9
0
        // ----------------------------------------------------------------------------------------------------------
        // INTERNAL
        // ----------------------------------------------------------------------------------------------------------

        internal void AddComponent(Entity entity, ComponentType componentType, bool ignoreDuplicateAdd)
        {
            if (ignoreDuplicateAdd && HasComponent(entity, componentType))
            {
                return;
            }

            BeforeStructuralChange();
            EntityComponentStore->AssertCanAddComponent(entity, componentType);
            EntityManagerChangeArchetypeUtility.AddComponent(entity, componentType, EntityComponentStore, ManagedComponentStore, EntityGroupManager);
        }
Beispiel #10
0
        public void AddComponent(Entity entity, ComponentType componentType)
        {
            CheckAccess();
            m_EntityComponentStore->AssertCanAddComponent(entity, componentType);
            var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();

            EntityManagerChangeArchetypeUtility.AddComponent(entity, componentType, EntityComponentStore, ManagedComponentStore);

            var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);

            EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
        }
Beispiel #11
0
 /// <summary>
 /// Removes a component from the chunks identified by a EntityQuery.
 /// </summary>
 /// <remarks>
 /// A chunk component is common to all entities in a chunk. You can access a chunk <see cref="IComponentData"/>
 /// instance through either the chunk itself or through an entity stored in that chunk.
 ///
 /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
 /// currently running Jobs to complete before removing 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="entityQuery">The EntityQuery identifying the chunks to modify.</param>
 /// <typeparam name="T">The type of component to remove.</typeparam>
 public void RemoveChunkComponentData <T>(EntityQuery entityQuery)
 {
     using (var chunks = entityQuery.CreateArchetypeChunkArray(Allocator.TempJob))
     {
         if (chunks.Length == 0)
         {
             return;
         }
         BeforeStructuralChange();
         EntityManagerChangeArchetypeUtility.RemoveComponent(chunks, ComponentType.ChunkComponent <T>(),
                                                             EntityComponentStore, ManagedComponentStore, EntityGroupManager);
     }
 }
Beispiel #12
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);

            EntityManagerChangeArchetypeUtility.SetSharedComponentDataIndex(entity, typeIndex, newSharedComponentDataIndex,
                                                                            EntityComponentStore, ManagedComponentStore);
            m_ManagedComponentStore.RemoveReference(newSharedComponentDataIndex);
        }
        public void SetSharedComponentData <T>(Entity entity, T componentData) where T : struct, ISharedComponentData
        {
            CheckAccess();

            var typeIndex = TypeManager.GetTypeIndex <T>();

            m_EntityComponentStore->AssertEntityHasComponent(entity, typeIndex);

            var newSharedComponentDataIndex = ManagedComponentStore.InsertSharedComponent(componentData);

            EntityManagerChangeArchetypeUtility.SetSharedComponentDataIndex(entity, typeIndex, newSharedComponentDataIndex,
                                                                            EntityComponentStore, ManagedComponentStore, EntityGroupManager);

            ManagedComponentStore.RemoveReference(newSharedComponentDataIndex);
        }
Beispiel #14
0
        // ----------------------------------------------------------------------------------------------------------
        // INTERNAL
        // ----------------------------------------------------------------------------------------------------------

        internal void AddComponent(Entity entity, ComponentType componentType, bool ignoreDuplicateAdd)
        {
            if (ignoreDuplicateAdd && HasComponent(entity, componentType))
            {
                return;
            }

            BeforeStructuralChange();
            var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();

            EntityComponentStore->AssertCanAddComponent(entity, componentType);
            EntityManagerChangeArchetypeUtility.AddComponent(entity, componentType, EntityComponentStore, ManagedComponentStore);

            var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);

            EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
        }
Beispiel #15
0
        /// <summary>
        /// Removes a component from the chunks identified by a EntityQuery.
        /// </summary>
        /// <remarks>
        /// A chunk component is common to all entities in a chunk. You can access a chunk <see cref="IComponentData"/>
        /// instance through either the chunk itself or through an entity stored in that chunk.
        ///
        /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
        /// currently running Jobs to complete before removing 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="entityQuery">The EntityQuery identifying the chunks to modify.</param>
        /// <typeparam name="T">The type of component to remove.</typeparam>
        public void RemoveChunkComponentData <T>(EntityQuery entityQuery)
        {
            using (var chunks = entityQuery.CreateArchetypeChunkArray(Allocator.TempJob))
            {
                if (chunks.Length == 0)
                {
                    return;
                }
                BeforeStructuralChange();
                var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();

                EntityManagerChangeArchetypeUtility.RemoveComponent(chunks, ComponentType.ChunkComponent <T>(),
                                                                    EntityComponentStore, ManagedComponentStore);

                var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);
                EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
            }
        }
Beispiel #16
0
        internal void AddSharedComponent <T>(NativeArray <ArchetypeChunk> chunks, T componentData) where T : struct, ISharedComponentData
        {
            CheckAccess();

            var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();

            var componentType = ComponentType.ReadWrite <T>();
            var newSharedComponentDataIndex = ManagedComponentStore.InsertSharedComponent(componentData);

            EntityComponentStore->AssertCanAddComponent(chunks, componentType);

            EntityManagerChangeArchetypeUtility.AddSharedComponent(chunks, componentType, newSharedComponentDataIndex, EntityComponentStore, ManagedComponentStore);
            ManagedComponentStore.RemoveReference(newSharedComponentDataIndex);

            var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);

            EntityGroupManager.AddAdditionalArchetypes(changedArchetypes);
        }
Beispiel #17
0
        /// <summary>
        /// Adds a shared component to a set of entities defined by a EntityQuery.
        /// </summary>
        /// <remarks>
        /// The fields of the `componentData` parameter are assigned to all of the added shared components.
        ///
        /// Adding a component to an entity changes its archetype and 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 adding 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="entityQuery">The EntityQuery defining a set of entities to modify.</param>
        /// <param name="componentData">The data to set.</param>
        /// <typeparam name="T">The data type of the shared component.</typeparam>
        public void AddSharedComponentData <T>(EntityQuery entityQuery, T componentData)
            where T : struct, ISharedComponentData
        {
            var componentType = ComponentType.ReadWrite <T>();

            using (var chunks = entityQuery.CreateArchetypeChunkArray(Allocator.TempJob))
            {
                if (chunks.Length == 0)
                {
                    return;
                }
                BeforeStructuralChange();
                var newSharedComponentDataIndex = m_ManagedComponentStore.InsertSharedComponent(componentData);
                EntityComponentStore->AssertCanAddComponent(chunks, componentType);
                EntityManagerChangeArchetypeUtility.AddSharedComponent(chunks, componentType, newSharedComponentDataIndex,
                                                                       EntityComponentStore, ManagedComponentStore, EntityGroupManager);
                m_ManagedComponentStore.RemoveReference(newSharedComponentDataIndex);
            }
        }
Beispiel #18
0
        internal void SetSharedComponentDataBoxed(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);
            }

            EntityManagerChangeArchetypeUtility.SetSharedComponentDataIndex(entity, typeIndex,
                                                                            newSharedComponentDataIndex,
                                                                            EntityComponentStore, ManagedComponentStore);

            m_ManagedComponentStore.RemoveReference(newSharedComponentDataIndex);
        }
Beispiel #19
0
 /// <summary>
 /// Adds a set of component to an entity.
 /// </summary>
 /// <remarks>
 /// Adding components changes the entity's archetype and results in the entity being moved to a different
 /// chunk.
 ///
 /// The added components have the default values for the type.
 ///
 /// If the <see cref="Entity"/> object refers to an entity that has been destroyed, this function throws an ArgumentError
 /// exception.
 ///
 /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
 /// currently running Jobs to complete before adding these components 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 to modify.</param>
 /// <param name="types">The types of components to add.</param>
 public void AddComponents(Entity entity, ComponentTypes types)
 {
     BeforeStructuralChange();
     EntityComponentStore->AssertCanAddComponents(entity, types);
     EntityManagerChangeArchetypeUtility.AddComponents(entity, types, EntityComponentStore, ManagedComponentStore, EntityGroupManager);
 }
Beispiel #20
0
        static void DestroyBatch(Entity *entities, Chunk *chunk, int indexInChunk, int batchCount,
                                 EntityComponentStore *entityComponentStore,
                                 ManagedComponentStore managedComponentStore)
        {
            var archetype = chunk->Archetype;

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

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

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

                chunk->Archetype->EntityCount -= batchCount;
                SetChunkCount(chunk, chunk->Count - batchCount, entityComponentStore, managedComponentStore);
            }
            else
            {
                var newType = archetype->SystemStateResidueArchetype;

                var sharedComponentValues = chunk->SharedComponentValues;

                if (RequiresBuildingResidueSharedComponentIndices(archetype, newType))
                {
                    var tempAlloc = stackalloc int[newType->NumSharedComponents];
                    BuildResidueSharedComponentIndices(archetype, newType, sharedComponentValues, tempAlloc);
                    sharedComponentValues = tempAlloc;
                }

                // See: https://github.com/Unity-Technologies/dots/issues/1387
                // For Locked Order Chunks specfically, need to make sure that structural changes are always done per-chunk.
                // If trying to muutate structure in a way that is not per chunk, will hit an exception in the else clause anyway.
                // This ultimately needs to be replaced by entity batch interface.

                if (batchCount == chunk->Count)
                {
                    managedComponentStore.IncrementComponentOrderVersion(archetype, chunk->SharedComponentValues);
                    entityComponentStore->IncrementComponentTypeOrderVersion(archetype);

                    EntityManagerChangeArchetypeUtility.SetArchetype(chunk, newType, sharedComponentValues,
                                                                     entityComponentStore, managedComponentStore);
                }
                else
                {
                    for (var i = 0; i < batchCount; i++)
                    {
                        var entity = entities[i];
                        managedComponentStore.IncrementComponentOrderVersion(archetype,
                                                                             entityComponentStore->GetChunk(entity)->SharedComponentValues);
                        entityComponentStore->IncrementComponentTypeOrderVersion(archetype);
                        EntityManagerChangeArchetypeUtility.SetArchetype(entity, newType, sharedComponentValues,
                                                                         entityComponentStore, managedComponentStore);
                    }
                }
            }
        }
Beispiel #21
0
 /// <summary>
 /// Removes a component from an entity.
 /// </summary>
 /// <remarks>
 /// Removing a component changes an entity's archetype and results in the entity being moved to a different
 /// chunk.
 ///
 /// **Important:** This function creates a sync point, which means that the EntityManager waits for all
 /// currently running Jobs to complete before removing 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 to modify.</param>
 /// <param name="type">The type of component to remove.</param>
 public void RemoveComponent(Entity entity, ComponentType type)
 {
     BeforeStructuralChange();
     EntityManagerChangeArchetypeUtility.RemoveComponent(entity, type, EntityComponentStore, ManagedComponentStore, EntityGroupManager);
 }
Beispiel #22
0
        public static unsafe void DeserializeWorld(ExclusiveEntityTransaction manager, BinaryReader reader, int numSharedComponents)
        {
            if (manager.EntityComponentStore->CountEntities() != 0)
            {
                throw new ArgumentException(
                          $"DeserializeWorld can only be used on completely empty EntityManager. Please create a new empty World and use EntityManager.MoveEntitiesFrom to move the loaded entities into the destination world instead.");
            }
            int storedVersion = reader.ReadInt();

            if (storedVersion != CurrentFileFormatVersion)
            {
                throw new ArgumentException(
                          $"Attempting to read a entity scene stored in an old file format version (stored version : {storedVersion}, current version : {CurrentFileFormatVersion})");
            }

            var types = ReadTypeArray(reader);
            int totalEntityCount;
            var archetypes = ReadArchetypes(reader, types, manager, out totalEntityCount);

            int sharedComponentArraysLength = reader.ReadInt();
            var sharedComponentArrays       = new NativeArray <int>(sharedComponentArraysLength, Allocator.Temp);

            reader.ReadArray(sharedComponentArrays, sharedComponentArraysLength);

            manager.AllocateConsecutiveEntitiesForLoading(totalEntityCount);

            int totalChunkCount             = reader.ReadInt();
            var chunksWithMetaChunkEntities = new NativeList <ArchetypeChunk>(totalChunkCount, Allocator.Temp);

            int   totalBlobAssetSize = reader.ReadInt();
            byte *allBlobAssetData   = null;

            NativeList <ArchetypeChunk> blobAssetRefChunks = new NativeList <ArchetypeChunk>();
            int blobAssetOwnerIndex = -1;

            if (totalBlobAssetSize != 0)
            {
                allBlobAssetData = (byte *)UnsafeUtility.Malloc(totalBlobAssetSize, 16, Allocator.Persistent);
                reader.ReadBytes(allBlobAssetData, totalBlobAssetSize);
                blobAssetOwnerIndex = manager.ManagedComponentStore.InsertSharedComponent(new BlobAssetOwner(allBlobAssetData, totalBlobAssetSize));
                blobAssetRefChunks  = new NativeList <ArchetypeChunk>(32, Allocator.Temp);
                var end    = allBlobAssetData + totalBlobAssetSize;
                var header = (BlobAssetHeader *)allBlobAssetData;
                while (header < end)
                {
                    header->ValidationPtr = header + 1;
                    header = (BlobAssetHeader *)OffsetFromPointer(header + 1, header->Length);
                }
            }

            int sharedComponentArraysIndex = 0;

            for (int i = 0; i < totalChunkCount; ++i)
            {
                var chunk = (Chunk *)UnsafeUtility.Malloc(Chunk.kChunkSize, 64, Allocator.Persistent);
                reader.ReadBytes(chunk, Chunk.kChunkSize);

                var  archetype = chunk->Archetype = archetypes[(int)chunk->Archetype].Archetype;
                var  numSharedComponentsInArchetype = chunk->Archetype->NumSharedComponents;
                int *sharedComponentValueArray      = (int *)sharedComponentArrays.GetUnsafePtr() + sharedComponentArraysIndex;

                for (int j = 0; j < numSharedComponentsInArchetype; ++j)
                {
                    // The shared component 0 is not part of the array, so an index equal to the array size is valid.
                    if (sharedComponentValueArray[j] > numSharedComponents)
                    {
                        throw new ArgumentException(
                                  $"Archetype uses shared component at index {sharedComponentValueArray[j]} but only {numSharedComponents} are available, check if the shared scene has been properly loaded.");
                    }
                }

                var remapedSharedComponentValues = stackalloc int[archetype->NumSharedComponents];
                RemapSharedComponentIndices(remapedSharedComponentValues, archetype, sharedComponentValueArray);

                sharedComponentArraysIndex += numSharedComponentsInArchetype;

                // Allocate additional heap memory for buffers that have overflown into the heap, and read their data.
                int bufferAllocationCount = reader.ReadInt();
                if (bufferAllocationCount > 0)
                {
                    var bufferPatches = new NativeArray <BufferPatchRecord>(bufferAllocationCount, Allocator.Temp);
                    reader.ReadArray(bufferPatches, bufferPatches.Length);

                    // TODO: PERF: Batch malloc interface.
                    for (int pi = 0; pi < bufferAllocationCount; ++pi)
                    {
                        var target = (BufferHeader *)OffsetFromPointer(chunk->Buffer, bufferPatches[pi].ChunkOffset);

                        // TODO: Alignment
                        target->Pointer = (byte *)UnsafeUtility.Malloc(bufferPatches[pi].AllocSizeBytes, 8, Allocator.Persistent);

                        reader.ReadBytes(target->Pointer, bufferPatches[pi].AllocSizeBytes);
                    }

                    bufferPatches.Dispose();
                }

                if (totalBlobAssetSize != 0 && archetype->ContainsBlobAssetRefs)
                {
                    blobAssetRefChunks.Add(new ArchetypeChunk(chunk, manager.EntityComponentStore));
                    PatchBlobAssetsInChunkAfterLoad(chunk, allBlobAssetData);
                }

                EntityManagerMoveEntitiesUtility.AddExistingChunk(chunk, remapedSharedComponentValues,
                                                                  manager.EntityComponentStore, manager.ManagedComponentStore);

                if (chunk->metaChunkEntity != Entity.Null)
                {
                    chunksWithMetaChunkEntities.Add(new ArchetypeChunk(chunk, manager.EntityComponentStore));
                }
            }

            if (totalBlobAssetSize != 0)
            {
                EntityManagerChangeArchetypeUtility.AddSharedComponent(blobAssetRefChunks, ComponentType.ReadWrite <BlobAssetOwner>(), blobAssetOwnerIndex, manager.EntityComponentStore, manager.ManagedComponentStore, manager.EntityGroupManager);
                manager.ManagedComponentStore.RemoveReference(blobAssetOwnerIndex);
                blobAssetRefChunks.Dispose();
            }

            for (int i = 0; i < chunksWithMetaChunkEntities.Length; ++i)
            {
                var chunk = chunksWithMetaChunkEntities[i].m_Chunk;
                manager.SetComponentData(chunk->metaChunkEntity, new ChunkHeader {
                    ArchetypeChunk = chunksWithMetaChunkEntities[i]
                });
            }

            chunksWithMetaChunkEntities.Dispose();
            sharedComponentArrays.Dispose();
            archetypes.Dispose();
            types.Dispose();
        }