Add VRChat and GitHub packages to Unity project
This commit is contained in:
1 parent
0334a52b21
commit
85538aaccc
3297 files changed
+847877
No files matched your search
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="BooleanSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="bool"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Boolean}" />
|
||||
public sealed class BooleanSerializer : Serializer<bool>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="bool" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override bool ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Boolean)
|
||||
{
|
||||
bool value;
|
||||
if (reader.ReadBoolean(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Boolean.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(bool);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="bool" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, bool value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteBoolean(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e8d8c5a97fdc322a8b8471aaf02f469
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ByteSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="byte"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Byte}" />
|
||||
public sealed class ByteSerializer : Serializer<byte>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="byte" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override byte ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
byte value;
|
||||
if (reader.ReadByte(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(byte);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="byte" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, byte value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteByte(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8aa9f52771b0e4e6f8f0c438a4f0430b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="CharSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="char"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Char}" />
|
||||
public sealed class CharSerializer : Serializer<char>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="char" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override char ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.String)
|
||||
{
|
||||
char value;
|
||||
if (reader.ReadChar(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.String.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(char);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="char" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, char value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteChar(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d44d1ae83013328d7b855275fa1cfad7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,663 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ComplexTypeSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer for all complex types; IE, types which are not primitives as determined by the <see cref="FormatterUtilities.IsPrimitiveType(Type)" /> method.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type which the <see cref="ComplexTypeSerializer{T}" /> can serialize and deserialize.</typeparam>
|
||||
/// <seealso cref="Serializer{T}" />
|
||||
public sealed class ComplexTypeSerializer<T> : Serializer<T>
|
||||
{
|
||||
private static readonly bool ComplexTypeMayBeBoxedValueType = typeof(T).IsInterface || typeof(T) == typeof(object) || typeof(T) == typeof(ValueType) || typeof(T) == typeof(Enum);
|
||||
private static readonly bool ComplexTypeIsAbstract = typeof(T).IsAbstract || typeof(T).IsInterface;
|
||||
private static readonly bool ComplexTypeIsNullable = typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>);
|
||||
private static readonly bool ComplexTypeIsValueType = typeof(T).IsValueType;
|
||||
private static readonly Type TypeOf_T = typeof(T);
|
||||
|
||||
private static readonly bool AllowDeserializeInvalidDataForT = typeof(T).IsDefined(typeof(AllowDeserializeInvalidDataAttribute), true);
|
||||
|
||||
private static readonly Dictionary<ISerializationPolicy, IFormatter<T>> FormattersByPolicy = new Dictionary<ISerializationPolicy, IFormatter<T>>(ReferenceEqualityComparer<ISerializationPolicy>.Default);
|
||||
private static readonly object FormattersByPolicy_LOCK = new object();
|
||||
|
||||
private static readonly ISerializationPolicy UnityPolicy = SerializationPolicies.Unity;
|
||||
private static readonly ISerializationPolicy StrictPolicy = SerializationPolicies.Strict;
|
||||
private static readonly ISerializationPolicy EverythingPolicy = SerializationPolicies.Everything;
|
||||
|
||||
private static IFormatter<T> UnityPolicyFormatter;
|
||||
private static IFormatter<T> StrictPolicyFormatter;
|
||||
private static IFormatter<T> EverythingPolicyFormatter;
|
||||
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="T" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override T ReadValue(IDataReader reader)
|
||||
{
|
||||
var context = reader.Context;
|
||||
|
||||
if (context.Config.SerializationPolicy.AllowNonSerializableTypes == false && TypeOf_T.IsSerializable == false)
|
||||
{
|
||||
context.Config.DebugContext.LogError("The type " + TypeOf_T.Name + " is not marked as serializable.");
|
||||
return default(T);
|
||||
}
|
||||
|
||||
bool exitNode = true;
|
||||
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (ComplexTypeIsValueType)
|
||||
{
|
||||
if (entry == EntryType.Null)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Expecting complex struct of type " + TypeOf_T.GetNiceFullName() + " but got null value.");
|
||||
reader.ReadNull();
|
||||
return default(T);
|
||||
}
|
||||
else if (entry != EntryType.StartOfNode)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Unexpected entry '" + name + "' of type " + entry.ToString() + ", when " + EntryType.StartOfNode + " was expected. A value has likely been lost.");
|
||||
reader.SkipEntry();
|
||||
return default(T);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Type expectedType = TypeOf_T;
|
||||
Type serializedType;
|
||||
|
||||
if (reader.EnterNode(out serializedType))
|
||||
{
|
||||
if (serializedType != expectedType)
|
||||
{
|
||||
if (serializedType != null)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Expected complex struct value " + expectedType.Name + " but the serialized value is of type " + serializedType.Name + ".");
|
||||
|
||||
if (serializedType.IsCastableTo(expectedType))
|
||||
{
|
||||
object value = FormatterLocator.GetFormatter(serializedType, context.Config.SerializationPolicy).Deserialize(reader);
|
||||
|
||||
bool serializedTypeIsNullable = serializedType.IsGenericType && serializedType.GetGenericTypeDefinition() == typeof(Nullable<>);
|
||||
bool allowCastMethod = !ComplexTypeIsNullable && !serializedTypeIsNullable;
|
||||
|
||||
var castMethod = allowCastMethod ? serializedType.GetCastMethodDelegate(expectedType) : null;
|
||||
|
||||
if (castMethod != null)
|
||||
{
|
||||
return (T)castMethod(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (T)value;
|
||||
}
|
||||
}
|
||||
else if (AllowDeserializeInvalidDataForT || reader.Context.Config.AllowDeserializeInvalidData)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Can't cast serialized type " + serializedType.Name + " into expected type " + expectedType.Name + ". Attempting to deserialize with possibly invalid data. Value may be lost or corrupted for node '" + name + "'.");
|
||||
return GetBaseFormatter(context.Config.SerializationPolicy).Deserialize(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Can't cast serialized type " + serializedType.Name + " into expected type " + expectedType.Name + ". Value lost for node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
else if (AllowDeserializeInvalidDataForT || reader.Context.Config.AllowDeserializeInvalidData)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Expected complex struct value " + expectedType.Name + " but the serialized type could not be resolved. Attempting to deserialize with possibly invalid data. Value may be lost or corrupted for node '" + name + "'.");
|
||||
return GetBaseFormatter(context.Config.SerializationPolicy).Deserialize(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Expected complex struct value " + expectedType.Name + " but the serialized type could not be resolved. Value lost for node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetBaseFormatter(context.Config.SerializationPolicy).Deserialize(reader);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Config.DebugContext.LogError("Failed to enter node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
catch (SerializationAbortException ex)
|
||||
{
|
||||
exitNode = false;
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
context.Config.DebugContext.LogException(ex);
|
||||
return default(T);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (exitNode)
|
||||
{
|
||||
reader.ExitNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
case EntryType.Null:
|
||||
{
|
||||
reader.ReadNull();
|
||||
return default(T);
|
||||
}
|
||||
|
||||
case EntryType.ExternalReferenceByIndex:
|
||||
{
|
||||
int index;
|
||||
reader.ReadExternalReference(out index);
|
||||
|
||||
object value = context.GetExternalObject(index);
|
||||
|
||||
try
|
||||
{
|
||||
return (T)value;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Can't cast external reference type " + value.GetType().Name + " into expected type " + TypeOf_T.Name + ". Value lost for node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
case EntryType.ExternalReferenceByGuid:
|
||||
{
|
||||
Guid guid;
|
||||
reader.ReadExternalReference(out guid);
|
||||
|
||||
object value = context.GetExternalObject(guid);
|
||||
|
||||
try
|
||||
{
|
||||
return (T)value;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Can't cast external reference type " + value.GetType().Name + " into expected type " + TypeOf_T.Name + ". Value lost for node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
case EntryType.ExternalReferenceByString:
|
||||
{
|
||||
string id;
|
||||
reader.ReadExternalReference(out id);
|
||||
|
||||
object value = context.GetExternalObject(id);
|
||||
|
||||
try
|
||||
{
|
||||
return (T)value;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Can't cast external reference type " + value.GetType().Name + " into expected type " + TypeOf_T.Name + ". Value lost for node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
case EntryType.InternalReference:
|
||||
{
|
||||
int id;
|
||||
reader.ReadInternalReference(out id);
|
||||
|
||||
object value = context.GetInternalReference(id);
|
||||
|
||||
try
|
||||
{
|
||||
return (T)value;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
context.Config.DebugContext.LogWarning("Can't cast internal reference type " + value.GetType().Name + " into expected type " + TypeOf_T.Name + ". Value lost for node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
case EntryType.StartOfNode:
|
||||
{
|
||||
try
|
||||
{
|
||||
Type expectedType = TypeOf_T;
|
||||
Type serializedType;
|
||||
int id;
|
||||
|
||||
if (reader.EnterNode(out serializedType))
|
||||
{
|
||||
id = reader.CurrentNodeId;
|
||||
|
||||
T result;
|
||||
|
||||
if (serializedType != null && expectedType != serializedType) // We have type metadata different from the expected type
|
||||
{
|
||||
bool success = false;
|
||||
var isPrimitive = FormatterUtilities.IsPrimitiveType(serializedType);
|
||||
|
||||
bool assignableCast;
|
||||
|
||||
if (ComplexTypeMayBeBoxedValueType && isPrimitive)
|
||||
{
|
||||
// It's a boxed primitive type, so simply read that straight and register success
|
||||
var serializer = Serializer.Get(serializedType);
|
||||
result = (T)serializer.ReadValueWeak(reader);
|
||||
success = true;
|
||||
}
|
||||
else if ((assignableCast = expectedType.IsAssignableFrom(serializedType)) || serializedType.HasCastDefined(expectedType, false))
|
||||
{
|
||||
try
|
||||
{
|
||||
object value;
|
||||
|
||||
if (isPrimitive)
|
||||
{
|
||||
var serializer = Serializer.Get(serializedType);
|
||||
value = serializer.ReadValueWeak(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
var alternateFormatter = FormatterLocator.GetFormatter(serializedType, context.Config.SerializationPolicy);
|
||||
value = alternateFormatter.Deserialize(reader);
|
||||
}
|
||||
|
||||
if (assignableCast)
|
||||
{
|
||||
result = (T)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var castMethod = serializedType.GetCastMethodDelegate(expectedType);
|
||||
|
||||
if (castMethod != null)
|
||||
{
|
||||
result = (T)castMethod(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let's just give it a go anyways
|
||||
result = (T)value;
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
}
|
||||
catch (SerializationAbortException ex)
|
||||
{
|
||||
exitNode = false;
|
||||
throw ex;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
success = false;
|
||||
result = default(T);
|
||||
}
|
||||
}
|
||||
else if (!ComplexTypeIsAbstract && (AllowDeserializeInvalidDataForT || reader.Context.Config.AllowDeserializeInvalidData))
|
||||
{
|
||||
// We will try to deserialize an instance of T with the invalid data.
|
||||
context.Config.DebugContext.LogWarning("Can't cast serialized type " + serializedType.Name + " into expected type " + expectedType.Name + ". Attempting to deserialize with invalid data. Value may be lost or corrupted for node '" + name + "'.");
|
||||
result = GetBaseFormatter(context.Config.SerializationPolicy).Deserialize(reader);
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We couldn't cast or use the type, but we still have to deserialize it and register
|
||||
// the reference so the reference isn't lost if it is referred to further down
|
||||
// the data stream.
|
||||
|
||||
var alternateFormatter = FormatterLocator.GetFormatter(serializedType, context.Config.SerializationPolicy);
|
||||
object value = alternateFormatter.Deserialize(reader);
|
||||
|
||||
if (id >= 0)
|
||||
{
|
||||
context.RegisterInternalReference(id, value);
|
||||
}
|
||||
|
||||
result = default(T);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// We can't use this
|
||||
context.Config.DebugContext.LogWarning("Can't cast serialized type " + serializedType.Name + " into expected type " + expectedType.Name + ". Value lost for node '" + name + "'.");
|
||||
result = default(T);
|
||||
}
|
||||
}
|
||||
else if (ComplexTypeIsAbstract)
|
||||
{
|
||||
result = default(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GetBaseFormatter(context.Config.SerializationPolicy).Deserialize(reader);
|
||||
}
|
||||
|
||||
if (id >= 0)
|
||||
{
|
||||
context.RegisterInternalReference(id, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Config.DebugContext.LogError("Failed to enter node '" + name + "'.");
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
catch (SerializationAbortException ex)
|
||||
{
|
||||
exitNode = false;
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
context.Config.DebugContext.LogException(ex);
|
||||
return default(T);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (exitNode)
|
||||
{
|
||||
reader.ExitNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The below cases are for when we expect an object, but have
|
||||
// serialized a straight primitive type. In such cases, we can
|
||||
// often box the primitive type as an object.
|
||||
//
|
||||
// Sadly, the exact primitive type might be lost in case of
|
||||
// integer and floating points numbers, as we don't know what
|
||||
// type to expect.
|
||||
//
|
||||
// To be safe, we read and box the most precise type available.
|
||||
//
|
||||
|
||||
case EntryType.Boolean:
|
||||
{
|
||||
if (!ComplexTypeMayBeBoxedValueType)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
bool value;
|
||||
reader.ReadBoolean(out value);
|
||||
return (T)(object)value;
|
||||
}
|
||||
|
||||
case EntryType.FloatingPoint:
|
||||
{
|
||||
if (!ComplexTypeMayBeBoxedValueType)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
double value;
|
||||
reader.ReadDouble(out value);
|
||||
return (T)(object)value;
|
||||
}
|
||||
|
||||
case EntryType.Integer:
|
||||
{
|
||||
if (!ComplexTypeMayBeBoxedValueType)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
long value;
|
||||
reader.ReadInt64(out value);
|
||||
return (T)(object)value;
|
||||
}
|
||||
|
||||
case EntryType.String:
|
||||
{
|
||||
if (!ComplexTypeMayBeBoxedValueType)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
string value;
|
||||
reader.ReadString(out value);
|
||||
return (T)(object)value;
|
||||
}
|
||||
|
||||
case EntryType.Guid:
|
||||
{
|
||||
if (!ComplexTypeMayBeBoxedValueType)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
Guid value;
|
||||
reader.ReadGuid(out value);
|
||||
return (T)(object)value;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
// Lost value somehow
|
||||
context.Config.DebugContext.LogWarning("Unexpected entry of type " + entry.ToString() + ", when a reference or node start was expected. A value has been lost.");
|
||||
reader.SkipEntry();
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IFormatter<T> GetBaseFormatter(ISerializationPolicy serializationPolicy)
|
||||
{
|
||||
// This is an optimization - it's a lot cheaper to compare three references and do a null check,
|
||||
// than it is to look something up in a dictionary. By far most of the time, we will be using
|
||||
// one of these three policies.
|
||||
|
||||
if (object.ReferenceEquals(serializationPolicy, UnityPolicy))
|
||||
{
|
||||
if (UnityPolicyFormatter == null)
|
||||
{
|
||||
UnityPolicyFormatter = FormatterLocator.GetFormatter<T>(UnityPolicy);
|
||||
}
|
||||
|
||||
return UnityPolicyFormatter;
|
||||
}
|
||||
else if (object.ReferenceEquals(serializationPolicy, EverythingPolicy))
|
||||
{
|
||||
if (EverythingPolicyFormatter == null)
|
||||
{
|
||||
EverythingPolicyFormatter = FormatterLocator.GetFormatter<T>(EverythingPolicy);
|
||||
}
|
||||
|
||||
return EverythingPolicyFormatter;
|
||||
}
|
||||
else if (object.ReferenceEquals(serializationPolicy, StrictPolicy))
|
||||
{
|
||||
if (StrictPolicyFormatter == null)
|
||||
{
|
||||
StrictPolicyFormatter = FormatterLocator.GetFormatter<T>(StrictPolicy);
|
||||
}
|
||||
|
||||
return StrictPolicyFormatter;
|
||||
}
|
||||
|
||||
IFormatter<T> formatter;
|
||||
|
||||
lock (FormattersByPolicy_LOCK)
|
||||
{
|
||||
if (!FormattersByPolicy.TryGetValue(serializationPolicy, out formatter))
|
||||
{
|
||||
formatter = FormatterLocator.GetFormatter<T>(serializationPolicy);
|
||||
FormattersByPolicy.Add(serializationPolicy, formatter);
|
||||
}
|
||||
}
|
||||
|
||||
return formatter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="T" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, T value, IDataWriter writer)
|
||||
{
|
||||
var context = writer.Context;
|
||||
var policy = context.Config.SerializationPolicy;
|
||||
|
||||
if (policy.AllowNonSerializableTypes == false && TypeOf_T.IsSerializable == false)
|
||||
{
|
||||
context.Config.DebugContext.LogError("The type " + TypeOf_T.Name + " is not marked as serializable.");
|
||||
return;
|
||||
}
|
||||
|
||||
FireOnSerializedType();
|
||||
|
||||
if (ComplexTypeIsValueType)
|
||||
{
|
||||
bool endNode = true;
|
||||
|
||||
try
|
||||
{
|
||||
writer.BeginStructNode(name, TypeOf_T);
|
||||
GetBaseFormatter(policy).Serialize(value, writer);
|
||||
}
|
||||
catch (SerializationAbortException ex)
|
||||
{
|
||||
endNode = false;
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (endNode)
|
||||
{
|
||||
writer.EndNode(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int id;
|
||||
int index;
|
||||
string strId;
|
||||
Guid guid;
|
||||
|
||||
bool endNode = true;
|
||||
|
||||
if (object.ReferenceEquals(value, null))
|
||||
{
|
||||
writer.WriteNull(name);
|
||||
}
|
||||
else if (context.TryRegisterExternalReference(value, out index))
|
||||
{
|
||||
writer.WriteExternalReference(name, index);
|
||||
}
|
||||
else if (context.TryRegisterExternalReference(value, out guid))
|
||||
{
|
||||
writer.WriteExternalReference(name, guid);
|
||||
}
|
||||
else if (context.TryRegisterExternalReference(value, out strId))
|
||||
{
|
||||
writer.WriteExternalReference(name, strId);
|
||||
}
|
||||
else if (context.TryRegisterInternalReference(value, out id))
|
||||
{
|
||||
Type type = value.GetType(); // Get type of actual stored object
|
||||
|
||||
if (ComplexTypeMayBeBoxedValueType && FormatterUtilities.IsPrimitiveType(type))
|
||||
// It's a boxed primitive type
|
||||
{
|
||||
try
|
||||
{
|
||||
writer.BeginReferenceNode(name, type, id);
|
||||
|
||||
var serializer = Serializer.Get(type);
|
||||
serializer.WriteValueWeak(value, writer);
|
||||
}
|
||||
catch (SerializationAbortException ex)
|
||||
{
|
||||
endNode = false;
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (endNode)
|
||||
{
|
||||
writer.EndNode(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IFormatter formatter;
|
||||
|
||||
if (object.ReferenceEquals(type, TypeOf_T))
|
||||
{
|
||||
formatter = GetBaseFormatter(policy);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter = FormatterLocator.GetFormatter(type, policy);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
writer.BeginReferenceNode(name, type, id);
|
||||
formatter.Serialize(value, writer);
|
||||
}
|
||||
catch (SerializationAbortException ex)
|
||||
{
|
||||
endNode = false;
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (endNode)
|
||||
{
|
||||
writer.EndNode(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteInternalReference(name, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a2a43b51cef79fd0e85028650394b55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="DecimalSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="decimal"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Decimal}" />
|
||||
public sealed class DecimalSerializer : Serializer<decimal>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="decimal" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override decimal ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.FloatingPoint || entry == EntryType.Integer)
|
||||
{
|
||||
decimal value;
|
||||
if (reader.ReadDecimal(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.FloatingPoint.ToString() + " or " + EntryType.Integer.ToString() + ", but got entry of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(decimal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="decimal" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, decimal value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteDecimal(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50c67937d611e4749188b838e4cff5dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="DoubleSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="double"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Double}" />
|
||||
public sealed class DoubleSerializer : Serializer<double>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="double" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override double ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.FloatingPoint || entry == EntryType.Integer)
|
||||
{
|
||||
double value;
|
||||
if (reader.ReadDouble(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.FloatingPoint.ToString() + " or " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(double);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="double" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, double value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteDouble(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fc4716f683bc313c24bfa537cdd97f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,115 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="EnumSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer for all enums.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the enum to serialize and deserialize.</typeparam>
|
||||
/// <seealso cref="Serializer{T}" />
|
||||
#if CSHARP_7_3_OR_NEWER
|
||||
public unsafe sealed class EnumSerializer<T> : Serializer<T> where T : unmanaged, Enum
|
||||
{
|
||||
private static readonly int SizeOf_T = sizeof(T);
|
||||
#else
|
||||
public sealed class EnumSerializer<T> : Serializer<T>
|
||||
{
|
||||
static EnumSerializer()
|
||||
{
|
||||
if (typeof(T).IsEnum == false)
|
||||
{
|
||||
throw new Exception("Type " + typeof(T).Name + " is not an enum.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Reads an enum value of type <see cref="T" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override T ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
ulong value;
|
||||
if (reader.ReadUInt64(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
|
||||
#if CSHARP_7_3_OR_NEWER
|
||||
return *(T*)&value;
|
||||
#else
|
||||
return (T)Enum.ToObject(typeof(T), value);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an enum value of type <see cref="T" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, T value, IDataWriter writer)
|
||||
{
|
||||
ulong ul;
|
||||
|
||||
FireOnSerializedType();
|
||||
|
||||
#if CSHARP_7_3_OR_NEWER
|
||||
byte* toPtr = (byte*)&ul;
|
||||
byte* fromPtr = (byte*)&value;
|
||||
|
||||
for (int i = 0; i < SizeOf_T; i++)
|
||||
{
|
||||
*toPtr++ = *fromPtr++;
|
||||
}
|
||||
#else
|
||||
try
|
||||
{
|
||||
ul = Convert.ToUInt64(value as Enum);
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
ul = (ulong)Convert.ToInt64(value as Enum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
writer.WriteUInt64(name, ul);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a5d23b139cd8e692702aa431b071d07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="GuidSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="Guid"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Guid}" />
|
||||
public sealed class GuidSerializer : Serializer<Guid>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="Guid" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override Guid ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Guid)
|
||||
{
|
||||
Guid value;
|
||||
if (reader.ReadGuid(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Guid.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(Guid);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="Guid" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, Guid value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteGuid(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19dcfa9f6a40979fc2b6c3ae0f24b67c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Int16Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="short"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Int16}" />
|
||||
public sealed class Int16Serializer : Serializer<short>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="short" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override short ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
short value;
|
||||
if (reader.ReadInt16(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(short);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="short" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, short value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteInt16(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d280b44f7c75a9a18484a84745998130
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Int32Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="int"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Int32}" />
|
||||
public sealed class Int32Serializer : Serializer<int>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="int" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override int ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
int value;
|
||||
if (reader.ReadInt32(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(int);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="int" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, int value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteInt32(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eafebb70813195e03b1ba467931eb686
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Int64Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="long"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Int64}" />
|
||||
public sealed class Int64Serializer : Serializer<long>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="long" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override long ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
long value;
|
||||
if (reader.ReadInt64(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(long);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="long" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, long value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteInt64(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afe45c48508431a62aba886d943d8501
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="IntPtrSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="IntPtr"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.IntPtr}" />
|
||||
public sealed class IntPtrSerializer : Serializer<IntPtr>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="IntPtr" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override IntPtr ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
long value;
|
||||
if (reader.ReadInt64(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return new IntPtr(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(IntPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="IntPtr" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, IntPtr value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteInt64(name, (long)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ccaffe3090611c2ada67d49cf834771
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SByteSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="sbyte"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.SByte}" />
|
||||
public sealed class SByteSerializer : Serializer<sbyte>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="sbyte" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override sbyte ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
sbyte value;
|
||||
if (reader.ReadSByte(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(sbyte);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="sbyte" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, sbyte value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteSByte(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88f3ec418fdfdd7eabd6134f1de91991
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,311 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using VRC.Udon.Serialization.OdinSerializer.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary>
|
||||
/// Serializes and deserializes a given type, and wraps serialization and deserialization with all the proper calls to free formatters from tedious boilerplate.
|
||||
/// <para />
|
||||
/// Whenever serializing or deserializing anything, it is *strongly recommended* to use <see cref="Serializer.Get{T}"/> to get a proper wrapping serializer for that type.
|
||||
/// <para />
|
||||
/// NOTE: This class should NOT be inherited from; it is hard-coded into the system.
|
||||
/// <para />
|
||||
/// To extend the serialization system, instead create custom formatters, which are used by the <see cref="ComplexTypeSerializer{T}"/> class.
|
||||
/// </summary>
|
||||
public abstract class Serializer
|
||||
{
|
||||
private static readonly Dictionary<Type, Type> PrimitiveReaderWriterTypes = new Dictionary<Type, Type>()
|
||||
{
|
||||
{ typeof(char), typeof(CharSerializer) },
|
||||
{ typeof(string), typeof(StringSerializer) },
|
||||
{ typeof(sbyte), typeof(SByteSerializer) },
|
||||
{ typeof(short), typeof(Int16Serializer) },
|
||||
{ typeof(int), typeof(Int32Serializer) },
|
||||
{ typeof(long), typeof(Int64Serializer) },
|
||||
{ typeof(byte), typeof(ByteSerializer) },
|
||||
{ typeof(ushort), typeof(UInt16Serializer) },
|
||||
{ typeof(uint), typeof(UInt32Serializer) },
|
||||
{ typeof(ulong), typeof(UInt64Serializer) },
|
||||
{ typeof(decimal), typeof(DecimalSerializer) },
|
||||
{ typeof(bool), typeof(BooleanSerializer) },
|
||||
{ typeof(float), typeof(SingleSerializer) },
|
||||
{ typeof(double), typeof(DoubleSerializer) },
|
||||
{ typeof(IntPtr), typeof(IntPtrSerializer) },
|
||||
{ typeof(UIntPtr), typeof(UIntPtrSerializer) },
|
||||
{ typeof(Guid), typeof(GuidSerializer) }
|
||||
};
|
||||
|
||||
private static readonly object LOCK = new object();
|
||||
|
||||
private static readonly Dictionary<Type, Serializer> ReaderWriterCache = new Dictionary<Type, Serializer>(FastTypeComparer.Instance);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Editor-only event that fires whenever a serializer serializes a type.
|
||||
/// </summary>
|
||||
public static event Action<Type> OnSerializedType;
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="OnSerializedType"/> event.
|
||||
/// </summary>
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
protected static void FireOnSerializedType(Type type)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (OnSerializedType != null)
|
||||
{
|
||||
OnSerializedType(type);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Serializer"/> for the given value. If the value is null, it will be treated as a value of type <see cref="object"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get a <see cref="Serializer"/> for.</param>
|
||||
/// <returns>A <see cref="Serializer"/> for the given value.</returns>
|
||||
public static Serializer GetForValue(object value)
|
||||
{
|
||||
if (object.ReferenceEquals(value, null))
|
||||
{
|
||||
return Get(typeof(object));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Get(value.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Serializer"/> for type T.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to get a <see cref="Serializer"/> for.</typeparam>
|
||||
/// <returns>A <see cref="Serializer"/> for type T.</returns>
|
||||
public static Serializer<T> Get<T>()
|
||||
{
|
||||
return (Serializer<T>)Serializer.Get(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Serializer"/> for the given type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to get a <see cref="Serializer"/> for.</param>
|
||||
/// <returns>A <see cref="Serializer"/> for the given type.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">The type argument is null.</exception>
|
||||
public static Serializer Get(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
Serializer result;
|
||||
|
||||
lock (LOCK)
|
||||
{
|
||||
if (ReaderWriterCache.TryGetValue(type, out result) == false)
|
||||
{
|
||||
result = Create(type);
|
||||
ReaderWriterCache.Add(type, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a value weakly, casting it into object. Use this method if you don't know what type you're going to be working with at compile time.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>The value which has been read.</returns>
|
||||
public abstract object ReadValueWeak(IDataReader reader);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a weakly typed value. Use this method if you don't know what type you're going to be working with at compile time.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public void WriteValueWeak(object value, IDataWriter writer)
|
||||
{
|
||||
this.WriteValueWeak(null, value, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a weakly typed value with a given name. Use this method if you don't know what type you're going to be working with at compile time.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public abstract void WriteValueWeak(string name, object value, IDataWriter writer);
|
||||
|
||||
private static Serializer Create(Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
Type resultType = null;
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
resultType = typeof(EnumSerializer<>).MakeGenericType(type);
|
||||
}
|
||||
else if (FormatterUtilities.IsPrimitiveType(type))
|
||||
{
|
||||
try
|
||||
{
|
||||
resultType = PrimitiveReaderWriterTypes[type];
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Failed to find primitive serializer for " + type.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resultType = typeof(ComplexTypeSerializer<>).MakeGenericType(type);
|
||||
}
|
||||
|
||||
return (Serializer)Activator.CreateInstance(resultType);
|
||||
}
|
||||
// System.ExecutionEngineException is marked obsolete in .NET 4.6
|
||||
// That's all very good for .NET, but Unity still uses it!
|
||||
#pragma warning disable 618
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
if (ex.GetBaseException() is ExecutionEngineException)
|
||||
{
|
||||
LogAOTError(type, ex.GetBaseException() as ExecutionEngineException);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
catch (TypeInitializationException ex)
|
||||
{
|
||||
if (ex.GetBaseException() is ExecutionEngineException)
|
||||
{
|
||||
LogAOTError(type, ex.GetBaseException() as ExecutionEngineException);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
catch (ExecutionEngineException ex)
|
||||
{
|
||||
LogAOTError(type, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LogAOTError(Type type, ExecutionEngineException ex)
|
||||
{
|
||||
UnityEngine.Debug.LogError("No AOT serializer was pre-generated for the type '" + type.GetNiceFullName() + "'. " +
|
||||
"Please use Odin's AOT generation feature to generate an AOT dll before building, and ensure that '" +
|
||||
type.GetNiceFullName() + "' is in the list of supported types after a scan. If it is not, please " +
|
||||
"report an issue and add it to the list manually.");
|
||||
|
||||
throw new SerializationAbortException("AOT serializer was missing for type '" + type.GetNiceFullName() + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 618
|
||||
|
||||
/// <summary>
|
||||
/// Serializes and deserializes the type <see cref="T"/>, and wraps serialization and deserialization with all the proper calls to free formatters from tedious boilerplate.
|
||||
/// <para />
|
||||
/// Whenever serializing or deserializing anything, it is *strongly recommended* to use <see cref="Serializer.Get{T}"/> to get a proper wrapping serializer for that type.
|
||||
/// <para />
|
||||
/// NOTE: This class should NOT be inherited from; it is hard-coded into the system.
|
||||
/// <para />
|
||||
/// To extend the serialization system, instead create custom formatters, which are used by the <see cref="ComplexTypeSerializer{T}"/> class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type which the <see cref="Serializer{T}"/> can serialize and deserialize.</typeparam>
|
||||
public abstract class Serializer<T> : Serializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="T"/> weakly, casting it into object. Use this method if you don't know what type you're going to be working with at compile time.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override object ReadValueWeak(IDataReader reader)
|
||||
{
|
||||
return this.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a weakly typed value of type <see cref="T"/> with a given name. Use this method if you don't know what type you're going to be working with at compile time.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValueWeak(string name, object value, IDataWriter writer)
|
||||
{
|
||||
this.WriteValue(name, (T)value, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="T"/>.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public abstract T ReadValue(IDataReader reader);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="T"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public void WriteValue(T value, IDataWriter writer)
|
||||
{
|
||||
this.WriteValue(null, value, writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="T"/> with a given name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public abstract void WriteValue(string name, T value, IDataWriter writer);
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="OnSerializedType"/> event with the T generic argument of the serializer.
|
||||
/// </summary>
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
protected static void FireOnSerializedType()
|
||||
{
|
||||
FireOnSerializedType(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29261eaea99f2d34c42cdc0b04f95daa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SingleSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="float"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.Single}" />
|
||||
public sealed class SingleSerializer : Serializer<float>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="float" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override float ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.FloatingPoint || entry == EntryType.Integer)
|
||||
{
|
||||
float value;
|
||||
if (reader.ReadSingle(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.FloatingPoint.ToString() + " or " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(float);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="float" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, float value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteSingle(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aa356971fd0b66eb59875b278fa7f03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="StringSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="string"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.String}" />
|
||||
public sealed class StringSerializer : Serializer<string>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="string" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override string ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.String)
|
||||
{
|
||||
string value;
|
||||
if (reader.ReadString(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else if (entry == EntryType.Null)
|
||||
{
|
||||
if (reader.ReadNull() == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.String.ToString() + " or " + EntryType.Null.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(string);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="string" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, string value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNull(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteString(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85996580a8691185d06ec342c5c43747
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UInt16Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="ushort"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.UInt16}" />
|
||||
public sealed class UInt16Serializer : Serializer<ushort>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="ushort" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override ushort ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
ushort value;
|
||||
if (reader.ReadUInt16(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(ushort);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="ulong" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, ushort value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteUInt16(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3936194ea64890e11a7db8474eb0bbcf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UInt32Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="uint"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.UInt32}" />
|
||||
public sealed class UInt32Serializer : Serializer<uint>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="uint" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override uint ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
uint value;
|
||||
if (reader.ReadUInt32(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(uint);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="uint" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, uint value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteUInt32(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f30e426f88b471e498dd1853b7bbaee6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UInt64Serializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="ulong"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.UInt64}" />
|
||||
public sealed class UInt64Serializer : Serializer<ulong>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="ulong" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override ulong ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
ulong value;
|
||||
if (reader.ReadUInt64(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(ulong);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="ulong" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, ulong value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteUInt64(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f55c085325e12800428d01e3535cb297
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="IntPtrSerializer.cs" company="Sirenix IVS">
|
||||
// Copyright (c) 2018 Sirenix IVS
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer for the <see cref="UIntPtr"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Serializer{System.UIntPtr}" />
|
||||
public sealed class UIntPtrSerializer : Serializer<UIntPtr>
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a value of type <see cref="UIntPtr" />.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
/// <returns>
|
||||
/// The value which has been read.
|
||||
/// </returns>
|
||||
public override UIntPtr ReadValue(IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
var entry = reader.PeekEntry(out name);
|
||||
|
||||
if (entry == EntryType.Integer)
|
||||
{
|
||||
ulong value;
|
||||
if (reader.ReadUInt64(out value) == false)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read entry '" + name + "' of type " + entry.ToString());
|
||||
}
|
||||
return new UIntPtr(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Expected entry of type " + EntryType.Integer.ToString() + ", but got entry '" + name + "' of type " + entry.ToString());
|
||||
reader.SkipEntry();
|
||||
return default(UIntPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a value of type <see cref="UIntPtr" />.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the value to write.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
public override void WriteValue(string name, UIntPtr value, IDataWriter writer)
|
||||
{
|
||||
FireOnSerializedType();
|
||||
writer.WriteUInt64(name, (ulong)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ee9dd19c234e4b16c835b9188459e36
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user