Beispiel #1
0
        /// <summary>
        /// Destroys all entities described in the <see cref="EntityChangeSet"/>
        /// </summary>
        /// <remarks>
        /// Since building the <see cref="NativeMultiHashMap{TEntityGuidComponent, Entity}"/> the entire world is expensive
        /// this method will incrementally update the map based on the destroyed entities.
        /// </remarks>
        private static unsafe void ApplyDestroyEntities(
            EntityManager entityManager,
            EntityChangeSet changeSet,
            NativeMultiHashMap <int, Entity> packedEntities,
            NativeMultiHashMap <EntityGuid, Entity> entityGuidToEntity)
        {
            for (var i = changeSet.Entities.Length - changeSet.DestroyedEntityCount; i < changeSet.Entities.Length; i++)
            {
                if (!packedEntities.TryGetFirstValue(i, out var entity, out var iterator))
                {
                    continue;
                }

                do
                {
                    // Perform incremental updates on the entityGuidToEntity map to avoid a full rebuild.
                    // @NOTE We do NOT remove from the `entityToEntityGuid` here since the LinkedEntityGroup removal will need it to map back groups.
                    entityGuidToEntity.Remove(changeSet.Entities[i], entity);

                    if (entityManager.EntityComponentStore->Exists(entity))
                    {
                        entityManager.DestroyEntity(entity);
                    }
                    else
                    {
                        Debug.LogWarning($"DestroyEntity({entity}) but it does not exist.");
                    }
                }while (packedEntities.TryGetNextValue(out entity, ref iterator));
            }
        }
Beispiel #2
0
 public void ApplyChangeSet(EntityChangeSet changes)
 {
     using (s_PatchesMarker.Auto())
     {
         EntityManagerPatcherUtility.ApplyChangeSet(
             m_EntityManager,
             m_EntityQuery,
             m_PrefabQuery,
             m_LinkedEntityGroupQuery,
             changes);
     }
 }
Beispiel #3
0
 private static void ApplyEntityNames(
     EntityManager entityManager,
     EntityChangeSet changeSet,
     NativeMultiHashMap <int, Entity> packedEntities)
 {
     for (var i = 0; i < changeSet.Entities.Length; i++)
     {
         if (packedEntities.TryGetFirstValue(i, out var entity, out var it))
         {
             do
             {
                 entityManager.SetName(entity, changeSet.Names[i].ToString());
             } while (packedEntities.TryGetNextValue(out entity, ref it));
         }
     }
 }
Beispiel #4
0
        /// <summary>
        /// Creates all new entities described in the <see cref="EntityChangeSet"/>
        /// </summary>
        /// <remarks>
        /// This method only creates the entities and does not set any data.
        /// </remarks>
        private static unsafe void ApplyCreateEntities(
            EntityManager entityManager,
            EntityChangeSet changeSet,
            NativeMultiHashMap <int, Entity> packedEntities)
        {
            var types = stackalloc ComponentType[0];
            var entityGuidArchetype = entityManager.CreateArchetype(types, 0);

            using (var entities = new NativeArray <Entity>(changeSet.CreatedEntityCount, Allocator.Temp))
            {
                entityManager.CreateEntity(entityGuidArchetype, entities);
                for (var i = 0; i < changeSet.CreatedEntityCount; ++i)
                {
                    packedEntities.Add(i, entities[i]);
                }
            }
        }
        public EntityChangeSet GetChangeSet(Allocator allocator)
        {
            // IMPORTANT. This can add to the packed collections. It must be done before adding destroyed entities.
            var sharedComponentDataChanges = GetChangedSharedComponents(
                m_PackedEntities,
                m_PackedStableTypeHashes,
                m_ComponentDataStream.DeferredSharedComponentChanges,
                m_BeforeState.ManagedComponentStore,
                m_AfterState.ManagedComponentStore);

            var entities = m_PackedEntities.List;

            for (var i = 0; i < m_DestroyedEntities.Length; i++)
            {
                entities.Add(m_DestroyedEntities[i].Component);
            }

            var names = GetEntityNames(entities,
                                       m_CreatedEntities,
                                       m_ModifiedEntities,
                                       m_DestroyedEntities,
                                       m_AfterState.EntityManager,
                                       m_BeforeState.EntityManager,
                                       allocator);

            // Allocate and copy in to the results buffers.
            var result = new EntityChangeSet
                         (
                m_CreatedEntities.Length,
                m_DestroyedEntities.Length,
                m_PackedEntities.List.ToArray(allocator),
                m_PackedStableTypeHashes.List.ToArray(allocator),
                names,
                m_AddComponents.ToArray(allocator),
                m_RemoveComponents.ToArray(allocator),
                m_ComponentDataStream.ComponentDataChanges.ToArray(allocator),
                m_ComponentDataStream.Payload.ToArray(allocator),
                m_EntityReference.ToArray(allocator),
                sharedComponentDataChanges,
                m_LinkedEntityGroupAdditions.ToArray(allocator),
                m_LinkedEntityGroupRemovals.ToArray(allocator)
                         );

            return(result);
        }
