Example #1
0
        static void DestroyChunks(EntityManager entityManager, NativeList <ArchetypeChunk> chunks)
        {
            s_DestroyChunksProfilerMarker.Begin();
            new DestroyChunksJob
            {
                EntityManager = entityManager,
                Chunks        = chunks
            }.Run();
            s_PlaybackManagedChangesMarker.Begin();
            var access = entityManager.GetCheckedEntityDataAccess();
            var ecs    = access->EntityComponentStore;
            var mcs    = access->ManagedComponentStore;

            mcs.Playback(ref ecs->ManagedChangesTracker);
            s_PlaybackManagedChangesMarker.End();
            s_DestroyChunksProfilerMarker.End();
        }
Example #2
0
        /// <summary>
        /// Generates a detailed change set for the world.
        /// All entities to be considered for diffing must have the <see cref="EntityGuid"/> component with a unique value.
        /// The resulting <see cref="EntityChanges"/> must be disposed when no longer needed.
        /// </summary>
        /// <param name="options">A set of options which can be toggled.</param>
        /// <param name="allocator">The allocator to use for the results object.</param>
        /// <returns>A Change set containing the differences between the two worlds.</returns>
        public EntityChanges GetChanges(EntityManagerDifferOptions options, Allocator allocator)
        {
            s_GetChangesMarker.Begin();

            var changes = EntityManagerDifferUtility.GetChanges(
                m_SrcWorld.EntityManager,
                m_SrcWorldEntityQuery,
                m_ShadowWorld.EntityManager,
                m_ShadowWorldEntityQuery,
                m_TypeInfoStream,
                options,
                allocator);

            s_GetChangesMarker.End();

            return(changes);
        }
Example #3
0
        static void CloneAndAddChunks(EntityManager srcEntityManager, EntityManager dstEntityManager, NativeList <ArchetypeChunk> chunks)
        {
            s_CloneAndAddChunksProfilerMarker.Begin();

            // sort chunks by archetype and clone chunks
            var srcSharedComponentIndices = new NativeList <int>(128, Allocator.TempJob);

            new CollectSharedComponentIndices
            {
                Chunks = chunks,
                SharedComponentIndices = srcSharedComponentIndices,
            }.Run();

            // copy shared components
            s_CopySharedComponentsMarker.Begin();
            var srcAccess = srcEntityManager.GetCheckedEntityDataAccess();
            var dstAccess = dstEntityManager.GetCheckedEntityDataAccess();
            var srcManagedComponentStore = srcAccess->ManagedComponentStore;
            var dstManagedComponentStore = dstAccess->ManagedComponentStore;

            var dstSharedComponentIndicesRemapped = new NativeArray <int>(srcSharedComponentIndices, Allocator.TempJob);

            dstManagedComponentStore.CopySharedComponents(srcManagedComponentStore, (int *)dstSharedComponentIndicesRemapped.GetUnsafeReadOnlyPtr(), dstSharedComponentIndicesRemapped.Length);
            s_CopySharedComponentsMarker.End();

            // clone chunks
            var cloned = new NativeArray <ArchetypeChunk>(chunks.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            new CreateNewChunks
            {
                Chunks                    = chunks,
                ClonedChunks              = cloned,
                DstEntityManager          = dstEntityManager,
                SrcSharedComponentIndices = srcSharedComponentIndices,
                DstSharedComponentIndices = dstSharedComponentIndicesRemapped,
            }.Run();

            var copyJob = new CopyChunkBuffers
            {
                Chunks       = chunks,
                ClonedChunks = cloned
            }.Schedule(chunks.Length, default);

            JobHandle.ScheduleBatchedJobs();
            srcSharedComponentIndices.Dispose();

            s_PlaybackManagedChangesMarker.Begin();
            dstManagedComponentStore.Playback(ref dstAccess->EntityComponentStore->ManagedChangesTracker);

            // Release any references obtained by CopySharedComponents above
            for (var i = 0; i < dstSharedComponentIndicesRemapped.Length; i++)
            {
                dstAccess->RemoveSharedComponentReference(dstSharedComponentIndicesRemapped[i]);
            }
            s_PlaybackManagedChangesMarker.End();

            dstSharedComponentIndicesRemapped.Dispose();
            copyJob.Complete();

            s_CopyManagedComponentsMarker.Begin();
            for (int i = 0; i < cloned.Length; i++)
            {
                var dstChunk             = cloned[i].m_Chunk;
                var dstArchetype         = dstChunk->Archetype;
                var numManagedComponents = dstArchetype->NumManagedComponents;
                var hasHybridComponents  = dstArchetype->HasHybridComponents;
                for (int t = 0; t < numManagedComponents; ++t)
                {
                    int indexInArchetype = t + dstChunk->Archetype->FirstManagedComponent;
                    var offset           = dstChunk->Archetype->Offsets[indexInArchetype];
                    var a     = (int *)(dstChunk->Buffer + offset);
                    int count = dstChunk->Count;

                    if (hasHybridComponents)
                    {
                        // We consider hybrid components as always different, there's no reason to clone those at this point.
                        var typeCategory = TypeManager.GetTypeInfo(dstChunk->Archetype->Types[indexInArchetype].TypeIndex).Category;
                        if (typeCategory == TypeManager.TypeCategory.UnityEngineObject)
                        {
                            // We still need to patch their indices, because otherwise they might point to invalid memory in
                            // the managed component store. Setting them to the invalid index 0 is harmless, assuming nobody
                            // actually operates on the shadow world.
                            UnsafeUtility.MemSet(a, 0, sizeof(int) * count);
                            continue;
                        }
                    }

                    dstManagedComponentStore.CloneManagedComponentsFromDifferentWorld(a, count,
                                                                                      srcManagedComponentStore, ref *dstAccess->EntityComponentStore);
                }
            }
            s_CopyManagedComponentsMarker.End();

            // Ensure capacity in the dst world before we start linking entities.
            dstAccess->EntityComponentStore->EnsureCapacity(srcEntityManager.EntityCapacity);
            dstAccess->EntityComponentStore->CopyNextFreeEntityIndex(srcAccess->EntityComponentStore);

            new PatchAndAddClonedChunks
            {
                SrcChunks = chunks,
                DstChunks = cloned,
                DstEntityComponentStore = dstAccess->EntityComponentStore
            }.Schedule(chunks.Length, 64).Complete();

            cloned.Dispose();
            s_CloneAndAddChunksProfilerMarker.End();
        }