示例#1
0
 public void SyncDiff()
 {
     using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
     {
         WorldDiffer.ApplyDiff(m_DstWorld, diff);
     }
 }
示例#2
0
        public void StressTestRecreation()
        {
            // Add shared component to scramble src shared indices
            var ent = m_Manager.CreateEntity();

            m_Manager.AddSharedComponentData(ent, new EcsTestSharedComp(3));


            int end = 100;

            CreateStressData(0, end, false, true, true);
            SyncDiff();

            for (int i = 0; i < 10; i++)
            {
                m_Manager.DestroyEntity(m_Manager.GetAllEntities());
                CreateStressData(0, end, false, true, true);

                using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
                {
                    Assert.IsFalse(diff.HasChanges);
                    WorldDiffer.ApplyDiff(m_DstWorld, diff);
                }

                TestStressData(0, end, false, true, true);
            }

            Assert.AreEqual(end, m_DstManager.GetAllEntities().Length);
        }
示例#3
0
 public void Apply(World world)
 {
     foreach (var diff in m_WorldDiffs)
     {
         WorldDiffer.ApplyDiff(world, diff);
     }
 }
        public void WorldChangeTracker_DestroyEntityAndRestore()
        {
            var entity = m_EntityManager.CreateEntity(typeof(EntityGuid));

            UpdateWithoutChanges();

            m_EntityManager.DestroyEntity(entity);

            Assert.IsTrue(m_ChangeTracker.TryGetChanges(out var changes));

            try
            {
                Assert.IsTrue(changes.EntitiesWereDeleted);
                Assert.AreEqual(1, changes.WorldDiff.DeletedEntityCount);
                Assert.AreEqual(1, changes.InverseDiff.NewEntityCount);

                WorldDiffer.ApplyDiff(m_World, changes.InverseDiff);

                using (var entities = m_EntityManager.GetAllEntities(Allocator.Temp))
                {
                    Assert.AreEqual(1, entities.Length);
                }
            }
            finally
            {
                changes.Dispose();
            }
        }
示例#5
0
 public static void ConvertSceneAndApplyDiff(Scene scene, World previousStateShadowWorld, World dstEntityWorld)
 {
     using (var cleanConvertedEntityWorld = new World("Clean Entity Conversion World"))
     {
         ConvertScene(scene, default(Unity.Entities.Hash128), cleanConvertedEntityWorld, ConversionFlags.AddEntityGUID);
         WorldDiffer.DiffAndApply(cleanConvertedEntityWorld, previousStateShadowWorld, dstEntityWorld);
     }
 }
 public static void ConvertSceneAndApplyDiff(Scene scene, World previousStateShadowWorld, World dstEntityWorld)
 {
     using (var cleanConvertedEntityWorld = new World("Clean Entity Conversion World"))
     {
         GameObjectConversionUtility.ConvertScene(scene, cleanConvertedEntityWorld, true);
         WorldDiffer.DiffAndApply(cleanConvertedEntityWorld, previousStateShadowWorld, dstEntityWorld);
     }
 }
示例#7
0
    public static void ConvertSceneAndApplyDiff(Scene scene, World previousStateShadowWorld, World dstEntityWorld)
    {
        using (var cleanConvertedEntityWorld = new World("Clean Entity Conversion World"))
        {
            ConvertInternal(scene, cleanConvertedEntityWorld, true);

            using (var diff = WorldDiffer.UpdateDiff(cleanConvertedEntityWorld, previousStateShadowWorld, Allocator.TempJob))
            {
                WorldDiffer.ApplyDiff(dstEntityWorld, diff);
            }
        }
    }
