Exemple #1
0
        public bool TrySerialize <TValue>(UnsafeAppendBuffer *stream, ref TValue value)
        {
            if (null != UserDefinedAdapters && UserDefinedAdapters.Count > 0)
            {
                foreach (var adapter in UserDefinedAdapters)
                {
                    if (TrySerialize(adapter, stream, value))
                    {
                        return(true);
                    }
                }
            }

            if (null != GlobalAdapters && GlobalAdapters.Count > 0)
            {
                foreach (var adapter in GlobalAdapters)
                {
                    if (TrySerialize(adapter, stream, value))
                    {
                        return(true);
                    }
                }
            }

            return(TrySerialize(InternalAdapter, stream, value));
        }
        internal static unsafe void WritePrimitiveBoxed(UnsafeAppendBuffer *stream, object value, Type type)
        {
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.SByte:
                stream->Add((sbyte)value);
                return;

            case TypeCode.Int16:
                stream->Add((short)value);
                return;

            case TypeCode.Int32:
                stream->Add((int)value);
                return;

            case TypeCode.Int64:
                stream->Add((long)value);
                return;

            case TypeCode.Byte:
                stream->Add((byte)value);
                return;

            case TypeCode.UInt16:
                stream->Add((ushort)value);
                return;

            case TypeCode.UInt32:
                stream->Add((uint)value);
                return;

            case TypeCode.UInt64:
                stream->Add((ulong)value);
                return;

            case TypeCode.Single:
                stream->Add((float)value);
                return;

            case TypeCode.Double:
                stream->Add((double)value);
                return;

            case TypeCode.Boolean:
                stream->Add((bool)value ? (byte)1 : (byte)0);
                return;

            case TypeCode.Char:
                stream->Add((char)value);
                return;

            case TypeCode.String:
                stream->Add(value as string);
                return;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #3
0
        void Contravariant.IBinaryAdapter <UnityObject> .Serialize(UnsafeAppendBuffer *writer, UnityObject value)
        {
#if UNITY_EDITOR
            var id = UnityEditor.GlobalObjectId.GetGlobalObjectIdSlow(value).ToString();
            writer->Add(id);
#endif
        }
        internal static unsafe void WritePrimitiveUnsafe <TValue>(UnsafeAppendBuffer *stream, ref TValue value, Type type)
        {
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.SByte:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, sbyte>(ref value));
                return;

            case TypeCode.Int16:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, short>(ref value));
                return;

            case TypeCode.Int32:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, int>(ref value));
                return;

            case TypeCode.Int64:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, long>(ref value));
                return;

            case TypeCode.Byte:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, byte>(ref value));
                return;

            case TypeCode.UInt16:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, ushort>(ref value));
                return;

            case TypeCode.UInt32:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, uint>(ref value));
                return;

            case TypeCode.UInt64:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, ulong>(ref value));
                return;

            case TypeCode.Single:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, float>(ref value));
                return;

            case TypeCode.Double:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, double>(ref value));
                return;

            case TypeCode.Boolean:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, bool>(ref value) ? (byte)1 : (byte)0);
                return;

            case TypeCode.Char:
                stream->Add(System.Runtime.CompilerServices.Unsafe.As <TValue, char>(ref value));
                return;

            case TypeCode.String:
                stream->Add(value as string);
                return;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
 /// <summary>
 /// Initializes a new instance of <see cref="ManagedObjectBinaryWriter"/> which can be used to write managed objects to the given stream.
 /// </summary>
 /// <param name="stream">The stream to write to.</param>
 public ManagedObjectBinaryWriter(UnsafeAppendBuffer *stream)
 {
     m_Stream = stream;
     m_Params = new BinarySerializationParameters
     {
         UserDefinedAdapters = new List <IBinaryAdapter> {
             this
         },
         Context = new BinarySerializationContext(),
     };
 }
 void IBinaryAdapter <FileInfo> .Serialize(UnsafeAppendBuffer *writer, FileInfo value)
 {
     if (null == value)
     {
         writer->Add("null");
     }
     else
     {
         writer->Add(value.GetRelativePath());
     }
 }
