public static void Execute(NativeArray <byte> outputData, int typeSize, NativeArray <byte> componentByteArray, NativeArray <PersistenceState> persistenceStateArray) { const int amountFound = 1; int totalElementSize = typeSize + PersistenceMetaData.SizeOfStruct; for (int i = 0; i < persistenceStateArray.Length; i++) { PersistenceState persistenceState = persistenceStateArray[i]; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (persistenceState.ArrayIndex * totalElementSize >= outputData.Length) { throw new IndexOutOfRangeException("CopyComponentDataToByteArray:: persistenceState.ArrayIndex seems to be out of range. Or the totalElementSize is wrong."); } #endif PersistenceMetaData *outputMetaDataBytePtr = (PersistenceMetaData *)((byte *)outputData.GetUnsafePtr() + (persistenceState.ArrayIndex * totalElementSize)); void *outputDataBytePtr = outputMetaDataBytePtr + 1; void *compDataBytePtr = (byte *)componentByteArray.GetUnsafeReadOnlyPtr() + (i * typeSize); // Diff int diff = outputMetaDataBytePtr->AmountFound - amountFound; diff |= UnsafeUtility.MemCmp(outputDataBytePtr, compDataBytePtr, typeSize); // Write Meta Data *outputMetaDataBytePtr = new PersistenceMetaData(diff, amountFound); // 1 branch in this constructor // Write Data UnsafeUtility.MemCpy(outputDataBytePtr, compDataBytePtr, typeSize); } }
public static void Execute(NativeArray <byte> outputData, int maxElements, UnsafeUntypedBufferAccessor untypedBufferAccessor, NativeArray <PersistenceState> persistenceStateArray) { int elementSize = untypedBufferAccessor.ElementSize; int sizePerEntity = elementSize * maxElements + PersistenceMetaData.SizeOfStruct; for (int i = 0; i < persistenceStateArray.Length; i++) { PersistenceState persistenceState = persistenceStateArray[i]; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (persistenceState.ArrayIndex >= outputData.Length / sizePerEntity) { throw new IndexOutOfRangeException("CopyBufferElementsToByteArray:: persistenceState.ArrayIndex seems to be out of range. Or the sizePerEntity is wrong."); } #endif void *bufferDataPtr = untypedBufferAccessor.GetUnsafeReadOnlyPtrAndLength(i, out int length);; PersistenceMetaData *outputMetaBytePtr = (PersistenceMetaData *)((byte *)outputData.GetUnsafePtr() + persistenceState.ArrayIndex * sizePerEntity); void *outputDataBytePtr = outputMetaBytePtr + 1; int amountToCopy = math.clamp(length, 0, maxElements); // Diff int diff = outputMetaBytePtr->AmountFound - amountToCopy; diff |= UnsafeUtility.MemCmp(outputDataBytePtr, bufferDataPtr, amountToCopy * elementSize); // Write Meta Data *outputMetaBytePtr = new PersistenceMetaData(diff, (ushort)amountToCopy); // 1 branch in this constructor // Write Data UnsafeUtility.MemCpy(outputDataBytePtr, bufferDataPtr, elementSize * amountToCopy); } }
public static void Execute(NativeArray <byte> inputData, int maxElements, UnsafeUntypedBufferAccessor untypedBufferAccessor, NativeArray <PersistenceState> persistenceStateArray) { Debug.Assert(maxElements < PersistenceMetaData.MaxValueForAmount); int elementSize = untypedBufferAccessor.ElementSize; int sizePerEntity = elementSize * maxElements + PersistenceMetaData.SizeOfStruct; for (int i = 0; i < persistenceStateArray.Length; i++) { PersistenceState persistenceState = persistenceStateArray[i]; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (persistenceState.ArrayIndex >= inputData.Length / sizePerEntity) { throw new IndexOutOfRangeException("CopyByteArrayToBufferElements:: persistenceState.ArrayIndex seems to be out of range. Or the sizePerEntity is wrong."); } #endif PersistenceMetaData *inputMetaDataPtr = (PersistenceMetaData *)((byte *)inputData.GetUnsafeReadOnlyPtr() + persistenceState.ArrayIndex * sizePerEntity); void *inputDataBytePtr = inputMetaDataPtr + 1; // + 1 because it's a PersistenceMetaData pointer // Resize int amountToCopy = inputMetaDataPtr->AmountFound; untypedBufferAccessor.ResizeUninitialized(i, amountToCopy); // Get (Possibly modified because of resize) ptr to buffer data void *bufferDataPtr = untypedBufferAccessor.GetUnsafePtrAndLength(i, out int length); Debug.Assert(length == amountToCopy); // Write Data UnsafeUtility.MemCpy(bufferDataPtr, inputDataBytePtr, elementSize * amountToCopy); } }
public unsafe void TestApplyStoredData([Values(0, 1, 2, 3, 60, 401)] int total) { // Preparation CreateEntities(total); int entityAmount3 = total / 3; int entityAmount1 = entityAmount3 + (total % 3 > 0 ? 1 : 0); int entityAmount2 = entityAmount3 + (total % 3 > 1 ? 1 : 0); var array1IntData = new NativeArray <byte>(entityAmount1 * (UnsafeUtility.SizeOf <EcsPersistingTestData>() + PersistenceMetaData.SizeOfStruct), Allocator.TempJob); var array2FloatData = new NativeArray <byte>(entityAmount2 * (UnsafeUtility.SizeOf <EcsPersistingFloatTestData2>() + PersistenceMetaData.SizeOfStruct), Allocator.TempJob); var array5IntData = new NativeArray <byte>(entityAmount3 * (UnsafeUtility.SizeOf <EcsPersistingTestData5>() + PersistenceMetaData.SizeOfStruct), Allocator.TempJob); var query1 = m_Manager.CreateEntityQuery(typeof(EcsPersistingTestData), typeof(PersistenceState)); var query2 = m_Manager.CreateEntityQuery(typeof(EcsPersistingFloatTestData2), typeof(PersistenceState)); var query3 = m_Manager.CreateEntityQuery(typeof(EcsPersistingTestData5), typeof(PersistenceState)); Entities.WithAll <PersistenceState>().ForEach(entity => { int index = m_Manager.GetComponentData <PersistenceState>(entity).ArrayIndex; if (index < 3) { m_Manager.DestroyEntity(entity); } else if (m_Manager.HasComponent <EcsPersistingTestData>(entity)) { PersistenceMetaData *metaDataPtr = (PersistenceMetaData *)((byte *)array1IntData.GetUnsafePtr() + index * (UnsafeUtility.SizeOf <EcsPersistingTestData>() + PersistenceMetaData.SizeOfStruct)); *metaDataPtr = new PersistenceMetaData(0, 1); EcsPersistingTestData *dataPtr = (EcsPersistingTestData *)(metaDataPtr + 1); *dataPtr = m_Manager.GetComponentData <EcsPersistingTestData>(entity).Modified(); } else if (m_Manager.HasComponent <EcsPersistingFloatTestData2>(entity)) { PersistenceMetaData *metaDataPtr = (PersistenceMetaData *)((byte *)array2FloatData.GetUnsafePtr() + index * (UnsafeUtility.SizeOf <EcsPersistingFloatTestData2>() + PersistenceMetaData.SizeOfStruct)); *metaDataPtr = new PersistenceMetaData(0, 1); EcsPersistingFloatTestData2 *dataPtr = (EcsPersistingFloatTestData2 *)(metaDataPtr + 1); *dataPtr = m_Manager.GetComponentData <EcsPersistingFloatTestData2>(entity).Modified(); } else if (m_Manager.HasComponent <EcsPersistingTestData5>(entity)) { PersistenceMetaData *metaDataPtr = (PersistenceMetaData *)((byte *)array5IntData.GetUnsafePtr() + index * (UnsafeUtility.SizeOf <EcsPersistingTestData5>() + PersistenceMetaData.SizeOfStruct)); *metaDataPtr = new PersistenceMetaData(0, 1); EcsPersistingTestData5 *dataPtr = (EcsPersistingTestData5 *)(metaDataPtr + 1); *dataPtr = m_Manager.GetComponentData <EcsPersistingTestData5>(entity).Modified(); } }); int amount1 = query1.CalculateEntityCount(); int amount2 = query2.CalculateEntityCount(); int amount3 = query3.CalculateEntityCount(); Entities.WithAll <PersistenceState>().ForEach((Entity entity) => { int index = m_Manager.GetComponentData <PersistenceState>(entity).ArrayIndex; if (index % 2 == 1) { if (m_Manager.HasComponent <EcsPersistingTestData>(entity)) { m_Manager.RemoveComponent <EcsPersistingTestData>(entity); } else if (m_Manager.HasComponent <EcsPersistingFloatTestData2>(entity)) { m_Manager.RemoveComponent <EcsPersistingFloatTestData2>(entity); } else if (m_Manager.HasComponent <EcsPersistingTestData5>(entity)) { m_Manager.RemoveComponent <EcsPersistingTestData5>(entity); } } }); // Action using (EntityCommandBuffer cmds = new EntityCommandBuffer(Allocator.TempJob)) { new CopyByteArrayToComponentData() { ComponentTypeHandle = m_Manager.GetDynamicComponentTypeHandle(typeof(EcsPersistingTestData)), TypeSize = UnsafeUtility.SizeOf <EcsPersistingTestData>(), PersistenceStateType = m_Manager.GetComponentTypeHandle <PersistenceState>(true), RawContainerData = array1IntData, SubArrayOffset = 0, SubArrayByteSize = array1IntData.Length, ComponentType = typeof(EcsPersistingTestData), EntityType = m_Manager.GetEntityTypeHandle(), Ecb = cmds.AsParallelWriter() }.Run(m_Manager.CreateEntityQuery(typeof(EcsTestData), typeof(PersistenceState))); cmds.Playback(m_Manager); } using (EntityCommandBuffer cmds = new EntityCommandBuffer(Allocator.TempJob)) { new CopyByteArrayToComponentData() { ComponentTypeHandle = m_Manager.GetDynamicComponentTypeHandle(typeof(EcsPersistingFloatTestData2)), TypeSize = UnsafeUtility.SizeOf <EcsPersistingFloatTestData2>(), PersistenceStateType = m_Manager.GetComponentTypeHandle <PersistenceState>(true), RawContainerData = array2FloatData, SubArrayOffset = 0, SubArrayByteSize = array2FloatData.Length, ComponentType = typeof(EcsPersistingFloatTestData2), EntityType = m_Manager.GetEntityTypeHandle(), Ecb = cmds.AsParallelWriter() }.Run(m_Manager.CreateEntityQuery(typeof(EcsTestFloatData2), typeof(PersistenceState))); cmds.Playback(m_Manager); } using (EntityCommandBuffer cmds = new EntityCommandBuffer(Allocator.TempJob)) { new CopyByteArrayToComponentData() { ComponentTypeHandle = m_Manager.GetDynamicComponentTypeHandle(typeof(EcsPersistingTestData5)), TypeSize = UnsafeUtility.SizeOf <EcsPersistingTestData5>(), PersistenceStateType = m_Manager.GetComponentTypeHandle <PersistenceState>(true), RawContainerData = array5IntData, SubArrayOffset = 0, SubArrayByteSize = array5IntData.Length, ComponentType = typeof(EcsPersistingTestData5), EntityType = m_Manager.GetEntityTypeHandle(), Ecb = cmds.AsParallelWriter() }.Run(m_Manager.CreateEntityQuery(typeof(EcsTestData5), typeof(PersistenceState))); cmds.Playback(m_Manager); } // Check Results Entities.With(query1).ForEach(entity => { var newData = m_Manager.GetComponentData <EcsPersistingTestData>(entity); var originalData = new EcsPersistingTestData() { data = m_Manager.GetComponentData <EcsTestData>(entity) }; Assert.True(newData.Equals(originalData.Modified()), "CopyByteArrayToComponentData:: Restored data on entity is incorrect."); }); Entities.With(query2).ForEach(entity => { var newData = m_Manager.GetComponentData <EcsPersistingFloatTestData2>(entity); var originalData = new EcsPersistingFloatTestData2() { data = m_Manager.GetComponentData <EcsTestFloatData2>(entity) }; Assert.True(newData.Equals(originalData.Modified()), "CopyByteArrayToComponentData:: Restored data on entity is incorrect."); }); Entities.With(query3).ForEach(entity => { var newData = m_Manager.GetComponentData <EcsPersistingTestData5>(entity); var originalData = new EcsPersistingTestData5() { data = m_Manager.GetComponentData <EcsTestData5>(entity) }; Assert.True(newData.Equals(originalData.Modified()), "CopyByteArrayToComponentData:: Restored data on entity is incorrect."); }); // Check Results Assert.AreEqual(amount1, query1.CalculateEntityCount(), "AddMissingComponents:: Not all missing components have not been restored"); Entities.With(query1).ForEach(entity => { var newData = m_Manager.GetComponentData <EcsPersistingTestData>(entity); var originalData = new EcsPersistingTestData() { data = m_Manager.GetComponentData <EcsTestData>(entity) }; Assert.True(newData.Equals(originalData.Modified()), "AddMissingComponents:: Restored data on entity is incorrect."); }); Assert.AreEqual(amount2, query2.CalculateEntityCount(), "AddMissingComponents:: Not all missing components have not been restored"); Entities.With(query2).ForEach(entity => { var newData = m_Manager.GetComponentData <EcsPersistingFloatTestData2>(entity); var originalData = new EcsPersistingFloatTestData2() { data = m_Manager.GetComponentData <EcsTestFloatData2>(entity) }; Assert.True(newData.Equals(originalData.Modified()), "AddMissingComponents:: Restored data on entity is incorrect."); }); Assert.AreEqual(amount3, query3.CalculateEntityCount(), "AddMissingComponents:: Not all missing components have not been restored"); Entities.With(query3).ForEach(entity => { var newData = m_Manager.GetComponentData <EcsPersistingTestData5>(entity); var originalData = new EcsPersistingTestData5() { data = m_Manager.GetComponentData <EcsTestData5>(entity) }; Assert.True(newData.Equals(originalData.Modified()), "AddMissingComponents:: Restored data on entity is incorrect."); }); // Cleanup array1IntData.Dispose(); array2FloatData.Dispose(); array5IntData.Dispose(); m_Manager.DestroyEntity(m_Manager.CreateEntityQuery(typeof(PersistenceState))); }
public unsafe void TestApplyStoredBufferData([Values(0, 1, 2, 3, 60, 400)] int total) { CreateEntities(total); int maxElements = total + 4; ushort persistedElementAmount = (ushort)total; int entityAmount3 = total / 3; int entityAmount1 = entityAmount3 + (total % 3 > 0 ? 1 : 0); int entityAmount2 = entityAmount3 + (total % 3 > 1 ? 1 : 0); var array1Data = new NativeArray <byte>(entityAmount1 * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData1>() + PersistenceMetaData.SizeOfStruct), Allocator.TempJob); var array2Data = new NativeArray <byte>(entityAmount2 * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData2>() + PersistenceMetaData.SizeOfStruct), Allocator.TempJob); var array3Data = new NativeArray <byte>(entityAmount3 * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData3>() + PersistenceMetaData.SizeOfStruct), Allocator.TempJob); for (int i = 0; i < entityAmount1; i++) { PersistenceMetaData *mateDataPtr = (PersistenceMetaData *)((byte *)array1Data.GetUnsafePtr() + i * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData1>() + PersistenceMetaData.SizeOfStruct)); *mateDataPtr = new PersistenceMetaData(0, persistedElementAmount); PersistentDynamicBufferData1 *dataPtr = (PersistentDynamicBufferData1 *)(mateDataPtr + 1); for (int j = 0; j < maxElements; j++) { *(dataPtr + j) = new PersistentDynamicBufferData1 { Value = i }; } } for (int i = 0; i < entityAmount2; i++) { PersistenceMetaData *mateDataPtr = (PersistenceMetaData *)((byte *)array2Data.GetUnsafePtr() + i * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData2>() + PersistenceMetaData.SizeOfStruct)); *mateDataPtr = new PersistenceMetaData(0, persistedElementAmount); PersistentDynamicBufferData2 *dataPtr = (PersistentDynamicBufferData2 *)(mateDataPtr + 1); for (int j = 0; j < maxElements; j++) { *(dataPtr + j) = new PersistentDynamicBufferData2 { Value = i }; } } for (int i = 0; i < entityAmount3; i++) { PersistenceMetaData *mateDataPtr = (PersistenceMetaData *)((byte *)array3Data.GetUnsafePtr() + i * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData3>() + PersistenceMetaData.SizeOfStruct)); *mateDataPtr = new PersistenceMetaData(0, persistedElementAmount); PersistentDynamicBufferData3 *dataPtr = (PersistentDynamicBufferData3 *)(mateDataPtr + 1); for (int j = 0; j < maxElements; j++) { *(dataPtr + j) = new PersistentDynamicBufferData3 { Value = (byte)i }; } } var query1 = m_Manager.CreateEntityQuery(typeof(PersistentDynamicBufferData1), typeof(PersistenceState)); var query2 = m_Manager.CreateEntityQuery(typeof(PersistentDynamicBufferData2), typeof(PersistenceState)); var query3 = m_Manager.CreateEntityQuery(typeof(PersistentDynamicBufferData3), typeof(PersistenceState)); // Action var job1 = new CopyByteArrayToBufferElements() { PersistenceStateType = m_Manager.GetComponentTypeHandle <PersistenceState>(true), RawContainerData = array1Data, SubArrayOffset = 0, SubArrayByteSize = array1Data.Length, BufferTypeHandle = m_Manager.GetDynamicComponentTypeHandle(typeof(PersistentDynamicBufferData1)), MaxElements = maxElements }.Schedule(query1); var job2 = new CopyByteArrayToBufferElements() { PersistenceStateType = m_Manager.GetComponentTypeHandle <PersistenceState>(true), RawContainerData = array2Data, SubArrayOffset = 0, SubArrayByteSize = array2Data.Length, BufferTypeHandle = m_Manager.GetDynamicComponentTypeHandle(typeof(PersistentDynamicBufferData2)), MaxElements = maxElements }.Schedule(query2); var job3 = new CopyByteArrayToBufferElements() { PersistenceStateType = m_Manager.GetComponentTypeHandle <PersistenceState>(true), RawContainerData = array3Data, SubArrayOffset = 0, SubArrayByteSize = array3Data.Length, BufferTypeHandle = m_Manager.GetDynamicComponentTypeHandle(typeof(PersistentDynamicBufferData3)), MaxElements = maxElements }.Schedule(query3); JobHandle.CombineDependencies(job1, job2, job3).Complete(); // Check Results Entities.With(query1).ForEach(entity => { var newData = m_Manager.GetBuffer <PersistentDynamicBufferData1>(entity); var persistenceState = m_Manager.GetComponentData <PersistenceState>(entity); var byteIndex = persistenceState.ArrayIndex * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData1>() + PersistenceMetaData.SizeOfStruct); var metaDataPtr = (PersistenceMetaData *)((byte *)array1Data.GetUnsafeReadOnlyPtr() + byteIndex); var dataPtr = (PersistentDynamicBufferData1 *)(metaDataPtr + 1); Assert.AreEqual(metaDataPtr->AmountFound, newData.Length, "CopyByteArrayToBufferElements made a buffer that was the wrong size."); for (var i = 0; i < newData.Length; i++) { Assert.AreEqual(newData[i], *(dataPtr + i), "Data on entity set by CopyBufferElementsToByteArray does not match data in InputArray."); } }); Entities.With(query2).ForEach(entity => { var newData = m_Manager.GetBuffer <PersistentDynamicBufferData2>(entity); var persistenceState = m_Manager.GetComponentData <PersistenceState>(entity); var byteIndex = persistenceState.ArrayIndex * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData2>() + PersistenceMetaData.SizeOfStruct); var metaDataPtr = (PersistenceMetaData *)((byte *)array2Data.GetUnsafeReadOnlyPtr() + byteIndex); var dataPtr = (PersistentDynamicBufferData2 *)(metaDataPtr + 1); Assert.AreEqual(metaDataPtr->AmountFound, newData.Length, "CopyByteArrayToBufferElements made a buffer that was the wrong size."); for (var i = 0; i < newData.Length; i++) { Assert.AreEqual(newData[i], *(dataPtr + i), "Data on entity set by CopyBufferElementsToByteArray does not match data in InputArray."); } }); Entities.With(query3).ForEach(entity => { var newData = m_Manager.GetBuffer <PersistentDynamicBufferData3>(entity); var persistenceState = m_Manager.GetComponentData <PersistenceState>(entity); var byteIndex = persistenceState.ArrayIndex * (maxElements * UnsafeUtility.SizeOf <PersistentDynamicBufferData3>() + PersistenceMetaData.SizeOfStruct); var metaDataPtr = (PersistenceMetaData *)((byte *)array3Data.GetUnsafeReadOnlyPtr() + byteIndex); var dataPtr = (PersistentDynamicBufferData3 *)(metaDataPtr + 1); Assert.AreEqual(metaDataPtr->AmountFound, newData.Length, "CopyByteArrayToBufferElements made a buffer that was the wrong size."); for (var i = 0; i < newData.Length; i++) { Assert.AreEqual(newData[i], *(dataPtr + i), "Data on entity set by CopyBufferElementsToByteArray does not match data in InputArray."); } }); // Cleanup array1Data.Dispose(); array2Data.Dispose(); array3Data.Dispose(); m_Manager.DestroyEntity(m_Manager.CreateEntityQuery(typeof(PersistenceState))); }