/// <summary> /// Initializes a new instance of <see cref="ManagedObjectBinaryReader"/> which can be used to read managed objects from the given stream. /// </summary> /// <param name="stream">The stream to read from.</param> /// <param name="unityObjects">The table containing all <see cref="UnityEngine.Object"/> references. This is produce by the <see cref="ManagedObjectBinaryWriter"/>.</param> public ManagedObjectBinaryReader(UnsafeAppendBuffer.Reader *stream, UnityEngine.Object[] unityObjects) { m_Stream = stream; m_Params = new BinarySerializationParameters { UserDefinedAdapters = new List <IBinaryAdapter> { this }, Context = new BinarySerializationContext(), }; m_UnityObjects = unityObjects; }
unsafe UnityEngine.Object ReadObject(UnsafeAppendBuffer.Reader *stream) { stream->ReadNext(out int index); if (index != -1) { return(_ObjectTable[index]); } else { return(null); } }
object Contravariant.IBinaryAdapter <UnityObject> .Deserialize(UnsafeAppendBuffer.Reader *reader) { #if UNITY_EDITOR reader->ReadNext(out string value); if (UnityEditor.GlobalObjectId.TryParse(value, out var id)) { return(UnityEditor.GlobalObjectId.GlobalObjectIdentifierToObjectSlow(id)); } #endif return(null); }
public static EntityChangeSet Deserialize(UnsafeAppendBuffer.Reader *bufferReader, NativeArray <RuntimeGlobalObjectId> globalObjectIDs, GlobalAssetObjectResolver resolver) { bufferReader->ReadNext <ComponentTypeHash>(out var typeHashes, Allocator.Persistent); for (int i = 0; i != typeHashes.Length; i++) { var stableTypeHash = typeHashes[i].StableTypeHash; var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(stableTypeHash); if (typeIndex == -1) { typeHashes.Dispose(); throw new ArgumentException("The LiveLink Patch Type Layout doesn't match the Data Layout of the Components. Please Rebuild the Player."); } } var createdEntityCount = bufferReader->ReadNext <int>(); var destroyedEntityCount = bufferReader->ReadNext <int>(); bufferReader->ReadNext <EntityGuid>(out var entities, Allocator.Persistent); bufferReader->ReadNext <NativeString64>(out var names, Allocator.Persistent); bufferReader->ReadNext <PackedComponent>(out var addComponents, Allocator.Persistent); bufferReader->ReadNext <PackedComponent>(out var removeComponents, Allocator.Persistent); bufferReader->ReadNext <PackedComponentDataChange>(out var setComponents, Allocator.Persistent); bufferReader->ReadNext <byte>(out var componentData, Allocator.Persistent); bufferReader->ReadNext <EntityReferenceChange>(out var entityReferenceChanges, Allocator.Persistent); bufferReader->ReadNext <BlobAssetReferenceChange>(out var blobAssetReferenceChanges, Allocator.Persistent); bufferReader->ReadNext <LinkedEntityGroupChange>(out var linkedEntityGroupAdditions, Allocator.Persistent); bufferReader->ReadNext <LinkedEntityGroupChange>(out var linkedEntityGroupRemovals, Allocator.Persistent); bufferReader->ReadNext <BlobAssetChange>(out var createdBlobAssets, Allocator.Persistent); bufferReader->ReadNext <ulong>(out var destroyedBlobAssets, Allocator.Persistent); bufferReader->ReadNext <byte>(out var blobAssetData, Allocator.Persistent); bufferReader->ReadNext <PackedComponent>(out var setSharedComponentPackedComponents, Allocator.Persistent); var resolvedObjects = new UnityEngine.Object[globalObjectIDs.Length]; resolver.ResolveObjects(globalObjectIDs, resolvedObjects); var reader = new PropertiesBinaryReader(bufferReader, resolvedObjects); var setSharedComponents = new PackedSharedComponentDataChange[setSharedComponentPackedComponents.Length]; for (int i = 0; i < setSharedComponentPackedComponents.Length; i++) { object componentValue; if (bufferReader->ReadNext <int>() == 1) { var packedTypeIndex = setSharedComponentPackedComponents[i].PackedTypeIndex; var stableTypeHash = typeHashes[packedTypeIndex].StableTypeHash; var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(stableTypeHash); var type = TypeManager.GetType(typeIndex); componentValue = BoxedProperties.ReadBoxedStruct(type, reader); }
/// <summary> /// Deserializes from the specified stream and returns a new instance of <typeparamref name="T"/>. /// </summary> /// <param name="stream">The stream to read from.</param> /// <param name="parameters">The parameters to use when reading.</param> /// <typeparam name="T">The type to deserialize.</typeparam> /// <returns>A new instance of <typeparamref name="T"/> constructed from the serialized data.</returns> public static T FromBinary <T>(UnsafeAppendBuffer.Reader *stream, BinarySerializationParameters parameters = default) { var context = parameters.Context ?? (parameters.RequiresThreadSafety ? new BinarySerializationContext() : GetSharedContext()); var visitor = context.GetBinaryPropertyReader(); 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()); var container = new PropertyWrapper <T>(default);
static bool TryDeserialize <TValue>(IBinaryAdapter adapter, UnsafeAppendBuffer.Reader *buffer, ref TValue value) { if (adapter is IBinaryAdapter <TValue> typed) { value = typed.Deserialize(buffer); return(true); } if (adapter is Contravariant.IBinaryAdapter <TValue> typedContravariant) { value = (TValue)typedContravariant.Deserialize(buffer); return(true); } return(false); }
public static unsafe void GenerateAOTFunctions <TProperty, TContainer, TValue>() where TProperty : IProperty <TContainer, TValue> { TProperty property = default(TProperty); TContainer container = default(TContainer); ChangeTracker changeTracker = default(ChangeTracker); UnsafeAppendBuffer.Reader *reader = null; var propertyReader = new PropertiesBinaryReader(reader, null); propertyReader.VisitProperty <TProperty, TContainer, TValue>(property, ref container, ref changeTracker); propertyReader.IsExcluded <TProperty, TContainer, TValue>(property, ref container); Properties.AOTFunctionGenerator.GenerateAOTContainerFunctions <DictionaryContainer <object, object> >(); Properties.AOTFunctionGenerator.GenerateAOTContainerFunctions <PolymorphicTypeName>(); Properties.AOTFunctionGenerator.GenerateAOTContainerFunctions <PolymorphicTypeContainer <TContainer> >(); Properties.AOTFunctionGenerator.GenerateAOTContainerFunctions <PolymorphicTypeContainer <TValue> >(); }
static PackedManagedComponentDataChange[] ReadManagedComponentDataChanges(UnsafeAppendBuffer.Reader *buffer, ManagedObjectBinaryReader reader, NativeArray <ComponentTypeHash> typeHashes) { buffer->ReadNext <PackedComponent>(out var packedComponents, Allocator.Temp); var setManagedComponentDataChanges = new PackedManagedComponentDataChange[packedComponents.Length]; for (var i = 0; i < packedComponents.Length; i++) { var packedTypeIndex = packedComponents[i].PackedTypeIndex; var stableTypeHash = typeHashes[packedTypeIndex].StableTypeHash; var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(stableTypeHash); var type = TypeManager.GetType(typeIndex); var componentValue = reader.ReadObject(type); setManagedComponentDataChanges[i].Component = packedComponents[i]; setManagedComponentDataChanges[i].BoxedValue = componentValue; } packedComponents.Dispose(); return(setManagedComponentDataChanges); }
/// <summary> /// Invoked during deserialization any time we encounter a <see cref="UnityEngine.Object"/> type or any derived type. /// </summary> /// <param name="reader"></param> /// <returns></returns> /// <exception cref="ArgumentException">The adapter was not initialized with a valid object table.</exception> public object Deserialize(UnsafeAppendBuffer.Reader *reader) { if (m_DeserializeObjectTable == null) { throw new ArgumentException("We are reading a UnityEngine.Object however no ObjectTable was provided to the ManagedObjectBinaryReader."); } var index = reader->ReadNext <int>(); if (index == -1) { return(null); } if ((uint)index >= m_DeserializeObjectTable.Length) { throw new ArgumentException("We are reading a UnityEngine.Object but the deserialized index is out of range for the given object table."); } return(m_DeserializeObjectTable[index]); }
public void SetStream(UnsafeAppendBuffer.Reader *stream) { m_Stream = stream; m_SerializedTypeProvider.Stream = stream; }
object Unity.Serialization.Binary.Adapters.Contravariant.IBinaryAdapter <UnityEngine.Object> .Deserialize(UnsafeAppendBuffer.Reader *reader) { var index = reader->ReadNext <int>(); if (index == -1) { return(null); } if (m_UnityObjects == null) { throw new ArgumentException("We are reading a UnityEngine.Object however no ObjectTable was provided to the ManagedObjectBinaryReader."); } if ((uint)index >= m_UnityObjects.Length) { throw new ArgumentException("We are reading a UnityEngine.Object but the deserialized index is out of range for the given object table."); } return(m_UnityObjects[index]); }
object Unity.Serialization.Binary.Adapters.Contravariant.IBinaryAdapter <UnityEngine.Object> .Deserialize(UnsafeAppendBuffer.Reader *reader) { throw new InvalidOperationException($"Deserialize should never be invoked by {nameof(ManagedObjectBinaryWriter)}"); }
double IBinaryAdapter <double> .Deserialize(UnsafeAppendBuffer.Reader *reader) => reader->ReadNext <double>();
unsafe public PropertiesBinaryReader(UnsafeAppendBuffer.Reader *stream, UnityEngine.Object[] objectTable) { _PrimitiveReader = new BinaryPrimitiveReaderAdapter(stream); _ObjectTable = objectTable; AddAdapter(_PrimitiveReader); }
Guid IBinaryAdapter <Guid> .Deserialize(UnsafeAppendBuffer.Reader *reader) { reader->ReadNext(out string str); return(Guid.TryParseExact(str, "N", out var value) ? value : default);
public void SetStream(UnsafeAppendBuffer.Reader *stream) { m_Stream = stream; }
ulong IBinaryAdapter <ulong> .Deserialize(UnsafeAppendBuffer.Reader *reader) => reader->ReadNext <ulong>();
string IBinaryAdapter <string> .Deserialize(UnsafeAppendBuffer.Reader *reader) { reader->ReadNext(out string value); return(value); }
char IBinaryAdapter <char> .Deserialize(UnsafeAppendBuffer.Reader *reader) => reader->ReadNext <char>();
bool IBinaryAdapter <bool> .Deserialize(UnsafeAppendBuffer.Reader *reader) => reader->ReadNext <byte>() == 1;
public static EntityChangeSet Deserialize(UnsafeAppendBuffer.Reader *bufferReader, NativeArray <RuntimeGlobalObjectId> globalObjectIDs, GlobalAssetObjectResolver resolver) { bufferReader->ReadNext <ComponentTypeHash>(out var typeHashes, Allocator.Persistent); for (int i = 0; i != typeHashes.Length; i++) { var stableTypeHash = typeHashes[i].StableTypeHash; var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(stableTypeHash); if (typeIndex == -1) { typeHashes.Dispose(); throw new ArgumentException("The LiveLink Patch Type Layout doesn't match the Data Layout of the Components. Please Rebuild the Player."); } } var createdEntityCount = bufferReader->ReadNext <int>(); var destroyedEntityCount = bufferReader->ReadNext <int>(); bufferReader->ReadNext <EntityGuid>(out var entities, Allocator.Persistent); bufferReader->ReadNext <FixedString64>(out var names, Allocator.Persistent); bufferReader->ReadNext <PackedComponent>(out var addComponents, Allocator.Persistent); bufferReader->ReadNext <PackedComponent>(out var removeComponents, Allocator.Persistent); bufferReader->ReadNext <PackedComponentDataChange>(out var setComponents, Allocator.Persistent); bufferReader->ReadNext <byte>(out var componentData, Allocator.Persistent); bufferReader->ReadNext <EntityReferenceChange>(out var entityReferenceChanges, Allocator.Persistent); bufferReader->ReadNext <BlobAssetReferenceChange>(out var blobAssetReferenceChanges, Allocator.Persistent); bufferReader->ReadNext <LinkedEntityGroupChange>(out var linkedEntityGroupAdditions, Allocator.Persistent); bufferReader->ReadNext <LinkedEntityGroupChange>(out var linkedEntityGroupRemovals, Allocator.Persistent); bufferReader->ReadNext <BlobAssetChange>(out var createdBlobAssets, Allocator.Persistent); bufferReader->ReadNext <ulong>(out var destroyedBlobAssets, Allocator.Persistent); bufferReader->ReadNext <byte>(out var blobAssetData, Allocator.Persistent); var resolvedObjects = new UnityEngine.Object[globalObjectIDs.Length]; resolver.ResolveObjects(globalObjectIDs, resolvedObjects); var reader = new ManagedObjectBinaryReader(bufferReader, resolvedObjects); var setSharedComponents = ReadSharedComponentDataChanges(bufferReader, reader, typeHashes); var setManagedComponents = ReadManagedComponentDataChanges(bufferReader, reader, typeHashes); //if (!bufferReader->EndOfBuffer) // throw new Exception("Underflow in EntityChangeSet buffer"); return(new EntityChangeSet( createdEntityCount, destroyedEntityCount, entities, typeHashes, names, addComponents, removeComponents, setComponents, componentData, entityReferenceChanges, blobAssetReferenceChanges, setManagedComponents, setSharedComponents, linkedEntityGroupAdditions, linkedEntityGroupRemovals, createdBlobAssets, destroyedBlobAssets, blobAssetData)); }
internal static unsafe void ReadPrimitiveUnsafe <TValue>(UnsafeAppendBuffer.Reader *stream, ref TValue value, Type type) { #if UNITY_2020_1_OR_NEWER switch (Type.GetTypeCode(type)) { case TypeCode.SByte: stream->ReadNext <sbyte>(out var _sbyte); value = UnsafeUtility.As <sbyte, TValue>(ref _sbyte); return; case TypeCode.Int16: stream->ReadNext <short>(out var _short); value = UnsafeUtility.As <short, TValue>(ref _short); return; case TypeCode.Int32: stream->ReadNext <int>(out var _int); value = UnsafeUtility.As <int, TValue>(ref _int); return; case TypeCode.Int64: stream->ReadNext <long>(out var _long); value = UnsafeUtility.As <long, TValue>(ref _long); return; case TypeCode.Byte: stream->ReadNext <byte>(out var _byte); value = UnsafeUtility.As <byte, TValue>(ref _byte); return; case TypeCode.UInt16: stream->ReadNext <ushort>(out var _ushort); value = UnsafeUtility.As <ushort, TValue>(ref _ushort); return; case TypeCode.UInt32: stream->ReadNext <uint>(out var _uint); value = UnsafeUtility.As <uint, TValue>(ref _uint); return; case TypeCode.UInt64: stream->ReadNext <ulong>(out var _ulong); value = UnsafeUtility.As <ulong, TValue>(ref _ulong); return; case TypeCode.Single: stream->ReadNext <float>(out var _float); value = UnsafeUtility.As <float, TValue>(ref _float); return; case TypeCode.Double: stream->ReadNext <double>(out var _double); value = UnsafeUtility.As <double, TValue>(ref _double); return; case TypeCode.Boolean: stream->ReadNext <byte>(out var _boolean); var b = _boolean == 1; value = UnsafeUtility.As <bool, TValue>(ref b); return; case TypeCode.Char: stream->ReadNext <char>(out var _char); value = UnsafeUtility.As <char, TValue>(ref _char); return; case TypeCode.String: stream->ReadNext(out string _string); value = (TValue)(object)_string; return; default: throw new ArgumentOutOfRangeException(); } #else switch (Type.GetTypeCode(type)) { case TypeCode.SByte: stream->ReadNext <sbyte>(out var _sbyte); value = System.Runtime.CompilerServices.Unsafe.As <sbyte, TValue>(ref _sbyte); return; case TypeCode.Int16: stream->ReadNext <short>(out var _short); value = System.Runtime.CompilerServices.Unsafe.As <short, TValue>(ref _short); return; case TypeCode.Int32: stream->ReadNext <int>(out var _int); value = System.Runtime.CompilerServices.Unsafe.As <int, TValue>(ref _int); return; case TypeCode.Int64: stream->ReadNext <long>(out var _long); value = System.Runtime.CompilerServices.Unsafe.As <long, TValue>(ref _long); return; case TypeCode.Byte: stream->ReadNext <byte>(out var _byte); value = System.Runtime.CompilerServices.Unsafe.As <byte, TValue>(ref _byte); return; case TypeCode.UInt16: stream->ReadNext <ushort>(out var _ushort); value = System.Runtime.CompilerServices.Unsafe.As <ushort, TValue>(ref _ushort); return; case TypeCode.UInt32: stream->ReadNext <uint>(out var _uint); value = System.Runtime.CompilerServices.Unsafe.As <uint, TValue>(ref _uint); return; case TypeCode.UInt64: stream->ReadNext <ulong>(out var _ulong); value = System.Runtime.CompilerServices.Unsafe.As <ulong, TValue>(ref _ulong); return; case TypeCode.Single: stream->ReadNext <float>(out var _float); value = System.Runtime.CompilerServices.Unsafe.As <float, TValue>(ref _float); return; case TypeCode.Double: stream->ReadNext <double>(out var _double); value = System.Runtime.CompilerServices.Unsafe.As <double, TValue>(ref _double); return; case TypeCode.Boolean: stream->ReadNext <byte>(out var _boolean); var b = _boolean == 1; value = System.Runtime.CompilerServices.Unsafe.As <bool, TValue>(ref b); return; case TypeCode.Char: stream->ReadNext <char>(out var _char); value = System.Runtime.CompilerServices.Unsafe.As <char, TValue>(ref _char); return; case TypeCode.String: stream->ReadNext(out string _string); value = (TValue)(object)_string; return; default: throw new ArgumentOutOfRangeException(); } #endif }
FileInfo IBinaryAdapter <FileInfo> .Deserialize(UnsafeAppendBuffer.Reader *reader) { reader->ReadNext(out string str); return(str.Equals("null") ? null : new FileInfo(str)); }
UnityEditor.GUID IBinaryAdapter <UnityEditor.GUID> .Deserialize(UnsafeAppendBuffer.Reader *reader) { reader->ReadNext(out string str); return(UnityEditor.GUID.TryParse(str, out var value) ? value : default);
unsafe public PropertiesBinaryReader(UnsafeAppendBuffer.Reader *stream) { _PrimitiveReader = new BinaryPrimitiveReaderAdapter(stream); AddAdapter(_PrimitiveReader); }
float IBinaryAdapter <float> .Deserialize(UnsafeAppendBuffer.Reader *reader) => reader->ReadNext <float>();
internal static unsafe void ReadPrimitiveBoxed <TValue>(UnsafeAppendBuffer.Reader *stream, ref TValue value, Type type) { switch (Type.GetTypeCode(type)) { case TypeCode.SByte: value = (TValue)(object)stream->ReadNext <sbyte>(); return; case TypeCode.Int16: value = (TValue)(object)stream->ReadNext <short>(); return; case TypeCode.Int32: value = (TValue)(object)stream->ReadNext <int>(); return; case TypeCode.Int64: value = (TValue)(object)stream->ReadNext <long>(); return; case TypeCode.Byte: value = (TValue)(object)stream->ReadNext <byte>(); return; case TypeCode.UInt16: value = (TValue)(object)stream->ReadNext <ushort>(); return; case TypeCode.UInt32: value = (TValue)(object)stream->ReadNext <uint>(); return; case TypeCode.UInt64: value = (TValue)(object)stream->ReadNext <ulong>(); return; case TypeCode.Single: value = (TValue)(object)stream->ReadNext <float>(); return; case TypeCode.Double: value = (TValue)(object)stream->ReadNext <double>(); return; case TypeCode.Boolean: value = (TValue)(object)(stream->ReadNext <byte>() == 1); return; case TypeCode.Char: value = (TValue)(object)stream->ReadNext <char>(); return; case TypeCode.String: stream->ReadNext(out string _string); value = (TValue)(object)_string; return; default: throw new ArgumentOutOfRangeException(); } }
unsafe public BinaryPrimitiveReaderAdapter(UnsafeAppendBuffer.Reader *buffer) { Buffer = buffer; }