public unsafe void EntityDiffer_GetChanges_BlobAssets_SetComponent_SharedAsset()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var blobAssetReference = BlobAssetReference <int> .Create(10);

                try
                {
                    for (var i = 0; i < 100; i++)
                    {
                        var entity = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestDataBlobAssetRef));
                        SrcEntityManager.SetComponentData(entity, CreateEntityGuid());
                        SrcEntityManager.SetComponentData(entity, new EcsTestDataBlobAssetRef {
                            value = blobAssetReference
                        });
                    }

                    using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                    {
                        Assert.IsTrue(changes.HasForwardChangeSet);
                        var forward = changes.ForwardChangeSet;
                        Assert.That(forward.CreatedBlobAssets.Length, Is.EqualTo(1));
                        Assert.That(forward.BlobAssetReferenceChanges.Length, Is.EqualTo(100));
                        Assert.That(forward.BlobAssetData.Length, Is.EqualTo(sizeof(int)));
                        Assert.That(*(int *)forward.BlobAssetData.GetUnsafePtr(), Is.EqualTo(10));
                    }
                }
                finally
                {
                    blobAssetReference.Dispose();
                }
            }
        }
        public unsafe void EntityPatcher_ApplyChanges_CreateSharedComponent()
        {
            const int count = 3;

            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuids = stackalloc EntityGuid[count]
                {
                    CreateEntityGuid(),
                    CreateEntityGuid(),
                    CreateEntityGuid()
                };

                for (var i = 0; i != count; i++)
                {
                    var entity = SrcEntityManager.CreateEntity();
                    SrcEntityManager.AddComponentData(entity, entityGuids[i]);
                    SrcEntityManager.AddSharedComponentData(entity, new EcsTestSharedComp {
                        value = i * 2
                    });
                }

                PushChanges(differ, DstEntityManager);

                for (var i = 0; i != count; i++)
                {
                    var sharedData = GetSharedComponentData <EcsTestSharedComp>(DstEntityManager, entityGuids[i]);
                    Assert.AreEqual(i * 2, sharedData.value);
                }
            }
        }
        public void EntityDiffer_GetChanges_IgnoresSystemState()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid = CreateEntityGuid();
                var entity     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity, entityGuid);

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp)) {}

                SrcEntityManager.AddComponentData(entity, new EcsState1 {
                    Value = 9
                });
                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.IsFalse(changes.AnyChanges);
                }

                SrcEntityManager.SetComponentData(entity, new EcsState1 {
                    Value = 10
                });
                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.IsFalse(changes.AnyChanges);
                }

                // NOTE: the system state component being copied to shadow world is not required by the public API.
                //       This is simply defining the expected internal behaviour.
                Assert.AreEqual(10, differ.ShadowEntityManager.GetComponentData <EcsState1>(entity).Value);
            }
        }
        public void EntityDiffer_GetChanges_CreateEntityAndSetSharedComponentData_IncrementalChanges_ManagedComponents()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entity = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestSharedComp), typeof(EcsTestManagedComponent));

                SrcEntityManager.SetComponentData(entity, CreateEntityGuid());
                SrcEntityManager.SetComponentData(entity, new EcsTestManagedComponent {
                    value = "SomeString"
                });
                SrcEntityManager.SetSharedComponentData(entity, new EcsTestSharedComp {
                    value = 2
                });

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.IsTrue(changes.HasForwardChangeSet);
                    Assert.AreEqual(1, changes.ForwardChangeSet.CreatedEntityCount);
                    Assert.AreEqual(3, changes.ForwardChangeSet.AddComponents.Length);
                    Assert.AreEqual(1, changes.ForwardChangeSet.SetComponents.Length);
                    Assert.AreEqual(1, changes.ForwardChangeSet.SetSharedComponents.Length);
                    Assert.AreEqual(1, changes.ForwardChangeSet.SetManagedComponents.Length);
                }
            }
        }
        public void EntityPatcher_ApplyChanges_EntityPatchWithAmbiguousTargetDoesNotThrow()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid0 = CreateEntityGuid();
                var entity0     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity0, entityGuid0);

                var entityGuid1 = CreateEntityGuid();
                var entity1     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity1, entityGuid1);

                PushChanges(differ, DstEntityManager);

                // Create a patch
                SrcEntityManager.AddComponentData(entity1, new EcsTestDataEntity {
                    value1 = entity0
                });

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.IncludeForwardChangeSet, Allocator.TempJob))
                {
                    var forward = changes.ForwardChangeSet;

                    Assert.That(forward.EntityReferenceChanges.Length, Is.EqualTo(1));

                    // Create a new entity in the dst world with the same ID the patch target.
                    var dstEntity0 = DstEntityManager.CreateEntity();
                    DstEntityManager.AddComponentData(dstEntity0, entityGuid1);

                    Assert.DoesNotThrow(() => { EntityPatcher.ApplyChangeSet(DstEntityManager, forward); });
                }
            }
        }
        public void PerformanceTest_EntityDiffer_GetChanges_ForwardChangesOnly_SingleChange(int entityCount)
        {
            CreateEntitiesWithMockComponentData(SrcEntityManager, entityCount, typeof(EcsTestData), typeof(EcsTestData2), typeof(EcsTestSharedComp));

            var entity = default(Entity);

            using (var entities = SrcEntityManager.GetAllEntities(Allocator.Temp))
            {
                entity = entities[0];
            }

            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                // Fast forward the shadow world
                using (differ.GetChanges(EntityManagerDifferOptions.FastForwardShadowWorld, Allocator.TempJob))
                {
                }

                var startValue = 99;

                Measure.Method(() =>
                {
                    SrcEntityManager.SetComponentData(entity, new EcsTestData(startValue++));

                    // Get changes with all options selected
                    using (differ.GetChanges(EntityManagerDifferOptions.IncludeForwardChangeSet, Allocator.TempJob))
                    {
                    }
                })
                .Definition("EntityDiffer")
                .WarmupCount(1)
                .MeasurementCount(100)
                .Run();
            }
        }
        public void EntityPatcher_ApplyChanges_EntityPatchWithMissingValueDoesNotThrow()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid0 = CreateEntityGuid();
                var entity0     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity0, entityGuid0);

                var entityGuid1 = CreateEntityGuid();
                var entity1     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity1, entityGuid1);

                PushChanges(differ, DstEntityManager);

                // Create a component with an entity reference
                SrcEntityManager.AddComponentData(entity1, new EcsTestDataEntity {
                    value1 = entity0
                });

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.IncludeForwardChangeSet, Allocator.TempJob))
                {
                    var forward = changes.ForwardChangeSet;

                    Assert.That(forward.EntityReferenceChanges.Length, Is.EqualTo(1));

                    // Destroy the entity the patch references
                    SrcEntityManager.DestroyEntity(entity0);

                    Assert.DoesNotThrow(() => { EntityPatcher.ApplyChangeSet(DstEntityManager, forward); });
                }
            }
        }
        public void EntityDiffer_GetChanges_CreateEntityAndSetComponentData_IncrementalChanges()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid = CreateEntityGuid();
                var entity     = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestData));

                SrcEntityManager.SetComponentData(entity, entityGuid);
                SrcEntityManager.SetComponentData(entity, new EcsTestData {
                    value = 9
                });

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.IsTrue(changes.AnyChanges);
                }

                // Mutate some component data.
                SrcEntityManager.SetComponentData(entity, entityGuid);
                SrcEntityManager.SetComponentData(entity, new EcsTestData {
                    value = 10
                });

                // The entityGuid value is the same so it should not be picked up during change tracking.
                // We should only see the one data change.
                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    // The ForwardChangeSet will contain a set value 10
                    Assert.IsTrue(changes.HasForwardChangeSet);
                    Assert.AreEqual(0, changes.ForwardChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(0, changes.ForwardChangeSet.CreatedEntityCount);
                    Assert.AreEqual(1, changes.ForwardChangeSet.SetComponents.Length);
                    Assert.AreEqual(0, changes.ForwardChangeSet.AddComponents.Length);

                    // The ReverseChangeSet will contain a set value 9
                    Assert.IsTrue(changes.HasReverseChangeSet);
                    Assert.AreEqual(0, changes.ReverseChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(0, changes.ReverseChangeSet.CreatedEntityCount);
                    Assert.AreEqual(1, changes.ReverseChangeSet.SetComponents.Length);
                    Assert.AreEqual(0, changes.ReverseChangeSet.AddComponents.Length);
                }

                SrcEntityManager.DestroyEntity(entity);
                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.IsTrue(changes.HasForwardChangeSet);
                    Assert.AreEqual(1, changes.ForwardChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(0, changes.ForwardChangeSet.CreatedEntityCount);
                    Assert.AreEqual(0, changes.ForwardChangeSet.SetComponents.Length);
                    Assert.AreEqual(0, changes.ForwardChangeSet.RemoveComponents.Length);

                    // In this case the ReverseChangeSet should describe how to get this entity back in it's entirety
                    Assert.IsTrue(changes.HasReverseChangeSet);
                    Assert.AreEqual(0, changes.ReverseChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(1, changes.ReverseChangeSet.CreatedEntityCount);
                    Assert.AreEqual(2, changes.ReverseChangeSet.AddComponents.Length);
                    Assert.AreEqual(2, changes.ReverseChangeSet.SetComponents.Length);
                }
            }
        }
        public void EntityPatcher_ApplyChanges_ChangeSharedComponent()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid = CreateEntityGuid();
                var entity     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity, entityGuid);
                SrcEntityManager.AddComponent <EcsTestSharedComp>(entity);

                PushChanges(differ, DstEntityManager);
                var dstEntity = GetEntity(DstEntityManager, entityGuid);
                Assert.AreEqual(0, DstEntityManager.GetSharedComponentDataIndex <EcsTestSharedComp>(dstEntity));
                Assert.AreEqual(0, DstEntityManager.GetSharedComponentData <EcsTestSharedComp>(dstEntity).value);

                SrcEntityManager.SetSharedComponentData(entity, new EcsTestSharedComp {
                    value = 2
                });
                PushChanges(differ, DstEntityManager);
                Assert.AreEqual(2, DstEntityManager.GetSharedComponentData <EcsTestSharedComp>(dstEntity).value);

                SrcEntityManager.SetSharedComponentData(entity, new EcsTestSharedComp {
                    value = 3
                });
                PushChanges(differ, DstEntityManager);
                Assert.AreEqual(3, DstEntityManager.GetSharedComponentData <EcsTestSharedComp>(dstEntity).value);

                SrcEntityManager.SetSharedComponentData(entity, new EcsTestSharedComp {
                    value = 0
                });
                PushChanges(differ, DstEntityManager);
                Assert.AreEqual(0, DstEntityManager.GetSharedComponentDataIndex <EcsTestSharedComp>(dstEntity));
                Assert.AreEqual(0, DstEntityManager.GetSharedComponentData <EcsTestSharedComp>(dstEntity).value);
            }
        }
        public void EntityPatcher_ApplyChanges_AddComponent()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid = CreateEntityGuid();
                var entity     = SrcEntityManager.CreateEntity();
                SrcEntityManager.AddComponentData(entity, entityGuid);
                SrcEntityManager.AddComponentData(entity, new EcsTestData {
                    value = 9
                });

                PushChanges(differ, DstEntityManager);

                // Add a component in the source world.
                SrcEntityManager.AddComponentData(entity, new EcsTestData2(10));

                // Mutate the dst world
                SetComponentData(DstEntityManager, entityGuid, new EcsTestData(-1));

                PushChanges(differ, DstEntityManager);

                // Both changes should be present in the output
                Assert.AreEqual(10, GetComponentData <EcsTestData2>(DstEntityManager, entityGuid).value0);
                Assert.AreEqual(-1, GetComponentData <EcsTestData>(DstEntityManager, entityGuid).value);
            }
        }
        public void EntityPatcher_ApplyChanges_CreateEntityWithTestData()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entity = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestData));

                var entityGuid = CreateEntityGuid();

                SrcEntityManager.SetComponentData(entity, entityGuid);
                SrcEntityManager.SetComponentData(entity, new EcsTestData {
                    value = 9
                });

                PushChanges(differ, DstEntityManager);

                Assert.AreEqual(1, DstEntityManager.Debug.EntityCount);
                Assert.AreEqual(9, GetComponentData <EcsTestData>(DstEntityManager, entityGuid).value);

                // Mutate some component data.
                SrcEntityManager.SetComponentData(entity, entityGuid);
                SrcEntityManager.SetComponentData(entity, new EcsTestData {
                    value = 10
                });

                PushChanges(differ, DstEntityManager);

                Assert.AreEqual(1, DstEntityManager.Debug.EntityCount);
                Assert.AreEqual(10, GetComponentData <EcsTestData>(DstEntityManager, entityGuid).value);

                // Destroy the entity
                SrcEntityManager.DestroyEntity(entity);
                PushChanges(differ, DstEntityManager);
                Assert.AreEqual(0, DstEntityManager.Debug.EntityCount);
            }
        }
        public void EntityPatcher_ApplyChanges_LinkedEntityGroups()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var rootEntityGuid  = CreateEntityGuid();
                var childEntityGuid = CreateEntityGuid();

                var srcRootEntity  = SrcEntityManager.CreateEntity(typeof(EcsTestDataEntity), typeof(LinkedEntityGroup));
                var srcChildEntity = SrcEntityManager.CreateEntity(typeof(EcsTestDataEntity));

                SrcEntityManager.AddComponentData(srcRootEntity, rootEntityGuid);
                SrcEntityManager.AddComponentData(srcChildEntity, childEntityGuid);

                var srcLinkedEntityGroup = SrcEntityManager.GetBuffer <LinkedEntityGroup>(srcRootEntity);

                srcLinkedEntityGroup.Add(srcRootEntity);
                srcLinkedEntityGroup.Add(srcChildEntity);

                PushChanges(differ, DstEntityManager);

                var dstRootEntity  = GetEntity(DstEntityManager, rootEntityGuid);
                var dstChildEntity = GetEntity(DstEntityManager, childEntityGuid);

                var dstLinkedEntityGroup = DstEntityManager.GetBuffer <LinkedEntityGroup>(dstRootEntity);
                Assert.AreEqual(dstLinkedEntityGroup.Length, 2);
                Assert.AreEqual(dstLinkedEntityGroup[0].Value, dstRootEntity);
                Assert.AreEqual(dstLinkedEntityGroup[1].Value, dstChildEntity);
            }
        }
        public void EntityPatcher_ApplyChanges_RemapEntityReferences()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                // Create extra entity to make sure test doesn't accidentally succeed with no remapping
                SrcEntityManager.CreateEntity();

                var entityGuid0 = CreateEntityGuid();
                var entityGuid1 = CreateEntityGuid();

                var e0 = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestDataEntity));
                var e1 = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestDataEntity));

                SrcEntityManager.SetComponentData(e0, entityGuid0);
                SrcEntityManager.SetComponentData(e1, entityGuid1);

                SrcEntityManager.SetComponentData(e0, new EcsTestDataEntity {
                    value1 = e1
                });
                SrcEntityManager.SetComponentData(e1, new EcsTestDataEntity {
                    value1 = e0
                });

                PushChanges(differ, DstEntityManager);

                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid1), GetComponentData <EcsTestDataEntity>(DstEntityManager, entityGuid0).value1);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid0), GetComponentData <EcsTestDataEntity>(DstEntityManager, entityGuid1).value1);
            }
        }
    public void DeserializeWithDifferentDataLayoutThrows()
    {
        using (var differ = new EntityManagerDiffer(SrcWorld.EntityManager, Allocator.TempJob))
        {
            var entity = SrcEntityManager.CreateEntity();
            SrcEntityManager.AddComponentData(entity, CreateEntityGuid());
            SrcEntityManager.AddComponentData(entity, new EcsTestData(5));

            var options = EntityManagerDifferOptions.IncludeForwardChangeSet | EntityManagerDifferOptions.FastForwardShadowWorld;

            using (var changes = differ.GetChanges(options, Allocator.TempJob))
            {
                var typeHashes       = changes.ForwardChangeSet.TypeHashes;
                var modifiedTypeHash = typeHashes[0];
                modifiedTypeHash.StableTypeHash += 1;
                typeHashes[0] = modifiedTypeHash;

                var srcChange = new LiveLinkChangeSet
                {
                    Changes = changes.ForwardChangeSet
                };

                Assert.Throws <ArgumentException>(() => SerializeAndDeserialize(srcChange));
            }
        }
    }
        [StandaloneFixme] // No support for PinGCObject
        public void EntityPatcher_ApplyChanges_RemapEntityReferencesInManagedComponentCollection()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                // Create extra entity to make sure test doesn't accidentally succeed with no remapping
                SrcEntityManager.CreateEntity();

                var entityGuid0 = CreateEntityGuid();
                var entityGuid1 = CreateEntityGuid();

                var e0 = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestManagedDataEntityCollection));
                var e1 = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestManagedDataEntityCollection));

                SrcEntityManager.SetComponentData(e0, entityGuid0);
                SrcEntityManager.SetComponentData(e1, entityGuid1);

                SrcEntityManager.SetComponentData(e0, new EcsTestManagedDataEntityCollection(new string[] { e1.ToString() }, new Entity[] { e1, e1, e1 }));
                SrcEntityManager.SetComponentData(e1, new EcsTestManagedDataEntityCollection(new string[] { e0.ToString() }, new Entity[] { e0, e0, e0 }));

                PushChanges(differ, DstEntityManager);

                var c0 = GetManagedComponentData <EcsTestManagedDataEntityCollection>(DstEntityManager, entityGuid0);
                var c1 = GetManagedComponentData <EcsTestManagedDataEntityCollection>(DstEntityManager, entityGuid1);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid1), c0.value1[0]);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid1), c0.value1[1]);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid1), c0.value1[2]);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid0), c1.value1[0]);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid0), c1.value1[1]);
                Assert.AreEqual(GetEntity(DstEntityManager, entityGuid0), c1.value1[2]);
            }
        }
        public void EntityPatcher_ApplyChanges_CreateDynamicBuffer([Values(1, 100)] int bufferLength)
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entityGuid = CreateEntityGuid();
                var entity     = SrcEntityManager.CreateEntity();

                SrcEntityManager.AddComponentData(entity, entityGuid);
                var buffer = SrcEntityManager.AddBuffer <EcsIntElement>(entity);

                for (var i = 0; i < bufferLength; ++i)
                {
                    buffer.Add(new EcsIntElement {
                        Value = i
                    });
                }

                PushChanges(differ, DstEntityManager);

                var dstEntity = GetEntity(DstEntityManager, entityGuid);
                var dstBuffer = DstEntityManager.GetBuffer <EcsIntElement>(dstEntity);

                Assert.AreEqual(bufferLength, dstBuffer.Length);
                for (var i = 0; i != dstBuffer.Length; i++)
                {
                    Assert.AreEqual(i, dstBuffer[i].Value);
                }
            }
        }
