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(); } }
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()); } }
/// <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() }; }
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); } }
/// <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); }
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); }
/// <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); }
/// <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(); } }
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; }
public void SetStream(UnsafeAppendBuffer *stream) => m_Stream = stream;
void IBinaryAdapter <Guid> .Serialize(UnsafeAppendBuffer *writer, Guid value) => writer->Add(value.ToString("N", CultureInfo.InvariantCulture));
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));
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);