示例#8
0
        public void ComputeDiffOnly()
        {
            EntityGuid[] guids = new EntityGuid[4];
            Entity[]     ents  = new Entity[4];

            // create 4 entities
            for (int i = 0; i < 4; ++i)
            {
                guids[i] = GenerateEntityGuid(i + 1);
                ents[i]  = m_Manager.CreateEntity(typeof(EntityGuid), typeof(EcsTestData));
                m_Manager.SetComponentData(ents[i], guids[i]);
                m_Manager.SetComponentData(ents[i], new EcsTestData {
                    value = i
                });
            }

            WorldDiff diff = default;

            // Calculate initial diff
            diff = WorldDiffer.CreateDiff(m_After, m_Shadow, Allocator.TempJob);
            Assert.AreEqual(diff.NewEntityCount, 4);
            diff.Dispose();

            // These shouldn't exist in the shadow world
            foreach (var guid in guids)
            {
                Assert.AreEqual(Entity.Null, GetEntityByGuid(m_Shadow.EntityManager, guid));
            }

            // Calculate same diff again; results should be the same as above
            diff = WorldDiffer.CreateDiff(m_After, m_Shadow, Allocator.TempJob);
            Assert.AreEqual(diff.NewEntityCount, 4);

            // These still shouldn't exist in the shadow world
            foreach (var guid in guids)
            {
                Assert.AreEqual(Entity.Null, GetEntityByGuid(m_Shadow.EntityManager, guid));
            }

            // Now apply the diff to the dst world
            WorldDiffer.ApplyDiff(m_DstWorld, diff);
            diff.Dispose();

            // and now they should exist in the dst world
            for (int i = 0; i < 4; ++i)
            {
                Assert.AreEqual(ents[i], GetEntityByGuid(m_DstManager, guids[i]));
            }
        }
示例#9
0
        public void DiffOnly()
        {
            using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
            {
                Assert.IsFalse(diff.HasChanges);
            }

            var guid = GenerateEntityGuid(0);

            var e = m_Manager.CreateEntity(typeof(EntityGuid), typeof(EcsTestData));

            m_Manager.SetComponentData(e, guid);
            m_Manager.SetComponentData(e, new EcsTestData {
                value = 9
            });

            using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
            {
                Assert.AreEqual(0, diff.DeletedEntityCount);
                Assert.AreEqual(1, diff.NewEntityCount);
                Assert.AreEqual(2, diff.AddComponents.Length);
                Assert.AreEqual(2, diff.SetCommands.Length);
            }

            m_Manager.SetComponentData(e, guid);
            m_Manager.SetComponentData(e, new EcsTestData {
                value = 10
            });

            using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
            {
                Assert.AreEqual(0, diff.DeletedEntityCount);
                Assert.AreEqual(0, diff.NewEntityCount);
                Assert.AreEqual(1, diff.SetCommands.Length);
                Assert.AreEqual(0, diff.AddComponents.Length);
            }

            m_Manager.DestroyEntity(e);

            using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
            {
                Assert.AreEqual(1, diff.DeletedEntityCount);
                Assert.AreEqual(0, diff.NewEntityCount);
                Assert.AreEqual(0, diff.SetCommands.Length);
                Assert.AreEqual(0, diff.RemoveComponents.Length);
            }
        }
示例#10
0
        public void SharedComponentDiff()
        {
            var e    = m_Manager.CreateEntity();
            var guid = GenerateEntityGuid(0);

            m_Manager.AddComponentData(e, guid);
            m_Manager.AddSharedComponentData(e, new EcsTestSharedComp {
                value = 2
            });

            using (var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob))
            {
                Assert.AreEqual(1, diff.NewEntityCount);
                Assert.AreEqual(2, diff.AddComponents.Length);
                Assert.AreEqual(1, diff.SetCommands.Length);
                Assert.AreEqual(1, diff.SharedSetCommands.Length);
            }
        }
示例#11
0
        public void EntityPatchWithAmbiguousTargetDoesNotThrow()
        {
            var guid            = GenerateEntityGuid(0);
            var srcWorldEntity0 = m_Manager.CreateEntity();

            m_Manager.AddComponentData(srcWorldEntity0, guid);

            var dstWorldEntity0 = m_DstManager.CreateEntity();

            m_DstManager.AddComponentData(dstWorldEntity0, guid);

            Assert.DoesNotThrow(() =>
            {
                var diff = WorldDiffer.UpdateDiff(m_After, m_Shadow, Allocator.TempJob);
                Append(ref diff.EntityPatches, new DiffEntityPatch {
                    Guid = guid
                });
                using (diff)
                    WorldDiffer.ApplyDiff(m_DstWorld, diff);
            });
        }