Beispiel #17
0
        public void EntityManagerPatcher_ApplyChanges_NewEntityIsReplicatedIntoExistingPrefabInstances([Values(1, 10)] int instanceCount)
        {
            using (var differ = new EntityManagerDiffer(SrcWorld, Allocator.TempJob))
                using (var patcher = new EntityManagerPatcher(DstWorld, Allocator.TempJob))
                {
                    var rootEntityGuid  = CreateEntityGuid();
                    var childEntityGuid = CreateEntityGuid();

                    var srcRootEntity = SrcEntityManager.CreateEntity(typeof(EcsTestDataEntity), typeof(Prefab), typeof(LinkedEntityGroup));

                    SrcEntityManager.AddComponentData(srcRootEntity, rootEntityGuid);
                    SrcEntityManager.GetBuffer <LinkedEntityGroup>(srcRootEntity).Add(srcRootEntity);

                    PushChanges(differ, patcher);

                    var dstRootEntity = GetEntity(DstEntityManager, rootEntityGuid);

                    // Instantiate root in dst world
                    var dstRootInstances = new Entity[instanceCount];
                    for (var i = 0; i != dstRootInstances.Length; i++)
                    {
                        var dstRootInstance = DstEntityManager.Instantiate(dstRootEntity);
                        dstRootInstances[i] = dstRootInstance;
                        Assert.AreEqual(1, DstEntityManager.GetBuffer <LinkedEntityGroup>(dstRootInstance).Length);
                        Assert.AreEqual(dstRootInstance, DstEntityManager.GetBuffer <LinkedEntityGroup>(dstRootInstance)[0].Value);
                    }

                    // Add a new entity into the prefab
                    var srcChildEntity = SrcEntityManager.CreateEntity(typeof(EcsTestDataEntity), typeof(Prefab));
                    SrcEntityManager.AddComponentData(srcChildEntity, childEntityGuid);
                    SrcEntityManager.GetBuffer <LinkedEntityGroup>(srcRootEntity).Add(srcChildEntity);

                    SrcEntityManager.SetComponentData(srcRootEntity, new EcsTestDataEntity {
                        value1 = srcChildEntity
                    });
                    SrcEntityManager.SetComponentData(srcChildEntity, new EcsTestDataEntity {
                        value1 = srcRootEntity
                    });

                    PushChanges(differ, patcher);

                    for (var i = 0; i != dstRootInstances.Length; i++)
                    {
                        var dstRootInstance = dstRootInstances[i];

                        var dstInstanceGroup = DstEntityManager.GetBuffer <LinkedEntityGroup>(dstRootInstance);
                        Assert.AreEqual(2, dstInstanceGroup.Length);
                        Assert.AreEqual(dstRootInstance, dstInstanceGroup[0].Value);
                        var dstChildInstance = dstInstanceGroup[1].Value;

                        Assert.IsTrue(DstEntityManager.HasComponent <Prefab>(dstRootEntity));
                        Assert.IsFalse(DstEntityManager.HasComponent <Prefab>(dstRootInstance));
                        Assert.IsFalse(DstEntityManager.HasComponent <Prefab>(dstChildInstance));

                        Assert.AreEqual(dstRootInstance, DstEntityManager.GetComponentData <EcsTestDataEntity>(dstChildInstance).value1);
                        Assert.AreEqual(dstChildInstance, DstEntityManager.GetComponentData <EcsTestDataEntity>(dstRootInstance).value1);
                    }
                }
        }
        public unsafe void EntityDiffer_GetChanges_BlobAssets_SetComponent_SameContentHash()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var blobAssetReference0 = BlobAssetReference <int> .Create(10);

                var blobAssetReference1 = BlobAssetReference <int> .Create(10);

                var entity0 = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestDataBlobAssetRef));

                SrcEntityManager.SetComponentData(entity0, CreateEntityGuid());
                SrcEntityManager.SetComponentData(entity0, new EcsTestDataBlobAssetRef
                {
                    value = blobAssetReference0
                });

                var entity1 = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestDataBlobAssetRef));

                SrcEntityManager.SetComponentData(entity1, CreateEntityGuid());
                SrcEntityManager.SetComponentData(entity1, new EcsTestDataBlobAssetRef
                {
                    value = blobAssetReference1
                });

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.IsTrue(changes.HasForwardChangeSet);
                    var forward = changes.ForwardChangeSet;

                    // Only one blob asset is created
                    Assert.That(forward.CreatedBlobAssets.Length, Is.EqualTo(1));
                    Assert.That(forward.DestroyedBlobAssets.Length, Is.EqualTo(0));

                    Assert.That(forward.BlobAssetReferenceChanges.Length, Is.EqualTo(2));
                    Assert.That(forward.BlobAssetReferenceChanges[0].Value, Is.EqualTo(forward.CreatedBlobAssets[0].Hash));
                    Assert.That(forward.BlobAssetReferenceChanges[1].Value, Is.EqualTo(forward.CreatedBlobAssets[0].Hash));

                    Assert.That(forward.BlobAssetData.Length, Is.EqualTo(sizeof(int)));
                    Assert.That(*(int *)forward.BlobAssetData.GetUnsafePtr(), Is.EqualTo(10));
                }

                SrcEntityManager.DestroyEntity(entity1);

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.That(changes.ForwardChangeSet.DestroyedBlobAssets.Length, Is.EqualTo(0));
                }

                SrcEntityManager.DestroyEntity(entity0);

                using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                {
                    Assert.That(changes.ForwardChangeSet.DestroyedBlobAssets.Length, Is.EqualTo(1));
                }

                blobAssetReference0.Dispose();
                blobAssetReference1.Dispose();
            }
        }
    public void CanSerializeAndDeserializeManagedComponents()
    {
        using (var differ = new EntityManagerDiffer(SrcWorld.EntityManager, Allocator.TempJob))
        {
            var entityGuid = CreateEntityGuid();
            var entity     = SrcEntityManager.CreateEntity();

            var srcManagedComponent = new EcsTestManagedDataEntity
            {
                value0    = "Hello",
                value2    = 42,
                nullField = new ClassWithClassFields
                {
                    ClassWithString = new ClassWithString
                    {
                        String = "World"
                    }
                }
            };

            SrcEntityManager.AddComponentData(entity, entityGuid);
            SrcEntityManager.AddComponentData(entity, srcManagedComponent);
            SrcEntityManager.AddComponentData(entity, (EcsTestManagedComponent2)null);

            var options = EntityManagerDifferOptions.IncludeForwardChangeSet | EntityManagerDifferOptions.FastForwardShadowWorld;

            using (var changes = differ.GetChanges(options, Allocator.TempJob))
            {
                var srcChange = new LiveLinkChangeSet
                {
                    Changes   = changes.ForwardChangeSet,
                    SceneName = "Boing",
                    UnloadAllPreviousEntities = true,
                    SceneGUID = new Unity.Entities.Hash128(),
                    FramesToRetainBlobAssets = 1
                };

                var changeSet = SerializeAndDeserialize(srcChange);
                AssertChangeSetsAreEqual(srcChange, changeSet);
                EntityPatcher.ApplyChangeSet(DstEntityManager, changeSet.Changes);
                changeSet.Dispose();
            }

            var dstManagedComponent = GetManagedComponentData <EcsTestManagedDataEntity>(DstEntityManager, entityGuid);

            Assert.That(dstManagedComponent, Is.Not.Null);
            Assert.That(dstManagedComponent, Is.Not.SameAs(srcManagedComponent));
            Assert.That(dstManagedComponent.value0, Is.EqualTo(srcManagedComponent.value0));
            Assert.That(dstManagedComponent.value1, Is.EqualTo(srcManagedComponent.value1));
            Assert.That(dstManagedComponent.value2, Is.EqualTo(srcManagedComponent.value2));
            Assert.That(dstManagedComponent.nullField, Is.Not.SameAs(srcManagedComponent.nullField));
            Assert.That(dstManagedComponent.nullField.ClassWithString, Is.Not.SameAs(srcManagedComponent.nullField.ClassWithString));
            Assert.That(dstManagedComponent.nullField.ClassWithString.String, Is.EqualTo(srcManagedComponent.nullField.ClassWithString.String));

            Assert.That(GetManagedComponentData <EcsTestManagedComponent2>(DstEntityManager, entityGuid), Is.Null);
        }
    }
        public void EntityPatcher_ApplyChanges_WithChunkData_ManagedComponents()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var    guid   = CreateEntityGuid();
                var    entity = SrcEntityManager.CreateEntity();
                Entity dstRootEntity;
                // Chunk component is added but no values are copied
                // Because chunks are generally caches and thus must be rebuildable automatically.
                // They are also likely a totally different set of chunks.
                // Diff & Patch is generally working against entities not on chunk level
                {
                    SrcEntityManager.AddComponentData(entity, guid);
                    SrcEntityManager.AddComponentData(entity, new EcsTestData(1));
                    SrcEntityManager.AddChunkComponentData <EcsTestData2>(entity);
                    SrcEntityManager.SetChunkComponentData(SrcEntityManager.GetChunk(entity), new EcsTestData2(3));
                    SrcEntityManager.AddChunkComponentData <EcsTestManagedComponent>(entity);
                    SrcEntityManager.SetChunkComponentData(SrcEntityManager.GetChunk(entity), new EcsTestManagedComponent()
                    {
                        value = "SomeString"
                    });

                    PushChanges(differ, DstEntityManager);

                    dstRootEntity = GetEntity(DstEntityManager, guid);
                    Assert.AreEqual(1, DstEntityManager.GetComponentData <EcsTestData>(dstRootEntity).value);
                    Assert.IsTrue(DstEntityManager.HasChunkComponent <EcsTestData2>(dstRootEntity));
                    Assert.IsTrue(DstEntityManager.HasChunkComponent <EcsTestManagedComponent>(dstRootEntity));
                    Assert.AreEqual(0, DstEntityManager.GetChunkComponentData <EcsTestData2>(dstRootEntity).value0);
                    Assert.AreEqual(null, DstEntityManager.GetChunkComponentData <EcsTestManagedComponent>(dstRootEntity));
                    Assert.AreEqual(1, DstEntityManager.CreateEntityQuery(typeof(ChunkHeader)).CalculateEntityCount());
                }

                // Changing Chunk component creates no diff
                {
                    SrcEntityManager.SetChunkComponentData(SrcEntityManager.GetChunk(entity), new EcsTestData2(7));
                    SrcEntityManager.SetChunkComponentData(SrcEntityManager.GetChunk(entity), new EcsTestManagedComponent()
                    {
                        value = "SomeOtherString"
                    });
                    using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                    {
                        Assert.IsFalse(changes.AnyChanges);
                    }
                }

                // Removing chunk component, removes chunk component again
                {
                    SrcEntityManager.RemoveChunkComponent <EcsTestData2>(entity);
                    SrcEntityManager.RemoveChunkComponent <EcsTestManagedComponent>(entity);
                    PushChanges(differ, DstEntityManager);
                    Assert.IsFalse(DstEntityManager.HasChunkComponent <EcsTestData2>(dstRootEntity));
                    Assert.IsFalse(DstEntityManager.HasChunkComponent <EcsTestManagedComponent>(dstRootEntity));
                    Assert.AreEqual(0, DstEntityManager.CreateEntityQuery(typeof(ChunkHeader)).CalculateEntityCount());
                }
            }
        }
        public void EntityPatcher_ApplyChanges_NoChanges()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                PushChanges(differ, DstEntityManager);

                Assert.AreEqual(0, DstEntityManager.Debug.EntityCount);
            }
        }
 public LiveLinkScene(World destinationWorld, LiveLinkMode mode)
 {
     DestinationWorld        = destinationWorld;
     ConvertedWorld          = new World("Clean Entity Conversion World");
     LiveLinkDiffer          = new EntityManagerDiffer(ConvertedWorld, Allocator.Persistent);
     LiveLinkPatcher         = new EntityManagerPatcher(destinationWorld, Allocator.Persistent);
     _RequestCleanConversion = true;
     _LiveLinkMode           = mode;
 }
        public unsafe void EntityDiffer_GetChanges_BlobAssets_SetComponent_TypeMemoryOrdering()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var blobAssetReferences = new NativeArray <BlobAssetReference <int> >(100, Allocator.Temp);

                for (var i = 0; i < blobAssetReferences.Length; i++)
                {
                    // Construct the archetype in an order which will NOT match the memory order.
                    var archetype = SrcEntityManager.CreateArchetype(
                        typeof(EntityGuid),
                        typeof(EcsTestDataBlobAssetRef),
                        typeof(EcsTestData4));

                    // Validate the assumption that the archetype is created in this way.
                    Assert.That(archetype.Archetype->TypeMemoryOrder[0], Is.EqualTo(0));
                    Assert.That(archetype.Archetype->TypeMemoryOrder[1], Is.EqualTo(2));
                    Assert.That(archetype.Archetype->TypeMemoryOrder[2], Is.EqualTo(1));

                    // Validate the component sizes are different
                    Assert.That(UnsafeUtility.SizeOf <EcsTestDataBlobAssetRef>(), Is.Not.EqualTo(UnsafeUtility.SizeOf <EcsTestData4>()));

                    var entity = SrcEntityManager.CreateEntity(archetype);

                    blobAssetReferences[i] = BlobAssetReference <int> .Create(i);

                    SrcEntityManager.SetComponentData(entity, CreateEntityGuid());
                    SrcEntityManager.SetComponentData(entity, new EcsTestData4());
                    SrcEntityManager.SetComponentData(entity, new EcsTestDataBlobAssetRef
                    {
                        value = blobAssetReferences[i]
                    });
                }

                try
                {
                    using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                    {
                        Assert.IsTrue(changes.HasForwardChangeSet);
                        var forward = changes.ForwardChangeSet;
                        Assert.That(forward.CreatedBlobAssets.Length, Is.EqualTo(100));
                        Assert.That(forward.BlobAssetReferenceChanges.Length, Is.EqualTo(100));
                        Assert.That(forward.BlobAssetData.Length, Is.EqualTo(sizeof(int) * 100));
                    }
                }
                finally
                {
                    for (var i = 0; i < blobAssetReferences.Length; i++)
                    {
                        blobAssetReferences[i].Dispose();
                    }

                    blobAssetReferences.Dispose();
                }
            }
        }
 public void EntityDiffer_GetChanges_NoChanges()
 {
     using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
     {
         using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
         {
             Assert.IsFalse(changes.AnyChanges);
         }
     }
 }
        public void EntityDiffer_GetChanges_BlobAssets_SetBuffer_MultipleEntities()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var blobAssetReferences = new NativeArray <BlobAssetReference <int> >(100, Allocator.Temp);

                for (var i = 0; i < blobAssetReferences.Length; i++)
                {
                    blobAssetReferences[i] = BlobAssetReference <int> .Create(i);
                }

                for (var i = 0; i < blobAssetReferences.Length; i += 4)
                {
                    var entity = SrcEntityManager.CreateEntity(typeof(EntityGuid));

                    SrcEntityManager.SetComponentData(entity, CreateEntityGuid());

                    var buffer = SrcEntityManager.AddBuffer <EcsTestDataBlobAssetElement>(entity);

                    buffer.Add(new EcsTestDataBlobAssetElement {
                        blobElement = blobAssetReferences[i + 0]
                    });
                    buffer.Add(new EcsTestDataBlobAssetElement {
                        blobElement = blobAssetReferences[i + 1]
                    });
                    buffer.Add(new EcsTestDataBlobAssetElement {
                        blobElement = blobAssetReferences[i + 2]
                    });
                    buffer.Add(new EcsTestDataBlobAssetElement {
                        blobElement = blobAssetReferences[i + 3]
                    });
                }

                try
                {
                    using (var changes = differ.GetChanges(EntityManagerDifferOptions.Default, Allocator.Temp))
                    {
                        Assert.IsTrue(changes.HasForwardChangeSet);
                        var forward = changes.ForwardChangeSet;
                        Assert.That(forward.CreatedBlobAssets.Length, Is.EqualTo(100));
                        Assert.That(forward.BlobAssetReferenceChanges.Length, Is.EqualTo(100));
                        Assert.That(forward.BlobAssetData.Length, Is.EqualTo(sizeof(int) * 100));
                    }
                }
                finally
                {
                    for (var i = 0; i < blobAssetReferences.Length; i++)
                    {
                        blobAssetReferences[i].Dispose();
                    }

                    blobAssetReferences.Dispose();
                }
            }
        }
        public void EntityDiffer_GetChanges_CreateEntityAndSetComponentData_WithoutFastForward_ManagedComponents()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var entity = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(EcsTestData), typeof(EcsTestManagedComponent));

                SrcEntityManager.SetComponentData(entity, CreateEntityGuid());
                SrcEntityManager.SetComponentData(entity, new EcsTestData {
                    value = 9
                });
                SrcEntityManager.SetComponentData(entity, new EcsTestManagedComponent {
                    value = "SomeString"
                });

                const EntityManagerDifferOptions options = EntityManagerDifferOptions.IncludeForwardChangeSet |
                                                           EntityManagerDifferOptions.IncludeReverseChangeSet;

                using (var changes = differ.GetChanges(options, Allocator.Temp))
                {
                    // ForwardChanges defines all operations needed to go from the shadow state to the current state.
                    Assert.IsTrue(changes.HasForwardChangeSet);
                    Assert.AreEqual(0, changes.ForwardChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(1, changes.ForwardChangeSet.CreatedEntityCount);
                    Assert.AreEqual(3, changes.ForwardChangeSet.AddComponents.Length);
                    Assert.AreEqual(2, changes.ForwardChangeSet.SetComponents.Length);
                    Assert.AreEqual(1, changes.ForwardChangeSet.SetManagedComponents.Length);

                    // ReverseChanges defines all operations needed to go from the current state back to the last shadow state. (i.e. Undo)
                    Assert.IsTrue(changes.HasReverseChangeSet);
                    Assert.AreEqual(1, changes.ReverseChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(0, changes.ReverseChangeSet.CreatedEntityCount);
                    Assert.AreEqual(0, changes.ReverseChangeSet.AddComponents.Length);
                    Assert.AreEqual(0, changes.ReverseChangeSet.SetComponents.Length);
                    Assert.AreEqual(0, changes.ReverseChangeSet.SetManagedComponents.Length);
                }

                // Since we did not fast forward the inner shadow world. We should be able to generate the exact same changes again.
                using (var changes = differ.GetChanges(options, Allocator.Temp))
                {
                    Assert.IsTrue(changes.HasForwardChangeSet);
                    Assert.AreEqual(0, changes.ForwardChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(1, changes.ForwardChangeSet.CreatedEntityCount);
                    Assert.AreEqual(3, changes.ForwardChangeSet.AddComponents.Length);
                    Assert.AreEqual(2, changes.ForwardChangeSet.SetComponents.Length);
                    Assert.AreEqual(1, changes.ForwardChangeSet.SetManagedComponents.Length);

                    Assert.IsTrue(changes.HasReverseChangeSet);
                    Assert.AreEqual(1, changes.ReverseChangeSet.DestroyedEntityCount);
                    Assert.AreEqual(0, changes.ReverseChangeSet.CreatedEntityCount);
                    Assert.AreEqual(0, changes.ReverseChangeSet.AddComponents.Length);
                    Assert.AreEqual(0, changes.ReverseChangeSet.SetComponents.Length);
                    Assert.AreEqual(0, changes.ReverseChangeSet.SetManagedComponents.Length);
                }
            }
        }
 public void EntityPatcher_ApplyChanges_CreateEntityWithDisabledComponent()
 {
     using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
     {
         var entityGuid = CreateEntityGuid();
         var entity     = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(Disabled));
         SrcEntityManager.SetComponentData(entity, entityGuid);
         PushChanges(differ, DstEntityManager);
         Assert.IsTrue(HasComponent <Disabled>(DstEntityManager, entityGuid));
     }
 }
