public unsafe void SerializeAndDeserialize_MultidimensionalArray()
        {
            var src = new ClassWithMultidimensionalArray
            {
                MultidimensionalArrayInt32 = new[, ]
                {
                    { 1, 2 },
                    { 3, 4 }
                }
            };

            var parameters = new BinarySerializationParameters
            {
                UserDefinedAdapters = new List <IBinaryAdapter>
                {
                    new Array2Adapter <int>()
                }
            };

            using (var stream = new UnsafeAppendBuffer(16, 4, Allocator.Temp))
            {
                BinarySerialization.ToBinary(&stream, src, parameters);
                var reader = stream.AsReader();
                var dst    = BinarySerialization.FromBinary <ClassWithMultidimensionalArray>(&reader, parameters);

                Assert.That(dst.MultidimensionalArrayInt32, Is.EqualTo(new[, ]
                {
                    { 1, 2 },
                    { 3, 4 }
                }));
            }
        }
Beispiel #2
0
        static object CloneManagedComponent(object obj)
        {
            if (obj == null)
            {
                return(null);
            }
            else
            {
#if !NET_DOTS
                var type   = obj.GetType();
                var buffer = new UnsafeAppendBuffer(16, 16, Allocator.Temp);
                var writer = new PropertiesBinaryWriter(&buffer);
                BoxedProperties.WriteBoxedType(obj, writer);

                var    readBuffer = buffer.AsReader();
                var    r2         = new PropertiesBinaryReader(&readBuffer, writer.GetObjectTable());
                object newObj     = BoxedProperties.ReadBoxedClass(type, r2);
                buffer.Dispose();
                return(newObj);
#else
                // Until DOTS Runtime supports Properties just reuse the same instance
                return(obj);
#endif
            }
        }
Beispiel #3
0
    unsafe public void ReadWriteBoxed()
    {
        var srcData = ConfigureStruct();

        // Write to stream
        var buffer = new UnsafeAppendBuffer(0, 16, Allocator.Persistent);
        var writer = new ManagedObjectBinaryWriter(&buffer);

        var boxedSrcData = (object)srcData;

        writer.WriteObject(boxedSrcData);

        var objectTable = writer.GetUnityObjects();

        // Read from stream
        var readStream = buffer.AsReader();
        var reader     = new ManagedObjectBinaryReader(&readStream, objectTable);

        var boxedRead = reader.ReadObject(typeof(TestStruct));

        // Check same
        TestStruct.AreEqual(srcData, (TestStruct)boxedRead);

        buffer.Dispose();
    }
    public unsafe void UnsafeAppendBuffer_PushHeadersWithPackets()
    {
        var buffer         = new UnsafeAppendBuffer(0, 8, Allocator.Temp);
        var scratchPayload = stackalloc byte[1024];
        var expectedSize   = 0;

        for (int i = 0; i < 1024; i++)
        {
            var packeType  = i;
            var packetSize = i;

            buffer.Add(new TestHeader
            {
                Type        = packeType,
                PayloadSize = packetSize
            });
            expectedSize += UnsafeUtility.SizeOf <TestHeader>();

            buffer.Add(scratchPayload, i);
            expectedSize += i;
        }
        Assert.True(expectedSize == buffer.Length);

        buffer.Dispose();
    }
