public static EntityQuery CreateLinkedEntityGroupQuery(EntityManager entityManager) { return(entityManager.CreateEntityQuery(new EntityQueryDesc { All = new ComponentType[] { typeof(EntityGuid), typeof(LinkedEntityGroup) }, Options = EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab })); }
public World(string name) { m_SequenceNumber = ms_NextSequenceNumber; ms_NextSequenceNumber++; // Debug.LogError("Create World "+ name + " - " + GetHashCode()); Name = name; allWorlds.Add(this); m_EntityManager = new EntityManager(this); m_TimeSingletonQuery = EntityManager.CreateEntityQuery(ComponentType.ReadWrite <WorldTime>(), ComponentType.ReadWrite <WorldTimeQueue>()); }
internal World(string name, WorldFlags flags) { Systems = new NoAllocReadOnlyCollection <ComponentSystemBase>(m_Systems); m_SequenceNumber = ms_NextSequenceNumber; ms_NextSequenceNumber++; // Debug.LogError("Create World "+ name + " - " + GetHashCode()); Name = name; Flags = flags; s_AllWorlds.Add(this); m_EntityManager = new EntityManager(this); m_TimeSingletonQuery = EntityManager.CreateEntityQuery(ComponentType.ReadWrite <WorldTime>(), ComponentType.ReadWrite <WorldTimeQueue>()); }
public void ReleaseUnusedBlobAssets() { using (var chunks = EntityManager.CreateEntityQuery(EntityGuidQueryDesc).CreateArchetypeChunkArray(Allocator.TempJob)) using (var blobAssets = new NativeList <BlobAssetPtr>(1, Allocator.TempJob)) using (var blobAssetsMap = new NativeHashMap <ulong, int>(1, Allocator.TempJob)) { new EntityDiffer.GatherUniqueBlobAssetReferences { TypeInfo = TypeManager.GetTypeInfoPointer(), BlobAssetRefOffsets = TypeManager.GetBlobAssetRefOffsetsPointer(), Chunks = chunks, BlobAssets = blobAssets, BlobAssetsMap = blobAssetsMap }.Schedule().Complete(); m_BlobAssetBatchPtr->RemoveUnusedBlobAssets(blobAssetsMap); } }
public void CheckInternalConsistency() { #if ENABLE_UNITY_COLLECTIONS_CHECKS //@TODO: Validate from perspective of chunkquery... var entityCountByEntity = m_Manager.EntityComponentStore->CheckInternalConsistency(); var entityCountByArchetype = EntityManagerDebugUtility.CheckInternalConsistency(m_Manager.EntityComponentStore); Assert.AreEqual(entityCountByEntity, entityCountByArchetype); Assert.IsTrue(m_Manager.ManagedComponentStore.AllSharedComponentReferencesAreFromChunks(m_Manager.EntityComponentStore)); m_Manager.ManagedComponentStore.CheckInternalConsistency(); var chunkQuery = m_Manager.CreateEntityQuery(new EntityQueryDesc { All = new ComponentType[] { typeof(ChunkHeader) } }); int totalEntitiesFromQuery = m_Manager.UniversalQuery.CalculateLength() + chunkQuery.CalculateLength(); Assert.AreEqual(entityCountByEntity, totalEntitiesFromQuery); chunkQuery.Dispose(); #endif }
public void CheckInternalConsistency() { //@TODO: Validate from perspective of chunkquery... m_Manager.EntityComponentStore->CheckInternalConsistency(); Assert.IsTrue( m_Manager.ManagedComponentStore.AllSharedComponentReferencesAreFromChunks(m_Manager .EntityComponentStore)); m_Manager.ManagedComponentStore.CheckInternalConsistency(); var chunkQuery = m_Manager.CreateEntityQuery(new EntityQueryDesc { All = new ComponentType[] { typeof(ChunkHeader) } }); int totalEntitiesFromQuery = m_Manager.UniversalQuery.CalculateEntityCount() + chunkQuery.CalculateEntityCount(); Assert.AreEqual(m_Manager.EntityComponentStore->CountEntities(), totalEntitiesFromQuery); chunkQuery.Dispose(); }
/// <summary> /// Instantiates / Copies all entities from srcEntityManager and copies them into this EntityManager. /// Entity references on components that are being cloned to entities inside the srcEntities set are remapped to the instantiated entities. /// </summary> public void CopyEntitiesFrom(EntityManager srcEntityManager, NativeArray <Entity> srcEntities, NativeArray <Entity> outputEntities = default) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (outputEntities.IsCreated && outputEntities.Length != srcEntities.Length) { throw new ArgumentException("outputEntities.Length must match srcEntities.Length"); } #endif using (var srcManagerInstances = new NativeArray <Entity>(srcEntities.Length, Allocator.Temp)) { srcEntityManager.CopyEntities(srcEntities, srcManagerInstances); srcEntityManager.AddComponent(srcManagerInstances, ComponentType.ReadWrite <IsolateCopiedEntities>()); var instantiated = srcEntityManager.CreateEntityQuery(new EntityQueryDesc { All = new ComponentType[] { typeof(IsolateCopiedEntities) }, Options = EntityQueryOptions.IncludeDisabled | EntityQueryOptions.IncludePrefab }); using (var entityRemapping = srcEntityManager.CreateEntityRemapArray(Allocator.TempJob)) { MoveEntitiesFromInternalQuery(srcEntityManager, instantiated, entityRemapping); EntityRemapUtility.GetTargets(out var output, entityRemapping); RemoveComponent(output, ComponentType.ReadWrite <IsolateCopiedEntities>()); output.Dispose(); if (outputEntities.IsCreated) { for (int i = 0; i != outputEntities.Length; i++) { outputEntities[i] = entityRemapping[srcManagerInstances[i].Index].Target; } } } } }
/// <summary> /// Generates a detailed change set between <see cref="srcEntityManager"/> and <see cref="dstEntityManager"/>. /// All entities to be considered must have the <see cref="EntityGuid"/> component with a unique value. /// The resulting <see cref="Entities.EntityChanges"/> must be disposed when no longer needed. /// </summary> /// <remarks> /// When using the <see cref="EntityManagerDifferOptions.FastForwardShadowWorld"/> the destination world must be a direct ancestor to /// the source world, and must only be updated using this call or similar methods. There should be no direct changes to destination world. /// </remarks> internal static EntityChanges GetChanges( EntityManager srcEntityManager, EntityManager dstEntityManager, EntityManagerDifferOptions options, EntityQueryDesc entityQueryDesc, BlobAssetCache blobAssetCache, Allocator allocator) { #if ENABLE_PROFILER || UNITY_EDITOR s_GetChangesProfilerMarker.Begin(); #endif CheckEntityGuidComponent(entityQueryDesc); var changes = default(EntityChanges); if (options == EntityManagerDifferOptions.None) { return(changes); } srcEntityManager.CompleteAllJobs(); dstEntityManager.CompleteAllJobs(); var srcEntityQuery = srcEntityManager.CreateEntityQuery(entityQueryDesc); var dstEntityQuery = dstEntityManager.CreateEntityQuery(entityQueryDesc); // Gather a set of a chunks to consider for diffing in both the src and dst worlds. using (var srcChunks = srcEntityQuery.CreateArchetypeChunkArray(Allocator.TempJob, out var srcChunksJob)) using (var dstChunks = dstEntityQuery.CreateArchetypeChunkArray(Allocator.TempJob, out var dstChunksJob)) { JobHandle clearMissingReferencesJob = default; if (CheckOption(options, EntityManagerDifferOptions.ClearMissingReferences)) { // Opt-in feature. // This is a special user case for references to destroyed entities. // If entity is destroyed, any references to that entity will remain set but become invalid (i.e. broken). // This option ensures that references to non-existent entities will be explicitly set to Entity.Null which // will force it to be picked up in the change set. ClearMissingReferences(srcEntityManager, srcChunks, out clearMissingReferencesJob, srcChunksJob); } // @TODO NET_DOTS does not support JobHandle.CombineDependencies with 3 arguments. #if NET_DOTS var archetypeChunkChangesJobDependencies = CombineDependencies(srcChunksJob, dstChunksJob, clearMissingReferencesJob); #else var archetypeChunkChangesJobDependencies = JobHandle.CombineDependencies(srcChunksJob, dstChunksJob, clearMissingReferencesJob); #endif // Broad phased chunk comparison. using (var archetypeChunkChanges = GetArchetypeChunkChanges( srcChunks: srcChunks, dstChunks: dstChunks, allocator: Allocator.TempJob, jobHandle: out var archetypeChunkChangesJob, dependsOn: archetypeChunkChangesJobDependencies)) { // Explicitly sync at this point to parallelize subsequent jobs by chunk. archetypeChunkChangesJob.Complete(); // Gather a sorted set of entities based on which chunks have changes. using (var srcEntities = GetSortedEntitiesInChunk( archetypeChunkChanges.CreatedSrcChunks, Allocator.TempJob, jobHandle: out var srcEntitiesJob)) using (var dstEntities = GetSortedEntitiesInChunk( archetypeChunkChanges.DestroyedDstChunks, Allocator.TempJob, jobHandle: out var dstEntitiesJob)) using (var srcBlobAssets = GetReferencedBlobAssets( srcChunks, Allocator.TempJob, jobHandle: out var srcBlobAssetsJob)) using (var dstBlobAssets = blobAssetCache.BlobAssetBatch->ToNativeList(Allocator.TempJob)) { var duplicateEntityGuids = default(NativeList <DuplicateEntityGuid>); var forwardEntityChanges = default(EntityInChunkChanges); var reverseEntityChanges = default(EntityInChunkChanges); var forwardComponentChanges = default(ComponentChanges); var reverseComponentChanges = default(ComponentChanges); var forwardBlobAssetChanges = default(BlobAssetChanges); var reverseBlobAssetChanges = default(BlobAssetChanges); try { JobHandle getDuplicateEntityGuidsJob = default; JobHandle forwardChangesJob = default; JobHandle reverseChangesJob = default; if (CheckOption(options, EntityManagerDifferOptions.ValidateUniqueEntityGuid)) { // Guid validation will happen incrementally and only consider changed entities in the source world. duplicateEntityGuids = GetDuplicateEntityGuids( srcEntities, Allocator.TempJob, jobHandle: out getDuplicateEntityGuidsJob, dependsOn: srcEntitiesJob); } if (CheckOption(options, EntityManagerDifferOptions.IncludeForwardChangeSet)) { forwardEntityChanges = GetEntityInChunkChanges( srcEntityManager, dstEntityManager, srcEntities, dstEntities, Allocator.TempJob, jobHandle: out var forwardEntityChangesJob, dependsOn: JobHandle.CombineDependencies(srcEntitiesJob, dstEntitiesJob)); forwardComponentChanges = GetComponentChanges( forwardEntityChanges,