Exemple #1
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);
        }
Exemple #2
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);
            }
        }
Exemple #3
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);
            }
        }
Exemple #4
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();
        }