Beispiel #5
0
            public void Init(Hasher hasher, RedrawScope frameRedrawScope, RedrawScope customRedrawScope, bool isGizmos)
            {
                if (state != State.Reserved)
                {
                    throw new System.InvalidOperationException();
                }

                meta = new Meta {
                    hasher       = hasher,
                    redrawScope1 = frameRedrawScope,
                    redrawScope2 = customRedrawScope,
                    isGizmos     = isGizmos,
                    version      = 0,                // Will be filled in later
                };

                if (meshes == null)
                {
                    meshes = new List <Mesh>();
                }
                if (!commandBuffers.IsCreated)
                {
                    commandBuffers = new NativeArray <UnsafeAppendBuffer>(JobsUtility.MaxJobThreadCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
                    for (int i = 0; i < commandBuffers.Length; i++)
                    {
                        commandBuffers[i] = new UnsafeAppendBuffer(0, 4, Allocator.Persistent);
                    }
                }

                state = State.Initialized;
            }
Beispiel #6
0
    unsafe public void ReadWriteBoxedWithStringArrayWithOneElement()
    {
        var srcData = new ComponentWithStringArray()
        {
            StringArray = new string[] { "One" }
        };

        // Write to stream
        var buffer = new UnsafeAppendBuffer(0, 16, Allocator.Persistent);
        var writer = new ManagedObjectBinaryWriter(&buffer);

        var boxedSrcData = (object)srcData;

        writer.WriteObject(boxedSrcData);

        var objectTable = writer.GetUnityObjects();

        // Read from stream
        var readStream = buffer.AsReader();
        var reader     = new ManagedObjectBinaryReader(&readStream, objectTable);

        var boxedRead = reader.ReadObject(typeof(ComponentWithStringArray));

        // Check same
        ComponentWithStringArray.AreEqual(srcData, (ComponentWithStringArray)boxedRead);

        buffer.Dispose();
    }
    public unsafe void UnsafeAppendBuffer_AddAndPop()
    {
        var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp);

        buffer.Add <int>(123);
        buffer.Add <int>(234);
        buffer.Add <int>(345);

        {
            var array = new NativeArray <int>(3, Allocator.Temp);
            buffer.Pop(array.GetUnsafePtr(), 3 * UnsafeUtility.SizeOf <int>());
            CollectionAssert.AreEqual(new[] { 123, 234, 345 }, array);
        }

        {
            var array = new NativeArray <int>(4, Allocator.Temp);
            array.CopyFrom(new[] { 987, 876, 765, 654 });
            buffer.Add(array.GetUnsafePtr(), 4 * UnsafeUtility.SizeOf <int>());
        }

        Assert.AreEqual(654, buffer.Pop <int>());
        Assert.AreEqual(765, buffer.Pop <int>());
        Assert.AreEqual(876, buffer.Pop <int>());
        Assert.AreEqual(987, buffer.Pop <int>());

        buffer.Dispose();
    }
Beispiel #8
0
        public static unsafe int ManagedGetHashCode(object lhs, TypeInfo typeInfo)
        {
            var fn = (TypeInfo.ManagedGetHashCodeDelegate)typeInfo.GetHashFn;

            if (fn != null)
            {
                return(fn(lhs));
            }

            var hash = 0;

            using (var buffer = new UnsafeAppendBuffer(16, 16, Allocator.Temp))
            {
                var writer = new ManagedObjectBinaryWriter(&buffer);
                writer.WriteObject(lhs);

                hash = Hash32(buffer.Ptr, (uint)buffer.Length);

                foreach (var obj in writer.GetUnityObjects())
                {
                    hash *= FNV_32_PRIME;
                    hash ^= obj.GetHashCode();
                }
            }

            return(hash);
        }
Beispiel #9
0
    unsafe public void ReadWriteObjectTableIndex()
    {
        var srcData = ConfigureStruct();

        // Write to stream
        var buffer = new UnsafeAppendBuffer(0, 16, Allocator.Persistent);
        var writer = new PropertiesBinaryWriter(&buffer);

        PropertyContainer.Visit(ref srcData, writer);

        var objectTable = writer.GetObjectTable();

        // Read from stream
        var readStream = writer.Buffer.AsReader();
        var reader     = new PropertiesBinaryReader(&readStream, objectTable);

        var readData = new TestStruct();

        PropertyContainer.Visit(ref readData, reader);

        // Check same
        TestStruct.AreEqual(srcData, readData);

        buffer.Dispose();
    }
Beispiel #10
0
    unsafe public void ReadWriteBoxedWithStringArrayWithOneElement()
    {
        var srcData = new ComponentWithStringArray()
        {
            StringArray = new string[] { "One" }
        };

        // Write to stream
        var buffer = new UnsafeAppendBuffer(0, 16, Allocator.Persistent);
        var writer = new PropertiesBinaryWriter(&buffer);

        var boxedSrcData = (object)srcData;

        BoxedProperties.WriteBoxedType(boxedSrcData, writer);

        var objectTable = writer.GetObjectTable();

        // Read from stream
        var readStream = writer.Buffer.AsReader();
        var reader     = new PropertiesBinaryReader(&readStream, objectTable);

        var boxedRead = BoxedProperties.ReadBoxedClass(typeof(ComponentWithStringArray), reader);

        // Check same
        ComponentWithStringArray.AreEqual(srcData, (ComponentWithStringArray)boxedRead);

        buffer.Dispose();
    }