Beispiel #28
0
 public void EntityManagerPatcher_ApplyChanges_CreateEntityWithPrefabComponent()
 {
     using (var differ = new EntityManagerDiffer(SrcWorld, Allocator.TempJob))
         using (var patcher = new EntityManagerPatcher(DstWorld, Allocator.TempJob))
         {
             var entityGuid = CreateEntityGuid();
             var entity     = SrcEntityManager.CreateEntity(typeof(EntityGuid), typeof(Prefab));
             SrcEntityManager.SetComponentData(entity, entityGuid);
             PushChanges(differ, patcher);
             Assert.IsTrue(HasComponent <Prefab>(DstEntityManager, entityGuid));
         }
 }
Beispiel #29
0
        /// <summary>
        /// Pushes forward changes from the tracker to the applier.
        /// </summary>
        protected static void PushChanges(EntityManagerDiffer differ, EntityManagerPatcher patcher, bool fastForward = true)
        {
            var options = EntityManagerDifferOptions.IncludeForwardChangeSet;

            if (fastForward)
            {
                options |= EntityManagerDifferOptions.FastForwardShadowWorld;
            }

            using (var changes = differ.GetChanges(options, Allocator.TempJob))
            {
                patcher.ApplyChangeSet(changes.ForwardChangeSet);
            }
        }
Beispiel #30
0
        public void EntityPatcher_ApplyChanges_LinkedEntityGroups_CombineTwoGroups()
        {
            using (var differ = new EntityManagerDiffer(SrcEntityManager, Allocator.TempJob))
            {
                var rootEntityGuid  = CreateEntityGuid();
                var childEntityGuid = CreateEntityGuid();

                var srcChildEntity = SrcEntityManager.CreateEntity(typeof(EcsTestDataEntity), typeof(LinkedEntityGroup));
                var srcRootEntity  = SrcEntityManager.CreateEntity(typeof(EcsTestDataEntity), typeof(LinkedEntityGroup));

                SrcEntityManager.AddComponentData(srcRootEntity, rootEntityGuid);
                SrcEntityManager.AddComponentData(srcChildEntity, childEntityGuid);

                SrcEntityManager.GetBuffer <LinkedEntityGroup>(srcRootEntity).Add(srcRootEntity);
                SrcEntityManager.GetBuffer <LinkedEntityGroup>(srcChildEntity).Add(srcChildEntity);

                // verify that we have two different groups in the output
                PushChanges(differ, DstEntityManager);

                var dstRootEntity  = GetEntity(DstEntityManager, rootEntityGuid);
                var dstChildEntity = GetEntity(DstEntityManager, childEntityGuid);

                {
                    var dstLinkedEntityGroup = DstEntityManager.GetBuffer <LinkedEntityGroup>(dstRootEntity);
                    Assert.AreEqual(dstLinkedEntityGroup.Length, 1);
                    Assert.AreEqual(dstLinkedEntityGroup[0].Value, dstRootEntity);
                }

                {
                    var dstLinkedEntityGroup = DstEntityManager.GetBuffer <LinkedEntityGroup>(dstChildEntity);
                    Assert.AreEqual(dstLinkedEntityGroup.Length, 1);
                    Assert.AreEqual(dstLinkedEntityGroup[0].Value, dstChildEntity);
                }

                // now combine the two groups and verify that they are the same
                SrcEntityManager.RemoveComponent <LinkedEntityGroup>(srcChildEntity);
                SrcEntityManager.GetBuffer <LinkedEntityGroup>(srcRootEntity).Add(srcChildEntity);

                PushChanges(differ, DstEntityManager);

                {
                    var dstLinkedEntityGroup = DstEntityManager.GetBuffer <LinkedEntityGroup>(dstRootEntity);
                    Assert.AreEqual(dstLinkedEntityGroup.Length, 2);
                    Assert.AreEqual(dstLinkedEntityGroup[0].Value, dstRootEntity);
                    Assert.AreEqual(dstLinkedEntityGroup[1].Value, dstChildEntity);
                }
            }
        }