Exemple #7
0
 /// <summary>
 /// Initializes a new instance of <see cref="ManagedObjectBinaryWriter"/> which can be used to write managed objects to the given stream.
 /// </summary>
 /// <param name="stream">The stream to write to.</param>
 public ManagedObjectBinaryWriter(UnsafeAppendBuffer *stream)
 {
     m_Stream = stream;
     m_UnityEngineObjectAdapter = new UnityEngineObjectBinaryAdapter(null);
     m_Params = new BinarySerializationParameters
     {
         UserDefinedAdapters = new List <IBinaryAdapter> {
             m_UnityEngineObjectAdapter
         },
         Context = new BinarySerializationContext()
     };
 }
Exemple #8
0
        static void WriteManagedComponentDataChanges(UnsafeAppendBuffer *buffer, ManagedObjectBinaryWriter writer, PackedManagedComponentDataChange[] changes)
        {
            buffer->Add(changes.Length);

            for (var i = 0; i < changes.Length; i++)
            {
                buffer->Add(changes[i].Component);
            }

            for (var i = 0; i < changes.Length; i++)
            {
                writer.WriteObject(changes[i].BoxedValue);
            }
        }
Exemple #9
0
        /// <summary>
        /// Invoked during serialization any time we encounter a <see cref="UnityEngine.Object"/> type or any derived type.
        ///
        /// We add the object to the internal table and write the index to the stream.
        /// </summary>
        /// <remarks>
        /// Objects can be retrieved by calling <see cref="GetSerializeObjectTable"/> after writing all data.
        /// </remarks>
        /// <param name="writer">The stream to write to.</param>
        /// <param name="value">The value to write.</param>
        public void Serialize(UnsafeAppendBuffer *writer, UnityEngine.Object value)
        {
            var index = -1;

            if (value != null)
            {
                if (!m_SerializeObjectTableMap.TryGetValue(value, out index))
                {
                    index = m_SerializeObjectTable.Count;
                    m_SerializeObjectTableMap.Add(value, index);
                    m_SerializeObjectTable.Add(value);
                }
            }

            writer->Add(index);
        }
Exemple #10
0
        static bool TrySerialize <TValue>(IBinaryAdapter adapter, UnsafeAppendBuffer *buffer, TValue value)
        {
            if (adapter is IBinaryAdapter <TValue> typed)
            {
                typed.Serialize(buffer, value);
                return(true);
            }

            if (adapter is Contravariant.IBinaryAdapter <TValue> typedContravariant)
            {
                typedContravariant.Serialize(buffer, value);
                return(true);
            }

            return(false);
        }
Exemple #11
0
        /// <summary>
        /// Serializes the given object to the given stream as binary.
        /// </summary>
        /// <param name="stream">The stream to write the object to.</param>
        /// <param name="value">The object to serialize.</param>
        /// <param name="parameters">Parameters to use when writing.</param>
        /// <typeparam name="T">The type to serialize.</typeparam>
        public static void ToBinary <T>(UnsafeAppendBuffer *stream, T value, BinarySerializationParameters parameters = default)
        {
            var container = new PropertyWrapper <T>(value);

            var context = parameters.Context ?? (parameters.RequiresThreadSafety ? new BinarySerializationContext() : GetSharedContext());
            var visitor = context.GetBinaryPropertyWriter();

            visitor.SetStream(stream);
            visitor.SetSerializedType(parameters.SerializedType);
            visitor.SetDisableRootAdapters(parameters.DisableRootAdapters);
            visitor.SetGlobalAdapters(GetGlobalAdapters());
            visitor.SetUserDefinedAdapters(parameters.UserDefinedAdapters);

            visitor.SetSerializedReferences(parameters.DisableSerializedReferences ? default : context.GetSerializedReferences());

            using (visitor.Lock()) PropertyContainer.Visit(ref container, visitor);
        }
