public unsafe JobHandle GetEntityQueryMatchDiffAsync(EntityQuery query, NativeList <Entity> newEntities, NativeList <Entity> missingEntities)
        {
            using (k_GetEntityQueryMatchDiffAsync.Auto())
            {
                newEntities.Clear();
                missingEntities.Clear();

                var queryMask = m_World.EntityManager.GetEntityQueryMask(query);

                var chunks = query.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var chunksJobHandle);
                k_GetEntityQueryMatchDiffAsyncAllocateBuffers.Begin();
                m_GatheredChanges.Clear();
                m_GatheredChanges.Resize(chunks.Length, NativeArrayOptions.ClearMemory);
                m_AllocatedShadowChunksForTheFrame.Clear();
                m_AllocatedShadowChunksForTheFrame.ResizeUninitialized(chunks.Length);
                m_RemovedChunkEntities.Clear();
                k_GetEntityQueryMatchDiffAsyncAllocateBuffers.End();

                k_GetEntityQueryMatchDiffAsyncScheduling.Begin();
                var gatherEntityChangesJob = new GatherEntityChangesJob
                {
                    QueryMask = queryMask,
                    Chunks    = chunks,
                    ShadowChunksBySequenceNumber = m_ShadowChunks,
                    GatheredChanges = (ChangesCollector *)m_GatheredChanges.GetUnsafeList()->Ptr
                }.Schedule(chunks.Length, 1, chunksJobHandle);

                var allocateNewShadowChunksJobHandle = new AllocateNewShadowChunksJob
                {
                    QueryMask = queryMask,
                    Chunks    = chunks,
                    ShadowChunksBySequenceNumber = m_ShadowChunks,
                    AllocatedShadowChunks        = (ShadowChunk *)m_AllocatedShadowChunksForTheFrame.GetUnsafeList()->Ptr
                }.Schedule(chunks.Length, 1, chunksJobHandle);

                var copyJobHandle = new CopyEntityDataJob
                {
                    QueryMask = queryMask,
                    Chunks    = chunks, // deallocate on job completion
                    ShadowChunksBySequenceNumber = m_ShadowChunks,
                    AllocatedShadowChunks        = m_AllocatedShadowChunksForTheFrame,
                    RemovedChunkEntities         = m_RemovedChunkEntities
                }.Schedule(JobHandle.CombineDependencies(gatherEntityChangesJob, allocateNewShadowChunksJobHandle));

                var concatResults = new ConcatResultsJob
                {
                    GatheredChanges      = m_GatheredChanges, // deallocate on job completion
                    RemovedChunkEntities = m_RemovedChunkEntities,
                    AddedEntities        = newEntities,
                    RemovedEntities      = missingEntities
                }.Schedule(copyJobHandle);
                k_GetEntityQueryMatchDiffAsyncScheduling.End();

                return(concatResults);
            }
        }