Beispiel #6
0
        /// <summary>
        /// This method will generate lookups into the packed change set.
        ///
        /// 1) Maps existing entities in the world to <see cref="EntityChangeSet.Entities"/>
        /// 2) Maps types in the world to <see cref="EntityChangeSet.TypeHashes"/>
        ///
        /// These tables are used by subsequent methods to quickly access the packed data.
        /// </summary>
        private static void BuildPackedLookups(
            EntityChangeSet changeSet,
            NativeMultiHashMap <EntityGuid, Entity> entityGuidToEntity,
            NativeMultiHashMap <int, Entity> packedEntities,
            NativeArray <ComponentType> packedTypes)
        {
            var buildPackedEntityLookups = new BuildPackedEntityLookupJob
            {
                StartIndex         = changeSet.CreatedEntityCount,
                EntityGuids        = changeSet.Entities,
                EntityGuidToEntity = entityGuidToEntity,
                PackedEntities     = packedEntities.AsParallelWriter()
            }.Schedule(changeSet.Entities.Length - changeSet.CreatedEntityCount, 64);

            var buildPackedTypeLookups = new BuildPackedTypeLookupJob
            {
                TypeHashes  = changeSet.TypeHashes,
                PackedTypes = packedTypes,
            }.Schedule(changeSet.TypeHashes.Length, 64);

            JobHandle.CombineDependencies(buildPackedEntityLookups, buildPackedTypeLookups).Complete();
        }
 public EntityChanges(EntityChangeSet forwardChangeSet, EntityChangeSet reverseChangeSet)
 {
     m_ForwardChangeSet = forwardChangeSet;
     m_ReverseChangeSet = reverseChangeSet;
 }
Beispiel #8
0
        internal static void ApplyChangeSet(
            EntityManager entityManager,
            EntityQuery entityQuery,
            EntityQuery prefabQuery,
            EntityQuery linkedEntityGroupQuery,
            EntityChangeSet changeSet)
        {
            if (!changeSet.IsCreated)
            {
                return;
            }

            var entityCount = entityQuery.CalculateEntityCount();

            using (var packedEntities = new NativeMultiHashMap <int, Entity>(entityCount, Allocator.TempJob))
                using (var packedTypes = new NativeArray <ComponentType>(changeSet.TypeHashes.Length, Allocator.TempJob))
                    using (var entityGuidToEntity = new NativeMultiHashMap <EntityGuid, Entity>(entityCount, Allocator.TempJob))
                        using (var entityToEntityGuid = new NativeHashMap <Entity, EntityGuid>(entityQuery.CalculateEntityCount(), Allocator.TempJob))
                        {
                            BuildEntityLookups(
                                entityManager,
                                entityQuery,
                                entityGuidToEntity,
                                entityToEntityGuid);

                            BuildPackedLookups(
                                changeSet,
                                entityGuidToEntity,
                                packedEntities,
                                packedTypes);

                            ApplyDestroyEntities(
                                entityManager,
                                changeSet,
                                packedEntities,
                                entityGuidToEntity);

                            ApplyCreateEntities(
                                entityManager,
                                changeSet,
                                packedEntities);

#if UNITY_EDITOR
                            ApplyEntityNames(
                                entityManager,
                                changeSet,
                                packedEntities);
#endif

                            ApplyRemoveComponents(
                                entityManager,
                                changeSet.RemoveComponents,
                                changeSet.Entities,
                                packedEntities,
                                packedTypes);

                            ApplyAddComponents(
                                entityManager,
                                changeSet.AddComponents,
                                changeSet.Entities,
                                packedEntities,
                                packedTypes);

                            ApplySetSharedComponents(
                                entityManager,
                                changeSet.SetSharedComponents,
                                changeSet.Entities,
                                packedEntities,
                                packedTypes);

                            ApplySetComponents(
                                entityManager,
                                changeSet.SetComponents,
                                changeSet.Payload,
                                changeSet.Entities,
                                packedEntities,
                                packedTypes,
                                entityGuidToEntity,
                                entityToEntityGuid);

                            var linkedEntityGroupEntitiesLength = CalculateLinkedEntityGroupEntitiesLength(entityManager, linkedEntityGroupQuery);

                            using (var entityGuidToPrefab = new NativeHashMap <EntityGuid, Entity>(prefabQuery.CalculateEntityCount(), Allocator.TempJob))
                                using (var entityToLinkedEntityGroupRoot = new NativeHashMap <Entity, Entity>(linkedEntityGroupEntitiesLength, Allocator.TempJob))
                                {
                                    BuildPrefabAndLinkedEntityGroupLookups(
                                        entityManager,
                                        entityQuery,
                                        prefabQuery,
                                        linkedEntityGroupQuery,
                                        entityGuidToPrefab,
                                        entityToLinkedEntityGroupRoot);

                                    ApplyLinkedEntityGroupRemovals(
                                        entityManager,
                                        changeSet.LinkedEntityGroupRemovals,
                                        changeSet.Entities,
                                        packedEntities,
                                        entityGuidToEntity,
                                        entityToEntityGuid,
                                        entityToLinkedEntityGroupRoot);

                                    ApplyLinkedEntityGroupAdditions(
                                        entityManager,
                                        changeSet.LinkedEntityGroupAdditions,
                                        changeSet.Entities,
                                        packedEntities,
                                        entityGuidToEntity,
                                        entityToEntityGuid,
                                        entityGuidToPrefab,
                                        entityToLinkedEntityGroupRoot);

                                    ApplyEntityPatches(
                                        entityManager,
                                        changeSet.EntityPatches,
                                        changeSet.Entities,
                                        packedEntities,
                                        packedTypes,
                                        entityGuidToEntity,
                                        entityToEntityGuid,
                                        entityGuidToPrefab,
                                        entityToLinkedEntityGroupRoot);
                                }
                        }
        }