Exemple #12
0
        /// <summary>
        /// Serializes the given object to the given stream as binary.
        /// </summary>
        /// <param name="stream">The stream to write the object to.</param>
        /// <param name="value">The object to serialize.</param>
        /// <param name="parameters">Parameters to use when writing.</param>
        /// <typeparam name="T">The type to serialize.</typeparam>
        public static void ToBinary <T>(UnsafeAppendBuffer *stream, T value, BinarySerializationParameters parameters = default)
        {
            var container = new PropertyWrapper <T>(value);

            var state   = parameters.State ?? (parameters.RequiresThreadSafety ? new BinarySerializationState() : GetSharedState());
            var visitor = state.GetBinaryPropertyWriter();

            visitor.SetStream(stream);
            visitor.SetSerializedType(parameters.SerializedType);
            visitor.SetDisableRootAdapters(parameters.DisableRootAdapters);
            visitor.SetGlobalAdapters(GetGlobalAdapters());
            visitor.SetUserDefinedAdapters(parameters.UserDefinedAdapters);

            visitor.SetSerializedReferences(parameters.DisableSerializedReferences ? default : state.GetSerializedReferences());

            using (visitor.Lock()) PropertyContainer.Accept(visitor, ref container);

            if (!parameters.DisableSerializedReferences)
            {
                state.GetSerializedReferences().Clear();
            }
        }
Exemple #13
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;
        }
Exemple #14
0
 public void SetStream(UnsafeAppendBuffer *stream)
 => m_Stream = stream;
 void IBinaryAdapter <Guid> .Serialize(UnsafeAppendBuffer *writer, Guid value)
 => writer->Add(value.ToString("N", CultureInfo.InvariantCulture));
Exemple #16
0
        public static void Serialize(EntityChangeSet entityChangeSet, UnsafeAppendBuffer *buffer, out NativeArray <RuntimeGlobalObjectId> outAssets)
        {
            // @FIXME Workaround to solve an issue with hybrid components, LiveLink player builds do NOT support hybrid components.
            //
            // An implementation detail of hybrid components is the `CompanionLink` component.
            // This component is used to link an entity to a GameObject which hosts all of the hybrid components.
            // This companion GameObject lives in the scene and is NOT being serialized across to the player yet.
            //
            // In order to avoid crashing the companion link system in the player build we strip this component during serialization.
            //
            var companionLinkPackedTypeIndex             = GetCompanionLinkPackedTypeIndex(entityChangeSet.TypeHashes);
            var addComponentsWithoutCompanionLinks       = GetPackedComponentsWithoutCompanionLinks(entityChangeSet.AddComponents, companionLinkPackedTypeIndex, Allocator.Temp);
            var removeComponentWithoutCompanionLinks     = GetPackedComponentsWithoutCompanionLinks(entityChangeSet.RemoveComponents, companionLinkPackedTypeIndex, Allocator.Temp);
            var setManagedComponentWithoutCompanionLinks = GetPackedManagedComponentChangesWithoutCompanionLinks(entityChangeSet.SetManagedComponents, companionLinkPackedTypeIndex);

            // Write EntityChangeSet
            buffer->Add(entityChangeSet.TypeHashes);
            buffer->Add(entityChangeSet.CreatedEntityCount);
            buffer->Add(entityChangeSet.DestroyedEntityCount);
            buffer->Add(entityChangeSet.Entities);
            buffer->Add(entityChangeSet.Names);
            buffer->Add(addComponentsWithoutCompanionLinks.AsArray());
            buffer->Add(removeComponentWithoutCompanionLinks.AsArray());
            buffer->Add(entityChangeSet.SetComponents);
            buffer->Add(entityChangeSet.ComponentData);
            buffer->Add(entityChangeSet.EntityReferenceChanges);
            buffer->Add(entityChangeSet.BlobAssetReferenceChanges);
            buffer->Add(entityChangeSet.LinkedEntityGroupAdditions);
            buffer->Add(entityChangeSet.LinkedEntityGroupRemovals);
            buffer->Add(entityChangeSet.CreatedBlobAssets);
            buffer->Add(entityChangeSet.DestroyedBlobAssets);
            buffer->Add(entityChangeSet.BlobAssetData);

            var writer = new ManagedObjectBinaryWriter(buffer);

            WriteSharedComponentDataChanges(buffer, writer, entityChangeSet.SetSharedComponents);
            WriteManagedComponentDataChanges(buffer, writer, setManagedComponentWithoutCompanionLinks);

            var objectTable     = writer.GetUnityObjects();
            var globalObjectIds = new GlobalObjectId[objectTable.Length];

            GlobalObjectId.GetGlobalObjectIdsSlow(objectTable, globalObjectIds);

            outAssets = new NativeArray <RuntimeGlobalObjectId>(globalObjectIds.Length, Allocator.Persistent);
            for (int i = 0; i != globalObjectIds.Length; i++)
            {
                var globalObjectId = globalObjectIds[i];

                //@TODO: HACK (Object is a scene object)
                if (globalObjectId.identifierType == 2)
                {
                    Debug.LogWarning($"{objectTable[i]} is part of a scene, LiveLink can't transfer scene objects. (Note: LiveConvertSceneView currently triggers this)");
                    globalObjectId = new GlobalObjectId();
                }

                if (globalObjectId.assetGUID == new GUID())
                {
                    //@TODO: How do we handle this
                    Debug.LogWarning($"{objectTable[i]} has no valid GUID. LiveLink currently does not support built-in assets.");
                    globalObjectId = new GlobalObjectId();
                }

                outAssets[i] = UnsafeUtility.AsRef <RuntimeGlobalObjectId>(&globalObjectId);
            }

            addComponentsWithoutCompanionLinks.Dispose();
            removeComponentWithoutCompanionLinks.Dispose();
        }
        void Unity.Serialization.Binary.Adapters.Contravariant.IBinaryAdapter <UnityEngine.Object> .Serialize(UnsafeAppendBuffer *writer, UnityEngine.Object value)
        {
            var index = -1;

            if (value != null)
            {
                if (null == m_UnityObjects)
                {
                    m_UnityObjects = new List <UnityEngine.Object>();
                }

                if (null == m_UnityObjectsMap)
                {
                    m_UnityObjectsMap = new Dictionary <UnityEngine.Object, int>();
                }

                if (!m_UnityObjectsMap.TryGetValue(value, out index))
                {
                    index = m_UnityObjects.Count;
                    m_UnityObjectsMap.Add(value, index);
                    m_UnityObjects.Add(value);
                }
            }

            writer->Add(index);
        }
 void IBinaryAdapter <byte> .Serialize(UnsafeAppendBuffer *writer, byte value)
 => writer->Add(value);
 void IBinaryAdapter <bool> .Serialize(UnsafeAppendBuffer *writer, bool value)
 => writer->Add((byte)(value ? 1 : 0));