Пример #2
0
        public unsafe JobHandle GetEntityQueryMatchDiffAsync(EntityQuery query, NativeList <Entity> newEntities, NativeList <Entity> missingEntities)
        {
            newEntities.Clear();
            missingEntities.Clear();

            var queryMask = m_World.EntityManager.GetEntityQueryMask(query);

            var chunks          = query.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var chunksJobHandle);
            var gatheredChanges = new NativeArray <ChangesCollector>(chunks.Length, Allocator.TempJob);
            var allocatedShadowChunksForTheFrame = new NativeArray <ShadowChunk>(chunks.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var removedChunkEntities             = new NativeList <Entity>(Allocator.TempJob);

            var gatherEntityChangesJob = new GatherEntityChangesJob
            {
                QueryMask = queryMask,
                Chunks    = chunks,
                ShadowChunksBySequenceNumber = m_ShadowChunks,
                GatheredChanges = (ChangesCollector *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(gatheredChanges)
            }.Schedule(chunks.Length, 1, chunksJobHandle);

            var allocateNewShadowChunksJobHandle = new AllocateNewShadowChunksJob
            {
                QueryMask = queryMask,
                Chunks    = chunks,
                ShadowChunksBySequenceNumber = m_ShadowChunks,
                AllocatedShadowChunks        = (ShadowChunk *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(allocatedShadowChunksForTheFrame)
            }.Schedule(chunks.Length, 1, chunksJobHandle);

            var copyJobHandle = new CopyEntityDataJob
            {
                QueryMask = queryMask,
                Chunks    = chunks,                                              // deallocate on job completion
                ShadowChunksBySequenceNumber = m_ShadowChunks,
                AllocatedShadowChunks        = allocatedShadowChunksForTheFrame, // deallocate on job completion
                RemovedChunkEntities         = removedChunkEntities
            }.Schedule(JobHandle.CombineDependencies(gatherEntityChangesJob, allocateNewShadowChunksJobHandle));

            var concatResults = new ConcatResultsJob
            {
                GatheredChanges      = gatheredChanges, // deallocate on job completion
                RemovedChunkEntities = removedChunkEntities.AsDeferredJobArray(),
                AddedEntities        = newEntities,
                RemovedEntities      = missingEntities
            }.Schedule(copyJobHandle);

            return(removedChunkEntities.Dispose(concatResults));
        }
        public unsafe ComponentChanges GatherComponentChanges(EntityManager entityManager, EntityQuery query, Allocator allocator)
        {
            using (k_GatherComponentChanges.Auto())
            {
                var chunks = query.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var chunksJobHandle);
                k_GatherComponentChangesBufferAlloc.Begin();
                m_AllocatedShadowChunksForTheFrame.Clear();
                m_AllocatedShadowChunksForTheFrame.ResizeUninitialized(chunks.Length);
                m_GatheredChanges.Clear();
                m_GatheredChanges.Resize(chunks.Length, NativeArrayOptions.ClearMemory);
                m_RemovedShadowChunks.Clear();
                k_GatherComponentChangesBufferAlloc.End();
                k_GatherComponentChangesResultBufferAlloc.Begin();
                var sharedComponentDataBuffer = new NativeList <GCHandle>(allocator);
                var addedEntities             = new NativeList <Entity>(allocator);
                var addedEntitiesMapping      = new NativeList <int>(allocator);
                var removedEntities           = new NativeList <Entity>(allocator);
                var removedEntitiesMapping    = new NativeList <int>(allocator);

                var indexOfFirstAdded = 0;
                var indicesInManagedComponentStore = new NativeList <int>(Allocator.TempJob);
                k_GatherComponentChangesResultBufferAlloc.End();

                k_GatherComponentChangesJobWorkScheduling.Begin();
                var changesJobHandle = new GatherChangesJob
                {
                    TypeIndex = m_TypeIndex,
                    Chunks    = chunks,
                    ShadowChunksBySequenceNumber = m_ShadowChunks,
                    GatheredChanges = (ChangesCollector *)m_GatheredChanges.GetUnsafeList()->Ptr
                }.Schedule(chunks.Length, 1, chunksJobHandle);

                var allocateNewShadowChunksJobHandle = new AllocateNewShadowChunksJob
                {
                    TypeIndex = m_TypeIndex,
                    Chunks    = chunks,
                    ShadowChunksBySequenceNumber = m_ShadowChunks,
                    AllocatedShadowChunks        = (ShadowChunk *)m_AllocatedShadowChunksForTheFrame.GetUnsafeList()->Ptr
                }.Schedule(chunks.Length, 1, chunksJobHandle);

                var copyJobHandle = new CopyStateToShadowChunksJob
                {
                    TypeIndex = m_TypeIndex,
                    Chunks    = chunks,
                    ShadowChunksBySequenceNumber = m_ShadowChunks,
                    AllocatedShadowChunks        = (ShadowChunk *)m_AllocatedShadowChunksForTheFrame.GetUnsafeList()->Ptr,
                    RemovedChunks = m_RemovedShadowChunks
                }.Schedule(JobHandle.CombineDependencies(changesJobHandle, allocateNewShadowChunksJobHandle));

                var prepareResultJob = new PrepareResultsJob
                {
                    GatheredChanges                = m_GatheredChanges,
                    RemovedShadowChunks            = m_RemovedShadowChunks.AsDeferredJobArray(),
                    IndexOfFirstAdded              = &indexOfFirstAdded,
                    ShadowChunksBySequenceNumber   = m_ShadowChunks,
                    IndicesInManagedComponentStore = indicesInManagedComponentStore,
                    AddedEntities = addedEntities,
                    AddedEntitiesMappingToComponent = addedEntitiesMapping,
                    RemovedEntities = removedEntities,
                    RemovedEntitiesMappingToComponent = removedEntitiesMapping,
                }.Schedule(copyJobHandle);

                var concatResultsJob = new ConcatResultsJob
                {
                    TypeIndex                         = m_TypeIndex,
                    GatheredChanges                   = m_GatheredChanges,
                    RemovedShadowChunks               = m_RemovedShadowChunks.AsDeferredJobArray(),
                    ShadowChunksBySequenceNumber      = m_ShadowChunks,
                    SharedComponentValueIndexByChunk  = m_ManagedComponentIndexInCopyByChunk,
                    IndicesInManagedComponentStore    = indicesInManagedComponentStore.AsDeferredJobArray(),
                    AddedEntities                     = addedEntities.AsDeferredJobArray(),
                    AddedEntitiesMappingToComponent   = addedEntitiesMapping.AsDeferredJobArray(),
                    RemovedEntities                   = removedEntities.AsDeferredJobArray(),
                    RemovedEntitiesMappingToComponent = removedEntitiesMapping.AsDeferredJobArray()
                }.Schedule(prepareResultJob);
                k_GatherComponentChangesJobWorkScheduling.End();

                k_GatherComponentChangesJobWorkCompleting.Begin();
                concatResultsJob.Complete();
                k_GatherComponentChangesJobWorkCompleting.End();

                k_GatherComponentChangesResultProcessing.Begin();
                sharedComponentDataBuffer.Capacity = indicesInManagedComponentStore.Length;
                for (var i = 0; i < indexOfFirstAdded; i++)
                {
                    sharedComponentDataBuffer.AddNoResize(GCHandle.Alloc(m_ManagedComponentStoreStateCopy[indicesInManagedComponentStore[i]]));
                }

                var count = entityManager.GetCheckedEntityDataAccess()->ManagedComponentStore.GetSharedComponentCount();
                m_ManagedComponentStoreStateCopy.Capacity = count;
                m_ManagedComponentStoreStateCopy.Clear();

                // Add the default component value in position 0
                // and query GetSharedComponentData *NonDefault* Boxed to avoid calling Activator.CreateInstance for the default value.
                // A downside is the default shared component value is reused between runs and can be mutated by user code.
                // Can be prevented by adding a check like TypeManager.Equals(m_DefaultComponentDataValue, default(T)) but that would be more expensive.
                m_ManagedComponentStoreStateCopy.Add(m_DefaultComponentDataValue);
                for (var i = 1; i < count; i++)
                {
                    var sharedComponentDataNonDefaultBoxed = entityManager.GetCheckedEntityDataAccess()->ManagedComponentStore.GetSharedComponentDataNonDefaultBoxed(i);
                    m_ManagedComponentStoreStateCopy.Add(sharedComponentDataNonDefaultBoxed);
                }

                for (var i = indexOfFirstAdded; i < indicesInManagedComponentStore.Length; i++)
                {
                    sharedComponentDataBuffer.AddNoResize(GCHandle.Alloc(m_ManagedComponentStoreStateCopy[indicesInManagedComponentStore[i]]));
                }
                k_GatherComponentChangesResultProcessing.End();

                k_GatherComponentChangesResultBufferDispose.Begin();
                for (var i = 0; i < m_GatheredChanges.Length; i++)
                {
                    var c = m_GatheredChanges[i];
                    c.Dispose();
                }

                chunks.Dispose();
                indicesInManagedComponentStore.Dispose();
                k_GatherComponentChangesResultBufferDispose.End();

                return(new ComponentChanges(m_TypeIndex, sharedComponentDataBuffer, addedEntities, addedEntitiesMapping, removedEntities, removedEntitiesMapping));
            }
        }
        public unsafe ComponentChanges GatherComponentChangesAsync(EntityQuery query, Allocator allocator, out JobHandle jobHandle)
        {
            using (k_GatherComponentChangesAsync.Auto())
            {
                var chunks = query.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var chunksJobHandle);

                k_GatherComponentChangesAsyncBufferAlloc.Begin();
                m_AllocatedShadowChunksForTheFrame.Clear();
                m_AllocatedShadowChunksForTheFrame.ResizeUninitialized(chunks.Length);
                m_GatheredChanges.Clear();
                m_GatheredChanges.Resize(chunks.Length, NativeArrayOptions.ClearMemory);
                m_RemovedChunkBuffer.Clear();
                m_RemovedChunkEntities.Clear();
                var result = new NativeReference <Result>(allocator);
                k_GatherComponentChangesAsyncBufferAlloc.End();

                k_GatherComponentChangesAsyncScheduling.Begin();
                var changesJobHandle = new GatherComponentChangesJob
                {
                    TypeIndex     = m_TypeIndex,
                    ComponentSize = m_ComponentSize,
                    Chunks        = chunks,
                    ShadowChunksBySequenceNumber = m_PreviousChunksBySequenceNumber,
                    GatheredChanges = (ChangesCollector *)m_GatheredChanges.GetUnsafeList()->Ptr
                }.Schedule(chunks.Length, 1, chunksJobHandle);

                var allocateNewShadowChunksJobHandle = new AllocateNewShadowChunksJob
                {
                    TypeIndex     = m_TypeIndex,
                    ComponentSize = m_ComponentSize,
                    Chunks        = chunks,
                    ShadowChunksBySequenceNumber = m_PreviousChunksBySequenceNumber,
                    AllocatedShadowChunks        = (ShadowChunk *)m_AllocatedShadowChunksForTheFrame.GetUnsafeList()->Ptr
                }.Schedule(chunks.Length, 1, chunksJobHandle);

                var copyJobHandle = new CopyComponentDataJob
                {
                    TypeIndex     = m_TypeIndex,
                    ComponentSize = m_ComponentSize,
                    Chunks        = chunks,
                    ShadowChunksBySequenceNumber    = m_PreviousChunksBySequenceNumber,
                    AllocatedShadowChunks           = (ShadowChunk *)m_AllocatedShadowChunksForTheFrame.GetUnsafeList()->Ptr,
                    RemovedChunkComponentDataBuffer = m_RemovedChunkBuffer,
                    RemovedChunkEntities            = m_RemovedChunkEntities
                }.Schedule(JobHandle.CombineDependencies(changesJobHandle, allocateNewShadowChunksJobHandle));

                var concatResultJobHandle = new ConcatResultJob
                {
                    ComponentSize   = m_ComponentSize,
                    Allocator       = allocator,
                    GatheredChanges = m_GatheredChanges.AsDeferredJobArray(),
                    RemovedChunkComponentDataBuffer = m_RemovedChunkBuffer.AsDeferredJobArray(),
                    RemovedChunkEntities            = m_RemovedChunkEntities.AsDeferredJobArray(),

                    Result = result
                }.Schedule(copyJobHandle);

                jobHandle = JobHandle.CombineDependencies(chunks.Dispose(copyJobHandle), concatResultJobHandle);
                k_GatherComponentChangesAsyncScheduling.End();

                return(new ComponentChanges(m_TypeIndex, result));
            }
        }