示例#12
0
        public void WorldDiffsShowNoChangesWithPatchedReferences()
        {
            EntityGuid[] guids = new EntityGuid[2];
            Entity[]     ents  = new Entity[2];

            for (int i = 0; i < 2; ++i)
            {
                guids[i] = GenerateEntityGuid(i + 1);
                ents[i]  = m_Manager.CreateEntity(typeof(EntityGuid), typeof(EcsTestDataEntity));
            }

            for (int i = 0; i < 2; ++i)
            {
                m_Manager.SetComponentData(ents[i], guids[i]);
                m_Manager.SetComponentData(ents[i], new EcsTestDataEntity {
                    value0 = i, value1 = ents[i]
                });
            }

            // create and destroy a dummy entity in dst world, bumping up the version number
            var e = m_DstWorld.EntityManager.CreateEntity(typeof(EcsTestData));

            m_DstWorld.EntityManager.DestroyEntity(e);

            // create and apply a diff of two entities being created with inner references
            var diff = WorldDiffer.CreateDiff(m_After, m_Shadow, Allocator.TempJob);

            using (diff)
            {
                WorldDiffer.ApplyDiff(m_DstWorld, diff);
            }

            // The diff between m_DstWorld and m_After should be empty, even though internally
            // they refer to different Entity index/version values (but the guids are the same).
            diff = WorldDiffer.CreateDiff(m_DstWorld, m_After, Allocator.TempJob);
            using (diff)
            {
                Assert.IsFalse(diff.HasChanges);
            }
        }
        void ApplyLiveLink(SubScene scene)
        {
            //Debug.Log("ApplyLiveLink: " + scene.SceneName);

            var streamingSystem = World.GetExistingManager <SubSceneStreamingSystem>();

            var isFirstTime = scene.LiveLinkShadowWorld == null;

            if (scene.LiveLinkShadowWorld == null)
            {
                scene.LiveLinkShadowWorld = new World("LiveLink");
            }


            using (var cleanConvertedEntityWorld = new World("Clean Entity Conversion World"))
            {
                // Unload scene
                //@TODO: We optimally shouldn't be unloading the scene here. We should simply prime the shadow world with the scene that we originally loaded into the player (Including Entity GUIDs)
                //       This way we can continue the live link, compared to exactly what we loaded into the player.
                if (isFirstTime)
                {
                    foreach (var s in scene._SceneEntities)
                    {
                        streamingSystem.UnloadSceneImmediate(s);
                        EntityManager.DestroyEntity(s);
                    }

                    var sceneEntity = EntityManager.CreateEntity();
                    EntityManager.SetName(sceneEntity, "Scene (LiveLink): " + scene.SceneName);
                    EntityManager.AddComponentObject(sceneEntity, scene);
                    EntityManager.AddComponentData(sceneEntity, new SubSceneStreamingSystem.StreamingState {
                        Status = SubSceneStreamingSystem.StreamingStatus.Loaded
                    });
                    EntityManager.AddComponentData(sceneEntity, new SubSceneStreamingSystem.IgnoreTag( ));

                    scene._SceneEntities = new List <Entity>();
                    scene._SceneEntities.Add(sceneEntity);
                }

                // Convert scene
                GameObjectConversionUtility.ConvertScene(scene.LoadedScene, scene.SceneGUID, cleanConvertedEntityWorld, GameObjectConversionUtility.ConversionFlags.AddEntityGUID | GameObjectConversionUtility.ConversionFlags.AssignName);

                var convertedEntityManager = cleanConvertedEntityWorld.GetOrCreateManager <EntityManager>();

                var liveLinkSceneEntity = scene._SceneEntities[0];

                /// We want to let the live linked scene be able to reference the already existing Scene Entity (Specifically SceneTag should point to the scene Entity after live link completes)
                // Add Scene tag to all entities using the convertedSceneEntity that will map to the already existing scene entity.
                convertedEntityManager.AddSharedComponentData(convertedEntityManager.UniversalGroup, new SceneTag {
                    SceneEntity = liveLinkSceneEntity
                });

                WorldDiffer.DiffAndApply(cleanConvertedEntityWorld, scene.LiveLinkShadowWorld, World);

                convertedEntityManager.Debug.CheckInternalConsistency();
                scene.LiveLinkShadowWorld.GetOrCreateManager <EntityManager>().Debug.CheckInternalConsistency();

                var group = EntityManager.CreateComponentGroup(typeof(SceneTag), ComponentType.Exclude <EditorRenderData>());
                group.SetFilter(new SceneTag {
                    SceneEntity = liveLinkSceneEntity
                });

                EntityManager.AddSharedComponentData(group, new EditorRenderData()
                {
                    SceneCullingMask = m_LiveLinkEditGameViewMask, PickableObject = scene.gameObject
                });

                group.Dispose();

                scene.LiveLinkDirtyID = GetSceneDirtyID(scene.LoadedScene);
                EditorUpdateUtility.EditModeQueuePlayerLoopUpdate();
            }
        }