Beispiel #11
0
    unsafe public void ReadWriteBoxed()
    {
        var srcData = ConfigureStruct();

        // Write to stream
        var buffer = new UnsafeAppendBuffer(0, 16, Allocator.Persistent);
        var writer = new PropertiesBinaryWriter(&buffer);

        var boxedSrcData = (object)srcData;

        BoxedProperties.WriteBoxedType(boxedSrcData, writer);

        var objectTable = writer.GetObjectTable();

        // Read from stream
        var readStream = writer.Buffer.AsReader();
        var reader     = new PropertiesBinaryReader(&readStream, objectTable);

        var boxedRead = BoxedProperties.ReadBoxedStruct(typeof(TestStruct), reader);

        // Check same
        TestStruct.AreEqual(srcData, (TestStruct)boxedRead);

        buffer.Dispose();
    }
 public void UnsafeAppendBuffer_ThrowZeroAlignment()
 {
     Assert.Throws <ArgumentException>(() =>
     {
         var buffer = new UnsafeAppendBuffer(0, 0, Allocator.Temp);
     });
 }
    public unsafe void UnsafeAppendBuffer_DisposeJob()
    {
        var sizeOf  = UnsafeUtility.SizeOf <int>();
        var alignOf = UnsafeUtility.AlignOf <int>();

        var container = new UnsafeAppendBuffer(5, 16, Allocator.Persistent);

        var disposeJob = container.Dispose(default);
    unsafe public void UnsafeAppendBuffer_DisposeExternal()
    {
        var data   = stackalloc int[1];
        var buffer = new UnsafeAppendBuffer(data, sizeof(int));

        buffer.Add(5);
        buffer.Dispose();
        Assert.AreEqual(5, data[0]);
    }
Beispiel #15
0
 public MeshBuffers(Allocator allocator)
 {
     splitterOutput = new UnsafeAppendBuffer(0, 4, allocator);
     vertices       = new UnsafeAppendBuffer(0, 4, allocator);
     triangles      = new UnsafeAppendBuffer(0, 4, allocator);
     solidVertices  = new UnsafeAppendBuffer(0, 4, allocator);
     solidTriangles = new UnsafeAppendBuffer(0, 4, allocator);
     bounds         = new Bounds();
 }
        public byte[] ToMsg()
        {
            var buffer = new UnsafeAppendBuffer(0, 16, Allocator.TempJob);

            Serialize(ref buffer);
            var bytes = buffer.ToBytes();

            buffer.Dispose();
            return(bytes);
        }
 public StructuralChangeQueue(UnsafeEntityManager uem, Allocator allocator)
 {
     _uem                      = uem;
     CreateChunks              = new UnsafeList(allocator);
     AddComponentToChunks      = new UnsafeList(allocator);
     RemoveComponentFromChunks = new UnsafeList(allocator);
     AddComponentBatches       = new UnsafeList(allocator);
     RemoveComponentBatches    = new UnsafeList(allocator);
     ChunkScratch              = new UnsafeAppendBuffer(4096, 4, Allocator.Persistent);
     BatchScratch              = new UnsafeAppendBuffer(4096, 4, Allocator.Persistent);
 }
Beispiel #18
0
            unsafe public static void SerializeResourcePacket(EntityChangeSet entityChangeSet, ref UnsafeAppendBuffer buffer)
            {
                var changeSetBuffer = new UnsafeAppendBuffer(1024, 16, Allocator.TempJob);

                Serialize(entityChangeSet, &changeSetBuffer, out var globalObjectIds);

                buffer.Add(globalObjectIds);
                buffer.Add(changeSetBuffer.Ptr, changeSetBuffer.Length);

                changeSetBuffer.Dispose();
                globalObjectIds.Dispose();
            }
        public byte[] Serialize()
        {
            var buffer = new UnsafeAppendBuffer(1024, 16, Allocator.Persistent);

            EntityChangeSetSerialization.ResourcePacket.SerializeResourcePacket(Changes, ref buffer);
            
            buffer.Add(SceneGUID);
            buffer.Add(SceneName);
            buffer.Add(UnloadAllPreviousEntities);

            return buffer.ToBytes();
        }
Beispiel #20
0
        unsafe static byte[] SerializeUnmanagedArray <T>(NativeArray <T> value) where T : unmanaged
        {
            var bytes = new byte[UnsafeUtility.SizeOf <T>() * value.Length + sizeof(int)];

            fixed(byte *ptr = bytes)
            {
                var buf = new UnsafeAppendBuffer(ptr, bytes.Length);

                buf.Add(value);
            }

            return(bytes);
        }
Beispiel #21
0
            public void ToBinary_StructWithInt32Property_DoesNotAllocate()
            {
                var container = new StructWithInt32Property();

                GCAllocTest.Method(() =>
                {
                    using (var stream = new UnsafeAppendBuffer(16, 8, Allocator.Temp))
                    {
                        BinarySerialization.ToBinary(&stream, container);
                    }
                })
                .ExpectedCount(0)
                .Warmup()
                .Run();
            }
Beispiel #22
0
            public ResourcePacket(byte[] buffer)
            {
                fixed(byte *ptr = buffer)
                {
                    var bufferReader = new UnsafeAppendBuffer.Reader(ptr, buffer.Length);

                    bufferReader.ReadNext(out GlobalObjectIds, Allocator.Persistent);

                    var entityChangeSetSourcePtr  = bufferReader.Ptr + bufferReader.Offset;
                    var entityChangeSetSourceSize = bufferReader.Size - bufferReader.Offset;

                    ChangeSet = new UnsafeAppendBuffer(entityChangeSetSourceSize, 16, Allocator.Persistent);
                    ChangeSet.Add(entityChangeSetSourcePtr, entityChangeSetSourceSize);
                }
            }
        internal static unsafe byte[] SerializeUnmanagedArray <T>(T[] value) where T : unmanaged
        {
            var bytes = new byte[UnsafeUtility.SizeOf <T>() * value.Length + sizeof(int)];

            fixed(byte *ptr = bytes)
            {
                var buf = new UnsafeAppendBuffer(ptr, bytes.Length);

                fixed(T *dataPtr = value)
                buf.AddArray <T>(dataPtr, value.Length);

                Assert.AreEqual(buf.Length, bytes.Length);
            }

            return(bytes);
        }
        void AppendObject(UnityEngine.Object obj, ref UnsafeAppendBuffer stream)
        {
            int index = -1;

            if (obj != null)
            {
                if (!_ObjectTableMap.TryGetValue(obj, out index))
                {
                    index = _ObjectTable.Count;
                    _ObjectTableMap.Add(obj, index);
                    _ObjectTable.Add(obj);
                }
            }

            stream.Add(index);
        }
        unsafe void SendBuildArtifact(string artifactPath, string artifactFileName, int playerId)
        {
            LiveLinkMsg.LogInfo($"SendBuildArtifact => artifactPath={artifactPath}, playerId={playerId}");

            if (!File.Exists(artifactPath))
            {
                Debug.LogError($"Attempting to send file that doesn't exist on editor. {artifactPath}");
                return;
            }

            using (FileStream fs = new FileStream(artifactPath, FileMode.Open, FileAccess.Read))
            {
                // TODO: Any OS/language supports wide chars here? Should be tested
                var bufferSize = fs.Length + artifactFileName.Length * sizeof(char) + sizeof(int);
                if (fs.Length > int.MaxValue)
                {
                    Debug.LogError($"File cannot be sent to the player because it exceeds the 2GB size limit. {artifactPath}");
                    return;
                }

                var buffer = new byte[bufferSize];
                fixed(byte *data = buffer)
                {
                    var writer = new UnsafeAppendBuffer(data, (int)bufferSize);

                    writer.Add(artifactFileName);

                    int numBytesToRead = (int)fs.Length;
                    int numBytesRead   = writer.Size;

                    while (numBytesToRead > 0)
                    {
                        int n = fs.Read(buffer, numBytesRead, numBytesToRead);

                        if (n == 0)
                        {
                            break;
                        }

                        numBytesRead   += n;
                        numBytesToRead -= n;
                    }
                }

                EditorConnection.instance.Send(LiveLinkMsg.SendBuildArtifact, buffer, playerId);
            }
        }
    public unsafe void UnsafeAppendBuffer_ReadNextArray()
    {
        var values = new NativeArray <int>(new[] { 123, 234, 345 }, Allocator.Temp);
        var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp);

        buffer.Add(values);

        var array = (int *)buffer.AsReader().ReadNextArray <int>(out var count);

        Assert.AreEqual(values.Length, count);
        for (int i = 0; i < count; ++i)
        {
            Assert.AreEqual(values[i], array[i]);
        }

        values.Dispose();
        buffer.Dispose();
    }
Beispiel #27
0
        protected override T SerializeAndDeserialize <T>(T value, CommonSerializationParameters parameters = default)
        {
            var stream = new UnsafeAppendBuffer(16, 8, Allocator.Temp);

            var binarySerializationParameters = new BinarySerializationParameters
            {
                DisableSerializedReferences = parameters.DisableSerializedReferences
            };

            try
            {
                BinarySerialization.ToBinary(&stream, value, binarySerializationParameters);
                var reader = stream.AsReader();
                return(BinarySerialization.FromBinary <T>(&reader, binarySerializationParameters));
            }
            finally
            {
                stream.Dispose();
            }
        }
Beispiel #28
0
        public MultiAppendBuffer(Allocator allocator, int initialCapacityPerThread = JobsUtility.CacheLineSize)
        {
            var bufferSize                 = UnsafeUtility.SizeOf <UnsafeAppendBuffer>();
            var bufferCount                = JobsUtility.MaxJobThreadCount + 1;
            var allocationSize             = bufferSize * bufferCount;
            var initialBufferCapacityBytes = initialCapacityPerThread;

            var ptr = (byte *)UnsafeUtility.Malloc(allocationSize, UnsafeUtility.AlignOf <int>(), allocator);

            UnsafeUtility.MemClear(ptr, allocationSize);
            UnsafeUtility.CopyStructureToPtr(ref allocator, ptr);

            var dataStartPtr = ptr + sizeof(Allocator);

            for (int i = 0; i < bufferCount; i++)
            {
                var bufferPtr = (UnsafeAppendBuffer *)(dataStartPtr + bufferSize * i);
                var buffer    = new UnsafeAppendBuffer(initialBufferCapacityBytes, UnsafeUtility.AlignOf <int>(), allocator);
                UnsafeUtility.CopyStructureToPtr(ref buffer, bufferPtr);
            }
            Ptr = (UnsafeAppendBuffer *)dataStartPtr;
        }
Beispiel #29
0
            public void FromBinary_StructWithInt32Property_DoesNotAllocate()
            {
                var container = new StructWithInt32Property();

                using (var writer = new UnsafeAppendBuffer(16, 8, Allocator.Temp))
                {
                    var writerPtr = &writer;

                    BinarySerialization.ToBinary(writerPtr, container);

                    GCAllocTest.Method(() =>
                    {
                        var reader    = writerPtr->AsReader();
                        var readerPtr = &reader;

                        BinarySerialization.FromBinary <StructWithInt32Property>(readerPtr);
                    })
                    .ExpectedCount(0)
                    .Warmup()
                    .Run();
                }
            }
Beispiel #30
0
        //@TODO: Encode type in hashcode...

#if !NET_DOTS
        public static unsafe int ManagedGetHashCode(object lhs, TypeInfo typeInfo)
        {
            var fn = (TypeInfo.ManagedGetHashCodeDelegate)typeInfo.GetHashFn;

            if (fn != null)
            {
                return(fn(lhs));
            }

            int hash = 0;

            using (var buffer = new UnsafeAppendBuffer(16, 16, Allocator.Temp))
            {
                var writer = new PropertiesBinaryWriter(&buffer);
                BoxedProperties.WriteBoxedType(lhs, writer);

                var remainder   = buffer.Length & (sizeof(int) - 1);
                var alignedSize = buffer.Length - remainder;
                var bufferPtrAtEndOfAlignedData = buffer.Ptr + alignedSize;
                for (int i = 0; i < alignedSize; i += sizeof(int))
                {
                    hash *= FNV_32_PRIME;
                    hash ^= *(int *)(buffer.Ptr + i);
                }
                for (var i = 0; i < remainder; i++)
                {
                    hash *= FNV_32_PRIME;
                    hash ^= *(byte *)(bufferPtrAtEndOfAlignedData + i);
                }
                foreach (var obj in writer.GetObjectTable())
                {
                    hash *= FNV_32_PRIME;
                    hash ^= obj.GetHashCode();
                }
            }

            return(hash);
        }