Пример #5
0
        public unsafe ComponentChanges GatherComponentChangesAsync(EntityQuery query, Allocator allocator, out JobHandle jobHandle)
        {
            var chunks = query.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var chunksJobHandle);
            var allocatedShadowChunksForTheFrame = new NativeArray <ShadowChunk>(chunks.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var gatheredChanges      = new NativeArray <ChangesCollector>(chunks.Length, Allocator.TempJob);
            var removedChunkBuffer   = new NativeList <byte>(Allocator.TempJob);
            var removedChunkEntities = new NativeList <Entity>(Allocator.TempJob);

            var buffer            = new NativeList <byte>(allocator);
            var addedComponents   = new NativeList <Entity>(allocator);
            var removedComponents = new NativeList <Entity>(allocator);

            var changesJobHandle = new GatherComponentChangesJob
            {
                TypeIndex     = m_TypeIndex,
                ComponentSize = m_ComponentSize,
                Chunks        = chunks,
                ShadowChunksBySequenceNumber = m_PreviousChunksBySequenceNumber,
                GatheredChanges = (ChangesCollector *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(gatheredChanges)
            }.Schedule(chunks.Length, 1, chunksJobHandle);

            var allocateNewShadowChunksJobHandle = new AllocateNewShadowChunksJob
            {
                TypeIndex     = m_TypeIndex,
                ComponentSize = m_ComponentSize,
                Chunks        = chunks,
                ShadowChunksBySequenceNumber = m_PreviousChunksBySequenceNumber,
                AllocatedShadowChunks        = (ShadowChunk *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(allocatedShadowChunksForTheFrame)
            }.Schedule(chunks.Length, 1, chunksJobHandle);

            var copyJobHandle = new CopyComponentDataJob
            {
                TypeIndex     = m_TypeIndex,
                ComponentSize = m_ComponentSize,
                Chunks        = chunks,
                ShadowChunksBySequenceNumber    = m_PreviousChunksBySequenceNumber,
                AllocatedShadowChunks           = (ShadowChunk *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(allocatedShadowChunksForTheFrame),
                RemovedChunkComponentDataBuffer = removedChunkBuffer,
                RemovedChunkEntities            = removedChunkEntities
            }.Schedule(JobHandle.CombineDependencies(changesJobHandle, allocateNewShadowChunksJobHandle));

            var concatResultJobHandle = new ConcatResultJob
            {
                ComponentSize   = m_ComponentSize,
                GatheredChanges = gatheredChanges,
                RemovedChunkComponentDataBuffer = removedChunkBuffer.AsDeferredJobArray(),
                RemovedChunkEntities            = removedChunkEntities.AsDeferredJobArray(),

                ComponentDataBuffer = buffer,
                AddedComponents     = addedComponents,
                RemovedComponents   = removedComponents
            }.Schedule(copyJobHandle);

            var handles = new NativeArray <JobHandle>(5, Allocator.Temp)
            {
                [0] = chunks.Dispose(copyJobHandle),
                [1] = gatheredChanges.Dispose(concatResultJobHandle),
                [2] = removedChunkBuffer.Dispose(concatResultJobHandle),
                [3] = removedChunkEntities.Dispose(concatResultJobHandle),
                [4] = allocatedShadowChunksForTheFrame.Dispose(copyJobHandle)
            };

            jobHandle = JobHandle.CombineDependencies(handles);
            handles.Dispose();

            return(new ComponentChanges(m_TypeIndex, buffer, addedComponents, removedComponents));
        }