Exemple #20
0
 void IBinaryAdapter <UnityEditor.GUID> .Serialize(UnsafeAppendBuffer *writer, UnityEditor.GUID value)
 {
     writer->Add(value.ToString());
 }
 public BinaryPrimitiveWriterAdapter(UnsafeAppendBuffer *buffer)
 {
     m_Buffer = buffer;
 }
 void IBinaryAdapter <ushort> .Serialize(UnsafeAppendBuffer *writer, ushort value)
 => writer->Add(value);
 void IBinaryAdapter <float> .Serialize(UnsafeAppendBuffer *writer, float value)
 => writer->Add(value);
 void IBinaryAdapter <string> .Serialize(UnsafeAppendBuffer *writer, string value)
 => writer->Add(value);
 void IBinaryAdapter <char> .Serialize(UnsafeAppendBuffer *writer, char value)
 => writer->Add(value);
 public PropertiesBinaryWriter(UnsafeAppendBuffer *stream)
 {
     PrimitiveWriter = new BinaryPrimitiveWriterAdapter(stream);
     AddAdapter(PrimitiveWriter);
 }
 void Unity.Serialization.Binary.Adapters.Contravariant.IBinaryAdapter <UnityEngine.Object> .Serialize(UnsafeAppendBuffer *writer, UnityEngine.Object value)
 {
     throw new InvalidOperationException($"Serialize should never be invoked by {nameof(ManagedObjectBinaryReader)}.");
 }
 void IBinaryAdapter <double> .Serialize(UnsafeAppendBuffer *writer, double value)
 => writer->Add(value);