Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 283d955e2208d4ad5ab108cd26f8c25b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class LooseAssemblyNameConverter : fsDirectConverter
|
||||
{
|
||||
public override Type ModelType => typeof(LooseAssemblyName);
|
||||
|
||||
public override object CreateInstance(fsData data, Type storageType)
|
||||
{
|
||||
return new object();
|
||||
}
|
||||
|
||||
public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType)
|
||||
{
|
||||
serialized = new fsData(((LooseAssemblyName)instance).name);
|
||||
|
||||
return fsResult.Success;
|
||||
}
|
||||
|
||||
public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType)
|
||||
{
|
||||
if (!data.IsString)
|
||||
{
|
||||
return fsResult.Fail("Expected string in " + data);
|
||||
}
|
||||
|
||||
instance = new LooseAssemblyName(data.AsString);
|
||||
|
||||
return fsResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6bc3b7ece49c6442d84ab192cce83e3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class NamespaceConverter : fsDirectConverter
|
||||
{
|
||||
public override Type ModelType => typeof(Namespace);
|
||||
|
||||
public override object CreateInstance(fsData data, Type storageType)
|
||||
{
|
||||
return new object();
|
||||
}
|
||||
|
||||
public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType)
|
||||
{
|
||||
serialized = new fsData(((Namespace)instance).FullName);
|
||||
|
||||
return fsResult.Success;
|
||||
}
|
||||
|
||||
public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType)
|
||||
{
|
||||
if (!data.IsString)
|
||||
{
|
||||
return fsResult.Fail("Expected string in " + data);
|
||||
}
|
||||
|
||||
instance = Namespace.FromFullName(data.AsString);
|
||||
|
||||
return fsResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e01cdd8435cb44f0c9756e6e0de8c548
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class Ray2DConverter : fsDirectConverter<Ray2D>
|
||||
{
|
||||
protected override fsResult DoSerialize(Ray2D model, Dictionary<string, fsData> serialized)
|
||||
{
|
||||
var result = fsResult.Success;
|
||||
|
||||
result += SerializeMember(serialized, null, "origin", model.origin);
|
||||
result += SerializeMember(serialized, null, "direction", model.direction);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override fsResult DoDeserialize(Dictionary<string, fsData> data, ref Ray2D model)
|
||||
{
|
||||
var result = fsResult.Success;
|
||||
|
||||
var origin = model.origin;
|
||||
result += DeserializeMember(data, null, "origin", out origin);
|
||||
model.origin = origin;
|
||||
|
||||
var direction = model.direction;
|
||||
result += DeserializeMember(data, null, "direction", out direction);
|
||||
model.direction = direction;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override object CreateInstance(fsData data, Type storageType)
|
||||
{
|
||||
return new Ray2D();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 94661dc2058024cd495360ea96be84a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class RayConverter : fsDirectConverter<Ray>
|
||||
{
|
||||
protected override fsResult DoSerialize(Ray model, Dictionary<string, fsData> serialized)
|
||||
{
|
||||
var result = fsResult.Success;
|
||||
|
||||
result += SerializeMember(serialized, null, "origin", model.origin);
|
||||
result += SerializeMember(serialized, null, "direction", model.direction);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override fsResult DoDeserialize(Dictionary<string, fsData> data, ref Ray model)
|
||||
{
|
||||
var result = fsResult.Success;
|
||||
|
||||
var origin = model.origin;
|
||||
result += DeserializeMember(data, null, "origin", out origin);
|
||||
model.origin = origin;
|
||||
|
||||
var direction = model.direction;
|
||||
result += DeserializeMember(data, null, "direction", out direction);
|
||||
model.direction = direction;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override object CreateInstance(fsData data, Type storageType)
|
||||
{
|
||||
return new Ray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09866f522fd194ad594f316ca5a60535
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class UnityObjectConverter : fsConverter
|
||||
{
|
||||
private List<UnityObject> objectReferences => Serializer.Context.Get<List<UnityObject>>();
|
||||
|
||||
public override bool CanProcess(Type type)
|
||||
{
|
||||
return typeof(UnityObject).IsAssignableFrom(type);
|
||||
}
|
||||
|
||||
public override bool RequestCycleSupport(Type storageType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool RequestInheritanceSupport(Type storageType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType)
|
||||
{
|
||||
var unityObject = (UnityObject)instance;
|
||||
var index = objectReferences.Count;
|
||||
serialized = new fsData(index);
|
||||
objectReferences.Add(unityObject);
|
||||
//Debug.Log($"<color=#88FF00>Serializing:\n<b>#{index}: {unityObject?.GetType().Name} [{unityObject?.GetHashCode()}]</b></color>");
|
||||
return fsResult.Success;
|
||||
}
|
||||
|
||||
public override fsResult TryDeserialize(fsData storage, ref object instance, Type storageType)
|
||||
{
|
||||
var index = (int)storage.AsInt64;
|
||||
|
||||
var result = fsResult.Success;
|
||||
|
||||
if (index >= 0 && index < objectReferences.Count)
|
||||
{
|
||||
var uo = objectReferences[index];
|
||||
instance = uo;
|
||||
|
||||
//Debug.Log($"<color=#FF8800>Deserializing:\n<b>#{index}: {instance?.GetType().Name} [{instance?.GetHashCode()}]</b></color>");
|
||||
|
||||
if (instance != null && !storageType.IsInstanceOfType(instance))
|
||||
{
|
||||
// Skip the error message if it's just that the instance couldn't be deserialized anymore
|
||||
// and it became a pseudo-null UnityEngine.Object, which seems to be a new thing in Unity 2018.3.
|
||||
// This can happen, for instance, when a applying changes to a prefab that contained a scene object.
|
||||
// IsUnityNull can't be called off the main thread, so we hack it with GetHashCode.
|
||||
if (uo.GetHashCode() != 0)
|
||||
{
|
||||
result.AddMessage($"Object reference at index #{index} does not match target type ({instance.GetType()} != {storageType}). Defaulting to null.");
|
||||
}
|
||||
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AddMessage($"No object reference provided at index #{index}. Defaulting to null.");
|
||||
instance = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override object CreateInstance(fsData data, Type storageType)
|
||||
{
|
||||
return storageType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f99d20d0d37dc4411a4b9303b7081cc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,104 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[IncludeInSettings(false)]
|
||||
public sealed class DictionaryAsset : LudiqScriptableObject, IDictionary<string, object>
|
||||
{
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return dictionary[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize]
|
||||
public Dictionary<string, object> dictionary { get; private set; } = new Dictionary<string, object>();
|
||||
|
||||
public int Count => dictionary.Count;
|
||||
|
||||
public ICollection<string> Keys => dictionary.Keys;
|
||||
|
||||
public ICollection<object> Values => dictionary.Values;
|
||||
|
||||
bool ICollection<KeyValuePair<string, object>>.IsReadOnly => ((ICollection<KeyValuePair<string, object>>)dictionary).IsReadOnly;
|
||||
|
||||
protected override void OnAfterDeserialize()
|
||||
{
|
||||
base.OnAfterDeserialize();
|
||||
|
||||
if (dictionary == null)
|
||||
{
|
||||
dictionary = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
dictionary.Clear();
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
public void Add(string key, object value)
|
||||
{
|
||||
dictionary.Add(key, value);
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
return dictionary.Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
return dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
return dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)dictionary).GetEnumerator();
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<string, object>>)dictionary).Add(item);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<string, object>>)dictionary).Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<string, object>>)dictionary).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<string, object>>)dictionary).Remove(item);
|
||||
}
|
||||
|
||||
[ContextMenu("Show Data...")]
|
||||
protected override void ShowData()
|
||||
{
|
||||
base.ShowData();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 65bae8b9f1bd244b3a27e92af4b23b2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class DoNotSerializeAttribute : Attribute
|
||||
{
|
||||
public DoNotSerializeAttribute() { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db30954ac2e284a7390463bc6ea7da20
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
// The dependency must always implement the receiver,
|
||||
// because it must always notify the dependency manager of its deserialization.
|
||||
public interface ISerializationDependency : ISerializationCallbackReceiver { }
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 74cb3a48f49084b4ea7970304b3889a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface ISerializationDepender : ISerializationCallbackReceiver
|
||||
{
|
||||
IEnumerable<ISerializationDependency> deserializationDependencies { get; }
|
||||
|
||||
void OnAfterDependenciesDeserialized();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ab267aba735c944839ba79767a1955e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,344 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using Debug = UnityEngine.Debug;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public static class Serialization
|
||||
{
|
||||
static Serialization()
|
||||
{
|
||||
freeOperations = new HashSet<SerializationOperation>();
|
||||
busyOperations = new HashSet<SerializationOperation>();
|
||||
}
|
||||
|
||||
public const string ConstructorWarning = "This parameterless constructor is only made public for serialization. Use another constructor instead.";
|
||||
|
||||
private static readonly HashSet<SerializationOperation> freeOperations;
|
||||
private static readonly HashSet<SerializationOperation> busyOperations;
|
||||
|
||||
private static readonly object @lock = new object();
|
||||
|
||||
public static bool isUnitySerializing { get; set; }
|
||||
|
||||
public static bool isCustomSerializing => busyOperations.Count > 0;
|
||||
|
||||
public static bool isSerializing => isUnitySerializing || isCustomSerializing;
|
||||
|
||||
private static SerializationOperation StartOperation()
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
if (freeOperations.Count == 0)
|
||||
{
|
||||
freeOperations.Add(new SerializationOperation());
|
||||
}
|
||||
|
||||
var operation = freeOperations.First();
|
||||
freeOperations.Remove(operation);
|
||||
busyOperations.Add(operation);
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EndOperation(SerializationOperation operation)
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
if (!busyOperations.Contains(operation))
|
||||
{
|
||||
throw new InvalidOperationException("Trying to finish an operation that isn't started.");
|
||||
}
|
||||
|
||||
operation.Reset();
|
||||
busyOperations.Remove(operation);
|
||||
freeOperations.Add(operation);
|
||||
}
|
||||
}
|
||||
|
||||
public static T CloneViaSerialization<T>(this T value, bool forceReflected = false)
|
||||
{
|
||||
return (T)Deserialize(Serialize(value, forceReflected), forceReflected);
|
||||
}
|
||||
|
||||
public static void CloneViaSerializationInto<TSource, TDestination>(this TSource value, ref TDestination instance, bool forceReflected = false)
|
||||
where TDestination : TSource
|
||||
{
|
||||
object _instance = instance;
|
||||
DeserializeInto(Serialize(value, forceReflected), ref _instance, forceReflected);
|
||||
}
|
||||
|
||||
public static SerializationData Serialize(this object value, bool forceReflected = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var operation = StartOperation();
|
||||
var json = SerializeJson(operation.serializer, value, forceReflected);
|
||||
var objectReferences = operation.objectReferences.ToArray();
|
||||
var data = new SerializationData(json, objectReferences);
|
||||
EndOperation(operation);
|
||||
|
||||
#if DEBUG_SERIALIZATION
|
||||
Debug.Log(data.ToString($"<color=#88FF00>Serialized: <b>{value?.GetType().Name ?? "null"} [{value?.GetHashCode().ToString() ?? "N/A"}]</b></color>"));
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new SerializationException($"Serialization of '{value?.GetType().ToString() ?? "null"}' failed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeserializeInto(this SerializationData data, ref object instance, bool forceReflected = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(data.json))
|
||||
{
|
||||
instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG_SERIALIZATION
|
||||
Debug.Log(data.ToString($"<color=#3388FF>Deserializing into: <b>{instance?.GetType().Name ?? "null"} [{instance?.GetHashCode().ToString() ?? "N/A"}]</b></color>"));
|
||||
#endif
|
||||
|
||||
var operation = StartOperation();
|
||||
operation.objectReferences.AddRange(data.objectReferences);
|
||||
DeserializeJson(operation.serializer, data.json, ref instance, forceReflected);
|
||||
EndOperation(operation);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.LogWarning(data.ToString("Deserialization Failure Data"), instance as UnityObject);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Debug.LogWarning("Failed to log deserialization failure data:\n" + ex2, instance as UnityObject);
|
||||
}
|
||||
|
||||
throw new SerializationException($"Deserialization into '{instance?.GetType().ToString() ?? "null"}' failed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static object Deserialize(this SerializationData data, bool forceReflected = false)
|
||||
{
|
||||
object instance = null;
|
||||
DeserializeInto(data, ref instance, forceReflected);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static string SerializeJson(fsSerializer serializer, object instance, bool forceReflected)
|
||||
{
|
||||
using (ProfilingUtility.SampleBlock("SerializeJson"))
|
||||
{
|
||||
fsData data;
|
||||
|
||||
fsResult result;
|
||||
|
||||
if (forceReflected)
|
||||
{
|
||||
result = serializer.TrySerialize(instance.GetType(), typeof(fsReflectedConverter), instance, out data);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = serializer.TrySerialize(instance, out data);
|
||||
}
|
||||
|
||||
HandleResult("Serialization", result, instance as UnityObject);
|
||||
|
||||
return fsJsonPrinter.CompressedJson(data);
|
||||
}
|
||||
}
|
||||
|
||||
private static fsResult DeserializeJsonUtil(fsSerializer serializer, string json, ref object instance, bool forceReflected)
|
||||
{
|
||||
var fsData = fsJsonParser.Parse(json);
|
||||
|
||||
fsResult result;
|
||||
|
||||
if (forceReflected)
|
||||
{
|
||||
result = serializer.TryDeserialize(fsData, instance.GetType(), typeof(fsReflectedConverter), ref instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = serializer.TryDeserialize(fsData, ref instance);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void DeserializeJson(fsSerializer serializer, string json, ref object instance, bool forceReflected)
|
||||
{
|
||||
using (ProfilingUtility.SampleBlock("DeserializeJson"))
|
||||
{
|
||||
fsResult result = DeserializeJsonUtil(serializer, json, ref instance, forceReflected);
|
||||
|
||||
HandleResult("Deserialization", result, instance as UnityObject);
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleResult(string label, fsResult result, UnityObject context = null)
|
||||
{
|
||||
result.AssertSuccess();
|
||||
|
||||
if (result.HasWarnings)
|
||||
{
|
||||
foreach (var warning in result.RawMessages)
|
||||
{
|
||||
Debug.LogWarning($"[{label}] {warning}\n", context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string PrettyPrint(string json)
|
||||
{
|
||||
return fsJsonPrinter.PrettyJson(fsJsonParser.Parse(json));
|
||||
}
|
||||
|
||||
#region Dependencies
|
||||
|
||||
private static readonly HashSet<ISerializationDepender> awaitingDependers = new HashSet<ISerializationDepender>();
|
||||
|
||||
private static readonly HashSet<object> availableDependencies = new HashSet<object>();
|
||||
|
||||
private static object WeakenSerializationDependencyReference(ISerializationDependency dependency)
|
||||
{
|
||||
/*
|
||||
We need to use weak references to UnityEngine.Object dependencies, because otherwise
|
||||
Unity will consider them to be always used, and never call OnDisable() on them when unloading,
|
||||
which in turn will never unregister them from our available dependencies.
|
||||
Using WeakReference is overkill and not actually helpful. We don't need to access the actual dependency
|
||||
object later on, and anyway the only way we could immmutably compare for equality in the hash set is based on the
|
||||
original hash code, which is not guaranteed to be unique... Except for UnityEngine.Objects,
|
||||
in which case the hash code is the native instance ID, which is guaranteed to be unique within a given assembly session.
|
||||
https://support.ludiq.io/communities/5/topics/4150-flowmachine-memory-leak#comment-11626
|
||||
*/
|
||||
if (dependency is UnityObject uo)
|
||||
{
|
||||
return uo.GetHashCode();
|
||||
}
|
||||
else
|
||||
{
|
||||
// In this case, we can't actually weaken the reference.
|
||||
// But it shouldn't be a problem, because in non-UO cases, the
|
||||
// dependency should be able to unregister itself as it doesn't rely
|
||||
// on the native unload callbacks of unused assets.
|
||||
return dependency;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AwaitDependencies(ISerializationDepender depender)
|
||||
{
|
||||
awaitingDependers.Add(depender);
|
||||
|
||||
CheckIfDependenciesMet(depender);
|
||||
}
|
||||
|
||||
public static void NotifyDependencyDeserializing(ISerializationDependency dependency)
|
||||
{
|
||||
NotifyDependencyUnavailable(dependency);
|
||||
}
|
||||
|
||||
public static void NotifyDependencyDeserialized(ISerializationDependency dependency)
|
||||
{
|
||||
NotifyDependencyAvailable(dependency);
|
||||
}
|
||||
|
||||
public static void NotifyDependencyUnavailable(ISerializationDependency dependency)
|
||||
{
|
||||
availableDependencies.Remove(WeakenSerializationDependencyReference(dependency));
|
||||
}
|
||||
|
||||
public static void NotifyDependencyAvailable(ISerializationDependency dependency)
|
||||
{
|
||||
availableDependencies.Add(WeakenSerializationDependencyReference(dependency));
|
||||
|
||||
foreach (var awaitingDepender in awaitingDependers.ToArray())
|
||||
{
|
||||
if (!awaitingDependers.Contains(awaitingDepender))
|
||||
{
|
||||
// In case the depender was already handled by a recursive
|
||||
// dependency via OnAfterDependenciesDeserialized,
|
||||
// we skip it. This is necessary because we duplicated
|
||||
// the set to safely iterate over it with removal.
|
||||
//
|
||||
// This should prevent OnAfterDependenciesDeserialized from
|
||||
// running twice on any given depender in a single deserialization
|
||||
// operation.
|
||||
continue;
|
||||
}
|
||||
|
||||
CheckIfDependenciesMet(awaitingDepender);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckIfDependenciesMet(ISerializationDepender depender)
|
||||
{
|
||||
var areDependenciesMet = true;
|
||||
|
||||
foreach (var requiredDependency in depender.deserializationDependencies)
|
||||
{
|
||||
var weakRequiredDependency = WeakenSerializationDependencyReference(requiredDependency);
|
||||
|
||||
if (!availableDependencies.Contains(weakRequiredDependency))
|
||||
{
|
||||
areDependenciesMet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (areDependenciesMet)
|
||||
{
|
||||
awaitingDependers.Remove(depender);
|
||||
|
||||
depender.OnAfterDependenciesDeserialized();
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogStuckDependers()
|
||||
{
|
||||
if (awaitingDependers.Any())
|
||||
{
|
||||
var message = awaitingDependers.Count + " awaiting dependers: \n";
|
||||
|
||||
foreach (var depender in awaitingDependers)
|
||||
{
|
||||
HashSet<object> missingDependencies = new HashSet<object>();
|
||||
|
||||
foreach (var requiredDependency in depender.deserializationDependencies)
|
||||
{
|
||||
var weakRequiredDependency = WeakenSerializationDependencyReference(requiredDependency);
|
||||
|
||||
if (!availableDependencies.Contains(weakRequiredDependency))
|
||||
{
|
||||
missingDependencies.Add(requiredDependency);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
message += $"{depender} is missing {missingDependencies.ToCommaSeparatedString()}\n";
|
||||
}
|
||||
|
||||
Debug.LogWarning(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("No stuck awaiting depender.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 676514219067342ecad392d89dedb5d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Serializable]
|
||||
public struct SerializationData
|
||||
{
|
||||
[SerializeField]
|
||||
private string _json;
|
||||
|
||||
public string json => _json;
|
||||
|
||||
[SerializeField]
|
||||
private UnityObject[] _objectReferences;
|
||||
|
||||
public UnityObject[] objectReferences => _objectReferences;
|
||||
|
||||
#if DEBUG_SERIALIZATION
|
||||
[SerializeField]
|
||||
private string _guid;
|
||||
|
||||
public string guid => _guid;
|
||||
#endif
|
||||
|
||||
public SerializationData(string json, IEnumerable<UnityObject> objectReferences)
|
||||
{
|
||||
_json = json;
|
||||
_objectReferences = objectReferences?.ToArray() ?? Empty<UnityObject>.array;
|
||||
|
||||
#if DEBUG_SERIALIZATION
|
||||
_guid = Guid.NewGuid().ToString();
|
||||
#endif
|
||||
}
|
||||
|
||||
public SerializationData(string json, params UnityObject[] objectReferences) : this(json, ((IEnumerable<UnityObject>)objectReferences)) { }
|
||||
|
||||
public string ToString(string title)
|
||||
{
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(title))
|
||||
{
|
||||
#if DEBUG_SERIALIZATION
|
||||
writer.WriteLine(title + $" ({guid})");
|
||||
#else
|
||||
|
||||
writer.WriteLine(title);
|
||||
#endif
|
||||
writer.WriteLine();
|
||||
}
|
||||
#if DEBUG_SERIALIZATION
|
||||
else
|
||||
{
|
||||
writer.WriteLine(guid);
|
||||
writer.WriteLine();
|
||||
}
|
||||
#endif
|
||||
|
||||
writer.WriteLine("Object References: ");
|
||||
|
||||
if (objectReferences.Length == 0)
|
||||
{
|
||||
writer.WriteLine("(None)");
|
||||
}
|
||||
else
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
foreach (var objectReference in objectReferences)
|
||||
{
|
||||
if (objectReference.IsUnityNull())
|
||||
{
|
||||
writer.WriteLine($"{index}: null");
|
||||
}
|
||||
else if (UnityThread.allowsAPI)
|
||||
{
|
||||
writer.WriteLine($"{index}: {objectReference.GetType().FullName} [{objectReference.GetHashCode()}] \"{objectReference.name}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine($"{index}: {objectReference.GetType().FullName} [{objectReference.GetHashCode()}]");
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine();
|
||||
writer.WriteLine("JSON: ");
|
||||
writer.WriteLine(Serialization.PrettyPrint(json));
|
||||
|
||||
return writer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(null);
|
||||
}
|
||||
|
||||
public void ShowString(string title = null)
|
||||
{
|
||||
var dataPath = Path.GetTempPath() + Guid.NewGuid() + ".json";
|
||||
File.WriteAllText(dataPath, ToString(title));
|
||||
Process.Start(dataPath);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: feb071ad285b241749d00ecf6335cb61
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,29 @@
|
|||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class SerializationOperation
|
||||
{
|
||||
public SerializationOperation()
|
||||
{
|
||||
objectReferences = new List<UnityObject>();
|
||||
serializer = new fsSerializer();
|
||||
serializer.AddConverter(new UnityObjectConverter());
|
||||
serializer.AddConverter(new RayConverter());
|
||||
serializer.AddConverter(new Ray2DConverter());
|
||||
serializer.AddConverter(new NamespaceConverter());
|
||||
serializer.AddConverter(new LooseAssemblyNameConverter());
|
||||
serializer.Context.Set(objectReferences);
|
||||
}
|
||||
|
||||
public fsSerializer serializer { get; private set; }
|
||||
public List<UnityObject> objectReferences { get; private set; }
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
objectReferences.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c3ff50e5514fb40fa967a7e53e3ca8ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class SerializationVersionAttribute : fsObjectAttribute
|
||||
{
|
||||
public SerializationVersionAttribute(string versionString, params Type[] previousModels) : base(versionString, previousModels) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9ed846b2a34e5470fae51b61586f2190
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
using Unity.VisualScripting.FullSerializer;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class SerializeAsAttribute : fsPropertyAttribute
|
||||
{
|
||||
public SerializeAsAttribute(string name) : base(name) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: feefb3a9e4a2544e292f1f9a9c259bcb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public class SerializeAttribute : Attribute
|
||||
{
|
||||
public SerializeAttribute() { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8f0e86da875e743bab78f0094f19b1f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue