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); } } }
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)); } }
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)); } }
/// <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); } }
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); } } }