From d1338ecabfbf055aaef2145ae36e77785f5377c6 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 10 Mar 2020 13:14:54 +0100 Subject: [PATCH 01/64] Add serialization core --- .../Editor/Serialization.meta | 3 + .../Editor/Serialization/FakeJsonObject.cs | 33 +++ .../Serialization/FakeJsonObject.cs.meta | 3 + .../Serialization/FakeScriptableObject.cs | 17 ++ .../FakeScriptableObject.cs.meta | 3 + .../Editor/Serialization/JsonObject.cs | 55 ++++ .../Editor/Serialization/JsonObject.cs.meta | 3 + .../Editor/Serialization/JsonRef.cs | 72 ++++++ .../Editor/Serialization/JsonRef.cs.meta | 3 + .../Editor/Serialization/MultiJson.cs | 19 ++ .../Editor/Serialization/MultiJson.cs.meta | 3 + .../Editor/Serialization/MultiJsonEntry.cs | 42 ++++ .../Serialization/MultiJsonEntry.cs.meta | 3 + .../Editor/Serialization/MultiJsonInternal.cs | 235 ++++++++++++++++++ .../Serialization/MultiJsonInternal.cs.meta | 3 + .../Serialization/SerializationExtensions.cs | 37 +++ .../SerializationExtensions.cs.meta | 3 + .../Editor/Serialization/TargetEnumerable.cs | 42 ++++ .../Serialization/TargetEnumerable.cs.meta | 3 + 19 files changed, 582 insertions(+) create mode 100644 com.unity.shadergraph/Editor/Serialization.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/JsonObject.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/JsonObject.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/JsonRef.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/JsonRef.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/MultiJson.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/MultiJson.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs.meta create mode 100644 com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs.meta diff --git a/com.unity.shadergraph/Editor/Serialization.meta b/com.unity.shadergraph/Editor/Serialization.meta new file mode 100644 index 00000000000..58a7c38a18a --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c495761f69a84f0fba9c9bd2b9cbdf86 +timeCreated: 1581413452 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs new file mode 100644 index 00000000000..d5a0c9e521e --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Serialization +{ + [Serializable] + public struct FakeJsonObject + { + [SerializeField] + string m_Type; + + [SerializeField] + string m_Id; + + public string id + { + get => m_Id; + set => m_Id = value; + } + + public string type + { + get => m_Type; + set => m_Type = value; + } + + public void Reset() + { + m_Id = null; + m_Type = null; + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs.meta b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs.meta new file mode 100644 index 00000000000..73262cdd3c8 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dbc783860c76444c874638295f87d551 +timeCreated: 1581604970 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs b/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs new file mode 100644 index 00000000000..4f3c7cb533a --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs @@ -0,0 +1,17 @@ +using System; + +namespace UnityEditor.ShaderGraph.Serialization +{ + [Serializable] + class FakeScriptableObject + { + public T MonoBehaviour; + + public FakeScriptableObject() {} + + public FakeScriptableObject(T value) + { + MonoBehaviour = value; + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta b/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta new file mode 100644 index 00000000000..2554b9600e7 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9e418566a25245bf83c1fed7f9cfe1da +timeCreated: 1581597833 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/JsonObject.cs b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs new file mode 100644 index 00000000000..392a1d2d31b --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs @@ -0,0 +1,55 @@ +using System; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Serialization +{ + [Serializable] + public class JsonObject : ISerializationCallbackReceiver + { + // We have some fields in here to match the output of ScriptableObject. + // This is to prevent introducing big changes to Shader Graph files + // when we make JsonObject inherit ScriptableObject in the future. +#pragma warning disable 414 + [SerializeField] + bool m_Enabled = true; + + [SerializeField] + int m_EditorHideFlags = 0; + + [SerializeField] + string m_Name = default; + + [SerializeField] + string m_EditorClassIdentifier = default; +#pragma warning restore 414 + + [SerializeField] + string m_Type; + + [SerializeField] + string m_Id = Guid.NewGuid().ToString("N"); + + public string id => m_Id; + + public string name + { + get => m_Name; + set => m_Name = value; + } + + void ISerializationCallbackReceiver.OnBeforeSerialize() + { + m_EditorClassIdentifier = $"{GetType().Assembly.GetName().Name}:{GetType().Namespace}:{GetType().Name}"; + m_Type = $"{GetType().FullName}"; + OnBeforeSerialize(); + } + + public virtual void OnBeforeSerialize() { } + + public virtual void OnAfterDeserialize() { } + + public virtual void OnAfterDeserialize(string json) { } + + public virtual void OnAfterMultiDeserialize(string json) { } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/JsonObject.cs.meta b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs.meta new file mode 100644 index 00000000000..b288915e8f6 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f6158a8f15f443948dffa7b689fcf586 +timeCreated: 1581596381 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs new file mode 100644 index 00000000000..fc90276b4d0 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Serialization +{ + [Serializable] + struct JsonRef : ISerializationCallbackReceiver + where T : JsonObject + { + T m_Target; + + [SerializeField] + string m_Id; + + public T target => m_Target; + + public void OnBeforeSerialize() + { + if (MultiJsonInternal.isSerializing && m_Target != null) + { + m_Id = m_Target.id; + + if (MultiJsonInternal.serializedSet.Add(m_Id)) + { + MultiJsonInternal.serializationQueue.Add(m_Target); + } + } + } + + public void OnAfterDeserialize() + { + if (MultiJsonInternal.isDeserializing) + { + try + { + m_Target = (T)MultiJsonInternal.instanceMap[m_Id]; + } + catch (Exception e) + { + // TODO: Allow custom logging function + Debug.LogException(e); + } + } + } + + public static implicit operator T(JsonRef jsonRef) + { + return jsonRef.m_Target; + } + + public static implicit operator JsonRef(T value) + { + return new JsonRef { m_Target = value }; + } + + public bool Equals(JsonRef other) + { + return EqualityComparer.Default.Equals(m_Target, other.m_Target); + } + + public override bool Equals(object obj) + { + return obj is JsonRef other && Equals(other); + } + + public override int GetHashCode() + { + return EqualityComparer.Default.GetHashCode(m_Target); + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs.meta b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs.meta new file mode 100644 index 00000000000..a05c40eba9d --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5b60e52a873c41dcbe02e5482b93d162 +timeCreated: 1581596299 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJson.cs b/com.unity.shadergraph/Editor/Serialization/MultiJson.cs new file mode 100644 index 00000000000..d179abb11b1 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/MultiJson.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Serialization +{ + static class MultiJson + { + public static T Deserialize(string json) where T : JsonObject + { + var entries = MultiJsonInternal.Parse(json); + return (T)MultiJsonInternal.Deserialize(entries); + } + + public static string Serialize(JsonObject mainObject) + { + return MultiJsonInternal.Serialize(mainObject); + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJson.cs.meta b/com.unity.shadergraph/Editor/Serialization/MultiJson.cs.meta new file mode 100644 index 00000000000..642986c179f --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/MultiJson.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1047c74693784ac4b128290963840500 +timeCreated: 1581414722 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs b/com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs new file mode 100644 index 00000000000..b41df660157 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs @@ -0,0 +1,42 @@ +namespace UnityEditor.ShaderGraph.Serialization +{ + struct MultiJsonEntry + { + public string id { get; } + public string type { get; } + public string json { get; } + + public MultiJsonEntry(string type, string id, string json) + { + this.id = id; + this.type = type; + this.json = json; + } + + public bool Equals(MultiJsonEntry other) + { + return id == other.id && type == other.type && json == other.json; + } + + public override bool Equals(object obj) + { + return obj is MultiJsonEntry other && Equals(other); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (id != null ? id.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (type != null ? type.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (json != null ? json.GetHashCode() : 0); + return hashCode; + } + } + + public override string ToString() + { + return $"{nameof(id)}: {id}, {nameof(type)}: {type}, {nameof(json)}:\n{json}"; + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs.meta b/com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs.meta new file mode 100644 index 00000000000..f48b9e9f7be --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonEntry.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f4edc0353630446093713b6b40464e5f +timeCreated: 1581423135 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs new file mode 100644 index 00000000000..f2bd2891a7a --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Serialization +{ + static class MultiJsonInternal + { + static readonly Dictionary k_TypeMap = CreateTypeMap(); + + internal static bool isDeserializing; + + internal static readonly Dictionary instanceMap = new Dictionary(); + + static List s_Entries; + + internal static bool isSerializing; + + internal static readonly List serializationQueue = new List(); + + internal static readonly HashSet serializedSet = new HashSet(); + + static Dictionary CreateTypeMap() + { + var map = new Dictionary(); + foreach (var type in TypeCache.GetTypesDerivedFrom()) + { + if (type.FullName != null) + { + map[type.FullName] = type; + } + } + + foreach (var type in TypeCache.GetTypesWithAttribute(typeof(FormerNameAttribute))) + { + if (type.IsAbstract || !typeof(JsonObject).IsAssignableFrom(type)) + { + continue; + } + + foreach (var attribute in type.GetCustomAttributes(typeof(FormerNameAttribute), false)) + { + var legacyAttribute = (FormerNameAttribute)attribute; + map[legacyAttribute.fullName] = type; + } + } + + return map; + } + + public static List Parse(string str) + { + var result = new List(); + var separatorStr = $"\n\n"; + var startIndex = 0; + var raw = new FakeScriptableObject(); + + while (startIndex < str.Length) + { + var jsonBegin = str.IndexOf("{", startIndex, StringComparison.Ordinal); + if (jsonBegin == -1) + { + break; + } + + var jsonEnd = str.IndexOf(separatorStr, jsonBegin, StringComparison.Ordinal); + if (jsonEnd == -1) + { + jsonEnd = str.LastIndexOf("}", StringComparison.Ordinal) + 1; + } + + var json = str.Substring(jsonBegin, jsonEnd - jsonBegin); + JsonUtility.FromJsonOverwrite(json, raw); + if (string.IsNullOrWhiteSpace(raw.MonoBehaviour.type)) + { + throw new InvalidOperationException("Type is null or whitespace."); + } + result.Add(new MultiJsonEntry(raw.MonoBehaviour.type, raw.MonoBehaviour.id, json)); + raw.MonoBehaviour.Reset(); + + startIndex = jsonEnd + separatorStr.Length; + } + + return result; + } + + public static void Enqueue(JsonObject jsonObject, string json) + { + if (s_Entries == null) + { + throw new InvalidOperationException("Can only Enqueue during JsonObject.OnAfterDeserialize."); + } + + instanceMap.Add(jsonObject.id, jsonObject); + s_Entries.Add(new MultiJsonEntry(jsonObject.GetType().FullName, jsonObject.id, json)); + } + + public static JsonObject CreateInstance(string typeString) + { + if (!k_TypeMap.TryGetValue(typeString, out var type)) + { + return null; + } + return (JsonObject)Activator.CreateInstance(type, true); + } + + public static JsonObject Deserialize(List entries) + { + if (isDeserializing) + { + throw new InvalidOperationException("Nested MultiJson deserialization is not supported."); + } + + try + { + isDeserializing = true; + + for (var index = 0; index < entries.Count; index++) + { + var entry = entries[index]; + try + { + var instance = CreateInstance(entry.type); + if (entry.id == null) + { + entries[index] = entry = new MultiJsonEntry(entry.type, instance.id, entry.json); + } + + instanceMap[entry.id] = instance; + } + catch (Exception e) + { + // External code could throw exceptions, but we don't want that to fail the whole thing. + // Potentially, the fallback type should also be used here. + // TODO: Allow custom logging function + Debug.LogException(e); + } + } + + s_Entries = entries; + + // Not a foreach because `entries` can be populated by calls to `Enqueue` as we go. + for (var i = 0; i < entries.Count; i++) + { + var entry = entries[i]; + try + { + var instance = instanceMap[entry.id]; + var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(instance.GetType()); + var fake = Activator.CreateInstance(fakeType, instance); + EditorJsonUtility.FromJsonOverwrite(entry.json, fake); + instance.OnAfterDeserialize(entry.json); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + s_Entries = null; + + foreach (var entry in entries) + { + try + { + var instance = instanceMap[entry.id]; + instance.OnAfterMultiDeserialize(entry.json); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + return instanceMap[entries[0].id]; + } + finally + { + instanceMap.Clear(); + isDeserializing = false; + } + } + + public static string Serialize(JsonObject mainObject) + { + if (isSerializing) + { + throw new InvalidOperationException("Nested MultiJson serialization is not supported."); + } + + try + { + isSerializing = true; + + serializedSet.Add(mainObject.id); + serializationQueue.Add(mainObject); + + var idJsonList = new List<(string, string)>(); + + // Not a foreach because the queue is populated by `JsonRef`s as we go. + for (var i = 0; i < serializationQueue.Count; i++) + { + var instance = serializationQueue[i]; + var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(instance.GetType()); + var fake = Activator.CreateInstance(fakeType, instance); + var json = EditorJsonUtility.ToJson(fake, true); + idJsonList.Add((instance.id, json)); + } + + idJsonList.Sort((x, y) => + // Main object needs to be placed first + x.Item1 == mainObject.id ? -1 : + y.Item1 == mainObject.id ? 1 : + // We sort everything else by ID to consistently maintain positions in the output + x.Item1.CompareTo(y.Item1)); + + var sb = new StringBuilder(); + foreach (var (_, json) in idJsonList) + { + sb.AppendLine(json); + sb.AppendLine(); + } + + return sb.ToString(); + } + finally + { + serializationQueue.Clear(); + serializedSet.Clear(); + isSerializing = false; + } + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs.meta b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs.meta new file mode 100644 index 00000000000..a13e8a2a061 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0caa65fda47242128d10c61c4f127a95 +timeCreated: 1581668666 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs b/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs new file mode 100644 index 00000000000..abaaca81e0c --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph.Serialization +{ + static class SerializationExtensions + { + public static TargetEnumerable SelectTarget(this List> list) where T : JsonObject => + new TargetEnumerable(list); + + public static void AddRange(this List> list, IEnumerable enumerable) + where T : JsonObject + { + foreach (var jsonObject in enumerable) + { + list.Add(jsonObject); + } + } + + public static void AddRange(this List> list, List enumerable) + where T : JsonObject + { + foreach (var jsonObject in enumerable) + { + list.Add(jsonObject); + } + } + + public static void AddRange(this List list, List> enumerable) + where T : JsonObject + { + foreach (var jsonObject in enumerable) + { + list.Add(jsonObject); + } + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs.meta b/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs.meta new file mode 100644 index 00000000000..347a9cc666b --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 75d8197dfa5346abaacd62fc929e67e0 +timeCreated: 1582191767 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs b/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs new file mode 100644 index 00000000000..df9323bb202 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs @@ -0,0 +1,42 @@ +using System.Collections; +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph.Serialization +{ + struct TargetEnumerable : IEnumerable + where T : JsonObject + { + List> m_List; + + public TargetEnumerable(List> list) + { + m_List = list; + } + + public Enumerator GetEnumerator() => new Enumerator(m_List.GetEnumerator()); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public struct Enumerator : IEnumerator + { + List>.Enumerator m_Enumerator; + + public Enumerator(List>.Enumerator enumerator) + { + m_Enumerator = enumerator; + } + + public bool MoveNext() => m_Enumerator.MoveNext(); + + void IEnumerator.Reset() => ((IEnumerator)m_Enumerator).Reset(); + + public T Current => m_Enumerator.Current.target; + + object IEnumerator.Current => Current; + + public void Dispose() => m_Enumerator.Dispose(); + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs.meta b/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs.meta new file mode 100644 index 00000000000..9bc27a28cb2 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6affc0753ed9408fa908d4a2285010ef +timeCreated: 1582191441 \ No newline at end of file From e7ee6942c472e51af67c9a52edb5853e71e2fc9a Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 10 Mar 2020 13:15:26 +0100 Subject: [PATCH 02/64] Convert GraphData to JsonObject, and use MultiJson in MaterialGraphEditWindow --- com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs | 9 +++++---- .../Editor/Drawing/MaterialGraphEditWindow.cs | 9 +++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index c8ddef07955..8fb43a66cc3 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -7,6 +7,7 @@ using UnityEditor.Graphing.Util; using UnityEditor.Rendering; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; using Edge = UnityEditor.Graphing.Edge; namespace UnityEditor.ShaderGraph @@ -15,7 +16,7 @@ namespace UnityEditor.ShaderGraph [FormerName("UnityEditor.ShaderGraph.MaterialGraph")] [FormerName("UnityEditor.ShaderGraph.SubGraph")] [FormerName("UnityEditor.ShaderGraph.AbstractMaterialGraph")] - sealed class GraphData : ISerializationCallbackReceiver + sealed class GraphData : JsonObject { public GraphObject owner { get; set; } @@ -1283,7 +1284,7 @@ internal void PasteGraph(CopyPasteGraph graphToPaste, List ValidateGraph(); } - public void OnBeforeSerialize() + public override void OnBeforeSerialize() { var nodes = GetNodes().ToList(); nodes.Sort((x1, x2) => x1.guid.CompareTo(x2.guid)); @@ -1295,7 +1296,7 @@ public void OnBeforeSerialize() m_ActiveOutputNodeGuidSerialized = m_ActiveOutputNodeGuid == Guid.Empty ? null : m_ActiveOutputNodeGuid.ToString(); } - public void OnAfterDeserialize() + public override void OnAfterDeserialize() { // have to deserialize 'globals' before nodes m_Properties = SerializationHelper.Deserialize(m_SerializedProperties, GraphUtil.GetLegacyTypeRemapping()); @@ -1417,7 +1418,7 @@ public void UpdateTargets() m_ValidTargets = foundTargets; m_ValidImplementations = foundImplementations.Where(s => s.targetType == foundTargets[0].GetType()).ToList(); - + } } diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index d16d732a6a6..45b36267e60 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -14,6 +14,7 @@ using Edge = UnityEditor.Experimental.GraphView.Edge; using UnityEditor.Experimental.GraphView; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; using UnityEngine.UIElements; using UnityEditor.VersionControl; @@ -383,7 +384,7 @@ public void UpdateAsset() if (shader != null) { GraphData.onSaveGraph(shader, (graphObject.graph.outputNode as AbstractMaterialNode).saveContext); - } + } } } @@ -804,9 +805,13 @@ public void Initialize(string assetGuid) selectedGuid = assetGuid; var textGraph = File.ReadAllText(path, Encoding.UTF8); + if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) + { + textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; + } graphObject = CreateInstance(); graphObject.hideFlags = HideFlags.HideAndDontSave; - graphObject.graph = JsonUtility.FromJson(textGraph); + graphObject.graph = MultiJson.Deserialize(textGraph); graphObject.graph.assetGuid = assetGuid; graphObject.graph.isSubGraph = isSubGraph; graphObject.graph.messageManager = messageManager; From 96f6acde2b36845288146bbb832f16b5f0d78f83 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 10 Mar 2020 14:07:01 +0100 Subject: [PATCH 03/64] Remove tempId --- .../Editor/EdgeTypeConversionTests.cs | 8 +- .../Editor/Data/Graphs/GraphData.cs | 50 ++---- .../Editor/Data/Nodes/AbstractMaterialNode.cs | 4 +- .../Data/Nodes/Math/Basic/MultiplyNode.cs | 2 +- .../Data/Nodes/Math/Matrix/MatrixSplitNode.cs | 2 +- .../Data/Nodes/Utility/CustomFunctionNode.cs | 10 +- .../Editor/Data/Nodes/Utility/SubGraphNode.cs | 40 ++--- .../Data/SubGraph/SubGraphOutputNode.cs | 4 +- .../Editor/Data/Util/PooledHashSet.cs | 48 ++++++ .../Editor/Data/Util/PooledHashSet.cs.meta | 3 + .../Editor/Drawing/PreviewManager.cs | 84 +++------- .../Editor/Drawing/Views/GraphEditorView.cs | 2 +- .../Editor/Generation/Processors/Generator.cs | 48 +++--- .../Editor/Importers/ShaderGraphImporter.cs | 6 +- .../Importers/ShaderSubGraphImporter.cs | 20 +-- .../Editor/Util/MessageManager.cs | 24 +-- .../Editor/UnitTests/MessageManagerTests.cs | 147 +++++++++--------- 17 files changed, 240 insertions(+), 262 deletions(-) create mode 100644 com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs create mode 100644 com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/EdgeTypeConversionTests.cs b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/EdgeTypeConversionTests.cs index 7e1521c01ee..4af36a1edb6 100644 --- a/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/EdgeTypeConversionTests.cs +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/EdgeTypeConversionTests.cs @@ -14,7 +14,7 @@ internal class EdgeTypeConversionTests static string kGraphName = "Assets/CommonAssets/Graphs/SlotConv.shadergraph"; GraphData m_Graph; CustomFunctionNode m_CFNode; - + [SetUp] public void LoadGraph() { @@ -25,7 +25,7 @@ public void LoadGraph() m_CFNode = m_Graph.GetNodes().FirstOrDefault(); Assert.NotNull(m_CFNode, $"No CustomFunctionNode found in {kGraphName}."); } - + [Test] public void TestAllCombos() { @@ -34,7 +34,7 @@ public void TestAllCombos() // Should only be one edge per slot on this graph var edge = m_Graph.GetEdges(slot.slotReference).FirstOrDefault(); if (edge == null) continue; - + var outputNode = m_Graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); var outputSlot = outputNode.GetOutputSlots().First(s => s.id == edge.outputSlot.slotId); var curOutputType = outputSlot.valueType.ToConcreteSlotValueType(); @@ -49,7 +49,7 @@ public void TestAllCombos() // Verify all errors are expected foreach (var message in m_Graph.messageManager.GetNodeMessages()) { - if (message.Key.Equals(m_CFNode.tempId) && message.Value.Exists(msg => + if (message.Key.Equals(m_CFNode.guid) && message.Value.Exists(msg => msg.severity == ShaderCompilerMessageSeverity.Error)) { Assert.IsFalse(SlotValueHelper.AreCompatible(slotValType, curOutputType), diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 8fb43a66cc3..be1ae26e779 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -495,19 +495,7 @@ void AddNodeNoValidate(AbstractMaterialNode node) throw new InvalidOperationException("Cannot add a node whose group doesn't exist."); } node.owner = this; - if (m_FreeNodeTempIds.Any()) - { - var id = m_FreeNodeTempIds.Pop(); - id.IncrementVersion(); - node.tempId = id; - m_Nodes[id.index] = node; - } - else - { - var id = new Identifier(m_Nodes.Count); - node.tempId = id; - m_Nodes.Add(node); - } + m_Nodes.Add(node); m_NodeDictionary.Add(node.guid, node); m_AddedNodes.Add(node); m_GroupItems[node.groupGuid].Add(node); @@ -530,10 +518,9 @@ void RemoveNodeNoValidate(AbstractMaterialNode node) throw new InvalidOperationException("Cannot remove a node that doesn't exist."); } - m_Nodes[node.tempId.index] = null; - m_FreeNodeTempIds.Push(node.tempId); + m_Nodes.Remove(node); m_NodeDictionary.Remove(node.guid); - messageManager?.RemoveNode(node.tempId); + messageManager?.RemoveNode(node.guid); m_RemovedNodes.Add(node); if (m_GroupItems.TryGetValue(node.groupGuid, out var groupItems)) @@ -673,18 +660,6 @@ public AbstractMaterialNode GetNodeFromGuid(Guid guid) return node; } - public AbstractMaterialNode GetNodeFromTempId(Identifier tempId) - { - if (tempId.index > m_Nodes.Count) - throw new ArgumentException("Trying to retrieve a node using an identifier that does not exist."); - var node = m_Nodes[tempId.index]; - if (node == null) - throw new Exception("Trying to retrieve a node using an identifier that does not exist."); - if (node.tempId.version != tempId.version) - throw new Exception("Trying to retrieve a node that was removed from the graph."); - return node; - } - public bool ContainsNodeGuid(Guid guid) { return m_NodeDictionary.ContainsKey(guid); @@ -979,8 +954,8 @@ public void ValidateGraph() } } - var temporaryMarks = IndexSetPool.Get(); - var permanentMarks = IndexSetPool.Get(); + var temporaryMarks = PooledHashSet.Get(); + var permanentMarks = PooledHashSet.Get(); var slots = ListPool.Get(); // Make sure we process a node's children before the node itself. @@ -992,19 +967,19 @@ public void ValidateGraph() while (stack.Count > 0) { var node = stack.Pop(); - if (permanentMarks.Contains(node.tempId.index)) + if (permanentMarks.Contains(node.guid)) { continue; } - if (temporaryMarks.Contains(node.tempId.index)) + if (temporaryMarks.Contains(node.guid)) { node.ValidateNode(); - permanentMarks.Add(node.tempId.index); + permanentMarks.Add(node.guid); } else { - temporaryMarks.Add(node.tempId.index); + temporaryMarks.Add(node.guid); stack.Push(node); node.GetInputSlots(slots); foreach (var inputSlot in slots) @@ -1026,8 +1001,8 @@ public void ValidateGraph() StackPool.Release(stack); ListPool.Release(slots); - IndexSetPool.Release(temporaryMarks); - IndexSetPool.Release(permanentMarks); + temporaryMarks.Dispose(); + permanentMarks.Dispose(); foreach (var edge in m_AddedEdges.ToList()) { @@ -1052,7 +1027,7 @@ public void ValidateGraph() } } - public void AddValidationError(Identifier id, string errorMessage, + public void AddValidationError(Guid id, string errorMessage, ShaderCompilerMessageSeverity severity = ShaderCompilerMessageSeverity.Error) { messageManager?.AddOrAppendError(this, id, new ShaderMessage(errorMessage, severity)); @@ -1316,7 +1291,6 @@ public override void OnAfterDeserialize() { node.owner = this; node.UpdateNodeAfterDeserialization(); - node.tempId = new Identifier(m_Nodes.Count); m_Nodes.Add(node); m_NodeDictionary.Add(node.guid, node); m_GroupItems[node.groupGuid].Add(node); diff --git a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs index e306dc6be03..039d6151bf2 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs @@ -41,8 +41,6 @@ abstract class AbstractMaterialNode : ISerializationCallbackReceiver, IGroupItem [SerializeField] List m_SerializableSlots = new List(); - public Identifier tempId { get; set; } - public GraphData owner { get; set; } OnNodeModified m_OnModified; @@ -514,7 +512,7 @@ public virtual void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(tempId, errorMessage); + ((GraphData) owner).AddValidationError(guid, errorMessage); } else { diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs index 94ef16d4750..d73c8faaeb6 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs @@ -251,7 +251,7 @@ public override void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(tempId, errorMessage); + ((GraphData) owner).AddValidationError(guid, errorMessage); } else { diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs index 19919569e1d..641a44dccb3 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs @@ -246,7 +246,7 @@ public override void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(tempId, errorMessage); + ((GraphData) owner).AddValidationError(guid, errorMessage); } else { diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs index daacad998a7..794bf5e7797 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs @@ -38,7 +38,7 @@ public void GetSourceAssetDependencies(List paths) } } } - + public static string[] s_ValidExtensions = { ".hlsl", ".cginc" }; const string k_InvalidFileType = "Source file is not a valid file type. Valid file extensions are .hlsl and .cginc"; const string k_MissingOutputSlot = "A Custom Function Node must have at least one output slot"; @@ -236,7 +236,7 @@ string SlotInputValue(MaterialSlot port, GenerationMode generationMode) return port.GetDefaultValue(generationMode); } - + bool IsValidFunction() { return IsValidFunction(sourceType, functionName, functionSource, functionBody); @@ -275,7 +275,7 @@ void ValidateSlotName() var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); if (error) { - owner.AddValidationError(tempId, errorMessage); + owner.AddValidationError(guid, errorMessage); break; } } @@ -285,7 +285,7 @@ public override void ValidateNode() { if (!this.GetOutputSlots().Any()) { - owner.AddValidationError(tempId, k_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); + owner.AddValidationError(guid, k_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); } if(sourceType == HlslSourceType.File) { @@ -297,7 +297,7 @@ public override void ValidateNode() string extension = path.Substring(path.LastIndexOf('.')); if(!s_ValidExtensions.Contains(extension)) { - owner.AddValidationError(tempId, k_InvalidFileType, ShaderCompilerMessageSeverity.Error); + owner.AddValidationError(guid, k_InvalidFileType, ShaderCompilerMessageSeverity.Error); } } } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs index 5b2a0170327..19608636643 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs @@ -72,7 +72,7 @@ public override string ToString() return $"fileID={fileID}, guid={guid}, type={type}"; } } - + [SerializeField] string m_SerializedSubGraph = string.Empty; @@ -102,7 +102,7 @@ void LoadSubGraph() { return; } - + var graphGuid = subGraphGuid; var assetPath = AssetDatabase.GUIDToAssetPath(graphGuid); m_SubGraph = AssetDatabase.LoadAssetAtPath(assetPath); @@ -110,7 +110,7 @@ void LoadSubGraph() { return; } - + name = m_SubGraph.name; concretePrecision = m_SubGraph.outputPrecision; } @@ -163,7 +163,7 @@ public override bool allowedInSubGraph { get { return true; } } - + public override bool canSetPrecision { get { return false; } @@ -180,12 +180,12 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo { sb.AppendLine($"{slot.concreteValueType.ToShaderString(outputPrecision)} {GetVariableNameForSlot(slot.id)} = {slot.GetDefaultValue(GenerationMode.ForReals)};"); } - + return; } var inputVariableName = $"_{GetVariableNameForNode()}"; - + GenerationUtils.GenerateSurfaceInputTransferCode(sb, asset.requirements, asset.inputStructName, inputVariableName); foreach (var outSlot in asset.outputs) @@ -193,7 +193,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo var arguments = new List(); foreach (var prop in asset.inputs) - { + { prop.ValidateConcretePrecision(asset.graphPrecision); var inSlotId = m_PropertyIds[m_PropertyGuids.IndexOf(prop.guid.ToString())]; @@ -230,7 +230,7 @@ public void OnEnable() { UpdateSlots(); } - + public void Reload(HashSet changedFileDependencies) { if (asset == null) @@ -276,7 +276,7 @@ public virtual void UpdateSlots() } var id = m_PropertyIds[propertyIndex]; MaterialSlot slot = MaterialSlot.CreateMaterialSlot(valueType, id, prop.displayName, prop.referenceName, SlotType.Input, Vector4.zero, ShaderStageCapability.All); - + // Copy defaults switch(prop.concreteShaderValueType) { @@ -388,7 +388,7 @@ public virtual void UpdateSlots() } break; } - + AddSlot(slot); validNames.Add(id); } @@ -397,7 +397,7 @@ public virtual void UpdateSlots() foreach (var slot in asset.outputs) { - AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(), + AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(), slot.shaderOutputName, SlotType.Output, Vector4.zero, outputStage)); validNames.Add(slot.id); } @@ -422,7 +422,7 @@ void ValidateShaderStage() public override void ValidateNode() { base.ValidateNode(); - + if (asset == null) { hasError = true; @@ -430,25 +430,25 @@ public override void ValidateNode() var assetPath = string.IsNullOrEmpty(subGraphGuid) ? null : AssetDatabase.GUIDToAssetPath(assetGuid); if (string.IsNullOrEmpty(assetPath)) { - owner.AddValidationError(tempId, $"Could not find Sub Graph asset with GUID {assetGuid}."); + owner.AddValidationError(guid, $"Could not find Sub Graph asset with GUID {assetGuid}."); } else { - owner.AddValidationError(tempId, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}."); + owner.AddValidationError(guid, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}."); } return; } - + if (asset.isRecursive || owner.isSubGraph && (asset.descendents.Contains(owner.assetGuid) || asset.assetGuid == owner.assetGuid)) { hasError = true; - owner.AddValidationError(tempId, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); + owner.AddValidationError(guid, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); } else if (!asset.isValid) { hasError = true; - owner.AddValidationError(tempId, $"Invalid Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); + owner.AddValidationError(guid, $"Invalid Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); } ValidateShaderStage(); @@ -475,13 +475,13 @@ public void CollectShaderKeywords(KeywordCollector keywords, GenerationMode gene foreach (var keyword in asset.keywords) { keywords.AddShaderKeyword(keyword as ShaderKeyword); - } + } } public override void CollectPreviewMaterialProperties(List properties) { base.CollectPreviewMaterialProperties(properties); - + if (asset == null) return; @@ -495,7 +495,7 @@ public virtual void GenerateNodeFunction(FunctionRegistry registry, GenerationMo { if (asset == null || hasError) return; - + foreach (var function in asset.functions) { registry.ProvideFunction(function.key, s => diff --git a/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs b/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs index 8ee6d261662..5de3da3d995 100644 --- a/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs +++ b/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs @@ -56,7 +56,7 @@ void ValidateSlotName() var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); if (error) { - owner.AddValidationError(tempId, errorMessage); + owner.AddValidationError(guid, errorMessage); break; } } @@ -68,7 +68,7 @@ public override void ValidateNode() if (!this.GetInputSlots().Any()) { - owner.AddValidationError(tempId, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); + owner.AddValidationError(guid, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); } base.ValidateNode(); diff --git a/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs b/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs new file mode 100644 index 00000000000..6f2d87d5ae2 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Assertions; + +namespace UnityEditor.ShaderGraph +{ + class PooledHashSet : HashSet + { + static Stack> s_Pool = new Stack>(); + bool m_Active; + + PooledHashSet() {} + + public static PooledHashSet Get() + { + if (s_Pool.Count == 0) + { + return new PooledHashSet { m_Active = true }; + } + + var list = s_Pool.Pop(); + list.m_Active = true; +#if DEBUG + GC.ReRegisterForFinalize(list); +#endif + return list; + } + + public void Dispose() + { + Assert.IsTrue(m_Active); + m_Active = false; + Clear(); + s_Pool.Push(this); +#if DEBUG + GC.SuppressFinalize(this); +#endif + } + +// Destructor causes some GC alloc so only do this sanity check in debug build +#if DEBUG + ~PooledHashSet() + { + throw new InvalidOperationException($"{nameof(PooledHashSet)} must be disposed manually."); + } +#endif + } +} diff --git a/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta b/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta new file mode 100644 index 00000000000..9bf72638e9b --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 11c00f8215374c368941cd4c06242ed7 +timeCreated: 1582812009 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index 6bfe1dec260..07aad2c76d5 100644 --- a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -20,9 +20,8 @@ class PreviewManager : IDisposable { GraphData m_Graph; MessageManager m_Messenger; - List m_RenderDatas = new List(); + Dictionary m_RenderDatas = new Dictionary(); PreviewRenderData m_MasterRenderData; - List m_Identifiers = new List(); HashSet m_NodesToUpdate = new HashSet(); HashSet m_NodesToDraw = new HashSet(); HashSet m_TimedNodes = new HashSet(); @@ -69,7 +68,7 @@ public void ResizeMasterPreview(Vector2 newSize) public PreviewRenderData GetPreview(AbstractMaterialNode node) { - return m_RenderDatas[node.tempId.index]; + return m_RenderDatas[node.guid]; } void AddPreview(AbstractMaterialNode node) @@ -114,8 +113,7 @@ void AddPreview(AbstractMaterialNode node) shaderData.mat = new Material(shaderData.shader) {hideFlags = HideFlags.HideAndDontSave}; renderData.shaderData = shaderData; - Set(m_Identifiers, node.tempId, node.tempId); - Set(m_RenderDatas, node.tempId, renderData); + m_RenderDatas.Add(node.guid, renderData); node.RegisterCallback(OnNodeModified); if (node.RequiresTime()) @@ -212,12 +210,12 @@ public bool HandleGraphChanges() { if (m_Graph.didActiveOutputNodeChange) { - DestroyPreview(masterRenderData.shaderData.node.tempId); + DestroyPreview(masterRenderData.shaderData.node.guid); } foreach (var node in m_Graph.removedNodes) { - DestroyPreview(node.tempId); + DestroyPreview(node.guid); m_NodesToUpdate.Remove(node); m_NodesToDraw.Remove(node); m_RefreshTimedNodes = true; @@ -295,7 +293,7 @@ public void RenderPreviews() if(node == null || !node.hasPreview || !node.previewExpanded) continue; - var renderData = GetRenderData(node.tempId); + var renderData = m_RenderDatas[node.guid]; CollectShaderProperties(node, renderData); renderData.shaderData.mat.SetVector("_TimeParameters", timeParameters); @@ -385,21 +383,18 @@ public void RenderPreviews() public void ForceShaderUpdate() { - foreach (var data in m_RenderDatas) + foreach (var data in m_RenderDatas.Values) { - if (data != null) - { - m_NodesToUpdate.Add(data.shaderData.node); - } + m_NodesToUpdate.Add(data.shaderData.node); } } void UpdateShaders() { // Check for shaders that finished compiling and set them to redraw - foreach (var renderData in m_RenderDatas) + foreach (var renderData in m_RenderDatas.Values) { - if (renderData != null && renderData.shaderData.isCompiling) + if (renderData.shaderData.isCompiling) { var isCompiled = true; for (var i = 0; i < renderData.shaderData.mat.passCount; i++) @@ -412,7 +407,7 @@ void UpdateShaders() } if (!isCompiled) - { + { continue; } @@ -448,13 +443,14 @@ void UpdateShaders() if (!node.hasPreview && !(node is SubGraphOutputNode || node is VfxMasterNode)) continue; - var renderData = GetRenderData(node.tempId); + Guid id = node.guid; + var renderData = m_RenderDatas[id]; if (renderData == null) { continue; } ShaderUtil.ClearCachedData(renderData.shaderData.shader); - + // Get shader code and compile var generator = new Generator(node.owner, node, GenerationMode.Preview, $"hidden/preview/{node.GetVariableNameForNode()}"); BeginCompile(renderData, generator.generatedShader); @@ -548,7 +544,7 @@ void CheckForErrors(PreviewShaderData shaderData) var messages = ShaderUtil.GetShaderMessages(shaderData.shader); if (messages.Length > 0) { - m_Messenger.AddOrAppendError(this, shaderData.node.tempId, messages[0]); + m_Messenger.AddOrAppendError(this, shaderData.node.guid, messages[0]); } } } @@ -560,7 +556,7 @@ void UpdateMasterNodeShader() if (masterNode == null) return; - + var generator = new Generator(m_Graph, shaderData?.node, GenerationMode.Preview, shaderData?.node.name); shaderData.shaderString = generator.generatedShader; @@ -609,18 +605,15 @@ void DestroyRenderData(PreviewRenderData renderData) renderData.shaderData.node.UnregisterCallback(OnNodeModified); } - void DestroyPreview(Identifier nodeId) + void DestroyPreview(Guid nodeId) { - var renderData = Get(m_RenderDatas, nodeId); - if (renderData == null) + if (!m_RenderDatas.TryGetValue(nodeId, out var renderData)) { return; } DestroyRenderData(renderData); - - Set(m_RenderDatas, nodeId, null); - Set(m_Identifiers, nodeId, default(Identifier)); + m_RenderDatas.Remove(nodeId); // Check if we're destroying the shader data used by the master preview if (masterRenderData == renderData) @@ -648,7 +641,7 @@ void ReleaseUnmanagedResources() m_SceneResources.Dispose(); m_SceneResources = null; } - foreach (var renderData in m_RenderDatas.Where(x => x != null)) + foreach (var renderData in m_RenderDatas.Values) DestroyRenderData(renderData); m_RenderDatas.Clear(); } @@ -705,43 +698,6 @@ fixed4 frag (v2f i) : SV_Target } } }"; - - T Get(List list, Identifier id) - { - var existingId = Get(m_Identifiers, id.index); - if (existingId.valid && existingId.version != id.version) - throw new InvalidOperationException($"Identifier version mismatch at index {id.index}: {id.version} != {existingId.version}"); - return Get(list, id.index); - } - - static T Get(List list, int index) - { - return index < list.Count ? list[index] : default(T); - } - - void Set(List list, Identifier id, T value) - { - var existingId = Get(m_Identifiers, id.index); - if (existingId.valid && existingId.version != id.version) - throw new InvalidOperationException($"Identifier version mismatch at index {id.index}: {id.version} != {existingId.version}"); - Set(list, id.index, value); - } - - static void Set(List list, int index, T value) - { - // Make sure the list is large enough for the index - for (var i = list.Count; i <= index; i++) - list.Add(default(T)); - list[index] = value; - } - - PreviewRenderData GetRenderData(Identifier id) - { - var value = Get(m_RenderDatas, id); - if (value != null && value.shaderData.node.tempId.version != id.version) - throw new InvalidOperationException("Trying to access render data of a previous version of a node"); - return value; - } } delegate void OnPreviewChanged(); diff --git a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index dbf4feb1bc9..1214bed3cae 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -733,7 +733,7 @@ void UpdateBadges() foreach (var messageData in m_MessageManager.GetNodeMessages()) { - var node = m_Graph.GetNodeFromTempId(messageData.Key); + var node = m_Graph.GetNodeFromGuid(messageData.Key); if (!(m_GraphView.GetNodeByGuid(node.guid.ToString()) is MaterialNodeView nodeView)) continue; diff --git a/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index 874acb4bf3d..fbb70301251 100644 --- a/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -90,8 +90,8 @@ void BuildShader() if(m_GraphData.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit) { - m_GraphData.AddValidationError(m_OutputNode.tempId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); - + m_GraphData.AddValidationError(m_OutputNode.guid, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); + m_ConfiguredTextures = shaderProperties.GetConfiguredTexutres(); m_Builder.AppendLines(ShaderGraphImporter.k_ErrorShader); } @@ -105,12 +105,12 @@ void BuildShader() using (m_Builder.BlockScope()) { GenerationUtils.GeneratePropertiesBlock(m_Builder, shaderProperties, shaderKeywords, m_Mode); - + for(int i = 0; i < m_TargetImplementations.Length; i++) { TargetSetupContext context = new TargetSetupContext(); context.SetMasterNode(m_OutputNode as IMasterNode); - m_TargetImplementations[i].SetupTarget(ref context); + m_TargetImplementations[i].SetupTarget(ref context); GetAssetDependencyPaths(context); GenerateSubShader(i, context.descriptor); } @@ -140,11 +140,11 @@ void GenerateSubShader(int targetIndex, SubShaderDescriptor descriptor) var activeFields = GatherActiveFieldsFromNode(m_OutputNode, pass.descriptor); // TODO: cleanup this preview check, needed for HD decal preview pass - if(m_Mode == GenerationMode.Preview) + if(m_Mode == GenerationMode.Preview) activeFields.baseInstance.Add(Fields.IsPreview); // Check masternode fields for valid passes - if(pass.TestActive(activeFields)) + if(pass.TestActive(activeFields)) GenerateShaderPass(targetIndex, pass.descriptor, activeFields); } } @@ -236,7 +236,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ foreach (var instance in activeFields.all.instances) { GenerationUtils.ApplyFieldDependencies(instance, pass.fieldDependencies); - } + } // -------------------------------------------------- // Pass Setup @@ -268,7 +268,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ using (var renderStateBuilder = new ShaderStringBuilder()) { // Render states need to be separated by RenderState.Type - // The first passing ConditionalRenderState of each type is inserted + // The first passing ConditionalRenderState of each type is inserted foreach(RenderStateType type in Enum.GetValues(typeof(RenderStateType))) { var renderStates = pass.renderStates?.Where(x => x.descriptor.type == type); @@ -352,7 +352,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ } // ----------------------------- - // Generated structs and Packing code + // Generated structs and Packing code var interpolatorBuilder = new ShaderStringBuilder(); var passStructs = new List(); @@ -363,12 +363,12 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ foreach (StructCollection.Item shaderStruct in pass.structs) { if(shaderStruct.descriptor.packFields == false) - continue; //skip structs that do not need interpolator packs + continue; //skip structs that do not need interpolator packs List packedCounts = new List(); var packStruct = new StructDescriptor(); - //generate packed functions + //generate packed functions if (activeFields.permutationCount > 0) { var generatedPackedTypes = new Dictionary)>(); @@ -404,18 +404,18 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ { GenerationUtils.GenerateInterpolatorFunctions(shaderStruct.descriptor, activeFields.baseInstance, out interpolatorBuilder); } - //using interp index from functions, generate packed struct descriptor + //using interp index from functions, generate packed struct descriptor GenerationUtils.GeneratePackedStruct(shaderStruct.descriptor, activeFields, out packStruct); passStructs.Add(packStruct); - } + } } - if(interpolatorBuilder.length != 0) //hard code interpolators to float, TODO: proper handle precision + if(interpolatorBuilder.length != 0) //hard code interpolators to float, TODO: proper handle precision interpolatorBuilder.ReplaceInCurrentMapping(PrecisionUtil.Token, ConcretePrecision.Float.ToShaderString()); else interpolatorBuilder.AppendLine("//Interpolator Packs: "); spliceCommands.Add("InterpolatorPack", interpolatorBuilder.ToCodeBlock()); - - // Generated String Builders for all struct types + + // Generated String Builders for all struct types var passStructBuilder = new ShaderStringBuilder(); if(passStructs != null) { @@ -423,11 +423,11 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ foreach(StructDescriptor shaderStruct in passStructs) { GenerationUtils.GenerateShaderStruct(shaderStruct, activeFields, out structBuilder); - structBuilder.ReplaceInCurrentMapping(PrecisionUtil.Token, ConcretePrecision.Float.ToShaderString()); //hard code structs to float, TODO: proper handle precision + structBuilder.ReplaceInCurrentMapping(PrecisionUtil.Token, ConcretePrecision.Float.ToShaderString()); //hard code structs to float, TODO: proper handle precision passStructBuilder.Concat(structBuilder); } } - if(passStructBuilder.length == 0) + if(passStructBuilder.length == 0) passStructBuilder.AppendLine("//Pass Structs: "); spliceCommands.Add("PassStructs", passStructBuilder.ToCodeBlock()); @@ -517,7 +517,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ pixelBuilder.AppendLines(pixelGraphOutputBuilder.ToString()); pixelBuilder.AppendNewLine(); pixelBuilder.AppendLines(pixelGraphFunctionBuilder.ToString()); - + // Add to splice commands if(pixelBuilder.length == 0) pixelBuilder.AppendLine("// GraphPixel: "); @@ -591,7 +591,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ using (var graphDefines = new ShaderStringBuilder()) { graphDefines.AppendLine("#define SHADERPASS {0}", pass.referenceName); - + if(pass.defines != null) { foreach(DefineCollection.Item define in pass.defines) @@ -648,7 +648,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ // Debug // Debug output all active fields - + using(var debugBuilder = new ShaderStringBuilder()) { if (isDebug) @@ -662,7 +662,7 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ } if(debugBuilder.length == 0) debugBuilder.AppendLine("// "); - + // Add to splice commands spliceCommands.Add("Debug", debugBuilder.ToCodeBlock()); } @@ -686,9 +686,9 @@ void GenerateShaderPass(int targetIndex, PassDescriptor pass, ActiveFields activ if (!File.Exists(passTemplatePath)) return; - + // Process Template - var templatePreprocessor = new ShaderSpliceUtil.TemplatePreprocessor(activeFields, spliceCommands, + var templatePreprocessor = new ShaderSpliceUtil.TemplatePreprocessor(activeFields, spliceCommands, isDebug, sharedTemplateDirectory, m_AssetDependencyPaths); templatePreprocessor.ProcessTemplateFile(passTemplatePath); m_Builder.Concat(templatePreprocessor.GetShaderCode()); diff --git a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index e76b05ce760..eba7002215f 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -59,7 +59,7 @@ fixed4 frag (v2f i) : SV_Target } Fallback Off }"; - + [SuppressMessage("ReSharper", "UnusedMember.Local")] static string[] GatherDependenciesFromSourceFile(string assetPath) { @@ -96,7 +96,7 @@ public override void OnImportAsset(AssetImportContext ctx) if (graph.outputNode is VfxMasterNode vfxMasterNode) { var vfxAsset = GenerateVfxShaderGraphAsset(vfxMasterNode); - + mainObject = vfxAsset; } else @@ -108,7 +108,7 @@ public override void OnImportAsset(AssetImportContext ctx) { foreach (var pair in graph.messageManager.GetNodeMessages()) { - var node = graph.GetNodeFromTempId(pair.Key); + var node = graph.GetNodeFromGuid(pair.Key); MessageManager.Log(node, path, pair.Value.First(), shader); } } diff --git a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index 5e05fed322c..b2ef9019871 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -59,7 +59,7 @@ public override void OnImportAsset(AssetImportContext ctx) graphAsset.isValid = false; foreach (var pair in messageManager.GetNodeMessages()) { - var node = graphData.GetNodeFromTempId(pair.Key); + var node = graphData.GetNodeFromGuid(pair.Key); foreach (var message in pair.Value) { MessageManager.Log(node, subGraphPath, message, graphAsset); @@ -116,10 +116,10 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph) asset.keywords = graph.keywords.ToList(); asset.graphPrecision = graph.concretePrecision; asset.outputPrecision = outputNode.concretePrecision; - + GatherFromGraph(assetPath, out var containsCircularDependency, out var descendents); asset.descendents.AddRange(descendents); - + var childrenSet = new HashSet(); var anyErrors = false; foreach (var node in nodes) @@ -132,7 +132,7 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph) asset.children.Add(subGraphGuid); } } - + if (node.hasError) { anyErrors = true; @@ -219,27 +219,27 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph) asset.OnBeforeSerialize(); } - + static void GatherFromGraph(string assetPath, out bool containsCircularDependency, out HashSet descendentGuids) { var dependencyMap = new Dictionary(); using (var tempList = ListPool.GetDisposable()) { GatherDependencies(assetPath, dependencyMap, tempList.value); - containsCircularDependency = ContainsCircularDependency(assetPath, dependencyMap, tempList.value); + containsCircularDependency = ContainsCircularDependency(assetPath, dependencyMap, tempList.value); } - + descendentGuids = new HashSet(); GatherDescendents(assetPath, descendentGuids, dependencyMap); } - + static void GatherDependencies(string assetPath, Dictionary dependencyMap, List dependencies) { if (!dependencyMap.ContainsKey(assetPath)) { if(assetPath.EndsWith(Extension)) MinimalGraphData.GetDependencyPaths(assetPath, dependencies); - + var dependencyPaths = dependencyMap[assetPath] = dependencies.ToArray(); dependencies.Clear(); foreach (var dependencyPath in dependencyPaths) @@ -267,7 +267,7 @@ static bool ContainsCircularDependency(string assetPath, Dictionary>> m_Messages = - new Dictionary>>(); + protected Dictionary>> m_Messages = + new Dictionary>>(); - Dictionary> m_Combined = new Dictionary>(); + Dictionary> m_Combined = new Dictionary>(); public bool nodeMessagesChanged { get; private set; } - Dictionary> m_FoundMessages; + Dictionary> m_FoundMessages; - public void AddOrAppendError(object errorProvider, Identifier nodeId, ShaderMessage error) + public void AddOrAppendError(object errorProvider, Guid nodeId, ShaderMessage error) { if (!m_Messages.TryGetValue(errorProvider, out var messages)) { - messages = new Dictionary>(); + messages = new Dictionary>(); m_Messages[errorProvider] = messages; } @@ -44,9 +46,9 @@ static int CompareMessages(ShaderMessage m1, ShaderMessage m2) return m1.severity > m2.severity ? 1 : m2.severity > m1.severity ? -1 : 0; } - public IEnumerable>> GetNodeMessages() + public IEnumerable>> GetNodeMessages() { - var fixedNodes = new List(); + var fixedNodes = new List(); m_Combined.Clear(); foreach (var messageMap in m_Messages) { @@ -79,7 +81,7 @@ public IEnumerable>> GetNodeMessage return m_Combined; } - public void RemoveNode(Identifier nodeId) + public void RemoveNode(Guid nodeId) { foreach (var messageMap in m_Messages) { @@ -107,7 +109,7 @@ public void ClearNodesFromProvider(object messageProvider, IEnumerable 0; messages.Clear(); @@ -131,7 +133,7 @@ void DebugPrint() output.AppendFormat("\tFrom Provider {0}:\n", messageMap.Key.GetType()); foreach (var messageList in messageMap.Value) { - output.AppendFormat("\t\tNode {0} has {1} messages:\n", messageList.Key.index, messageList.Value.Count); + output.AppendFormat("\t\tNode {0} has {1} messages:\n", messageList.Key, messageList.Value.Count); foreach (var message in messageList.Value) { output.AppendFormat("\t\t\t{0}\n", message.message); diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs index e5b64c52287..cf8205f56d3 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; @@ -11,21 +12,21 @@ namespace UnityEditor.ShaderGraph.UnitTests { class TestMessageManager : MessageManager { - public Dictionary>> Messages + public Dictionary>> Messages { get { return m_Messages; } } } - + class MessageManagerTests { TestMessageManager m_EmptyMgr; TestMessageManager m_ComplexMgr; string p0 = "Provider 0"; string p1 = "Provider 1"; - Identifier node0 = new Identifier(0); - Identifier node1 = new Identifier(1); - Identifier node2 = new Identifier(2); + AddNode node0 = new AddNode(); + AddNode node1 = new AddNode(); + AddNode node2 = new AddNode(); ShaderMessage e0 = new ShaderMessage("e0"); ShaderMessage e1 = new ShaderMessage("e1"); ShaderMessage e2 = new ShaderMessage("e2"); @@ -37,21 +38,21 @@ class MessageManagerTests public void Setup() { m_EmptyMgr = new TestMessageManager(); - + m_ComplexMgr = new TestMessageManager(); - m_ComplexMgr.AddOrAppendError(p0, node0, e0); - m_ComplexMgr.AddOrAppendError(p0, node0, e1); - m_ComplexMgr.AddOrAppendError(p0, node1, e2); - m_ComplexMgr.AddOrAppendError(p1, node0, e1); - m_ComplexMgr.AddOrAppendError(p1, node1, e0); - m_ComplexMgr.AddOrAppendError(p1, node1, e1); - m_ComplexMgr.AddOrAppendError(p1, node2, e3); + m_ComplexMgr.AddOrAppendError(p0, node0.guid, e0); + m_ComplexMgr.AddOrAppendError(p0, node0.guid, e1); + m_ComplexMgr.AddOrAppendError(p0, node1.guid, e2); + m_ComplexMgr.AddOrAppendError(p1, node0.guid, e1); + m_ComplexMgr.AddOrAppendError(p1, node1.guid, e0); + m_ComplexMgr.AddOrAppendError(p1, node1.guid, e1); + m_ComplexMgr.AddOrAppendError(p1, node2.guid, e3); } // Simple helper to avoid typing that ungodly generic type - static List>> GetListFrom(MessageManager mgr) + static List>> GetListFrom(MessageManager mgr) { - return new List>>(mgr.GetNodeMessages()); + return new List>>(mgr.GetNodeMessages()); } [Test] @@ -60,11 +61,11 @@ public void NewManager_IsEmpty() var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); } - + [Test] public void AddMessage_CreatesMessage() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); @@ -76,7 +77,7 @@ public void AddMessage_CreatesMessage() [Test] public void AddMessage_DirtiesManager() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); Assert.IsTrue(m_EmptyMgr.nodeMessagesChanged); } @@ -84,7 +85,7 @@ public void AddMessage_DirtiesManager() [Test] public void GettingMessages_ClearsDirtyFlag() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); GetListFrom(m_EmptyMgr); Assert.IsFalse(m_EmptyMgr.nodeMessagesChanged); @@ -93,68 +94,68 @@ public void GettingMessages_ClearsDirtyFlag() [Test] public void GettingMessages_DoesNotChangeLists() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.AddOrAppendError(p0, node0, e1); - m_EmptyMgr.AddOrAppendError(p1, node0, e2); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e1); + m_EmptyMgr.AddOrAppendError(p1, node0.guid, e2); GetListFrom(m_EmptyMgr); - - Assert.AreEqual(2, m_EmptyMgr.Messages[p0][node0].Count); - Assert.AreEqual(e0, m_EmptyMgr.Messages[p0][node0][0]); - Assert.AreEqual(e1, m_EmptyMgr.Messages[p0][node0][1]); - Assert.AreEqual(1, m_EmptyMgr.Messages[p1][node0].Count); - Assert.AreEqual(e2, m_EmptyMgr.Messages[p1][node0][0]); + + Assert.AreEqual(2, m_EmptyMgr.Messages[p0][node0.guid].Count); + Assert.AreEqual(e0, m_EmptyMgr.Messages[p0][node0.guid][0]); + Assert.AreEqual(e1, m_EmptyMgr.Messages[p0][node0.guid][1]); + Assert.AreEqual(1, m_EmptyMgr.Messages[p1][node0.guid].Count); + Assert.AreEqual(e2, m_EmptyMgr.Messages[p1][node0.guid][0]); } - + [Test] public void RemoveNode_DoesNotDirty_IfNodeDoesNotExist() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); GetListFrom(m_EmptyMgr); - - m_EmptyMgr.RemoveNode(node1); - + + m_EmptyMgr.RemoveNode(node1.guid); + Assert.IsFalse(m_EmptyMgr.nodeMessagesChanged); } - + [Test] public void RemoveNode_DirtiesList_IfNodeExists() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); GetListFrom(m_EmptyMgr); - - m_EmptyMgr.RemoveNode(node0); - + + m_EmptyMgr.RemoveNode(node0.guid); + Assert.IsTrue(m_EmptyMgr.nodeMessagesChanged); } [Test] public void RemoveNode_RemovesNode() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.RemoveNode(node0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.RemoveNode(node0.guid); var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); } - + [Test] public void RemoveNode_RemovesNode_FromAllProvides() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.AddOrAppendError(p1, node0, e1); - m_EmptyMgr.RemoveNode(node0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p1, node0.guid, e1); + m_EmptyMgr.RemoveNode(node0.guid); var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); } - + [Test] public void AppendMessage_AppendsMessage() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.AddOrAppendError(p0, node0, e1); - + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e1); + var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); Assert.AreEqual(node0, ret[0].Key); @@ -167,10 +168,10 @@ public void AppendMessage_AppendsMessage() public void Warnings_SortedAfterErrors() { var mixedMgr = new MessageManager(); - mixedMgr.AddOrAppendError(p0, node0, e0); - mixedMgr.AddOrAppendError(p0, node0, w0); - mixedMgr.AddOrAppendError(p0, node0, e1); - mixedMgr.AddOrAppendError(p0, node0, w1); + mixedMgr.AddOrAppendError(p0, node0.guid, e0); + mixedMgr.AddOrAppendError(p0, node0.guid, w0); + mixedMgr.AddOrAppendError(p0, node0.guid, e1); + mixedMgr.AddOrAppendError(p0, node0.guid, w1); var ret = GetListFrom(mixedMgr)[0].Value; Assert.AreEqual(e0, ret[0]); @@ -183,24 +184,24 @@ public void Warnings_SortedAfterErrors() public void Warnings_FromDifferentProviders_SortedAfterErrors() { var mixedMgr = new MessageManager(); - mixedMgr.AddOrAppendError(p0, node0, e0); - mixedMgr.AddOrAppendError(p0, node0, w0); - mixedMgr.AddOrAppendError(p1, node0, e1); - mixedMgr.AddOrAppendError(p1, node0, w1); - + mixedMgr.AddOrAppendError(p0, node0.guid, e0); + mixedMgr.AddOrAppendError(p0, node0.guid, w0); + mixedMgr.AddOrAppendError(p1, node0.guid, e1); + mixedMgr.AddOrAppendError(p1, node0.guid, w1); + var ret = GetListFrom(mixedMgr)[0].Value; Assert.AreEqual(e0, ret[0]); Assert.AreEqual(e1, ret[1]); Assert.AreEqual(w0, ret[2]); Assert.AreEqual(w1, ret[3]); } - + [Test] public void MultipleNodes_RemainSeparate() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.AddOrAppendError(p0, node1, e1); - + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node1.guid, e1); + var ret = GetListFrom(m_EmptyMgr); Assert.AreEqual(2, ret.Count); Assert.AreEqual(node0, ret[0].Key); @@ -208,13 +209,13 @@ public void MultipleNodes_RemainSeparate() Assert.AreEqual(node1, ret[1].Key); Assert.AreEqual(e1, ret[1].Value[0]); } - + [Test] public void MultipleCreators_AggregatePerNode() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.AddOrAppendError(p1, node0, e1); - + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p1, node0.guid, e1); + var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); Assert.AreEqual(node0, ret[0].Key); @@ -226,9 +227,9 @@ public void MultipleCreators_AggregatePerNode() [Test] public void DuplicateEntries_AreNotIgnored() { - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - m_EmptyMgr.AddOrAppendError(p0, node0, e0); - + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); Assert.AreEqual(node0, ret[0].Key); @@ -268,9 +269,7 @@ public void GetList_RemovesZeroLengthLists() [Test] public void ClearNodesFromProvider_ClearsNodes() { - var n0 = new AndNode {tempId = node0}; - var n2 = new AndNode {tempId = node2}; - var nodesToClear = new List() { n0, n2 }; + var nodesToClear = new List { node0, node2 }; m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); @@ -281,9 +280,7 @@ public void ClearNodesFromProvider_ClearsNodes() [Test] public void ClearNodesFromProvider_LeavesOtherNodes() { - var n0 = new AndNode {tempId = node0}; - var n2 = new AndNode {tempId = node2}; - var nodesToClear = new List() { n0, n2 }; + var nodesToClear = new List { node0, node2 }; m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); @@ -299,4 +296,4 @@ public void ClearNodesFromProvider_LeavesOtherNodes() // m_ComplexMgr.AddOrAppendError(p1, node0, e1); // m_ComplexMgr.AddOrAppendError(p1, node1, e0); // m_ComplexMgr.AddOrAppendError(p1, node1, e1); -// m_ComplexMgr.AddOrAppendError(p1, node2, e3); \ No newline at end of file +// m_ComplexMgr.AddOrAppendError(p1, node2, e3); From 7f5cf291f2dba9f56f875d172ea3ff2f3cd548e2 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 10 Mar 2020 14:18:06 +0100 Subject: [PATCH 04/64] Fix tests --- .../Editor/UnitTests/MessageManagerTests.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs index cf8205f56d3..6fe54f4e1cf 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs @@ -69,7 +69,7 @@ public void AddMessage_CreatesMessage() var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0, ret[0].Key); + Assert.AreEqual(node0.guid, ret[0].Key); Assert.IsNotEmpty(ret[0].Value); Assert.AreEqual(e0, ret[0].Value[0]); } @@ -158,7 +158,7 @@ public void AppendMessage_AppendsMessage() var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0, ret[0].Key); + Assert.AreEqual(node0.guid, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e1, ret[0].Value[1]); @@ -204,9 +204,9 @@ public void MultipleNodes_RemainSeparate() var ret = GetListFrom(m_EmptyMgr); Assert.AreEqual(2, ret.Count); - Assert.AreEqual(node0, ret[0].Key); + Assert.AreEqual(node0.guid, ret[0].Key); Assert.AreEqual(e0, ret[0].Value[0]); - Assert.AreEqual(node1, ret[1].Key); + Assert.AreEqual(node1.guid, ret[1].Key); Assert.AreEqual(e1, ret[1].Value[0]); } @@ -218,7 +218,7 @@ public void MultipleCreators_AggregatePerNode() var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0, ret[0].Key); + Assert.AreEqual(node0.guid, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e1, ret[0].Value[1]); @@ -232,7 +232,7 @@ public void DuplicateEntries_AreNotIgnored() var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0, ret[0].Key); + Assert.AreEqual(node0.guid, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e0, ret[0].Value[1]); @@ -246,11 +246,11 @@ public void ClearAllFromProvider_ZerosMessageLists() var ret = GetListFrom(m_ComplexMgr); Assert.IsNotEmpty(ret); Assert.AreEqual(3, ret.Count); - Assert.AreEqual(node0, ret[0].Key); + Assert.AreEqual(node0.guid, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); - Assert.AreEqual(node1, ret[1].Key); + Assert.AreEqual(node1.guid, ret[1].Key); Assert.AreEqual(1, ret[1].Value.Count); - Assert.AreEqual(node2, ret[2].Key); + Assert.AreEqual(node2.guid, ret[2].Key); Assert.IsEmpty(ret[2].Value); } @@ -259,11 +259,11 @@ public void GetList_RemovesZeroLengthLists() { m_ComplexMgr.ClearAllFromProvider(p1); var ret = GetListFrom(m_ComplexMgr); - Assert.IsNotEmpty(ret.Where(kvp => kvp.Key.Equals(node2))); - Assert.IsEmpty(ret.First(kvp => kvp.Key.Equals(node2)).Value); + Assert.IsNotEmpty(ret.Where(kvp => kvp.Key.Equals(node2.guid))); + Assert.IsEmpty(ret.First(kvp => kvp.Key.Equals(node2.guid)).Value); ret = GetListFrom(m_ComplexMgr); - Assert.IsEmpty(ret.Where(kvp => kvp.Key.Equals(node2))); + Assert.IsEmpty(ret.Where(kvp => kvp.Key.Equals(node2.guid))); } [Test] @@ -273,8 +273,8 @@ public void ClearNodesFromProvider_ClearsNodes() m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); - Assert.AreEqual(2, ret.Find(kpv => kpv.Key.Equals(node0)).Value.Count); - Assert.IsEmpty(ret.Find(kvp => kvp.Key.Equals(node2)).Value); + Assert.AreEqual(2, ret.Find(kpv => kpv.Key.Equals(node0.guid)).Value.Count); + Assert.IsEmpty(ret.Find(kvp => kvp.Key.Equals(node2.guid)).Value); } [Test] @@ -284,7 +284,7 @@ public void ClearNodesFromProvider_LeavesOtherNodes() m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); - Assert.AreEqual(3, ret.Find(kpv => kpv.Key.Equals(node1)).Value.Count); + Assert.AreEqual(3, ret.Find(kpv => kpv.Key.Equals(node1.guid)).Value.Count); } } } From 3d670b3b588e31ada818fcf635e4ff62b1fe87ea Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Wed, 11 Mar 2020 13:20:54 +0100 Subject: [PATCH 05/64] Fix remaining cases of `JsonUtility.FromJson` --- .../Editor/Importers/ShaderGraphImporter.cs | 15 ++++++++++++--- .../Editor/Importers/ShaderSubGraphImporter.cs | 10 ++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index eba7002215f..a54ee23333b 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -9,6 +9,7 @@ using UnityEditor.Graphing; using UnityEditor.Graphing.Util; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; using Object = System.Object; namespace UnityEditor.ShaderGraph @@ -87,7 +88,11 @@ public override void OnImportAsset(AssetImportContext ctx) UnityEngine.Object mainObject; var textGraph = File.ReadAllText(path, Encoding.UTF8); - GraphData graph = JsonUtility.FromJson(textGraph); + if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) + { + textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; + } + var graph = MultiJson.Deserialize(textGraph); graph.messageManager = new MessageManager(); graph.assetGuid = AssetDatabase.AssetPathToGUID(path); graph.OnEnable(); @@ -180,7 +185,11 @@ internal static string GetShaderText(string path, out List configuredTextures, List sourceAssetDependencyPaths, out GraphData graph) { var textGraph = File.ReadAllText(path, Encoding.UTF8); - graph = JsonUtility.FromJson(textGraph); + if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) + { + textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; + } + graph = MultiJson.Deserialize(textGraph); graph.messageManager = new MessageManager(); graph.assetGuid = AssetDatabase.AssetPathToGUID(path); graph.OnEnable(); @@ -192,7 +201,7 @@ internal static string GetShaderText(string path, out List configuredTextures) { var textGraph = File.ReadAllText(path, Encoding.UTF8); - GraphData graph = JsonUtility.FromJson(textGraph); + GraphData graph = MultiJson.Deserialize(textGraph); graph.messageManager = new MessageManager(); graph.assetGuid = AssetDatabase.AssetPathToGUID(path); graph.OnEnable(); diff --git a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index b2ef9019871..0a96dcae5fa 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -9,6 +9,7 @@ using UnityEditor.Graphing; using UnityEditor.Graphing.Util; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; namespace UnityEditor.ShaderGraph { @@ -38,10 +39,15 @@ public override void OnImportAsset(AssetImportContext ctx) var subGraphGuid = AssetDatabase.AssetPathToGUID(subGraphPath); graphAsset.assetGuid = subGraphGuid; var textGraph = File.ReadAllText(subGraphPath, Encoding.UTF8); - var graphData = new GraphData { isSubGraph = true, assetGuid = subGraphGuid }; + if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) + { + textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; + } + var graphData = MultiJson.Deserialize(textGraph); + graphData.isSubGraph = true; + graphData.assetGuid = subGraphGuid; var messageManager = new MessageManager(); graphData.messageManager = messageManager; - JsonUtility.FromJsonOverwrite(textGraph, graphData); try { From 000a07c84d520e13c889dac7d9d58758b709d2b4 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Wed, 11 Mar 2020 16:18:31 +0100 Subject: [PATCH 06/64] Replace GraphData serialisation with MultiJson --- .../Editor/Drawing/MaterialGraphEditWindow.cs | 2 +- com.unity.shadergraph/Editor/Util/FileUtilities.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index 45b36267e60..97a390d0a0f 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -278,7 +278,7 @@ bool IsDirty() if (m_Deleted) return false; // Not dirty; it's gone. - var currentJson = EditorJsonUtility.ToJson(graphObject.graph, true); + var currentJson = MultiJson.Serialize(graphObject.graph); var fileJson = File.ReadAllText(AssetDatabase.GUIDToAssetPath(selectedGuid)); return !string.Equals(currentJson, fileJson, StringComparison.Ordinal); } diff --git a/com.unity.shadergraph/Editor/Util/FileUtilities.cs b/com.unity.shadergraph/Editor/Util/FileUtilities.cs index cfa92b7e3e5..5750aadbb88 100644 --- a/com.unity.shadergraph/Editor/Util/FileUtilities.cs +++ b/com.unity.shadergraph/Editor/Util/FileUtilities.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using UnityEditor.ShaderGraph.Serialization; using Debug = UnityEngine.Debug; using UnityEditor.VersionControl; @@ -7,14 +8,14 @@ namespace UnityEditor.ShaderGraph { static class FileUtilities { - public static bool WriteShaderGraphToDisk(string path, T data) + public static bool WriteShaderGraphToDisk(string path, GraphData data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } - return WriteToDisk(path, EditorJsonUtility.ToJson(data, true)); + return WriteToDisk(path, MultiJson.Serialize(data)); } public static bool WriteToDisk(string path, string text) From efb38873c265482ec7e86ef4ed9d16431f886243 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 12 Mar 2020 13:03:42 +0100 Subject: [PATCH 07/64] Strong & weak references - Added `JsonData` to represent strong references, i.e. include the value in the file. - `JsonRef` is now a weak reference, i.e. don't care if the referenced value is in the file or not. - Renamed `JsonRef.target` to `JsonRef.value` due to _target_ already being used heavily to mean other things in Shader Graph. --- .../Editor/Serialization/JsonData.cs | 68 +++++++++++++++++++ .../Editor/Serialization/JsonData.cs.meta | 3 + .../Editor/Serialization/JsonRef.cs | 24 +++---- .../Editor/Serialization/TargetEnumerable.cs | 2 +- 4 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 com.unity.shadergraph/Editor/Serialization/JsonData.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/JsonData.cs.meta diff --git a/com.unity.shadergraph/Editor/Serialization/JsonData.cs b/com.unity.shadergraph/Editor/Serialization/JsonData.cs new file mode 100644 index 00000000000..bd5c2714c3c --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/JsonData.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Serialization +{ + [Serializable] + struct JsonData : ISerializationCallbackReceiver + where T : JsonObject + { + [NonSerialized] + T m_Value; + + [SerializeField] + string m_Id; + + public T value => m_Value; + + public void OnBeforeSerialize() + { + if (MultiJsonInternal.isSerializing && m_Value != null && MultiJsonInternal.serializedSet.Add(m_Id)) + { + MultiJsonInternal.serializationQueue.Add(m_Value); + } + } + + public void OnAfterDeserialize() + { + if (MultiJsonInternal.isDeserializing) + { + try + { + m_Value = (T)MultiJsonInternal.instanceMap[m_Id]; + } + catch (Exception e) + { + // TODO: Allow custom logging function + Debug.LogException(e); + } + } + } + + public static implicit operator T(JsonData jsonRef) + { + return jsonRef.m_Value; + } + + public static implicit operator JsonData(T value) + { + return new JsonData { m_Value = value, m_Id = value.id }; + } + + public bool Equals(JsonData other) + { + return EqualityComparer.Default.Equals(m_Value, other.m_Value); + } + + public override bool Equals(object obj) + { + return obj is JsonData other && Equals(other); + } + + public override int GetHashCode() + { + return EqualityComparer.Default.GetHashCode(m_Value); + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/JsonData.cs.meta b/com.unity.shadergraph/Editor/Serialization/JsonData.cs.meta new file mode 100644 index 00000000000..66d7a5b6e65 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/JsonData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c1812610876546da8194467050b17d62 +timeCreated: 1584013614 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs index fc90276b4d0..32882450b94 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs @@ -8,24 +8,16 @@ namespace UnityEditor.ShaderGraph.Serialization struct JsonRef : ISerializationCallbackReceiver where T : JsonObject { - T m_Target; + [NonSerialized] + T m_Value; [SerializeField] string m_Id; - public T target => m_Target; + public T value => m_Value; public void OnBeforeSerialize() { - if (MultiJsonInternal.isSerializing && m_Target != null) - { - m_Id = m_Target.id; - - if (MultiJsonInternal.serializedSet.Add(m_Id)) - { - MultiJsonInternal.serializationQueue.Add(m_Target); - } - } } public void OnAfterDeserialize() @@ -34,7 +26,7 @@ public void OnAfterDeserialize() { try { - m_Target = (T)MultiJsonInternal.instanceMap[m_Id]; + m_Value = (T)MultiJsonInternal.instanceMap[m_Id]; } catch (Exception e) { @@ -46,17 +38,17 @@ public void OnAfterDeserialize() public static implicit operator T(JsonRef jsonRef) { - return jsonRef.m_Target; + return jsonRef.m_Value; } public static implicit operator JsonRef(T value) { - return new JsonRef { m_Target = value }; + return new JsonRef { m_Value = value, m_Id = value.id }; } public bool Equals(JsonRef other) { - return EqualityComparer.Default.Equals(m_Target, other.m_Target); + return EqualityComparer.Default.Equals(m_Value, other.m_Value); } public override bool Equals(object obj) @@ -66,7 +58,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return EqualityComparer.Default.GetHashCode(m_Target); + return EqualityComparer.Default.GetHashCode(m_Value); } } } diff --git a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs b/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs index df9323bb202..a895174d13d 100644 --- a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs +++ b/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs @@ -32,7 +32,7 @@ public Enumerator(List>.Enumerator enumerator) void IEnumerator.Reset() => ((IEnumerator)m_Enumerator).Reset(); - public T Current => m_Enumerator.Current.target; + public T Current => m_Enumerator.Current.value; object IEnumerator.Current => Current; From 8d5d714f15c0b53d0fddf909396d6c9d45cb86a1 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 12 Mar 2020 14:55:52 +0100 Subject: [PATCH 08/64] Unify variable names to `value` to avoid confusion --- .../Editor/Serialization/JsonData.cs | 2 +- .../Editor/Serialization/JsonRef.cs | 2 +- .../Editor/Serialization/MultiJsonInternal.cs | 34 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/com.unity.shadergraph/Editor/Serialization/JsonData.cs b/com.unity.shadergraph/Editor/Serialization/JsonData.cs index bd5c2714c3c..658b100f208 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonData.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonData.cs @@ -30,7 +30,7 @@ public void OnAfterDeserialize() { try { - m_Value = (T)MultiJsonInternal.instanceMap[m_Id]; + m_Value = (T)MultiJsonInternal.valueMap[m_Id]; } catch (Exception e) { diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs index 32882450b94..3c1e06a754c 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs @@ -26,7 +26,7 @@ public void OnAfterDeserialize() { try { - m_Value = (T)MultiJsonInternal.instanceMap[m_Id]; + m_Value = (T)MultiJsonInternal.valueMap[m_Id]; } catch (Exception e) { diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs index f2bd2891a7a..4a42741202a 100644 --- a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs @@ -11,7 +11,7 @@ static class MultiJsonInternal internal static bool isDeserializing; - internal static readonly Dictionary instanceMap = new Dictionary(); + internal static readonly Dictionary valueMap = new Dictionary(); static List s_Entries; @@ -92,7 +92,7 @@ public static void Enqueue(JsonObject jsonObject, string json) throw new InvalidOperationException("Can only Enqueue during JsonObject.OnAfterDeserialize."); } - instanceMap.Add(jsonObject.id, jsonObject); + valueMap.Add(jsonObject.id, jsonObject); s_Entries.Add(new MultiJsonEntry(jsonObject.GetType().FullName, jsonObject.id, json)); } @@ -121,13 +121,13 @@ public static JsonObject Deserialize(List entries) var entry = entries[index]; try { - var instance = CreateInstance(entry.type); + var value = CreateInstance(entry.type); if (entry.id == null) { - entries[index] = entry = new MultiJsonEntry(entry.type, instance.id, entry.json); + entries[index] = entry = new MultiJsonEntry(entry.type, value.id, entry.json); } - instanceMap[entry.id] = instance; + valueMap[entry.id] = value; } catch (Exception e) { @@ -146,11 +146,11 @@ public static JsonObject Deserialize(List entries) var entry = entries[i]; try { - var instance = instanceMap[entry.id]; - var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(instance.GetType()); - var fake = Activator.CreateInstance(fakeType, instance); + var value = valueMap[entry.id]; + var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(value.GetType()); + var fake = Activator.CreateInstance(fakeType, value); EditorJsonUtility.FromJsonOverwrite(entry.json, fake); - instance.OnAfterDeserialize(entry.json); + value.OnAfterDeserialize(entry.json); } catch (Exception e) { @@ -164,8 +164,8 @@ public static JsonObject Deserialize(List entries) { try { - var instance = instanceMap[entry.id]; - instance.OnAfterMultiDeserialize(entry.json); + var value = valueMap[entry.id]; + value.OnAfterMultiDeserialize(entry.json); } catch (Exception e) { @@ -173,11 +173,11 @@ public static JsonObject Deserialize(List entries) } } - return instanceMap[entries[0].id]; + return valueMap[entries[0].id]; } finally { - instanceMap.Clear(); + valueMap.Clear(); isDeserializing = false; } } @@ -201,11 +201,11 @@ public static string Serialize(JsonObject mainObject) // Not a foreach because the queue is populated by `JsonRef`s as we go. for (var i = 0; i < serializationQueue.Count; i++) { - var instance = serializationQueue[i]; - var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(instance.GetType()); - var fake = Activator.CreateInstance(fakeType, instance); + var value = serializationQueue[i]; + var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(value.GetType()); + var fake = Activator.CreateInstance(fakeType, value); var json = EditorJsonUtility.ToJson(fake, true); - idJsonList.Add((instance.id, json)); + idJsonList.Add((value.id, json)); } idJsonList.Sort((x, y) => From f28825e9e4d36a0d2870109ece9e283b46283683 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 12 Mar 2020 14:56:07 +0100 Subject: [PATCH 09/64] Use `MultiJson` in `GraphObject` --- .../Editor/Data/Implementation/GraphObject.cs | 21 ++++++++++++------- .../Editor/Drawing/MaterialGraphEditWindow.cs | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs b/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs index 16b6deaa4c3..2a63d1741d3 100644 --- a/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs +++ b/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs @@ -1,5 +1,6 @@ using System; using UnityEditor.ShaderGraph; +using UnityEditor.ShaderGraph.Serialization; using UnityEngine; namespace UnityEditor.Graphing @@ -58,7 +59,8 @@ public void OnBeforeSerialize() { if (graph != null) { - m_SerializedGraph = SerializationHelper.Serialize(graph); + var json = MultiJson.Serialize(graph); + m_SerializedGraph = new SerializationHelper.JSONSerializedElement { JSONnodeData = json }; m_IsSubGraph = graph.isSubGraph; m_AssetGuid = graph.assetGuid; } @@ -66,10 +68,6 @@ public void OnBeforeSerialize() public void OnAfterDeserialize() { - if (graph == null) - { - graph = DeserializeGraph(); - } } public bool wasUndoRedoPerformed => m_DeserializedVersion != m_SerializedVersion; @@ -83,11 +81,16 @@ public void HandleUndoRedo() GraphData DeserializeGraph() { - var deserializedGraph = SerializationHelper.Deserialize(m_SerializedGraph, GraphUtil.GetLegacyTypeRemapping()); + var json = m_SerializedGraph.JSONnodeData; + if (!json.StartsWith("{\n \"MonoBehaviour\":")) + { + json = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{json.Substring(json.IndexOf("{")+1)}}}"; + } + var deserializedGraph = MultiJson.Deserialize(json); deserializedGraph.isSubGraph = m_IsSubGraph; deserializedGraph.assetGuid = m_AssetGuid; m_DeserializedVersion = m_SerializedVersion; - m_SerializedGraph = default(SerializationHelper.JSONSerializedElement); + m_SerializedGraph = default; return deserializedGraph; } @@ -102,6 +105,10 @@ public void Validate() void OnEnable() { + if (graph == null && m_SerializedGraph.JSONnodeData != null) + { + graph = DeserializeGraph(); + } Validate(); } diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index 97a390d0a0f..a1a751a920e 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -275,7 +275,7 @@ void OnDisable() bool IsDirty() { - if (m_Deleted) + if (m_Deleted || graphObject.graph == null) return false; // Not dirty; it's gone. var currentJson = MultiJson.Serialize(graphObject.graph); From 7f0d87b67b9132318d5cd67ebeca72caa7159788 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 12 Mar 2020 15:06:16 +0100 Subject: [PATCH 10/64] Remove unused variable from TempId removal --- com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index be1ae26e779..6b4454bee78 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -74,9 +74,6 @@ public IEnumerable movedInputs #region Node data - [NonSerialized] - Stack m_FreeNodeTempIds = new Stack(); - [NonSerialized] List m_Nodes = new List(); From f383263cedc3a190170d5fafd8c7ce984aabdf5d Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Mon, 16 Mar 2020 16:12:31 +0100 Subject: [PATCH 11/64] Get rid of `FakeScriptableObject` --- .../Editor/Drawing/MaterialGraphEditWindow.cs | 4 --- .../Editor/Importers/ShaderGraphImporter.cs | 8 ----- .../Importers/ShaderSubGraphImporter.cs | 4 --- .../Editor/Serialization/FakeJsonObject.cs | 2 +- .../Serialization/FakeScriptableObject.cs | 17 ---------- .../FakeScriptableObject.cs.meta | 3 -- .../Editor/Serialization/JsonObject.cs | 24 -------------- .../Editor/Serialization/MultiJson.cs | 2 +- .../Editor/Serialization/MultiJsonInternal.cs | 31 +++++++++++-------- 9 files changed, 20 insertions(+), 75 deletions(-) delete mode 100644 com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs delete mode 100644 com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index a1a751a920e..a74842b2026 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -805,10 +805,6 @@ public void Initialize(string assetGuid) selectedGuid = assetGuid; var textGraph = File.ReadAllText(path, Encoding.UTF8); - if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) - { - textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; - } graphObject = CreateInstance(); graphObject.hideFlags = HideFlags.HideAndDontSave; graphObject.graph = MultiJson.Deserialize(textGraph); diff --git a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index a54ee23333b..752ad3ffda4 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -88,10 +88,6 @@ public override void OnImportAsset(AssetImportContext ctx) UnityEngine.Object mainObject; var textGraph = File.ReadAllText(path, Encoding.UTF8); - if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) - { - textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; - } var graph = MultiJson.Deserialize(textGraph); graph.messageManager = new MessageManager(); graph.assetGuid = AssetDatabase.AssetPathToGUID(path); @@ -185,10 +181,6 @@ internal static string GetShaderText(string path, out List configuredTextures, List sourceAssetDependencyPaths, out GraphData graph) { var textGraph = File.ReadAllText(path, Encoding.UTF8); - if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) - { - textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; - } graph = MultiJson.Deserialize(textGraph); graph.messageManager = new MessageManager(); graph.assetGuid = AssetDatabase.AssetPathToGUID(path); diff --git a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index 0a96dcae5fa..bd51e93247f 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -39,10 +39,6 @@ public override void OnImportAsset(AssetImportContext ctx) var subGraphGuid = AssetDatabase.AssetPathToGUID(subGraphPath); graphAsset.assetGuid = subGraphGuid; var textGraph = File.ReadAllText(subGraphPath, Encoding.UTF8); - if (!textGraph.StartsWith("{\n \"MonoBehaviour\":")) - { - textGraph = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{textGraph.Substring(textGraph.IndexOf("{")+1)}}}"; - } var graphData = MultiJson.Deserialize(textGraph); graphData.isSubGraph = true; graphData.assetGuid = subGraphGuid; diff --git a/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs index d5a0c9e521e..b578213da9c 100644 --- a/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs +++ b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs @@ -4,7 +4,7 @@ namespace UnityEditor.ShaderGraph.Serialization { [Serializable] - public struct FakeJsonObject + public class FakeJsonObject { [SerializeField] string m_Type; diff --git a/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs b/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs deleted file mode 100644 index 4f3c7cb533a..00000000000 --- a/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace UnityEditor.ShaderGraph.Serialization -{ - [Serializable] - class FakeScriptableObject - { - public T MonoBehaviour; - - public FakeScriptableObject() {} - - public FakeScriptableObject(T value) - { - MonoBehaviour = value; - } - } -} diff --git a/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta b/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta deleted file mode 100644 index 2554b9600e7..00000000000 --- a/com.unity.shadergraph/Editor/Serialization/FakeScriptableObject.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9e418566a25245bf83c1fed7f9cfe1da -timeCreated: 1581597833 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/JsonObject.cs b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs index 392a1d2d31b..425098eb8ef 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonObject.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs @@ -6,23 +6,6 @@ namespace UnityEditor.ShaderGraph.Serialization [Serializable] public class JsonObject : ISerializationCallbackReceiver { - // We have some fields in here to match the output of ScriptableObject. - // This is to prevent introducing big changes to Shader Graph files - // when we make JsonObject inherit ScriptableObject in the future. -#pragma warning disable 414 - [SerializeField] - bool m_Enabled = true; - - [SerializeField] - int m_EditorHideFlags = 0; - - [SerializeField] - string m_Name = default; - - [SerializeField] - string m_EditorClassIdentifier = default; -#pragma warning restore 414 - [SerializeField] string m_Type; @@ -31,15 +14,8 @@ public class JsonObject : ISerializationCallbackReceiver public string id => m_Id; - public string name - { - get => m_Name; - set => m_Name = value; - } - void ISerializationCallbackReceiver.OnBeforeSerialize() { - m_EditorClassIdentifier = $"{GetType().Assembly.GetName().Name}:{GetType().Namespace}:{GetType().Name}"; m_Type = $"{GetType().FullName}"; OnBeforeSerialize(); } diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJson.cs b/com.unity.shadergraph/Editor/Serialization/MultiJson.cs index d179abb11b1..ff96eae6343 100644 --- a/com.unity.shadergraph/Editor/Serialization/MultiJson.cs +++ b/com.unity.shadergraph/Editor/Serialization/MultiJson.cs @@ -7,7 +7,7 @@ static class MultiJson { public static T Deserialize(string json) where T : JsonObject { - var entries = MultiJsonInternal.Parse(json); + var entries = MultiJsonInternal.Parse(json, typeof(T).FullName); return (T)MultiJsonInternal.Deserialize(entries); } diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs index 4a42741202a..d0664fdbe73 100644 --- a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs @@ -49,12 +49,12 @@ static Dictionary CreateTypeMap() return map; } - public static List Parse(string str) + public static List Parse(string str, string mainTypeFallback) { var result = new List(); - var separatorStr = $"\n\n"; + const string separatorStr = "\n\n"; var startIndex = 0; - var raw = new FakeScriptableObject(); + var raw = new FakeJsonObject(); while (startIndex < str.Length) { @@ -71,13 +71,22 @@ public static List Parse(string str) } var json = str.Substring(jsonBegin, jsonEnd - jsonBegin); + JsonUtility.FromJsonOverwrite(json, raw); - if (string.IsNullOrWhiteSpace(raw.MonoBehaviour.type)) + if (string.IsNullOrWhiteSpace(raw.type)) { - throw new InvalidOperationException("Type is null or whitespace."); + if (startIndex == 0) + { + raw.type = mainTypeFallback; + } + else + { + throw new InvalidOperationException($"Type is null or whitespace in JSON:\n{json}"); + } } - result.Add(new MultiJsonEntry(raw.MonoBehaviour.type, raw.MonoBehaviour.id, json)); - raw.MonoBehaviour.Reset(); + + result.Add(new MultiJsonEntry(raw.type, raw.id, json)); + raw.Reset(); startIndex = jsonEnd + separatorStr.Length; } @@ -147,9 +156,7 @@ public static JsonObject Deserialize(List entries) try { var value = valueMap[entry.id]; - var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(value.GetType()); - var fake = Activator.CreateInstance(fakeType, value); - EditorJsonUtility.FromJsonOverwrite(entry.json, fake); + EditorJsonUtility.FromJsonOverwrite(entry.json, value); value.OnAfterDeserialize(entry.json); } catch (Exception e) @@ -202,9 +209,7 @@ public static string Serialize(JsonObject mainObject) for (var i = 0; i < serializationQueue.Count; i++) { var value = serializationQueue[i]; - var fakeType = typeof(FakeScriptableObject<>).MakeGenericType(value.GetType()); - var fake = Activator.CreateInstance(fakeType, value); - var json = EditorJsonUtility.ToJson(fake, true); + var json = EditorJsonUtility.ToJson(value, true); idJsonList.Add((value.id, json)); } From b414433a75d115f4b808f8571ad2896eb1a0010d Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 17 Mar 2020 10:23:43 +0100 Subject: [PATCH 12/64] Enumerables for weak/strong references --- .../Editor/Serialization/RefDataEnumerable.cs | 42 +++++++++++++++++++ .../Serialization/RefDataEnumerable.cs.meta | 3 ++ ...getEnumerable.cs => RefValueEnumerable.cs} | 4 +- ...ble.cs.meta => RefValueEnumerable.cs.meta} | 0 .../Serialization/SerializationExtensions.cs | 7 +++- 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs create mode 100644 com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs.meta rename com.unity.shadergraph/Editor/Serialization/{TargetEnumerable.cs => RefValueEnumerable.cs} (90%) rename com.unity.shadergraph/Editor/Serialization/{TargetEnumerable.cs.meta => RefValueEnumerable.cs.meta} (100%) diff --git a/com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs b/com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs new file mode 100644 index 00000000000..af4f6f03d83 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs @@ -0,0 +1,42 @@ +using System.Collections; +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph.Serialization +{ + struct DataValueEnumerable : IEnumerable + where T : JsonObject + { + List> m_List; + + public DataValueEnumerable(List> list) + { + m_List = list; + } + + public Enumerator GetEnumerator() => new Enumerator(m_List.GetEnumerator()); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public struct Enumerator : IEnumerator + { + List>.Enumerator m_Enumerator; + + public Enumerator(List>.Enumerator enumerator) + { + m_Enumerator = enumerator; + } + + public bool MoveNext() => m_Enumerator.MoveNext(); + + void IEnumerator.Reset() => ((IEnumerator)m_Enumerator).Reset(); + + public T Current => m_Enumerator.Current.value; + + object IEnumerator.Current => Current; + + public void Dispose() => m_Enumerator.Dispose(); + } + } +} diff --git a/com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs.meta b/com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs.meta new file mode 100644 index 00000000000..836fa220545 --- /dev/null +++ b/com.unity.shadergraph/Editor/Serialization/RefDataEnumerable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 57a79624959347419f3ed039bdee4f81 +timeCreated: 1584023353 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs b/com.unity.shadergraph/Editor/Serialization/RefValueEnumerable.cs similarity index 90% rename from com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs rename to com.unity.shadergraph/Editor/Serialization/RefValueEnumerable.cs index a895174d13d..6b30d24c4fa 100644 --- a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs +++ b/com.unity.shadergraph/Editor/Serialization/RefValueEnumerable.cs @@ -3,12 +3,12 @@ namespace UnityEditor.ShaderGraph.Serialization { - struct TargetEnumerable : IEnumerable + struct RefValueEnumerable : IEnumerable where T : JsonObject { List> m_List; - public TargetEnumerable(List> list) + public RefValueEnumerable(List> list) { m_List = list; } diff --git a/com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs.meta b/com.unity.shadergraph/Editor/Serialization/RefValueEnumerable.cs.meta similarity index 100% rename from com.unity.shadergraph/Editor/Serialization/TargetEnumerable.cs.meta rename to com.unity.shadergraph/Editor/Serialization/RefValueEnumerable.cs.meta diff --git a/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs b/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs index abaaca81e0c..a2acedbaea4 100644 --- a/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs +++ b/com.unity.shadergraph/Editor/Serialization/SerializationExtensions.cs @@ -4,8 +4,11 @@ namespace UnityEditor.ShaderGraph.Serialization { static class SerializationExtensions { - public static TargetEnumerable SelectTarget(this List> list) where T : JsonObject => - new TargetEnumerable(list); + public static RefValueEnumerable SelectValue(this List> list) where T : JsonObject => + new RefValueEnumerable(list); + + public static DataValueEnumerable SelectValue(this List> list) where T : JsonObject => + new DataValueEnumerable(list); public static void AddRange(this List> list, IEnumerable enumerable) where T : JsonObject From fde60c2303e3c26d07bab0da70ef9bed78dedca2 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 17 Mar 2020 10:25:18 +0100 Subject: [PATCH 13/64] Forgot a FakeScriptableObject upgrade path --- .../Editor/Data/Implementation/GraphObject.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs b/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs index 2a63d1741d3..553502c9e07 100644 --- a/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs +++ b/com.unity.shadergraph/Editor/Data/Implementation/GraphObject.cs @@ -82,10 +82,6 @@ public void HandleUndoRedo() GraphData DeserializeGraph() { var json = m_SerializedGraph.JSONnodeData; - if (!json.StartsWith("{\n \"MonoBehaviour\":")) - { - json = $"{{\"MonoBehaviour\":{{\"m_Type\":\"{typeof(GraphData).FullName}\",{json.Substring(json.IndexOf("{")+1)}}}"; - } var deserializedGraph = MultiJson.Deserialize(json); deserializedGraph.isSubGraph = m_IsSubGraph; deserializedGraph.assetGuid = m_AssetGuid; From 44bc94df8e7d0c4fcca2124958b7c1b86acf90f6 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 17 Mar 2020 10:46:30 +0100 Subject: [PATCH 14/64] Convert AbstractMaterialNode to JsonObject --- .../Editor/Data/Graphs/GraphData.cs | 66 +++++++++++++------ com.unity.shadergraph/Editor/Data/Legacy.meta | 3 + .../Editor/Data/Legacy/GraphData0.cs | 12 ++++ .../Editor/Data/Legacy/GraphData0.cs.meta | 3 + .../Editor/Data/Nodes/AbstractMaterialNode.cs | 7 +- 5 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 com.unity.shadergraph/Editor/Data/Legacy.meta create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs.meta diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 6b4454bee78..c7c80436687 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Text.RegularExpressions; using UnityEngine; using UnityEditor.Graphing; using UnityEditor.Graphing.Util; using UnityEditor.Rendering; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Legacy; using UnityEditor.ShaderGraph.Serialization; using Edge = UnityEditor.Graphing.Edge; @@ -18,6 +20,11 @@ namespace UnityEditor.ShaderGraph [FormerName("UnityEditor.ShaderGraph.AbstractMaterialGraph")] sealed class GraphData : JsonObject { + const int k_CurrentVersion = 1; + + [SerializeField] + int m_Version; + public GraphObject owner { get; set; } #region Input data @@ -74,20 +81,17 @@ public IEnumerable movedInputs #region Node data - [NonSerialized] - List m_Nodes = new List(); + [SerializeField] + List> m_Nodes = new List>(); [NonSerialized] Dictionary m_NodeDictionary = new Dictionary(); public IEnumerable GetNodes() { - return m_Nodes.Where(x => x != null).OfType(); + return m_Nodes.SelectValue().OfType(); } - [SerializeField] - List m_SerializableNodes = new List(); - [NonSerialized] List m_AddedNodes = new List(); @@ -1098,7 +1102,7 @@ public void ReplaceWith(GraphData other) using (var removedNodesPooledObject = ListPool.GetDisposable()) { var removedNodeGuids = removedNodesPooledObject.value; - removedNodeGuids.AddRange(m_Nodes.Where(n => n != null).Select(n => n.guid)); + removedNodeGuids.AddRange(m_Nodes.Select(n => n.value.guid)); foreach (var nodeGuid in removedNodeGuids) RemoveNodeNoValidate(m_NodeDictionary[nodeGuid]); } @@ -1258,9 +1262,6 @@ internal void PasteGraph(CopyPasteGraph graphToPaste, List public override void OnBeforeSerialize() { - var nodes = GetNodes().ToList(); - nodes.Sort((x1, x2) => x1.guid.CompareTo(x2.guid)); - m_SerializableNodes = SerializationHelper.Serialize(nodes.AsEnumerable()); m_Edges.Sort(); m_SerializableEdges = SerializationHelper.Serialize(m_Edges); m_SerializedProperties = SerializationHelper.Serialize(m_Properties); @@ -1268,27 +1269,56 @@ public override void OnBeforeSerialize() m_ActiveOutputNodeGuidSerialized = m_ActiveOutputNodeGuid == Guid.Empty ? null : m_ActiveOutputNodeGuid.ToString(); } - public override void OnAfterDeserialize() + static JsonObject DeserializeLegacy(string typeString, string json) + { + var value = MultiJsonInternal.CreateInstance(typeString); + if (value == null) + { + Debug.Log($"Cannot create instance for {typeString}"); + return null; + } + + MultiJsonInternal.Enqueue(value, json); + + return value; + } + + public override void OnAfterDeserialize(string json) + { + if (m_Version == 0) + { + var graphData0 = JsonUtility.FromJson(json); + foreach (var serializedElement in graphData0.m_SerializableNodes) + { + var node = (AbstractMaterialNode)DeserializeLegacy(serializedElement.typeInfo.fullName, serializedElement.JSONnodeData); + if (node == null) + { + continue; + } + m_Nodes.Add(node); + } + } + + m_Version = k_CurrentVersion; + } + + public override void OnAfterMultiDeserialize(string json) { // have to deserialize 'globals' before nodes m_Properties = SerializationHelper.Deserialize(m_SerializedProperties, GraphUtil.GetLegacyTypeRemapping()); m_Keywords = SerializationHelper.Deserialize(m_SerializedKeywords, GraphUtil.GetLegacyTypeRemapping()); - var nodes = SerializationHelper.Deserialize(m_SerializableNodes, GraphUtil.GetLegacyTypeRemapping()); - - m_Nodes = new List(nodes.Count); - m_NodeDictionary = new Dictionary(nodes.Count); + m_NodeDictionary = new Dictionary(m_Nodes.Count); foreach (var group in m_Groups) { m_GroupItems.Add(group.guid, new List()); } - foreach (var node in nodes) + foreach (var node in m_Nodes.SelectValue()) { node.owner = this; node.UpdateNodeAfterDeserialization(); - m_Nodes.Add(node); m_NodeDictionary.Add(node.guid, node); m_GroupItems[node.groupGuid].Add(node); } @@ -1298,8 +1328,6 @@ public override void OnAfterDeserialize() m_GroupItems[stickyNote.groupGuid].Add(stickyNote); } - m_SerializableNodes = null; - m_Edges = SerializationHelper.Deserialize(m_SerializableEdges, GraphUtil.GetLegacyTypeRemapping()); m_SerializableEdges = null; foreach (var edge in m_Edges) diff --git a/com.unity.shadergraph/Editor/Data/Legacy.meta b/com.unity.shadergraph/Editor/Data/Legacy.meta new file mode 100644 index 00000000000..a660623ca23 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 624f34d4e59649fd80163f3590d97d73 +timeCreated: 1584021721 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs new file mode 100644 index 00000000000..70c8639e636 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using UnityEditor.Graphing; + +namespace UnityEditor.ShaderGraph.Legacy +{ + [Serializable] + class GraphData0 + { + public List m_SerializableNodes; + } +} diff --git a/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs.meta b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs.meta new file mode 100644 index 00000000000..55f5316c81c --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f557c79fd76a40d6a39798750426c9f8 +timeCreated: 1584021741 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs index 039d6151bf2..8e737eb578a 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs @@ -5,11 +5,12 @@ using UnityEditor.Graphing; using UnityEditor.ShaderGraph.Drawing.Colors; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; namespace UnityEditor.ShaderGraph { [Serializable] - abstract class AbstractMaterialNode : ISerializationCallbackReceiver, IGroupItem + abstract class AbstractMaterialNode : JsonObject, IGroupItem { [NonSerialized] private Guid m_Guid; @@ -692,14 +693,14 @@ public virtual IEnumerable GetInputsWithNoConnection() return this.GetInputSlots().Where(x => !owner.GetEdges(GetSlotReference(x.id)).Any()); } - public virtual void OnBeforeSerialize() + public override void OnBeforeSerialize() { m_GuidSerialized = m_Guid.ToString(); m_GroupGuidSerialized = m_GroupGuid.ToString(); m_SerializableSlots = SerializationHelper.Serialize(m_Slots); } - public virtual void OnAfterDeserialize() + public override void OnAfterDeserialize() { if (!string.IsNullOrEmpty(m_GuidSerialized)) m_Guid = new Guid(m_GuidSerialized); From a90d02a5b5b4aa34317e24ee42d9dc330eeb2fde Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 17 Mar 2020 10:48:12 +0100 Subject: [PATCH 15/64] Fix formatting in MinimalGraphData --- .../Editor/Data/Graphs/MinimalGraphData.cs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs index ad403f876dd..13b8f20a338 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs @@ -5,7 +5,7 @@ using UnityEditor.Graphing; using UnityEngine; - namespace UnityEditor.ShaderGraph +namespace UnityEditor.ShaderGraph { /// /// Minimal version of used for gathering dependencies. This allows us to not deserialize @@ -19,7 +19,7 @@ class MinimalGraphData : ISerializationCallbackReceiver { static Dictionary s_MinimalTypeMap = CreateMinimalTypeMap(); - static Dictionary CreateMinimalTypeMap() + static Dictionary CreateMinimalTypeMap() { var types = new Dictionary(); foreach (var nodeType in TypeCache.GetTypesWithAttribute()) @@ -31,23 +31,24 @@ static Dictionary CreateMinimalTypeMap() continue; } - types.Add(nodeType.FullName, dependencyAttribute.minimalType); + types.Add(nodeType.FullName, dependencyAttribute.minimalType); - var formerNameAttributes = (FormerNameAttribute[])nodeType.GetCustomAttributes(typeof(FormerNameAttribute), false); + var formerNameAttributes = (FormerNameAttribute[])nodeType.GetCustomAttributes(typeof(FormerNameAttribute), false); foreach (var formerNameAttribute in formerNameAttributes) { types.Add(formerNameAttribute.fullName, dependencyAttribute.minimalType); } } + return types; } - [SerializeField] + [SerializeField] List m_SerializableNodes = new List(); - public List dependencies { get; set; } + public List dependencies { get; set; } - public void OnAfterDeserialize() + public void OnAfterDeserialize() { foreach (var element in m_SerializableNodes) { @@ -60,22 +61,20 @@ public void OnAfterDeserialize() } } - public void OnBeforeSerialize() - { - } + public void OnBeforeSerialize() { } - public static string[] GetDependencyPaths(string assetPath) + public static string[] GetDependencyPaths(string assetPath) { var dependencies = new List(); GetDependencyPaths(assetPath, dependencies); return dependencies.ToArray(); } - public static void GetDependencyPaths(string assetPath, List dependencies) + public static void GetDependencyPaths(string assetPath, List dependencies) { var textGraph = File.ReadAllText(assetPath, Encoding.UTF8); var minimalGraphData = new MinimalGraphData { dependencies = dependencies }; JsonUtility.FromJsonOverwrite(textGraph, minimalGraphData); } } -} \ No newline at end of file +} From ddb5c51aa57f85015b7abd827d54ed237da553fe Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Tue, 17 Mar 2020 15:56:51 +0100 Subject: [PATCH 16/64] Upgrade MinimalGraphData to use MultiJson --- .../Editor/Data/Graphs/MinimalGraphData.cs | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs index 13b8f20a338..9f03be67702 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/MinimalGraphData.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text; using UnityEditor.Graphing; +using UnityEditor.ShaderGraph.Serialization; using UnityEngine; namespace UnityEditor.ShaderGraph @@ -15,25 +17,25 @@ namespace UnityEditor.ShaderGraph /// want to avoid the extra GC pressure. /// [Serializable] - class MinimalGraphData : ISerializationCallbackReceiver + class MinimalGraphData { static Dictionary s_MinimalTypeMap = CreateMinimalTypeMap(); static Dictionary CreateMinimalTypeMap() { var types = new Dictionary(); - foreach (var nodeType in TypeCache.GetTypesWithAttribute()) + foreach (var type in TypeCache.GetTypesWithAttribute()) { - var dependencyAttribute = (HasDependenciesAttribute)nodeType.GetCustomAttributes(typeof(HasDependenciesAttribute), false)[0]; + var dependencyAttribute = (HasDependenciesAttribute)type.GetCustomAttributes(typeof(HasDependenciesAttribute), false)[0]; if (!typeof(IHasDependencies).IsAssignableFrom(dependencyAttribute.minimalType)) { - Debug.LogError($"{nodeType} must implement {typeof(IHasDependencies)} to be used in {typeof(HasDependenciesAttribute)}"); + Debug.LogError($"{type} must implement {typeof(IHasDependencies)} to be used in {typeof(HasDependenciesAttribute)}"); continue; } - types.Add(nodeType.FullName, dependencyAttribute.minimalType); + types.Add(type.FullName, dependencyAttribute.minimalType); - var formerNameAttributes = (FormerNameAttribute[])nodeType.GetCustomAttributes(typeof(FormerNameAttribute), false); + var formerNameAttributes = (FormerNameAttribute[])type.GetCustomAttributes(typeof(FormerNameAttribute), false); foreach (var formerNameAttribute in formerNameAttributes) { types.Add(formerNameAttribute.fullName, dependencyAttribute.minimalType); @@ -46,23 +48,6 @@ static Dictionary CreateMinimalTypeMap() [SerializeField] List m_SerializableNodes = new List(); - public List dependencies { get; set; } - - public void OnAfterDeserialize() - { - foreach (var element in m_SerializableNodes) - { - if (s_MinimalTypeMap.TryGetValue(element.typeInfo.fullName, out var minimalType)) - { - var instance = (IHasDependencies)Activator.CreateInstance(minimalType); - JsonUtility.FromJsonOverwrite(element.JSONnodeData, instance); - instance.GetSourceAssetDependencies(dependencies); - } - } - } - - public void OnBeforeSerialize() { } - public static string[] GetDependencyPaths(string assetPath) { var dependencies = new List(); @@ -73,8 +58,27 @@ public static string[] GetDependencyPaths(string assetPath) public static void GetDependencyPaths(string assetPath, List dependencies) { var textGraph = File.ReadAllText(assetPath, Encoding.UTF8); - var minimalGraphData = new MinimalGraphData { dependencies = dependencies }; - JsonUtility.FromJsonOverwrite(textGraph, minimalGraphData); + var minimalGraphDataName = typeof(MinimalGraphData).FullName; + var entries = MultiJsonInternal.Parse(textGraph, minimalGraphDataName); + + if (entries[0].type == minimalGraphDataName) + { + var minimalGraphData = JsonUtility.FromJson(textGraph); + foreach (var node in minimalGraphData.m_SerializableNodes) + { + entries.Add(new MultiJsonEntry(node.typeInfo.fullName, null, node.JSONnodeData)); + } + } + + foreach (var entry in entries) + { + if (s_MinimalTypeMap.TryGetValue(entry.type, out var minimalType)) + { + var instance = (IHasDependencies)Activator.CreateInstance(minimalType); + JsonUtility.FromJsonOverwrite(entry.json, instance); + instance.GetSourceAssetDependencies(dependencies); + } + } } } } From 707a9efbb36bfc2eb2791fe626f33e052439dc3b Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Wed, 18 Mar 2020 12:42:00 +0100 Subject: [PATCH 17/64] Comment out copy paste and to sub graph implementation for now --- .../Editor/Data/Graphs/GraphData.cs | 261 ++++---- .../Editor/Drawing/MaterialGraphEditWindow.cs | 628 +++++++++--------- 2 files changed, 444 insertions(+), 445 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index c7c80436687..0a2ffb0ece6 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -1128,142 +1128,141 @@ public void ReplaceWith(GraphData other) internal void PasteGraph(CopyPasteGraph graphToPaste, List remappedNodes, List remappedEdges) { - var groupGuidMap = new Dictionary(); - foreach (var group in graphToPaste.groups) - { - var position = group.position; - position.x += 30; - position.y += 30; - - GroupData newGroup = new GroupData(group.title, position); - - var oldGuid = group.guid; - var newGuid = newGroup.guid; - groupGuidMap[oldGuid] = newGuid; - - AddGroup(newGroup); - m_PastedGroups.Add(newGroup); - } - - foreach (var stickyNote in graphToPaste.stickyNotes) - { - var position = stickyNote.position; - position.x += 30; - position.y += 30; - - StickyNoteData pastedStickyNote = new StickyNoteData(stickyNote.title, stickyNote.content, position); - if (groupGuidMap.ContainsKey(stickyNote.groupGuid)) - { - pastedStickyNote.groupGuid = groupGuidMap[stickyNote.groupGuid]; - } - - AddStickyNote(pastedStickyNote); - m_PastedStickyNotes.Add(pastedStickyNote); - } - - var nodeGuidMap = new Dictionary(); - foreach (var node in graphToPaste.GetNodes()) - { - AbstractMaterialNode pastedNode = node; - - var oldGuid = node.guid; - var newGuid = node.RewriteGuid(); - nodeGuidMap[oldGuid] = newGuid; - - // Check if the property nodes need to be made into a concrete node. - if (node is PropertyNode propertyNode) - { - // If the property is not in the current graph, do check if the - // property can be made into a concrete node. - if (!m_Properties.Select(x => x.guid).Contains(propertyNode.propertyGuid)) - { - // If the property is in the serialized paste graph, make the property node into a property node. - var pastedGraphMetaProperties = graphToPaste.metaProperties.Where(x => x.guid == propertyNode.propertyGuid); - if (pastedGraphMetaProperties.Any()) - { - pastedNode = pastedGraphMetaProperties.FirstOrDefault().ToConcreteNode(); - pastedNode.drawState = node.drawState; - nodeGuidMap[oldGuid] = pastedNode.guid; - } - } - } - - AbstractMaterialNode abstractMaterialNode = (AbstractMaterialNode)node; - - // If the node has a group guid and no group has been copied, reset the group guid. - // Check if the node is inside a group - if (abstractMaterialNode.groupGuid != Guid.Empty) - { - if (groupGuidMap.ContainsKey(abstractMaterialNode.groupGuid)) - { - var absNode = pastedNode as AbstractMaterialNode; - absNode.groupGuid = groupGuidMap[abstractMaterialNode.groupGuid]; - pastedNode = absNode; - } - else - { - pastedNode.groupGuid = Guid.Empty; - } - } - - var drawState = node.drawState; - var position = drawState.position; - position.x += 30; - position.y += 30; - drawState.position = position; - node.drawState = drawState; - remappedNodes.Add(pastedNode); - AddNode(pastedNode); - - // add the node to the pasted node list - m_PastedNodes.Add(pastedNode); - - // Check if the keyword nodes need to have their keywords copied. - if (node is KeywordNode keywordNode) - { - // If the keyword is not in the current graph and is in the serialized paste graph copy it. - if (!keywords.Select(x => x.guid).Contains(keywordNode.keywordGuid)) - { - var pastedGraphMetaKeywords = graphToPaste.metaKeywords.Where(x => x.guid == keywordNode.keywordGuid); - if (pastedGraphMetaKeywords.Any()) - { - var keyword = pastedGraphMetaKeywords.FirstOrDefault(x => x.guid == keywordNode.keywordGuid); - SanitizeGraphInputName(keyword); - SanitizeGraphInputReferenceName(keyword, keyword.overrideReferenceName); - AddGraphInput(keyword); - } - } - - // Always update Keyword nodes to handle any collisions resolved on the Keyword - keywordNode.UpdateNode(); - } - } - - // only connect edges within pasted elements, discard - // external edges. - foreach (var edge in graphToPaste.edges) - { - var outputSlot = edge.outputSlot; - var inputSlot = edge.inputSlot; - - Guid remappedOutputNodeGuid; - Guid remappedInputNodeGuid; - if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid) - && nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid)) - { - var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId); - var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId); - remappedEdges.Add(Connect(outputSlotRef, inputSlotRef)); - } - } - - ValidateGraph(); + // var groupGuidMap = new Dictionary(); + // foreach (var group in graphToPaste.groups) + // { + // var position = group.position; + // position.x += 30; + // position.y += 30; + // + // GroupData newGroup = new GroupData(group.title, position); + // + // var oldGuid = group.guid; + // var newGuid = newGroup.guid; + // groupGuidMap[oldGuid] = newGuid; + // + // AddGroup(newGroup); + // m_PastedGroups.Add(newGroup); + // } + // + // foreach (var stickyNote in graphToPaste.stickyNotes) + // { + // var position = stickyNote.position; + // position.x += 30; + // position.y += 30; + // + // StickyNoteData pastedStickyNote = new StickyNoteData(stickyNote.title, stickyNote.content, position); + // if (groupGuidMap.ContainsKey(stickyNote.groupGuid)) + // { + // pastedStickyNote.groupGuid = groupGuidMap[stickyNote.groupGuid]; + // } + // + // AddStickyNote(pastedStickyNote); + // m_PastedStickyNotes.Add(pastedStickyNote); + // } + // + // var nodeGuidMap = new Dictionary(); + // foreach (var node in graphToPaste.GetNodes()) + // { + // AbstractMaterialNode pastedNode = node; + // + // var oldGuid = node.guid; + // var newGuid = node.RewriteGuid(); + // nodeGuidMap[oldGuid] = newGuid; + // + // // Check if the property nodes need to be made into a concrete node. + // if (node is PropertyNode propertyNode) + // { + // // If the property is not in the current graph, do check if the + // // property can be made into a concrete node. + // if (!m_Properties.Select(x => x.guid).Contains(propertyNode.propertyGuid)) + // { + // // If the property is in the serialized paste graph, make the property node into a property node. + // var pastedGraphMetaProperties = graphToPaste.metaProperties.Where(x => x.guid == propertyNode.propertyGuid); + // if (pastedGraphMetaProperties.Any()) + // { + // pastedNode = pastedGraphMetaProperties.FirstOrDefault().ToConcreteNode(); + // pastedNode.drawState = node.drawState; + // nodeGuidMap[oldGuid] = pastedNode.guid; + // } + // } + // } + // + // AbstractMaterialNode abstractMaterialNode = (AbstractMaterialNode)node; + // + // // If the node has a group guid and no group has been copied, reset the group guid. + // // Check if the node is inside a group + // if (abstractMaterialNode.groupGuid != Guid.Empty) + // { + // if (groupGuidMap.ContainsKey(abstractMaterialNode.groupGuid)) + // { + // var absNode = pastedNode as AbstractMaterialNode; + // absNode.groupGuid = groupGuidMap[abstractMaterialNode.groupGuid]; + // pastedNode = absNode; + // } + // else + // { + // pastedNode.groupGuid = Guid.Empty; + // } + // } + // + // var drawState = node.drawState; + // var position = drawState.position; + // position.x += 30; + // position.y += 30; + // drawState.position = position; + // node.drawState = drawState; + // remappedNodes.Add(pastedNode); + // AddNode(pastedNode); + // + // // add the node to the pasted node list + // m_PastedNodes.Add(pastedNode); + // + // // Check if the keyword nodes need to have their keywords copied. + // if (node is KeywordNode keywordNode) + // { + // // If the keyword is not in the current graph and is in the serialized paste graph copy it. + // if (!keywords.Select(x => x.guid).Contains(keywordNode.keywordGuid)) + // { + // var pastedGraphMetaKeywords = graphToPaste.metaKeywords.Where(x => x.guid == keywordNode.keywordGuid); + // if (pastedGraphMetaKeywords.Any()) + // { + // var keyword = pastedGraphMetaKeywords.FirstOrDefault(x => x.guid == keywordNode.keywordGuid); + // SanitizeGraphInputName(keyword); + // SanitizeGraphInputReferenceName(keyword, keyword.overrideReferenceName); + // AddGraphInput(keyword); + // } + // } + // + // // Always update Keyword nodes to handle any collisions resolved on the Keyword + // keywordNode.UpdateNode(); + // } + // } + // + // // only connect edges within pasted elements, discard + // // external edges. + // foreach (var edge in graphToPaste.edges) + // { + // var outputSlot = edge.outputSlot; + // var inputSlot = edge.inputSlot; + // + // Guid remappedOutputNodeGuid; + // Guid remappedInputNodeGuid; + // if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid) + // && nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid)) + // { + // var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId); + // var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId); + // remappedEdges.Add(Connect(outputSlotRef, inputSlotRef)); + // } + // } + // + // ValidateGraph(); } public override void OnBeforeSerialize() { m_Edges.Sort(); - m_SerializableEdges = SerializationHelper.Serialize(m_Edges); m_SerializedProperties = SerializationHelper.Serialize(m_Properties); m_SerializedKeywords = SerializationHelper.Serialize(m_Keywords); m_ActiveOutputNodeGuidSerialized = m_ActiveOutputNodeGuid == Guid.Empty ? null : m_ActiveOutputNodeGuid.ToString(); diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index a74842b2026..e7c99a5a27e 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -443,320 +443,320 @@ bool SaveAsImplementation() public void ToSubGraph() { - var graphView = graphEditorView.graphView; - - var path = EditorUtility.SaveFilePanelInProject("Save Sub Graph", "New Shader Sub Graph", ShaderSubGraphImporter.Extension, ""); - path = path.Replace(Application.dataPath, "Assets"); - if (path.Length == 0) - return; - - graphObject.RegisterCompleteObjectUndo("Convert To Subgraph"); - - var nodes = graphView.selection.OfType().Where(x => !(x.node is PropertyNode || x.node is SubGraphOutputNode)).Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(); - var bounds = Rect.MinMaxRect(float.PositiveInfinity, float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity); - foreach (var node in nodes) - { - var center = node.drawState.position.center; - bounds = Rect.MinMaxRect( - Mathf.Min(bounds.xMin, center.x), - Mathf.Min(bounds.yMin, center.y), - Mathf.Max(bounds.xMax, center.x), - Mathf.Max(bounds.yMax, center.y)); - } - var middle = bounds.center; - bounds.center = Vector2.zero; - - // Collect graph inputs - var graphInputs = graphView.selection.OfType().Select(x => x.userData as ShaderInput); - - // Collect the property nodes and get the corresponding properties - var propertyNodeGuids = graphView.selection.OfType().Where(x => (x.node is PropertyNode)).Select(x => ((PropertyNode)x.node).propertyGuid); - var metaProperties = graphView.graph.properties.Where(x => propertyNodeGuids.Contains(x.guid)); - - // Collect the keyword nodes and get the corresponding keywords - var keywordNodeGuids = graphView.selection.OfType().Where(x => (x.node is KeywordNode)).Select(x => ((KeywordNode)x.node).keywordGuid); - var metaKeywords = graphView.graph.keywords.Where(x => keywordNodeGuids.Contains(x.guid)); - - var copyPasteGraph = new CopyPasteGraph( - graphView.graph.assetGuid, - graphView.selection.OfType().Select(x => x.userData), - graphView.selection.OfType().Where(x => !(x.node is PropertyNode || x.node is SubGraphOutputNode)).Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(), - graphView.selection.OfType().Select(x => x.userData as IEdge), - graphInputs, - metaProperties, - metaKeywords, - graphView.selection.OfType().Select(x => x.userData)); - - var deserialized = CopyPasteGraph.FromJson(JsonUtility.ToJson(copyPasteGraph, false)); - if (deserialized == null) - return; - - var subGraph = new GraphData { isSubGraph = true }; - subGraph.path = "Sub Graphs"; - var subGraphOutputNode = new SubGraphOutputNode(); - { - var drawState = subGraphOutputNode.drawState; - drawState.position = new Rect(new Vector2(bounds.xMax + 200f, 0f), drawState.position.size); - subGraphOutputNode.drawState = drawState; - } - subGraph.AddNode(subGraphOutputNode); - - // Always copy deserialized keyword inputs - foreach (ShaderKeyword keyword in deserialized.metaKeywords) - { - ShaderInput copiedInput = keyword.Copy(); - subGraph.SanitizeGraphInputName(copiedInput); - subGraph.SanitizeGraphInputReferenceName(copiedInput, keyword.overrideReferenceName); - subGraph.AddGraphInput(copiedInput); - - // Update the keyword nodes that depends on the copied keyword - var dependentKeywordNodes = deserialized.GetNodes().Where(x => x.keywordGuid == keyword.guid); - foreach (var node in dependentKeywordNodes) - { - node.owner = graphView.graph; - node.keywordGuid = copiedInput.guid; - } - } - - var groupGuidMap = new Dictionary(); - foreach (GroupData groupData in deserialized.groups) - { - var oldGuid = groupData.guid; - var newGuid = groupData.RewriteGuid(); - groupGuidMap[oldGuid] = newGuid; - subGraph.CreateGroup(groupData); - } - - List groupGuids = new List(); - var nodeGuidMap = new Dictionary(); - foreach (var node in deserialized.GetNodes()) - { - var oldGuid = node.guid; - var newGuid = node.RewriteGuid(); - nodeGuidMap[oldGuid] = newGuid; - var drawState = node.drawState; - drawState.position = new Rect(drawState.position.position - middle, drawState.position.size); - node.drawState = drawState; - - if (!groupGuids.Contains(node.groupGuid)) - { - groupGuids.Add(node.groupGuid); - } - - // Checking if the group guid is also being copied. - // If not then nullify that guid - if (node.groupGuid != Guid.Empty) - { - node.groupGuid = !groupGuidMap.ContainsKey(node.groupGuid) ? Guid.Empty : groupGuidMap[node.groupGuid]; - } - - subGraph.AddNode(node); - } - - foreach (var note in deserialized.stickyNotes) - { - if (!groupGuids.Contains(note.groupGuid)) - { - groupGuids.Add(note.groupGuid); - } - - if (note.groupGuid != Guid.Empty) - { - note.groupGuid = !groupGuidMap.ContainsKey(note.groupGuid) ? Guid.Empty : groupGuidMap[note.groupGuid]; - } - - note.RewriteGuid(); - subGraph.AddStickyNote(note); - } - - // figure out what needs remapping - var externalOutputSlots = new List(); - var externalInputSlots = new List(); - foreach (var edge in deserialized.edges) - { - var outputSlot = edge.outputSlot; - var inputSlot = edge.inputSlot; - - Guid remappedOutputNodeGuid; - Guid remappedInputNodeGuid; - var outputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid); - var inputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid); - - // pasting nice internal links! - if (outputSlotExistsInSubgraph && inputSlotExistsInSubgraph) - { - var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId); - var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId); - subGraph.Connect(outputSlotRef, inputSlotRef); - } - // one edge needs to go to outside world - else if (outputSlotExistsInSubgraph) - { - externalInputSlots.Add(edge); - } - else if (inputSlotExistsInSubgraph) - { - externalOutputSlots.Add(edge); - } - } - - // Find the unique edges coming INTO the graph - var uniqueIncomingEdges = externalOutputSlots.GroupBy( - edge => edge.outputSlot, - edge => edge, - (key, edges) => new { slotRef = key, edges = edges.ToList() }); - - var externalInputNeedingConnection = new List>(); - - var amountOfProps = uniqueIncomingEdges.Count(); - const int height = 40; - const int subtractHeight = 20; - var propPos = new Vector2(0, -((amountOfProps / 2) + height) - subtractHeight); - - foreach (var group in uniqueIncomingEdges) - { - var sr = group.slotRef; - var fromNode = graphObject.graph.GetNodeFromGuid(sr.nodeGuid); - var fromSlot = fromNode.FindOutputSlot(sr.slotId); - - AbstractShaderProperty prop; - switch (fromSlot.concreteValueType) - { - case ConcreteSlotValueType.Texture2D: - prop = new Texture2DShaderProperty(); - break; - case ConcreteSlotValueType.Texture2DArray: - prop = new Texture2DArrayShaderProperty(); - break; - case ConcreteSlotValueType.Texture3D: - prop = new Texture3DShaderProperty(); - break; - case ConcreteSlotValueType.Cubemap: - prop = new CubemapShaderProperty(); - break; - case ConcreteSlotValueType.Vector4: - prop = new Vector4ShaderProperty(); - break; - case ConcreteSlotValueType.Vector3: - prop = new Vector3ShaderProperty(); - break; - case ConcreteSlotValueType.Vector2: - prop = new Vector2ShaderProperty(); - break; - case ConcreteSlotValueType.Vector1: - prop = new Vector1ShaderProperty(); - break; - case ConcreteSlotValueType.Boolean: - prop = new BooleanShaderProperty(); - break; - case ConcreteSlotValueType.Matrix2: - prop = new Matrix2ShaderProperty(); - break; - case ConcreteSlotValueType.Matrix3: - prop = new Matrix3ShaderProperty(); - break; - case ConcreteSlotValueType.Matrix4: - prop = new Matrix4ShaderProperty(); - break; - case ConcreteSlotValueType.SamplerState: - prop = new SamplerStateShaderProperty(); - break; - case ConcreteSlotValueType.Gradient: - prop = new GradientShaderProperty(); - break; - default: - throw new ArgumentOutOfRangeException(); - } - - if (prop != null) - { - var materialGraph = (GraphData)graphObject.graph; - var fromPropertyNode = fromNode as PropertyNode; - var fromProperty = fromPropertyNode != null ? materialGraph.properties.FirstOrDefault(p => p.guid == fromPropertyNode.propertyGuid) : null; - prop.displayName = fromProperty != null ? fromProperty.displayName : fromSlot.concreteValueType.ToString(); - prop.displayName = GraphUtil.SanitizeName(subGraph.addedInputs.Select(p => p.displayName), "{0} ({1})", prop.displayName); - - subGraph.AddGraphInput(prop); - var propNode = new PropertyNode(); - { - var drawState = propNode.drawState; - drawState.position = new Rect(new Vector2(bounds.xMin - 300f, 0f) + propPos, drawState.position.size); - propPos += new Vector2(0, height); - propNode.drawState = drawState; - } - subGraph.AddNode(propNode); - propNode.propertyGuid = prop.guid; - - foreach (var edge in group.edges) - { - subGraph.Connect( - new SlotReference(propNode.guid, PropertyNode.OutputSlotId), - new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId)); - externalInputNeedingConnection.Add(new KeyValuePair(edge, prop)); - } - } - } - - var uniqueOutgoingEdges = externalInputSlots.GroupBy( - edge => edge.outputSlot, - edge => edge, - (key, edges) => new { slot = key, edges = edges.ToList() }); - - var externalOutputsNeedingConnection = new List>(); - foreach (var group in uniqueOutgoingEdges) - { - var outputNode = subGraph.outputNode as SubGraphOutputNode; - - AbstractMaterialNode node = graphView.graph.GetNodeFromGuid(group.edges[0].outputSlot.nodeGuid); - MaterialSlot slot = node.FindSlot(group.edges[0].outputSlot.slotId); - var slotId = outputNode.AddSlot(slot.concreteValueType); - - var inputSlotRef = new SlotReference(outputNode.guid, slotId); - - foreach (var edge in group.edges) - { - var newEdge = subGraph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef); - externalOutputsNeedingConnection.Add(new KeyValuePair(edge, newEdge)); - } - } - - if(FileUtilities.WriteShaderGraphToDisk(path, subGraph)) - AssetDatabase.ImportAsset(path); - - var loadedSubGraph = AssetDatabase.LoadAssetAtPath(path, typeof(SubGraphAsset)) as SubGraphAsset; - if (loadedSubGraph == null) - return; - - var subGraphNode = new SubGraphNode(); - var ds = subGraphNode.drawState; - ds.position = new Rect(middle - new Vector2(100f, 150f), Vector2.zero); - subGraphNode.drawState = ds; - - // Add the subgraph into the group if the nodes was all in the same group group - if (groupGuids.Count == 1) - { - subGraphNode.groupGuid = groupGuids[0]; - } - - graphObject.graph.AddNode(subGraphNode); - subGraphNode.asset = loadedSubGraph; - - foreach (var edgeMap in externalInputNeedingConnection) - { - graphObject.graph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.guid.GetHashCode())); - } - - foreach (var edgeMap in externalOutputsNeedingConnection) - { - graphObject.graph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot); - } - - graphObject.graph.RemoveElements( - graphView.selection.OfType().Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(), - new IEdge[] {}, - new GroupData[] {}, - graphView.selection.OfType().Select(x => x.userData).ToArray()); - graphObject.graph.ValidateGraph(); + // var graphView = graphEditorView.graphView; + // + // var path = EditorUtility.SaveFilePanelInProject("Save Sub Graph", "New Shader Sub Graph", ShaderSubGraphImporter.Extension, ""); + // path = path.Replace(Application.dataPath, "Assets"); + // if (path.Length == 0) + // return; + // + // graphObject.RegisterCompleteObjectUndo("Convert To Subgraph"); + // + // var nodes = graphView.selection.OfType().Where(x => !(x.node is PropertyNode || x.node is SubGraphOutputNode)).Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(); + // var bounds = Rect.MinMaxRect(float.PositiveInfinity, float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity); + // foreach (var node in nodes) + // { + // var center = node.drawState.position.center; + // bounds = Rect.MinMaxRect( + // Mathf.Min(bounds.xMin, center.x), + // Mathf.Min(bounds.yMin, center.y), + // Mathf.Max(bounds.xMax, center.x), + // Mathf.Max(bounds.yMax, center.y)); + // } + // var middle = bounds.center; + // bounds.center = Vector2.zero; + // + // // Collect graph inputs + // var graphInputs = graphView.selection.OfType().Select(x => x.userData as ShaderInput); + // + // // Collect the property nodes and get the corresponding properties + // var propertyNodeGuids = graphView.selection.OfType().Where(x => (x.node is PropertyNode)).Select(x => ((PropertyNode)x.node).propertyGuid); + // var metaProperties = graphView.graph.properties.Where(x => propertyNodeGuids.Contains(x.guid)); + // + // // Collect the keyword nodes and get the corresponding keywords + // var keywordNodeGuids = graphView.selection.OfType().Where(x => (x.node is KeywordNode)).Select(x => ((KeywordNode)x.node).keywordGuid); + // var metaKeywords = graphView.graph.keywords.Where(x => keywordNodeGuids.Contains(x.guid)); + // + // var copyPasteGraph = new CopyPasteGraph( + // graphView.graph.assetGuid, + // graphView.selection.OfType().Select(x => x.userData), + // graphView.selection.OfType().Where(x => !(x.node is PropertyNode || x.node is SubGraphOutputNode)).Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(), + // graphView.selection.OfType().Select(x => x.userData as IEdge), + // graphInputs, + // metaProperties, + // metaKeywords, + // graphView.selection.OfType().Select(x => x.userData)); + // + // var deserialized = CopyPasteGraph.FromJson(JsonUtility.ToJson(copyPasteGraph, false)); + // if (deserialized == null) + // return; + // + // var subGraph = new GraphData { isSubGraph = true }; + // subGraph.path = "Sub Graphs"; + // var subGraphOutputNode = new SubGraphOutputNode(); + // { + // var drawState = subGraphOutputNode.drawState; + // drawState.position = new Rect(new Vector2(bounds.xMax + 200f, 0f), drawState.position.size); + // subGraphOutputNode.drawState = drawState; + // } + // subGraph.AddNode(subGraphOutputNode); + // + // // Always copy deserialized keyword inputs + // foreach (ShaderKeyword keyword in deserialized.metaKeywords) + // { + // ShaderInput copiedInput = keyword.Copy(); + // subGraph.SanitizeGraphInputName(copiedInput); + // subGraph.SanitizeGraphInputReferenceName(copiedInput, keyword.overrideReferenceName); + // subGraph.AddGraphInput(copiedInput); + // + // // Update the keyword nodes that depends on the copied keyword + // var dependentKeywordNodes = deserialized.GetNodes().Where(x => x.keywordGuid == keyword.guid); + // foreach (var node in dependentKeywordNodes) + // { + // node.owner = graphView.graph; + // node.keywordGuid = copiedInput.guid; + // } + // } + // + // var groupGuidMap = new Dictionary(); + // foreach (GroupData groupData in deserialized.groups) + // { + // var oldGuid = groupData.guid; + // var newGuid = groupData.RewriteGuid(); + // groupGuidMap[oldGuid] = newGuid; + // subGraph.CreateGroup(groupData); + // } + // + // List groupGuids = new List(); + // var nodeGuidMap = new Dictionary(); + // foreach (var node in deserialized.GetNodes()) + // { + // var oldGuid = node.guid; + // var newGuid = node.RewriteGuid(); + // nodeGuidMap[oldGuid] = newGuid; + // var drawState = node.drawState; + // drawState.position = new Rect(drawState.position.position - middle, drawState.position.size); + // node.drawState = drawState; + // + // if (!groupGuids.Contains(node.groupGuid)) + // { + // groupGuids.Add(node.groupGuid); + // } + // + // // Checking if the group guid is also being copied. + // // If not then nullify that guid + // if (node.groupGuid != Guid.Empty) + // { + // node.groupGuid = !groupGuidMap.ContainsKey(node.groupGuid) ? Guid.Empty : groupGuidMap[node.groupGuid]; + // } + // + // subGraph.AddNode(node); + // } + // + // foreach (var note in deserialized.stickyNotes) + // { + // if (!groupGuids.Contains(note.groupGuid)) + // { + // groupGuids.Add(note.groupGuid); + // } + // + // if (note.groupGuid != Guid.Empty) + // { + // note.groupGuid = !groupGuidMap.ContainsKey(note.groupGuid) ? Guid.Empty : groupGuidMap[note.groupGuid]; + // } + // + // note.RewriteGuid(); + // subGraph.AddStickyNote(note); + // } + // + // // figure out what needs remapping + // var externalOutputSlots = new List(); + // var externalInputSlots = new List(); + // foreach (var edge in deserialized.edges) + // { + // var outputSlot = edge.outputSlot; + // var inputSlot = edge.inputSlot; + // + // Guid remappedOutputNodeGuid; + // Guid remappedInputNodeGuid; + // var outputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid); + // var inputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid); + // + // // pasting nice internal links! + // if (outputSlotExistsInSubgraph && inputSlotExistsInSubgraph) + // { + // var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId); + // var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId); + // subGraph.Connect(outputSlotRef, inputSlotRef); + // } + // // one edge needs to go to outside world + // else if (outputSlotExistsInSubgraph) + // { + // externalInputSlots.Add(edge); + // } + // else if (inputSlotExistsInSubgraph) + // { + // externalOutputSlots.Add(edge); + // } + // } + // + // // Find the unique edges coming INTO the graph + // var uniqueIncomingEdges = externalOutputSlots.GroupBy( + // edge => edge.outputSlot, + // edge => edge, + // (key, edges) => new { slotRef = key, edges = edges.ToList() }); + // + // var externalInputNeedingConnection = new List>(); + // + // var amountOfProps = uniqueIncomingEdges.Count(); + // const int height = 40; + // const int subtractHeight = 20; + // var propPos = new Vector2(0, -((amountOfProps / 2) + height) - subtractHeight); + // + // foreach (var group in uniqueIncomingEdges) + // { + // var sr = group.slotRef; + // var fromNode = graphObject.graph.GetNodeFromGuid(sr.nodeGuid); + // var fromSlot = fromNode.FindOutputSlot(sr.slotId); + // + // AbstractShaderProperty prop; + // switch (fromSlot.concreteValueType) + // { + // case ConcreteSlotValueType.Texture2D: + // prop = new Texture2DShaderProperty(); + // break; + // case ConcreteSlotValueType.Texture2DArray: + // prop = new Texture2DArrayShaderProperty(); + // break; + // case ConcreteSlotValueType.Texture3D: + // prop = new Texture3DShaderProperty(); + // break; + // case ConcreteSlotValueType.Cubemap: + // prop = new CubemapShaderProperty(); + // break; + // case ConcreteSlotValueType.Vector4: + // prop = new Vector4ShaderProperty(); + // break; + // case ConcreteSlotValueType.Vector3: + // prop = new Vector3ShaderProperty(); + // break; + // case ConcreteSlotValueType.Vector2: + // prop = new Vector2ShaderProperty(); + // break; + // case ConcreteSlotValueType.Vector1: + // prop = new Vector1ShaderProperty(); + // break; + // case ConcreteSlotValueType.Boolean: + // prop = new BooleanShaderProperty(); + // break; + // case ConcreteSlotValueType.Matrix2: + // prop = new Matrix2ShaderProperty(); + // break; + // case ConcreteSlotValueType.Matrix3: + // prop = new Matrix3ShaderProperty(); + // break; + // case ConcreteSlotValueType.Matrix4: + // prop = new Matrix4ShaderProperty(); + // break; + // case ConcreteSlotValueType.SamplerState: + // prop = new SamplerStateShaderProperty(); + // break; + // case ConcreteSlotValueType.Gradient: + // prop = new GradientShaderProperty(); + // break; + // default: + // throw new ArgumentOutOfRangeException(); + // } + // + // if (prop != null) + // { + // var materialGraph = (GraphData)graphObject.graph; + // var fromPropertyNode = fromNode as PropertyNode; + // var fromProperty = fromPropertyNode != null ? materialGraph.properties.FirstOrDefault(p => p.guid == fromPropertyNode.propertyGuid) : null; + // prop.displayName = fromProperty != null ? fromProperty.displayName : fromSlot.concreteValueType.ToString(); + // prop.displayName = GraphUtil.SanitizeName(subGraph.addedInputs.Select(p => p.displayName), "{0} ({1})", prop.displayName); + // + // subGraph.AddGraphInput(prop); + // var propNode = new PropertyNode(); + // { + // var drawState = propNode.drawState; + // drawState.position = new Rect(new Vector2(bounds.xMin - 300f, 0f) + propPos, drawState.position.size); + // propPos += new Vector2(0, height); + // propNode.drawState = drawState; + // } + // subGraph.AddNode(propNode); + // propNode.propertyGuid = prop.guid; + // + // foreach (var edge in group.edges) + // { + // subGraph.Connect( + // new SlotReference(propNode.guid, PropertyNode.OutputSlotId), + // new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId)); + // externalInputNeedingConnection.Add(new KeyValuePair(edge, prop)); + // } + // } + // } + // + // var uniqueOutgoingEdges = externalInputSlots.GroupBy( + // edge => edge.outputSlot, + // edge => edge, + // (key, edges) => new { slot = key, edges = edges.ToList() }); + // + // var externalOutputsNeedingConnection = new List>(); + // foreach (var group in uniqueOutgoingEdges) + // { + // var outputNode = subGraph.outputNode as SubGraphOutputNode; + // + // AbstractMaterialNode node = graphView.graph.GetNodeFromGuid(group.edges[0].outputSlot.nodeGuid); + // MaterialSlot slot = node.FindSlot(group.edges[0].outputSlot.slotId); + // var slotId = outputNode.AddSlot(slot.concreteValueType); + // + // var inputSlotRef = new SlotReference(outputNode.guid, slotId); + // + // foreach (var edge in group.edges) + // { + // var newEdge = subGraph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef); + // externalOutputsNeedingConnection.Add(new KeyValuePair(edge, newEdge)); + // } + // } + // + // if(FileUtilities.WriteShaderGraphToDisk(path, subGraph)) + // AssetDatabase.ImportAsset(path); + // + // var loadedSubGraph = AssetDatabase.LoadAssetAtPath(path, typeof(SubGraphAsset)) as SubGraphAsset; + // if (loadedSubGraph == null) + // return; + // + // var subGraphNode = new SubGraphNode(); + // var ds = subGraphNode.drawState; + // ds.position = new Rect(middle - new Vector2(100f, 150f), Vector2.zero); + // subGraphNode.drawState = ds; + // + // // Add the subgraph into the group if the nodes was all in the same group group + // if (groupGuids.Count == 1) + // { + // subGraphNode.groupGuid = groupGuids[0]; + // } + // + // graphObject.graph.AddNode(subGraphNode); + // subGraphNode.asset = loadedSubGraph; + // + // foreach (var edgeMap in externalInputNeedingConnection) + // { + // graphObject.graph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.guid.GetHashCode())); + // } + // + // foreach (var edgeMap in externalOutputsNeedingConnection) + // { + // graphObject.graph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot); + // } + // + // graphObject.graph.RemoveElements( + // graphView.selection.OfType().Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(), + // new IEdge[] {}, + // new GroupData[] {}, + // graphView.selection.OfType().Select(x => x.userData).ToArray()); + // graphObject.graph.ValidateGraph(); } void UpdateShaderGraphOnDisk(string path) From 2d453bb25a63b78b529b7722952faa1ab8fc9fa3 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Wed, 18 Mar 2020 15:34:39 +0100 Subject: [PATCH 18/64] AbstractMaterialNode guid -> id --- .../Editor/Data/Graphs/GraphData.cs | 208 +++++++----------- .../Editor/Data/Graphs/MaterialSlot.cs | 4 +- .../Editor/Data/Implementation/NodeUtils.cs | 14 +- .../Data/Interfaces/Graph/SlotReference.cs | 57 ++--- .../Data/Legacy/AbstractMaterialNode0.cs | 10 + .../Data/Legacy/AbstractMaterialNode0.cs.meta | 3 + .../Editor/Data/Legacy/Edge0.cs | 13 ++ .../Editor/Data/Legacy/Edge0.cs.meta | 3 + .../Editor/Data/Legacy/GraphData0.cs | 4 + .../Editor/Data/Legacy/SlotReference0.cs | 13 ++ .../Editor/Data/Legacy/SlotReference0.cs.meta | 3 + .../Editor/Data/Nodes/AbstractMaterialNode.cs | 60 +---- .../Editor/Data/Nodes/CodeFunctionNode.cs | 2 +- .../Data/Nodes/Math/Basic/MultiplyNode.cs | 8 +- .../Data/Nodes/Math/Matrix/MatrixSplitNode.cs | 4 +- .../Data/Nodes/Utility/CustomFunctionNode.cs | 8 +- .../Editor/Data/Nodes/Utility/SubGraphNode.cs | 8 +- .../Data/SubGraph/SubGraphOutputNode.cs | 4 +- .../Editor/Data/Util/GraphUtil.cs | 8 +- .../Editor/Drawing/MaterialGraphEditWindow.cs | 2 +- .../Editor/Drawing/PreviewManager.cs | 33 ++- .../Editor/Drawing/Views/GraphEditorView.cs | 18 +- .../Editor/Drawing/Views/MaterialNodeView.cs | 12 +- .../Editor/Drawing/Views/PropertyNodeView.cs | 2 +- .../Editor/Generation/Processors/Generator.cs | 2 +- .../Editor/Importers/ShaderGraphImporter.cs | 4 +- .../Importers/ShaderSubGraphImporter.cs | 2 +- .../Editor/Serialization/JsonRef.cs | 2 +- .../Editor/Util/CopyPasteGraph.cs | 2 +- .../Editor/Util/MessageManager.cs | 20 +- .../UnitTests/AbstractMaterialGraphTests.cs | 4 +- .../Editor/UnitTests/MessageManagerTests.cs | 122 +++++----- .../Editor/UnitTests/SerializedGraphTests.cs | 26 +-- 33 files changed, 318 insertions(+), 367 deletions(-) create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs.meta create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs.meta create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs.meta diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 0a2ffb0ece6..c822a29d5af 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -85,7 +85,7 @@ public IEnumerable movedInputs List> m_Nodes = new List>(); [NonSerialized] - Dictionary m_NodeDictionary = new Dictionary(); + Dictionary m_NodeDictionary = new Dictionary(); public IEnumerable GetNodes() { @@ -203,19 +203,13 @@ public IEnumerable GetItemsInGroup(GroupData groupData) #region Edge data - [NonSerialized] + [SerializeField] List m_Edges = new List(); - public IEnumerable edges - { - get { return m_Edges; } - } - - [SerializeField] - List m_SerializableEdges = new List(); + public IEnumerable edges => m_Edges; [NonSerialized] - Dictionary> m_NodeEdges = new Dictionary>(); + Dictionary> m_NodeEdges = new Dictionary>(); [NonSerialized] List m_AddedEdges = new List(); @@ -272,49 +266,13 @@ public ConcretePrecision concretePrecision set => m_ConcretePrecision = value; } - [NonSerialized] - Guid m_ActiveOutputNodeGuid; - - public Guid activeOutputNodeGuid - { - get { return m_ActiveOutputNodeGuid; } - set - { - if (value != m_ActiveOutputNodeGuid) - { - m_ActiveOutputNodeGuid = value; - m_OutputNode = null; - didActiveOutputNodeChange = true; - UpdateTargets(); - } - } - } - [SerializeField] - string m_ActiveOutputNodeGuidSerialized; - - [NonSerialized] - private AbstractMaterialNode m_OutputNode; + JsonRef m_OutputNode; public AbstractMaterialNode outputNode { - get - { - // find existing node - if (m_OutputNode == null) - { - if (isSubGraph) - { - m_OutputNode = GetNodes().FirstOrDefault(); - } - else - { - m_OutputNode = GetNodeFromGuid(m_ActiveOutputNodeGuid); - } - } - - return m_OutputNode; - } + get => m_OutputNode; + set => m_OutputNode = value; } #region Targets @@ -497,7 +455,7 @@ void AddNodeNoValidate(AbstractMaterialNode node) } node.owner = this; m_Nodes.Add(node); - m_NodeDictionary.Add(node.guid, node); + m_NodeDictionary.Add(node.id, node); m_AddedNodes.Add(node); m_GroupItems[node.groupGuid].Add(node); } @@ -506,7 +464,7 @@ public void RemoveNode(AbstractMaterialNode node) { if (!node.canDeleteNode) { - throw new InvalidOperationException($"Node {node.name} ({node.guid}) cannot be deleted."); + throw new InvalidOperationException($"Node {node.name} ({node.id}) cannot be deleted."); } RemoveNodeNoValidate(node); ValidateGraph(); @@ -514,14 +472,14 @@ public void RemoveNode(AbstractMaterialNode node) void RemoveNodeNoValidate(AbstractMaterialNode node) { - if (!m_NodeDictionary.ContainsKey(node.guid)) + if (!m_NodeDictionary.ContainsKey(node.id)) { throw new InvalidOperationException("Cannot remove a node that doesn't exist."); } m_Nodes.Remove(node); - m_NodeDictionary.Remove(node.guid); - messageManager?.RemoveNode(node.guid); + m_NodeDictionary.Remove(node.id); + messageManager?.RemoveNode(node.id); m_RemovedNodes.Add(node); if (m_GroupItems.TryGetValue(node.groupGuid, out var groupItems)) @@ -533,20 +491,20 @@ void RemoveNodeNoValidate(AbstractMaterialNode node) void AddEdgeToNodeEdges(IEdge edge) { List inputEdges; - if (!m_NodeEdges.TryGetValue(edge.inputSlot.nodeGuid, out inputEdges)) - m_NodeEdges[edge.inputSlot.nodeGuid] = inputEdges = new List(); + if (!m_NodeEdges.TryGetValue(edge.inputSlot.node.id, out inputEdges)) + m_NodeEdges[edge.inputSlot.node.id] = inputEdges = new List(); inputEdges.Add(edge); List outputEdges; - if (!m_NodeEdges.TryGetValue(edge.outputSlot.nodeGuid, out outputEdges)) - m_NodeEdges[edge.outputSlot.nodeGuid] = outputEdges = new List(); + if (!m_NodeEdges.TryGetValue(edge.outputSlot.node.id, out outputEdges)) + m_NodeEdges[edge.outputSlot.node.id] = outputEdges = new List(); outputEdges.Add(edge); } IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef) { - var fromNode = GetNodeFromGuid(fromSlotRef.nodeGuid); - var toNode = GetNodeFromGuid(toSlotRef.nodeGuid); + var fromNode = fromSlotRef.node; + var toNode = toSlotRef.node; if (fromNode == null || toNode == null) return null; @@ -609,7 +567,7 @@ public void RemoveElements(AbstractMaterialNode[] nodes, IEdge[] edges, GroupDat { if (!node.canDeleteNode) { - throw new InvalidOperationException($"Node {node.name} ({node.guid}) cannot be deleted."); + throw new InvalidOperationException($"Node {node.name} ({node.id}) cannot be deleted."); } } @@ -644,53 +602,47 @@ void RemoveEdgeNoValidate(IEdge e) m_Edges.Remove(e as Edge); List inputNodeEdges; - if (m_NodeEdges.TryGetValue(e.inputSlot.nodeGuid, out inputNodeEdges)) + if (m_NodeEdges.TryGetValue(e.inputSlot.node.id, out inputNodeEdges)) inputNodeEdges.Remove(e); List outputNodeEdges; - if (m_NodeEdges.TryGetValue(e.outputSlot.nodeGuid, out outputNodeEdges)) + if (m_NodeEdges.TryGetValue(e.outputSlot.node.id, out outputNodeEdges)) outputNodeEdges.Remove(e); m_RemovedEdges.Add(e); } - public AbstractMaterialNode GetNodeFromGuid(Guid guid) + public AbstractMaterialNode GetNodeFromId(string nodeId) { - AbstractMaterialNode node; - m_NodeDictionary.TryGetValue(guid, out node); - return node; + if (m_NodeDictionary.TryGetValue(nodeId, out var node)) + { + return node; + } + return null; } - public bool ContainsNodeGuid(Guid guid) + public T GetNodeFromId(string nodeId) where T : class { - return m_NodeDictionary.ContainsKey(guid); + return m_NodeDictionary[nodeId] as T; } - public T GetNodeFromGuid(Guid guid) where T : AbstractMaterialNode + public bool ContainsNode(AbstractMaterialNode node) { - var node = GetNodeFromGuid(guid); - if (node is T) - return (T)node; - return default(T); + return m_NodeDictionary.ContainsKey(node.id); } public void GetEdges(SlotReference s, List foundEdges) { - var node = GetNodeFromGuid(s.nodeGuid); - if (node == null) - { - return; - } - ISlot slot = node.FindSlot(s.slotId); + ISlot slot = s.slot; List candidateEdges; - if (!m_NodeEdges.TryGetValue(s.nodeGuid, out candidateEdges)) + if (!m_NodeEdges.TryGetValue(s.node.id, out candidateEdges)) return; foreach (var edge in candidateEdges) { var cs = slot.isInputSlot ? edge.inputSlot : edge.outputSlot; - if (cs.nodeGuid == s.nodeGuid && cs.slotId == s.slotId) + if (cs.node == s.node && cs.slotId == s.slotId) foundEdges.Add(edge); } } @@ -934,12 +886,12 @@ public void ValidateGraph() //debug view. foreach (var edge in edges.ToArray()) { - var outputNode = GetNodeFromGuid(edge.outputSlot.nodeGuid); - var inputNode = GetNodeFromGuid(edge.inputSlot.nodeGuid); + var outputNode = edge.outputSlot.node; + var inputNode = edge.inputSlot.node; MaterialSlot outputSlot = null; MaterialSlot inputSlot = null; - if (outputNode != null && inputNode != null) + if (ContainsNode(outputNode) && ContainsNode(inputNode)) { outputSlot = outputNode.FindOutputSlot(edge.outputSlot.slotId); inputSlot = inputNode.FindInputSlot(edge.inputSlot.slotId); @@ -955,8 +907,8 @@ public void ValidateGraph() } } - var temporaryMarks = PooledHashSet.Get(); - var permanentMarks = PooledHashSet.Get(); + var temporaryMarks = PooledHashSet.Get(); + var permanentMarks = PooledHashSet.Get(); var slots = ListPool.Get(); // Make sure we process a node's children before the node itself. @@ -968,19 +920,19 @@ public void ValidateGraph() while (stack.Count > 0) { var node = stack.Pop(); - if (permanentMarks.Contains(node.guid)) + if (permanentMarks.Contains(node.id)) { continue; } - if (temporaryMarks.Contains(node.guid)) + if (temporaryMarks.Contains(node.id)) { node.ValidateNode(); - permanentMarks.Add(node.guid); + permanentMarks.Add(node.id); } else { - temporaryMarks.Add(node.guid); + temporaryMarks.Add(node.id); stack.Push(node); node.GetInputSlots(slots); foreach (var inputSlot in slots) @@ -989,7 +941,7 @@ public void ValidateGraph() foreach (var edge in nodeEdges) { var fromSocketRef = edge.outputSlot; - var childNode = GetNodeFromGuid(fromSocketRef.nodeGuid); + var childNode = fromSocketRef.node; if (childNode != null) { stack.Push(childNode); @@ -1007,16 +959,16 @@ public void ValidateGraph() foreach (var edge in m_AddedEdges.ToList()) { - if (!ContainsNodeGuid(edge.outputSlot.nodeGuid) || !ContainsNodeGuid(edge.inputSlot.nodeGuid)) + if (!ContainsNode(edge.outputSlot.node) || !ContainsNode(edge.inputSlot.node)) { - Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.nodeGuid, edge.inputSlot.nodeGuid, Environment.StackTrace); + Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.node.id, edge.inputSlot.node.id, Environment.StackTrace); m_AddedEdges.Remove(edge); } } foreach (var groupChange in m_ParentGroupChanges.ToList()) { - if (groupChange.groupItem is AbstractMaterialNode node && !ContainsNodeGuid(node.guid)) + if (groupChange.groupItem is AbstractMaterialNode node && !ContainsNode(node)) { m_ParentGroupChanges.Remove(groupChange); } @@ -1028,7 +980,7 @@ public void ValidateGraph() } } - public void AddValidationError(Guid id, string errorMessage, + public void AddValidationError(string id, string errorMessage, ShaderCompilerMessageSeverity severity = ShaderCompilerMessageSeverity.Error) { messageManager?.AddOrAppendError(this, id, new ShaderMessage(errorMessage, severity)); @@ -1099,11 +1051,10 @@ public void ReplaceWith(GraphData other) RemoveEdgeNoValidate(edge); } - using (var removedNodesPooledObject = ListPool.GetDisposable()) + using (var removedNodeIds = PooledList.Get()) { - var removedNodeGuids = removedNodesPooledObject.value; - removedNodeGuids.AddRange(m_Nodes.Select(n => n.value.guid)); - foreach (var nodeGuid in removedNodeGuids) + removedNodeIds.AddRange(m_Nodes.Select(n => n.value.id)); + foreach (var nodeGuid in removedNodeIds) RemoveNodeNoValidate(m_NodeDictionary[nodeGuid]); } @@ -1265,7 +1216,6 @@ public override void OnBeforeSerialize() m_Edges.Sort(); m_SerializedProperties = SerializationHelper.Serialize(m_Properties); m_SerializedKeywords = SerializationHelper.Serialize(m_Keywords); - m_ActiveOutputNodeGuidSerialized = m_ActiveOutputNodeGuid == Guid.Empty ? null : m_ActiveOutputNodeGuid.ToString(); } static JsonObject DeserializeLegacy(string typeString, string json) @@ -1287,15 +1237,45 @@ public override void OnAfterDeserialize(string json) if (m_Version == 0) { var graphData0 = JsonUtility.FromJson(json); + + var nodeGuidMap = new Dictionary(); + foreach (var serializedElement in graphData0.m_SerializableNodes) { + var node0 = JsonUtility.FromJson(serializedElement.JSONnodeData); var node = (AbstractMaterialNode)DeserializeLegacy(serializedElement.typeInfo.fullName, serializedElement.JSONnodeData); if (node == null) { continue; } + nodeGuidMap.Add(node0.m_GuidSerialized, node); m_Nodes.Add(node); } + + if (isSubGraph) + { + m_OutputNode = GetNodes().FirstOrDefault(); + } + else if (!string.IsNullOrEmpty(graphData0.m_ActiveOutputNodeGuidSerialized)) + { + m_OutputNode = nodeGuidMap[graphData0.m_ActiveOutputNodeGuidSerialized]; + } + else + { + m_OutputNode = (AbstractMaterialNode)GetNodes().FirstOrDefault(); + } + + foreach (var serializedElement in graphData0.m_SerializableEdges) + { + var edge0 = JsonUtility.FromJson(serializedElement.JSONnodeData); + m_Edges.Add(new Edge( + new SlotReference( + nodeGuidMap[edge0.m_OutputSlot.m_NodeGUIDSerialized], + edge0.m_OutputSlot.m_SlotId), + new SlotReference( + nodeGuidMap[edge0.m_InputSlot.m_NodeGUIDSerialized], + edge0.m_InputSlot.m_SlotId))); + } } m_Version = k_CurrentVersion; @@ -1307,7 +1287,7 @@ public override void OnAfterMultiDeserialize(string json) m_Properties = SerializationHelper.Deserialize(m_SerializedProperties, GraphUtil.GetLegacyTypeRemapping()); m_Keywords = SerializationHelper.Deserialize(m_SerializedKeywords, GraphUtil.GetLegacyTypeRemapping()); - m_NodeDictionary = new Dictionary(m_Nodes.Count); + m_NodeDictionary = new Dictionary(m_Nodes.Count); foreach (var group in m_Groups) { @@ -1318,7 +1298,7 @@ public override void OnAfterMultiDeserialize(string json) { node.owner = this; node.UpdateNodeAfterDeserialization(); - m_NodeDictionary.Add(node.guid, node); + m_NodeDictionary.Add(node.id, node); m_GroupItems[node.groupGuid].Add(node); } @@ -1327,28 +1307,8 @@ public override void OnAfterMultiDeserialize(string json) m_GroupItems[stickyNote.groupGuid].Add(stickyNote); } - m_Edges = SerializationHelper.Deserialize(m_SerializableEdges, GraphUtil.GetLegacyTypeRemapping()); - m_SerializableEdges = null; foreach (var edge in m_Edges) AddEdgeToNodeEdges(edge); - - m_OutputNode = null; - - if (!isSubGraph) - { - if (string.IsNullOrEmpty(m_ActiveOutputNodeGuidSerialized)) - { - var node = (AbstractMaterialNode)GetNodes().FirstOrDefault(); - if (node != null) - { - m_ActiveOutputNodeGuid = node.guid; - } - } - else - { - m_ActiveOutputNodeGuid = new Guid(m_ActiveOutputNodeGuidSerialized); - } - } } public void OnEnable() @@ -1388,7 +1348,7 @@ public void UpdateTargets() } else if (isImplementation && !foundImplementations.Any(s => s.GetType() == type)) { - var masterNode = GetNodeFromGuid(m_ActiveOutputNodeGuid) as IMasterNode; + var masterNode = outputNode as IMasterNode; var implementation = (ITargetImplementation)Activator.CreateInstance(type); if(implementation.IsValid(masterNode)) { diff --git a/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs b/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs index 48f5262e389..8a2ad0ea886 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs @@ -168,7 +168,7 @@ public static MaterialSlot CreateMaterialSlot(SlotValueType type, int slotId, st public SlotReference slotReference { - get { return new SlotReference(owner.guid, m_Id); } + get { return new SlotReference(owner, m_Id); } } public AbstractMaterialNode owner { get; set; } @@ -291,7 +291,7 @@ public virtual void GetPreviewProperties(List properties, strin bool Equals(MaterialSlot other) { - return m_Id == other.m_Id && owner.guid.Equals(other.owner.guid); + return m_Id == other.m_Id && owner == other.owner; } public bool Equals(ISlot other) diff --git a/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs b/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs index 8b6e3e91e7c..3f849b8849f 100644 --- a/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs +++ b/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs @@ -115,7 +115,7 @@ public static void DepthFirstCollectNodesFromNode(List nod { foreach (var edge in node.owner.GetEdges(node.GetSlotReference(slot))) { - var outputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var outputNode = edge.outputSlot.node; if (outputNode != null) DepthFirstCollectNodesFromNode(nodeList, outputNode, keywordPermutation: keywordPermutation); } @@ -131,7 +131,7 @@ public static void CollectNodeSet(HashSet nodeSet, Materia var graph = node.owner; foreach (var edge in graph.GetEdges(node.GetSlotReference(slot.id))) { - var outputNode = graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var outputNode = edge.outputSlot.node; if (outputNode != null) { CollectNodeSet(nodeSet, outputNode); @@ -169,7 +169,7 @@ public static void CollectNodesNodeFeedsInto(List nodeList { foreach (var edge in node.owner.GetEdges(slot.slotReference)) { - var inputNode = node.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var inputNode = edge.inputSlot.node; CollectNodesNodeFeedsInto(nodeList, inputNode); } } @@ -200,7 +200,7 @@ public static ShaderStage GetEffectiveShaderStage(MaterialSlot initialSlot, bool { foreach (var edge in graph.GetEdges(slot.slotReference)) { - var node = graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var node = edge.outputSlot.node; s_SlotStack.Push(node.FindOutputSlot(edge.outputSlot.slotId)); } } @@ -208,7 +208,7 @@ public static ShaderStage GetEffectiveShaderStage(MaterialSlot initialSlot, bool { foreach (var edge in graph.GetEdges(slot.slotReference)) { - var node = graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var node = edge.inputSlot.node; s_SlotStack.Push(node.FindInputSlot(edge.inputSlot.slotId)); } } @@ -243,7 +243,7 @@ public static ShaderStageCapability GetEffectiveShaderStageCapability(MaterialSl { foreach (var edge in graph.GetEdges(slot.slotReference)) { - var node = graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var node = edge.outputSlot.node; s_SlotStack.Push(node.FindOutputSlot(edge.outputSlot.slotId)); } } @@ -251,7 +251,7 @@ public static ShaderStageCapability GetEffectiveShaderStageCapability(MaterialSl { foreach (var edge in graph.GetEdges(slot.slotReference)) { - var node = graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var node = edge.inputSlot.node; s_SlotStack.Push(node.FindInputSlot(edge.inputSlot.slotId)); } } diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs index 84407b6d7d7..0c043c3689b 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs @@ -1,74 +1,57 @@ using System; +using UnityEditor.ShaderGraph; +using UnityEditor.ShaderGraph.Serialization; using UnityEngine; namespace UnityEditor.Graphing { [Serializable] - struct SlotReference : ISerializationCallbackReceiver, IEquatable, IComparable + struct SlotReference : IEquatable, IComparable { [SerializeField] - private int m_SlotId; - - [NonSerialized] - private Guid m_NodeGUID; + JsonRef m_Node; [SerializeField] - private string m_NodeGUIDSerialized; + int m_SlotId; - public SlotReference(Guid nodeGuid, int slotId) + public SlotReference(AbstractMaterialNode node, int slotId) { - m_NodeGUID = nodeGuid; + m_Node = node; m_SlotId = slotId; - m_NodeGUIDSerialized = string.Empty; } - public Guid nodeGuid - { - get { return m_NodeGUID; } - } + public AbstractMaterialNode node => m_Node; - public int slotId - { - get { return m_SlotId; } - } + // public Guid nodeGuid => m_Node.value.guid; - public void OnBeforeSerialize() - { - m_NodeGUIDSerialized = m_NodeGUID.ToString(); - } + public int slotId => m_SlotId; - public void OnAfterDeserialize() - { - m_NodeGUID = new Guid(m_NodeGUIDSerialized); - } + public MaterialSlot slot => m_Node.value?.FindSlot(m_SlotId); - public bool Equals(SlotReference other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return m_SlotId == other.m_SlotId && m_NodeGUID.Equals(other.m_NodeGUID); - } + public bool Equals(SlotReference other) => m_SlotId == other.m_SlotId && m_Node.value == other.m_Node.value; public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((SlotReference)obj); + return obj.GetType() == GetType() && Equals((SlotReference)obj); } public override int GetHashCode() { unchecked { - return (m_SlotId * 397) ^ m_NodeGUID.GetHashCode(); + return (m_SlotId * 397) ^ m_Node.GetHashCode(); } } public int CompareTo(SlotReference other) { - var nodeGUIDComparison = m_NodeGUID.CompareTo(other.m_NodeGUID); - if (nodeGUIDComparison != 0) return nodeGUIDComparison; + var nodeIdComparison = m_Node.value.id.CompareTo(other.m_Node.value.id); + if (nodeIdComparison != 0) + { + return nodeIdComparison; + } + return m_SlotId.CompareTo(other.m_SlotId); } } diff --git a/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs new file mode 100644 index 00000000000..3bc50200121 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs @@ -0,0 +1,10 @@ +using System; + +namespace UnityEditor.ShaderGraph.Legacy +{ + [Serializable] + class AbstractMaterialNode0 + { + public string m_GuidSerialized; + } +} diff --git a/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs.meta b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs.meta new file mode 100644 index 00000000000..281ebd28cc4 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 36fb54922b1048cea6faba93b33ab02c +timeCreated: 1584530412 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs b/com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs new file mode 100644 index 00000000000..5259efeadf6 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs @@ -0,0 +1,13 @@ +using System; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Legacy +{ + [Serializable] + class Edge0 + { + public SlotReference0 m_OutputSlot; + + public SlotReference0 m_InputSlot; + } +} diff --git a/com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs.meta b/com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs.meta new file mode 100644 index 00000000000..86a2c3c3c80 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/Edge0.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f8a5526c8f5d497da61498f1d1bad15c +timeCreated: 1584526265 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs index 70c8639e636..ad3f8489b6d 100644 --- a/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs +++ b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs @@ -8,5 +8,9 @@ namespace UnityEditor.ShaderGraph.Legacy class GraphData0 { public List m_SerializableNodes; + + public List m_SerializableEdges; + + public string m_ActiveOutputNodeGuidSerialized; } } diff --git a/com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs b/com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs new file mode 100644 index 00000000000..5f8863a88cb --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs @@ -0,0 +1,13 @@ +using System; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Legacy +{ + [Serializable] + class SlotReference0 + { + public int m_SlotId; + + public string m_NodeGUIDSerialized; + } +} diff --git a/com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs.meta b/com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs.meta new file mode 100644 index 00000000000..9c40e8c37bd --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/SlotReference0.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: df26ecc5724d46aca68c8392ca3afb29 +timeCreated: 1584526270 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs index 8e737eb578a..0e4bcefacbf 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs @@ -12,12 +12,6 @@ namespace UnityEditor.ShaderGraph [Serializable] abstract class AbstractMaterialNode : JsonObject, IGroupItem { - [NonSerialized] - private Guid m_Guid; - - [SerializeField] - private string m_GuidSerialized; - [NonSerialized] Guid m_GroupGuid; @@ -62,11 +56,6 @@ public void Dirty(ModificationScope scope) m_OnModified(this, scope); } - public Guid guid - { - get { return m_Guid; } - } - public Guid groupGuid { get { return m_GroupGuid; } @@ -82,10 +71,7 @@ public string name protected virtual string documentationPage => name; public virtual string documentationURL => NodeUtils.GetDocumentationString(documentationPage); - public virtual bool canDeleteNode - { - get { return owner != null && guid != owner.activeOutputNodeGuid; } - } + public virtual bool canDeleteNode => owner != null && owner.outputNode != this; public DrawState drawState { @@ -171,17 +157,15 @@ public virtual bool hasError string m_DefaultVariableName; string m_NameForDefaultVariableName; - Guid m_GuidForDefaultVariableName; string defaultVariableName { get { - if (m_NameForDefaultVariableName != name || m_GuidForDefaultVariableName != guid) + if (m_NameForDefaultVariableName != name) { - m_DefaultVariableName = string.Format("{0}_{1}", NodeUtils.GetHLSLSafeName(name ?? "node"), GuidEncoder.Encode(guid)); + m_DefaultVariableName = string.Format("{0}_{1}", NodeUtils.GetHLSLSafeName(name ?? "node"), id); m_NameForDefaultVariableName = name; - m_GuidForDefaultVariableName = guid; } return m_DefaultVariableName; } @@ -211,16 +195,9 @@ public void SetColor(string provider, Color color) protected AbstractMaterialNode() { m_DrawState.expanded = true; - m_Guid = Guid.NewGuid(); version = 0; } - public Guid RewriteGuid() - { - m_Guid = Guid.NewGuid(); - return m_Guid; - } - public void GetInputSlots(List foundSlots) where T : ISlot { foreach (var slot in m_Slots) @@ -277,11 +254,9 @@ public string GetSlotValue(int inputSlotId, GenerationMode generationMode) if (edges.Any()) { var fromSocketRef = edges[0].outputSlot; - var fromNode = owner.GetNodeFromGuid(fromSocketRef.nodeGuid); - if (fromNode == null) - return string.Empty; + var fromNode = fromSocketRef.node; - var slot = fromNode.FindOutputSlot(fromSocketRef.slotId); + var slot = fromNode?.FindOutputSlot(fromSocketRef.slotId); if (slot == null) return string.Empty; @@ -361,7 +336,6 @@ public virtual bool ValidateConcretePrecision(ref string errorMessage) // Otherwise compare precisions from inputs var precisionsToCompare = new List(); - bool isInError = false; foreach (var inputSlot in tempSlots) { @@ -375,13 +349,7 @@ public virtual bool ValidateConcretePrecision(ref string errorMessage) // Get output node from edge var outputSlotRef = edges[0].outputSlot; - var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); - if (outputNode == null) - { - errorMessage = string.Format("Failed to find Node with Guid {0}", outputSlotRef.nodeGuid); - isInError = true; - continue; - } + var outputNode = outputSlotRef.node; // Use precision from connected Node precisionsToCompare.Add((int)outputNode.concretePrecision); @@ -391,7 +359,7 @@ public virtual bool ValidateConcretePrecision(ref string errorMessage) m_ConcretePrecision = (ConcretePrecision)precisionsToCompare.OrderBy(x => x).First(); // Clean up - return isInError; + return false; } } @@ -426,7 +394,7 @@ public virtual void ValidateNode() // get the output details var outputSlotRef = edges[0].outputSlot; - var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); + var outputNode = outputSlotRef.node; if (outputNode == null) continue; @@ -513,7 +481,7 @@ public virtual void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(guid, errorMessage); + ((GraphData) owner).AddValidationError(id, errorMessage); } else { @@ -538,7 +506,7 @@ protected virtual bool CalculateNodeHasError(ref string errorMessage) if (slot.isConnected) { var edge = owner.GetEdges(slot.slotReference).First(); - var outputNode = owner.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var outputNode = edge.outputSlot.node; var outputSlot = outputNode.GetOutputSlots().First(s => s.id == edge.outputSlot.slotId); if (!slot.IsCompatibleWith(outputSlot)) { @@ -655,7 +623,7 @@ public SlotReference GetSlotReference(int slotId) var slot = FindSlot(slotId); if (slot == null) throw new ArgumentException("Slot could not be found", "slotId"); - return new SlotReference(guid, slotId); + return new SlotReference(this, slotId); } public T FindSlot(int slotId) where T : ISlot @@ -695,18 +663,12 @@ public virtual IEnumerable GetInputsWithNoConnection() public override void OnBeforeSerialize() { - m_GuidSerialized = m_Guid.ToString(); m_GroupGuidSerialized = m_GroupGuid.ToString(); m_SerializableSlots = SerializationHelper.Serialize(m_Slots); } public override void OnAfterDeserialize() { - if (!string.IsNullOrEmpty(m_GuidSerialized)) - m_Guid = new Guid(m_GuidSerialized); - else - m_Guid = Guid.NewGuid(); - if (m_NodeVersion != GetCompiledNodeVersion()) { UpgradeNodeWithVersion(m_NodeVersion, GetCompiledNodeVersion()); diff --git a/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs index 68d80977fcd..97e1172caac 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs @@ -378,7 +378,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo private string GetFunctionName() { var function = GetFunctionToConvert(); - return function.Name + (function.IsStatic ? string.Empty : "_" + GuidEncoder.Encode(guid)) + "_" + concretePrecision.ToShaderString() + return function.Name + (function.IsStatic ? string.Empty : "_" + id) + "_" + concretePrecision.ToShaderString() + (this.GetSlots().Select(s => NodeUtils.GetSlotDimension(s.concreteValueType)).FirstOrDefault() ?? "") + (this.GetSlots().Select(s => NodeUtils.GetSlotDimension(s.concreteValueType)).FirstOrDefault() ?? ""); } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs index d73c8faaeb6..a4ae40982f9 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs @@ -122,7 +122,7 @@ public override void ValidateNode() // get the output details var outputSlotRef = edges[0].outputSlot; - var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); + var outputNode = outputSlotRef.node; if (outputNode == null) continue; @@ -251,7 +251,7 @@ public override void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(guid, errorMessage); + ((GraphData) owner).AddValidationError(id, errorMessage); } else { @@ -302,7 +302,7 @@ private MaterialSlot GetMatrixSlot() var edges = owner.GetEdges(slots[i].slotReference).ToList(); if (!edges.Any()) continue; - var outputNode = owner.GetNodeFromGuid(edges[0].outputSlot.nodeGuid); + var outputNode = edges[0].outputSlot.node; var outputSlot = outputNode.FindOutputSlot(edges[0].outputSlot.slotId); if (outputSlot.concreteValueType == ConcreteSlotValueType.Matrix4 || outputSlot.concreteValueType == ConcreteSlotValueType.Matrix3 @@ -317,7 +317,7 @@ private void SetConcreteValueTypeFromEdge(DynamicValueMaterialSlot slot) var edges = owner.GetEdges(slot.slotReference).ToList(); if (!edges.Any()) return; - var outputNode = owner.GetNodeFromGuid(edges[0].outputSlot.nodeGuid); + var outputNode = edges[0].outputSlot.node; var outputSlot = outputNode.FindOutputSlot(edges[0].outputSlot.slotId); slot.SetConcreteType(outputSlot.concreteValueType); } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs index 641a44dccb3..308b0e024be 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs @@ -157,7 +157,7 @@ public override void ValidateNode() // get the output details var outputSlotRef = edges[0].outputSlot; - var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); + var outputNode = outputSlotRef.node; if (outputNode == null) continue; @@ -246,7 +246,7 @@ public override void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(guid, errorMessage); + ((GraphData) owner).AddValidationError(id, errorMessage); } else { diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs index 794bf5e7797..a7fc4bb12e9 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs @@ -223,7 +223,7 @@ string SlotInputValue(MaterialSlot port, GenerationMode generationMode) if (edges.Any()) { var fromSocketRef = edges[0].outputSlot; - var fromNode = owner.GetNodeFromGuid(fromSocketRef.nodeGuid); + var fromNode = fromSocketRef.node; if (fromNode == null) return string.Empty; @@ -275,7 +275,7 @@ void ValidateSlotName() var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); if (error) { - owner.AddValidationError(guid, errorMessage); + owner.AddValidationError(id, errorMessage); break; } } @@ -285,7 +285,7 @@ public override void ValidateNode() { if (!this.GetOutputSlots().Any()) { - owner.AddValidationError(guid, k_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); + owner.AddValidationError(id, k_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); } if(sourceType == HlslSourceType.File) { @@ -297,7 +297,7 @@ public override void ValidateNode() string extension = path.Substring(path.LastIndexOf('.')); if(!s_ValidExtensions.Contains(extension)) { - owner.AddValidationError(guid, k_InvalidFileType, ShaderCompilerMessageSeverity.Error); + owner.AddValidationError(id, k_InvalidFileType, ShaderCompilerMessageSeverity.Error); } } } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs index 19608636643..dda5ea8a085 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs @@ -430,11 +430,11 @@ public override void ValidateNode() var assetPath = string.IsNullOrEmpty(subGraphGuid) ? null : AssetDatabase.GUIDToAssetPath(assetGuid); if (string.IsNullOrEmpty(assetPath)) { - owner.AddValidationError(guid, $"Could not find Sub Graph asset with GUID {assetGuid}."); + owner.AddValidationError(id, $"Could not find Sub Graph asset with GUID {assetGuid}."); } else { - owner.AddValidationError(guid, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}."); + owner.AddValidationError(id, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}."); } return; @@ -443,12 +443,12 @@ public override void ValidateNode() if (asset.isRecursive || owner.isSubGraph && (asset.descendents.Contains(owner.assetGuid) || asset.assetGuid == owner.assetGuid)) { hasError = true; - owner.AddValidationError(guid, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); + owner.AddValidationError(id, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); } else if (!asset.isValid) { hasError = true; - owner.AddValidationError(guid, $"Invalid Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); + owner.AddValidationError(id, $"Invalid Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); } ValidateShaderStage(); diff --git a/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs b/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs index 5de3da3d995..8ff84d586e0 100644 --- a/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs +++ b/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs @@ -56,7 +56,7 @@ void ValidateSlotName() var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); if (error) { - owner.AddValidationError(guid, errorMessage); + owner.AddValidationError(id, errorMessage); break; } } @@ -68,7 +68,7 @@ public override void ValidateNode() if (!this.GetInputSlots().Any()) { - owner.AddValidationError(guid, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); + owner.AddValidationError(id, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); } base.ValidateNode(); diff --git a/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs b/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs index a1afb0c6cbf..15edea4e18e 100644 --- a/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs +++ b/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs @@ -185,19 +185,19 @@ public static bool IsShaderGraph(this Shader shader) return importer is ShaderGraphImporter; } - static void Visit(List outputList, Dictionary unmarkedNodes, AbstractMaterialNode node) + static void Visit(List outputList, Dictionary unmarkedNodes, AbstractMaterialNode node) { - if (!unmarkedNodes.ContainsKey(node.guid)) + if (!unmarkedNodes.ContainsKey(node.id)) return; foreach (var slot in node.GetInputSlots()) { foreach (var edge in node.owner.GetEdges(slot.slotReference)) { - var inputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var inputNode = edge.outputSlot.node; Visit(outputList, unmarkedNodes, inputNode); } } - unmarkedNodes.Remove(node.guid); + unmarkedNodes.Remove(node.id); outputList.Add(node); } diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index e7c99a5a27e..e625f9a4d83 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -616,7 +616,7 @@ public void ToSubGraph() // foreach (var group in uniqueIncomingEdges) // { // var sr = group.slotRef; - // var fromNode = graphObject.graph.GetNodeFromGuid(sr.nodeGuid); + // var fromNode = graphObject.graph.sr.node; // var fromSlot = fromNode.FindOutputSlot(sr.slotId); // // AbstractShaderProperty prop; diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index 07aad2c76d5..40a28695832 100644 --- a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -20,7 +20,7 @@ class PreviewManager : IDisposable { GraphData m_Graph; MessageManager m_Messenger; - Dictionary m_RenderDatas = new Dictionary(); + Dictionary m_RenderDatas = new Dictionary(); PreviewRenderData m_MasterRenderData; HashSet m_NodesToUpdate = new HashSet(); HashSet m_NodesToDraw = new HashSet(); @@ -68,7 +68,7 @@ public void ResizeMasterPreview(Vector2 newSize) public PreviewRenderData GetPreview(AbstractMaterialNode node) { - return m_RenderDatas[node.guid]; + return m_RenderDatas[node.id]; } void AddPreview(AbstractMaterialNode node) @@ -77,7 +77,7 @@ void AddPreview(AbstractMaterialNode node) if (node is IMasterNode || node is SubGraphOutputNode) { - if (masterRenderData != null || (node is IMasterNode && node.guid != node.owner.activeOutputNodeGuid)) + if (masterRenderData != null || (node is IMasterNode && node != node.owner.outputNode)) { return; } @@ -113,7 +113,7 @@ void AddPreview(AbstractMaterialNode node) shaderData.mat = new Material(shaderData.shader) {hideFlags = HideFlags.HideAndDontSave}; renderData.shaderData = shaderData; - m_RenderDatas.Add(node.guid, renderData); + m_RenderDatas.Add(node.id, renderData); node.RegisterCallback(OnNodeModified); if (node.RequiresTime()) @@ -193,8 +193,7 @@ void GetConnectedNodes(AbstractMaterialNode node, PropagationDirection dir, T { // We look at each node we feed into. var connectedSlot = (dir == PropagationDirection.Downstream) ? edge.inputSlot : edge.outputSlot; - var connectedNodeGuid = connectedSlot.nodeGuid; - var connectedNode = m_Graph.GetNodeFromGuid(connectedNodeGuid); + var connectedNode = connectedSlot.node; // If the input node is already in the set, we don't need to process it. if (connections.Contains(connectedNode)) @@ -210,12 +209,12 @@ public bool HandleGraphChanges() { if (m_Graph.didActiveOutputNodeChange) { - DestroyPreview(masterRenderData.shaderData.node.guid); + DestroyPreview(masterRenderData.shaderData.node.id); } foreach (var node in m_Graph.removedNodes) { - DestroyPreview(node.guid); + DestroyPreview(node.id); m_NodesToUpdate.Remove(node); m_NodesToDraw.Remove(node); m_RefreshTimedNodes = true; @@ -231,7 +230,7 @@ public bool HandleGraphChanges() foreach (var edge in m_Graph.removedEdges) { - var node = m_Graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var node = edge.inputSlot.node; if (node != null) { m_NodesToUpdate.Add(node); @@ -240,7 +239,7 @@ public bool HandleGraphChanges() } foreach (var edge in m_Graph.addedEdges) { - var node = m_Graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var node = edge.inputSlot.node; if(node != null) { m_NodesToUpdate.Add(node); @@ -293,7 +292,7 @@ public void RenderPreviews() if(node == null || !node.hasPreview || !node.previewExpanded) continue; - var renderData = m_RenderDatas[node.guid]; + var renderData = m_RenderDatas[node.id]; CollectShaderProperties(node, renderData); renderData.shaderData.mat.SetVector("_TimeParameters", timeParameters); @@ -434,7 +433,7 @@ void UpdateShaders() foreach (var node in m_NodesToUpdate) { - if (node is IMasterNode && node == masterRenderData.shaderData.node && !(node is VfxMasterNode)) + if (node is IMasterNode && masterRenderData != null && node == masterRenderData.shaderData.node && !(node is VfxMasterNode)) { UpdateMasterNodeShader(); continue; @@ -443,9 +442,7 @@ void UpdateShaders() if (!node.hasPreview && !(node is SubGraphOutputNode || node is VfxMasterNode)) continue; - Guid id = node.guid; - var renderData = m_RenderDatas[id]; - if (renderData == null) + if (!m_RenderDatas.TryGetValue(node.id, out var renderData)) { continue; } @@ -544,7 +541,7 @@ void CheckForErrors(PreviewShaderData shaderData) var messages = ShaderUtil.GetShaderMessages(shaderData.shader); if (messages.Length > 0) { - m_Messenger.AddOrAppendError(this, shaderData.node.guid, messages[0]); + m_Messenger.AddOrAppendError(this, shaderData.node.id, messages[0]); } } } @@ -605,7 +602,7 @@ void DestroyRenderData(PreviewRenderData renderData) renderData.shaderData.node.UnregisterCallback(OnNodeModified); } - void DestroyPreview(Guid nodeId) + void DestroyPreview(string nodeId) { if (!m_RenderDatas.TryGetValue(nodeId, out var renderData)) { @@ -619,7 +616,7 @@ void DestroyPreview(Guid nodeId) if (masterRenderData == renderData) { m_MasterRenderData = null; - if (!m_Graph.isSubGraph && renderData.shaderData.node.guid != m_Graph.activeOutputNodeGuid) + if (!m_Graph.isSubGraph && renderData.shaderData.node != m_Graph.outputNode) { AddPreview(m_Graph.outputNode); } diff --git a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index 1214bed3cae..6e4a078d675 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -538,7 +538,7 @@ void OnNodeChanged(AbstractMaterialNode inNode, ModificationScope scope) foreach (var node in dependentNodes) { var theViews = m_GraphView.nodes.ToList().OfType(); - var viewsFound = theViews.Where(x => x.node.guid == node.guid).ToList(); + var viewsFound = theViews.Where(x => x.node == node).ToList(); foreach (var drawableNodeData in viewsFound) drawableNodeData.OnModified(scope); } @@ -567,7 +567,7 @@ public void HandleGraphChanges() { node.UnregisterCallback(OnNodeChanged); var nodeView = m_GraphView.nodes.ToList().OfType() - .FirstOrDefault(p => p.node != null && p.node.guid == node.guid); + .FirstOrDefault(p => p.node != null && p.node == node); if (nodeView != null) { nodeView.Dispose(); @@ -613,7 +613,7 @@ public void HandleGraphChanges() GraphElement graphElement = null; if (groupChange.groupItem is AbstractMaterialNode node) { - graphElement = m_GraphView.GetNodeByGuid(node.guid.ToString()); + graphElement = m_GraphView.GetNodeByGuid(node.id); } else if (groupChange.groupItem is StickyNoteData stickyNote) { @@ -656,7 +656,7 @@ public void HandleGraphChanges() foreach (var node in m_Graph.pastedNodes) { var nodeView = m_GraphView.nodes.ToList().OfType() - .FirstOrDefault(p => p.node != null && p.node.guid == node.guid); + .FirstOrDefault(p => p.node != null && p.node == node); m_GraphView.AddToSelection((Node)nodeView); } @@ -733,9 +733,9 @@ void UpdateBadges() foreach (var messageData in m_MessageManager.GetNodeMessages()) { - var node = m_Graph.GetNodeFromGuid(messageData.Key); + var node = m_Graph.GetNodeFromId(messageData.Key); - if (!(m_GraphView.GetNodeByGuid(node.guid.ToString()) is MaterialNodeView nodeView)) + if (!(m_GraphView.GetNodeByGuid(node.id) is MaterialNodeView nodeView)) continue; if (messageData.Value.Count == 0) @@ -776,7 +776,7 @@ void AddNode(AbstractMaterialNode node) node.RegisterCallback(OnNodeChanged); nodeView.MarkDirtyRepaint(); - if (m_SearchWindowProvider.nodeNeedsRepositioning && m_SearchWindowProvider.targetSlotReference.nodeGuid.Equals(node.guid)) + if (m_SearchWindowProvider.nodeNeedsRepositioning && m_SearchWindowProvider.targetSlotReference.node == node) { m_SearchWindowProvider.nodeNeedsRepositioning = false; foreach (var element in nodeView.inputContainer.Children().Union(nodeView.outputContainer.Children())) @@ -870,7 +870,7 @@ static void RepositionNode(GeometryChangedEvent evt) Edge AddEdge(IEdge edge) { - var sourceNode = m_Graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var sourceNode = edge.outputSlot.node; if (sourceNode == null) { Debug.LogWarning("Source node is null"); @@ -878,7 +878,7 @@ Edge AddEdge(IEdge edge) } var sourceSlot = sourceNode.FindOutputSlot(edge.outputSlot.slotId); - var targetNode = m_Graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var targetNode = edge.inputSlot.node; if (targetNode == null) { Debug.LogWarning("Target node is null"); diff --git a/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs b/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs index 5021905daee..0a55e8fae33 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs @@ -55,7 +55,7 @@ public void Initialize(AbstractMaterialNode inNode, PreviewManager previewManage m_ConnectorListener = connectorListener; node = inNode; - viewDataKey = node.guid.ToString(); + viewDataKey = node.id; UpdateTitle(); // Add controls container @@ -307,7 +307,7 @@ public override void BuildContextualMenu(ContextualMenuPopulateEvent evt) if (evt.target is Node) { var isMaster = node is IMasterNode; - var isActive = node.guid == node.owner.activeOutputNodeGuid; + var isActive = node == node.owner.outputNode; if (isMaster) { evt.menu.AppendAction("Set Active", SetMasterAsActive, @@ -335,7 +335,7 @@ public override void BuildContextualMenu(ContextualMenuPopulateEvent evt) void SetMasterAsActive(DropdownMenuAction action) { - node.owner.activeOutputNodeGuid = node.guid; + node.owner.outputNode = node; } void CopyToClipboard(DropdownMenuAction action) @@ -354,7 +354,7 @@ public void ShowGeneratedCode(DropdownMenuAction action) var mode = (GenerationMode)action.userData; string path = String.Format("Temp/GeneratedFromGraph-{0}-{1}-{2}{3}.shader", SanitizeName(name), - SanitizeName(node.name), node.guid, mode == GenerationMode.Preview ? "-Preview" : ""); + SanitizeName(node.name), node.id, mode == GenerationMode.Preview ? "-Preview" : ""); if (GraphUtil.WriteToFile(path, ConvertToShader(mode))) GraphUtil.OpenFile(path); } @@ -628,7 +628,7 @@ void UpdatePortInput(GeometryChangedEvent evt) { var port = (ShaderPort)evt.target; var inputViews = m_PortInputContainer.Children().OfType().Where(x => Equals(x.slot, port.slot)); - + // Ensure PortInputViews are initialized correctly // Dynamic port lists require one update to validate before init if(inputViews.Count() != 0) @@ -636,7 +636,7 @@ void UpdatePortInput(GeometryChangedEvent evt) var inputView = inputViews.First(); SetPortInputPosition(port, inputView); } - + port.UnregisterCallback(UpdatePortInput); } diff --git a/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs b/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs index d5de24ef939..6cadc513f7b 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs @@ -16,7 +16,7 @@ public PropertyNodeView(PropertyNode node, EdgeConnectorListener edgeConnectorLi { styleSheets.Add(Resources.Load("Styles/PropertyNodeView")); this.node = node; - viewDataKey = node.guid.ToString(); + viewDataKey = node.id.ToString(); userData = node; // Getting the generatePropertyBlock property to see if it is exposed or not diff --git a/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index fbb70301251..d8ced564eb2 100644 --- a/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -90,7 +90,7 @@ void BuildShader() if(m_GraphData.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit) { - m_GraphData.AddValidationError(m_OutputNode.guid, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); + m_GraphData.AddValidationError(m_OutputNode.id, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); m_ConfiguredTextures = shaderProperties.GetConfiguredTexutres(); m_Builder.AppendLines(ShaderGraphImporter.k_ErrorShader); diff --git a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index 752ad3ffda4..eb74427aa17 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -109,7 +109,7 @@ public override void OnImportAsset(AssetImportContext ctx) { foreach (var pair in graph.messageManager.GetNodeMessages()) { - var node = graph.GetNodeFromGuid(pair.Key); + var node = graph.GetNodeFromId(pair.Key); MessageManager.Log(node, path, pair.Value.First(), shader); } } @@ -322,7 +322,7 @@ static ShaderGraphVfxAsset GenerateVfxShaderGraphAsset(VfxMasterNode masterNode) var message = new StringBuilder($"Precision mismatch for function {name}:"); foreach (var node in source.nodes) { - message.AppendLine($"{node.name} ({node.guid}): {node.concretePrecision}"); + message.AppendLine($"{node.name} ({node.id}): {node.concretePrecision}"); } throw new InvalidOperationException(message.ToString()); } diff --git a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index bd51e93247f..527ec09960c 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -61,7 +61,7 @@ public override void OnImportAsset(AssetImportContext ctx) graphAsset.isValid = false; foreach (var pair in messageManager.GetNodeMessages()) { - var node = graphData.GetNodeFromGuid(pair.Key); + var node = graphData.GetNodeFromId(pair.Key); foreach (var message in pair.Value) { MessageManager.Log(node, subGraphPath, message, graphAsset); diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs index 3c1e06a754c..6ed3b33eb9b 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs @@ -43,7 +43,7 @@ public static implicit operator T(JsonRef jsonRef) public static implicit operator JsonRef(T value) { - return new JsonRef { m_Value = value, m_Id = value.id }; + return new JsonRef { m_Value = value, m_Id = value?.id }; } public bool Equals(JsonRef other) diff --git a/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs b/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs index 5722551e3d7..6ea0474b35b 100644 --- a/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs +++ b/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs @@ -74,7 +74,7 @@ public CopyPasteGraph(string sourceGraphGuid, IEnumerable groups, IEn { if (!node.canCopyNode) { - throw new InvalidOperationException($"Cannot copy node {node.name} ({node.guid})."); + throw new InvalidOperationException($"Cannot copy node {node.name} ({node.id})."); } AddNode(node); foreach (var edge in NodeUtils.GetAllEdges(node)) diff --git a/com.unity.shadergraph/Editor/Util/MessageManager.cs b/com.unity.shadergraph/Editor/Util/MessageManager.cs index 230043bab83..77a089cc74d 100644 --- a/com.unity.shadergraph/Editor/Util/MessageManager.cs +++ b/com.unity.shadergraph/Editor/Util/MessageManager.cs @@ -10,20 +10,20 @@ namespace UnityEditor.Graphing.Util { class MessageManager { - protected Dictionary>> m_Messages = - new Dictionary>>(); + protected Dictionary>> m_Messages = + new Dictionary>>(); - Dictionary> m_Combined = new Dictionary>(); + Dictionary> m_Combined = new Dictionary>(); public bool nodeMessagesChanged { get; private set; } - Dictionary> m_FoundMessages; + Dictionary> m_FoundMessages; - public void AddOrAppendError(object errorProvider, Guid nodeId, ShaderMessage error) + public void AddOrAppendError(object errorProvider, string nodeId, ShaderMessage error) { if (!m_Messages.TryGetValue(errorProvider, out var messages)) { - messages = new Dictionary>(); + messages = new Dictionary>(); m_Messages[errorProvider] = messages; } @@ -46,9 +46,9 @@ static int CompareMessages(ShaderMessage m1, ShaderMessage m2) return m1.severity > m2.severity ? 1 : m2.severity > m1.severity ? -1 : 0; } - public IEnumerable>> GetNodeMessages() + public IEnumerable>> GetNodeMessages() { - var fixedNodes = new List(); + var fixedNodes = new List(); m_Combined.Clear(); foreach (var messageMap in m_Messages) { @@ -81,7 +81,7 @@ public IEnumerable>> GetNodeMessages() return m_Combined; } - public void RemoveNode(Guid nodeId) + public void RemoveNode(string nodeId) { foreach (var messageMap in m_Messages) { @@ -109,7 +109,7 @@ public void ClearNodesFromProvider(object messageProvider, IEnumerable 0; messages.Clear(); diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs index 653eb826c18..f35daf9ba4f 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs @@ -46,8 +46,8 @@ public void TestCanGetMaterialNodeFromMaterialGraph() Assert.AreEqual(0, graph.edges.Count()); Assert.AreEqual(1, graph.GetNodes().Count()); - Assert.AreEqual(node, graph.GetNodeFromGuid(node.guid)); - Assert.AreEqual(node, graph.GetNodeFromGuid(node.guid)); + Assert.AreEqual(node, graph.GetNodeFromId(node.id)); + Assert.AreEqual(node, graph.GetNodeFromId(node.id)); } /* [Test] diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs index 6fe54f4e1cf..200eef4267c 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs @@ -12,7 +12,7 @@ namespace UnityEditor.ShaderGraph.UnitTests { class TestMessageManager : MessageManager { - public Dictionary>> Messages + public Dictionary>> Messages { get { return m_Messages; } } @@ -40,19 +40,19 @@ public void Setup() m_EmptyMgr = new TestMessageManager(); m_ComplexMgr = new TestMessageManager(); - m_ComplexMgr.AddOrAppendError(p0, node0.guid, e0); - m_ComplexMgr.AddOrAppendError(p0, node0.guid, e1); - m_ComplexMgr.AddOrAppendError(p0, node1.guid, e2); - m_ComplexMgr.AddOrAppendError(p1, node0.guid, e1); - m_ComplexMgr.AddOrAppendError(p1, node1.guid, e0); - m_ComplexMgr.AddOrAppendError(p1, node1.guid, e1); - m_ComplexMgr.AddOrAppendError(p1, node2.guid, e3); + m_ComplexMgr.AddOrAppendError(p0, node0.id, e0); + m_ComplexMgr.AddOrAppendError(p0, node0.id, e1); + m_ComplexMgr.AddOrAppendError(p0, node1.id, e2); + m_ComplexMgr.AddOrAppendError(p1, node0.id, e1); + m_ComplexMgr.AddOrAppendError(p1, node1.id, e0); + m_ComplexMgr.AddOrAppendError(p1, node1.id, e1); + m_ComplexMgr.AddOrAppendError(p1, node2.id, e3); } // Simple helper to avoid typing that ungodly generic type - static List>> GetListFrom(MessageManager mgr) + static List>> GetListFrom(MessageManager mgr) { - return new List>>(mgr.GetNodeMessages()); + return new List>>(mgr.GetNodeMessages()); } [Test] @@ -65,11 +65,11 @@ public void NewManager_IsEmpty() [Test] public void AddMessage_CreatesMessage() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.guid, ret[0].Key); + Assert.AreEqual(node0.id, ret[0].Key); Assert.IsNotEmpty(ret[0].Value); Assert.AreEqual(e0, ret[0].Value[0]); } @@ -77,7 +77,7 @@ public void AddMessage_CreatesMessage() [Test] public void AddMessage_DirtiesManager() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); Assert.IsTrue(m_EmptyMgr.nodeMessagesChanged); } @@ -85,7 +85,7 @@ public void AddMessage_DirtiesManager() [Test] public void GettingMessages_ClearsDirtyFlag() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); GetListFrom(m_EmptyMgr); Assert.IsFalse(m_EmptyMgr.nodeMessagesChanged); @@ -94,26 +94,26 @@ public void GettingMessages_ClearsDirtyFlag() [Test] public void GettingMessages_DoesNotChangeLists() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e1); - m_EmptyMgr.AddOrAppendError(p1, node0.guid, e2); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e1); + m_EmptyMgr.AddOrAppendError(p1, node0.id, e2); GetListFrom(m_EmptyMgr); - Assert.AreEqual(2, m_EmptyMgr.Messages[p0][node0.guid].Count); - Assert.AreEqual(e0, m_EmptyMgr.Messages[p0][node0.guid][0]); - Assert.AreEqual(e1, m_EmptyMgr.Messages[p0][node0.guid][1]); - Assert.AreEqual(1, m_EmptyMgr.Messages[p1][node0.guid].Count); - Assert.AreEqual(e2, m_EmptyMgr.Messages[p1][node0.guid][0]); + Assert.AreEqual(2, m_EmptyMgr.Messages[p0][node0.id].Count); + Assert.AreEqual(e0, m_EmptyMgr.Messages[p0][node0.id][0]); + Assert.AreEqual(e1, m_EmptyMgr.Messages[p0][node0.id][1]); + Assert.AreEqual(1, m_EmptyMgr.Messages[p1][node0.id].Count); + Assert.AreEqual(e2, m_EmptyMgr.Messages[p1][node0.id][0]); } [Test] public void RemoveNode_DoesNotDirty_IfNodeDoesNotExist() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); GetListFrom(m_EmptyMgr); - m_EmptyMgr.RemoveNode(node1.guid); + m_EmptyMgr.RemoveNode(node1.id); Assert.IsFalse(m_EmptyMgr.nodeMessagesChanged); } @@ -121,10 +121,10 @@ public void RemoveNode_DoesNotDirty_IfNodeDoesNotExist() [Test] public void RemoveNode_DirtiesList_IfNodeExists() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); GetListFrom(m_EmptyMgr); - m_EmptyMgr.RemoveNode(node0.guid); + m_EmptyMgr.RemoveNode(node0.id); Assert.IsTrue(m_EmptyMgr.nodeMessagesChanged); } @@ -132,8 +132,8 @@ public void RemoveNode_DirtiesList_IfNodeExists() [Test] public void RemoveNode_RemovesNode() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.RemoveNode(node0.guid); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.RemoveNode(node0.id); var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); @@ -142,9 +142,9 @@ public void RemoveNode_RemovesNode() [Test] public void RemoveNode_RemovesNode_FromAllProvides() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.AddOrAppendError(p1, node0.guid, e1); - m_EmptyMgr.RemoveNode(node0.guid); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p1, node0.id, e1); + m_EmptyMgr.RemoveNode(node0.id); var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); @@ -153,12 +153,12 @@ public void RemoveNode_RemovesNode_FromAllProvides() [Test] public void AppendMessage_AppendsMessage() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e1); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e1); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.guid, ret[0].Key); + Assert.AreEqual(node0.id, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e1, ret[0].Value[1]); @@ -168,10 +168,10 @@ public void AppendMessage_AppendsMessage() public void Warnings_SortedAfterErrors() { var mixedMgr = new MessageManager(); - mixedMgr.AddOrAppendError(p0, node0.guid, e0); - mixedMgr.AddOrAppendError(p0, node0.guid, w0); - mixedMgr.AddOrAppendError(p0, node0.guid, e1); - mixedMgr.AddOrAppendError(p0, node0.guid, w1); + mixedMgr.AddOrAppendError(p0, node0.id, e0); + mixedMgr.AddOrAppendError(p0, node0.id, w0); + mixedMgr.AddOrAppendError(p0, node0.id, e1); + mixedMgr.AddOrAppendError(p0, node0.id, w1); var ret = GetListFrom(mixedMgr)[0].Value; Assert.AreEqual(e0, ret[0]); @@ -184,10 +184,10 @@ public void Warnings_SortedAfterErrors() public void Warnings_FromDifferentProviders_SortedAfterErrors() { var mixedMgr = new MessageManager(); - mixedMgr.AddOrAppendError(p0, node0.guid, e0); - mixedMgr.AddOrAppendError(p0, node0.guid, w0); - mixedMgr.AddOrAppendError(p1, node0.guid, e1); - mixedMgr.AddOrAppendError(p1, node0.guid, w1); + mixedMgr.AddOrAppendError(p0, node0.id, e0); + mixedMgr.AddOrAppendError(p0, node0.id, w0); + mixedMgr.AddOrAppendError(p1, node0.id, e1); + mixedMgr.AddOrAppendError(p1, node0.id, w1); var ret = GetListFrom(mixedMgr)[0].Value; Assert.AreEqual(e0, ret[0]); @@ -199,26 +199,26 @@ public void Warnings_FromDifferentProviders_SortedAfterErrors() [Test] public void MultipleNodes_RemainSeparate() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.AddOrAppendError(p0, node1.guid, e1); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node1.id, e1); var ret = GetListFrom(m_EmptyMgr); Assert.AreEqual(2, ret.Count); - Assert.AreEqual(node0.guid, ret[0].Key); + Assert.AreEqual(node0.id, ret[0].Key); Assert.AreEqual(e0, ret[0].Value[0]); - Assert.AreEqual(node1.guid, ret[1].Key); + Assert.AreEqual(node1.id, ret[1].Key); Assert.AreEqual(e1, ret[1].Value[0]); } [Test] public void MultipleCreators_AggregatePerNode() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.AddOrAppendError(p1, node0.guid, e1); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p1, node0.id, e1); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.guid, ret[0].Key); + Assert.AreEqual(node0.id, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e1, ret[0].Value[1]); @@ -227,12 +227,12 @@ public void MultipleCreators_AggregatePerNode() [Test] public void DuplicateEntries_AreNotIgnored() { - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); - m_EmptyMgr.AddOrAppendError(p0, node0.guid, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.guid, ret[0].Key); + Assert.AreEqual(node0.id, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e0, ret[0].Value[1]); @@ -246,11 +246,11 @@ public void ClearAllFromProvider_ZerosMessageLists() var ret = GetListFrom(m_ComplexMgr); Assert.IsNotEmpty(ret); Assert.AreEqual(3, ret.Count); - Assert.AreEqual(node0.guid, ret[0].Key); + Assert.AreEqual(node0.id, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); - Assert.AreEqual(node1.guid, ret[1].Key); + Assert.AreEqual(node1.id, ret[1].Key); Assert.AreEqual(1, ret[1].Value.Count); - Assert.AreEqual(node2.guid, ret[2].Key); + Assert.AreEqual(node2.id, ret[2].Key); Assert.IsEmpty(ret[2].Value); } @@ -259,11 +259,11 @@ public void GetList_RemovesZeroLengthLists() { m_ComplexMgr.ClearAllFromProvider(p1); var ret = GetListFrom(m_ComplexMgr); - Assert.IsNotEmpty(ret.Where(kvp => kvp.Key.Equals(node2.guid))); - Assert.IsEmpty(ret.First(kvp => kvp.Key.Equals(node2.guid)).Value); + Assert.IsNotEmpty(ret.Where(kvp => kvp.Key.Equals(node2.id))); + Assert.IsEmpty(ret.First(kvp => kvp.Key.Equals(node2.id)).Value); ret = GetListFrom(m_ComplexMgr); - Assert.IsEmpty(ret.Where(kvp => kvp.Key.Equals(node2.guid))); + Assert.IsEmpty(ret.Where(kvp => kvp.Key.Equals(node2.id))); } [Test] @@ -273,8 +273,8 @@ public void ClearNodesFromProvider_ClearsNodes() m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); - Assert.AreEqual(2, ret.Find(kpv => kpv.Key.Equals(node0.guid)).Value.Count); - Assert.IsEmpty(ret.Find(kvp => kvp.Key.Equals(node2.guid)).Value); + Assert.AreEqual(2, ret.Find(kpv => kpv.Key.Equals(node0.id)).Value.Count); + Assert.IsEmpty(ret.Find(kvp => kvp.Key.Equals(node2.id)).Value); } [Test] @@ -284,7 +284,7 @@ public void ClearNodesFromProvider_LeavesOtherNodes() m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); - Assert.AreEqual(3, ret.Find(kpv => kpv.Key.Equals(node1.guid)).Value.Count); + Assert.AreEqual(3, ret.Find(kpv => kpv.Key.Equals(node1.id)).Value.Count); } } } diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs index 078139fd41d..c1052ac336a 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs @@ -91,14 +91,14 @@ public void TestChildClassCanModifyErrorState() Assert.IsFalse(node.hasError); } - [Test] - public void TestNodeGUIDCanBeRewritten() - { - var node = new TestNode(); - var guid = node.guid; - var newGuid = node.RewriteGuid(); - Assert.AreNotEqual(guid, newGuid); - } + // [Test] + // public void TestNodeGUIDCanBeRewritten() + // { + // var node = new TestNode(); + // var guid = node.guid; + // var newGuid = node.RewriteGuid(); + // Assert.AreNotEqual(guid, newGuid); + // } class TestableNode : TestNode { @@ -194,8 +194,8 @@ public void TestCanFindNodeInBaseMaterialGraph() graph.AddNode(node); Assert.AreEqual(1, graph.GetNodes().Count()); - Assert.IsNotNull(graph.GetNodeFromGuid(node.guid)); - Assert.IsNull(graph.GetNodeFromGuid(Guid.NewGuid())); + Assert.IsNotNull(graph.GetNodeFromId(node.id)); + Assert.IsNull(graph.GetNodeFromId("asdfffsd")); } [Test] @@ -410,12 +410,12 @@ public void TestCanConnectAndTraverseTwoNodesOnBaseMaterialGraph() Assert.AreEqual(createdEdge, edge); - var foundOutputNode = graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); + var foundOutputNode = edge.outputSlot.node; var foundOutputSlot = foundOutputNode.FindOutputSlot(edge.outputSlot.slotId); Assert.AreEqual(outputNode, foundOutputNode); Assert.IsNotNull(foundOutputSlot); - var foundInputNode = graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); + var foundInputNode = edge.inputSlot.node; var foundInputSlot = foundInputNode.FindInputSlot(edge.inputSlot.slotId); Assert.AreEqual(inputNode, foundInputNode); Assert.IsNotNull(foundInputSlot); @@ -554,7 +554,7 @@ public void TestCanNotConnectToNullSlot() Assert.AreEqual(2, graph.GetNodes().Count()); - var createdEdge2 = graph.Connect(outputNode.GetSlotReference(TestableNode.Output0), new SlotReference(Guid.NewGuid(), 666)); + var createdEdge2 = graph.Connect(outputNode.GetSlotReference(TestableNode.Output0), new SlotReference(null, 666)); Assert.AreEqual(0, graph.edges.Count()); Assert.IsNull(createdEdge2); } From 4f739848351c89979f2fd3691b699640f7d600f4 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 19 Mar 2020 09:53:58 +0100 Subject: [PATCH 19/64] Fix master node going blank after undo --- com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index c822a29d5af..23828fd683c 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -1074,6 +1074,8 @@ public void ReplaceWith(GraphData other) foreach (var edge in other.edges) ConnectNoValidate(edge.outputSlot, edge.inputSlot); + outputNode = other.outputNode; + ValidateGraph(); } From 7a7001e95c62f84f5c0e2ecdf0077bb12f67c7b2 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 19 Mar 2020 15:41:23 +0100 Subject: [PATCH 20/64] MaterialSlot -> JsonObject --- .../Editor/Data/Graphs/GraphData.cs | 71 +++++++---- .../Editor/Data/Graphs/MaterialSlot.cs | 10 +- .../Editor/Data/Implementation/NodeUtils.cs | 18 +-- .../Editor/Data/Interfaces/Graph/INode.cs | 6 +- .../Editor/Data/Interfaces/Graph/ISlot.cs | 17 --- .../Data/Interfaces/Graph/ISlot.cs.meta | 12 -- .../Data/Interfaces/Graph/SlotReference.cs | 2 +- .../Data/Interfaces/IMayRequireBitangent.cs | 2 +- .../IMayRequireCameraOpaqueTexture.cs | 2 +- .../Interfaces/IMayRequireDepthTexture.cs | 2 +- .../Data/Interfaces/IMayRequireFaceSign.cs | 2 +- .../Data/Interfaces/IMayRequireMeshUV.cs | 2 +- .../Data/Interfaces/IMayRequireNormal.cs | 2 +- .../Data/Interfaces/IMayRequirePosition.cs | 2 +- .../Interfaces/IMayRequireScreenPosition.cs | 2 +- .../Data/Interfaces/IMayRequireTangent.cs | 2 +- .../Data/Interfaces/IMayRequireVertexColor.cs | 2 +- .../Interfaces/IMayRequireVertexSkinning.cs | 2 +- .../Interfaces/IMayRequireViewDirection.cs | 2 +- .../Data/Legacy/AbstractMaterialNode0.cs | 4 + .../Editor/Data/Nodes/AbstractMaterialNode.cs | 82 +++++++------ .../Editor/Data/Nodes/CodeFunctionNode.cs | 2 +- .../Data/Nodes/Math/Basic/MultiplyNode.cs | 2 +- .../Data/Nodes/Math/Matrix/MatrixSplitNode.cs | 2 +- .../Data/Nodes/Utility/CustomFunctionNode.cs | 6 +- .../Editor/Data/Nodes/Utility/SubGraphNode.cs | 8 +- .../Data/SubGraph/SubGraphOutputNode.cs | 6 +- .../Editor/Data/Util/GraphUtil.cs | 6 +- .../Editor/Drawing/PreviewManager.cs | 14 +-- .../Editor/Drawing/SearchWindowProvider.cs | 2 +- .../Editor/Drawing/Views/GraphEditorView.cs | 4 +- .../Editor/Drawing/Views/MaterialNodeView.cs | 4 +- .../Editor/Drawing/Views/PropertyNodeView.cs | 2 +- .../Editor/Generation/Processors/Generator.cs | 2 +- .../Editor/Importers/ShaderGraphImporter.cs | 2 +- .../Editor/Serialization/FakeJsonObject.cs | 8 +- .../Editor/Serialization/JsonData.cs | 11 +- .../Editor/Serialization/JsonObject.cs | 4 +- .../Editor/Serialization/JsonRef.cs | 2 +- .../Editor/Serialization/MultiJsonInternal.cs | 16 +-- .../Editor/Util/CopyPasteGraph.cs | 2 +- .../Editor/Util/MessageManager.cs | 2 +- .../UnitTests/AbstractMaterialGraphTests.cs | 4 +- .../Editor/UnitTests/MaterialNodeTests.cs | 18 ++- .../Editor/UnitTests/MessageManagerTests.cs | 116 +++++++++--------- .../Editor/UnitTests/SerializedGraphTests.cs | 102 +++++++-------- 46 files changed, 294 insertions(+), 299 deletions(-) delete mode 100644 com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs delete mode 100644 com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs.meta diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 23828fd683c..240cddbf25a 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; using UnityEditor.Graphing; @@ -455,7 +456,7 @@ void AddNodeNoValidate(AbstractMaterialNode node) } node.owner = this; m_Nodes.Add(node); - m_NodeDictionary.Add(node.id, node); + m_NodeDictionary.Add(node.objectId, node); m_AddedNodes.Add(node); m_GroupItems[node.groupGuid].Add(node); } @@ -464,7 +465,7 @@ public void RemoveNode(AbstractMaterialNode node) { if (!node.canDeleteNode) { - throw new InvalidOperationException($"Node {node.name} ({node.id}) cannot be deleted."); + throw new InvalidOperationException($"Node {node.name} ({node.objectId}) cannot be deleted."); } RemoveNodeNoValidate(node); ValidateGraph(); @@ -472,14 +473,14 @@ public void RemoveNode(AbstractMaterialNode node) void RemoveNodeNoValidate(AbstractMaterialNode node) { - if (!m_NodeDictionary.ContainsKey(node.id)) + if (!m_NodeDictionary.ContainsKey(node.objectId)) { throw new InvalidOperationException("Cannot remove a node that doesn't exist."); } m_Nodes.Remove(node); - m_NodeDictionary.Remove(node.id); - messageManager?.RemoveNode(node.id); + m_NodeDictionary.Remove(node.objectId); + messageManager?.RemoveNode(node.objectId); m_RemovedNodes.Add(node); if (m_GroupItems.TryGetValue(node.groupGuid, out var groupItems)) @@ -491,13 +492,13 @@ void RemoveNodeNoValidate(AbstractMaterialNode node) void AddEdgeToNodeEdges(IEdge edge) { List inputEdges; - if (!m_NodeEdges.TryGetValue(edge.inputSlot.node.id, out inputEdges)) - m_NodeEdges[edge.inputSlot.node.id] = inputEdges = new List(); + if (!m_NodeEdges.TryGetValue(edge.inputSlot.node.objectId, out inputEdges)) + m_NodeEdges[edge.inputSlot.node.objectId] = inputEdges = new List(); inputEdges.Add(edge); List outputEdges; - if (!m_NodeEdges.TryGetValue(edge.outputSlot.node.id, out outputEdges)) - m_NodeEdges[edge.outputSlot.node.id] = outputEdges = new List(); + if (!m_NodeEdges.TryGetValue(edge.outputSlot.node.objectId, out outputEdges)) + m_NodeEdges[edge.outputSlot.node.objectId] = outputEdges = new List(); outputEdges.Add(edge); } @@ -518,8 +519,8 @@ IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef) if (dependentNodes.Contains(fromNode)) return null; - var fromSlot = fromNode.FindSlot(fromSlotRef.slotId); - var toSlot = toNode.FindSlot(toSlotRef.slotId); + var fromSlot = fromNode.FindSlot(fromSlotRef.slotId); + var toSlot = toNode.FindSlot(toSlotRef.slotId); if (fromSlot == null || toSlot == null) return null; @@ -567,7 +568,7 @@ public void RemoveElements(AbstractMaterialNode[] nodes, IEdge[] edges, GroupDat { if (!node.canDeleteNode) { - throw new InvalidOperationException($"Node {node.name} ({node.id}) cannot be deleted."); + throw new InvalidOperationException($"Node {node.name} ({node.objectId}) cannot be deleted."); } } @@ -602,11 +603,11 @@ void RemoveEdgeNoValidate(IEdge e) m_Edges.Remove(e as Edge); List inputNodeEdges; - if (m_NodeEdges.TryGetValue(e.inputSlot.node.id, out inputNodeEdges)) + if (m_NodeEdges.TryGetValue(e.inputSlot.node.objectId, out inputNodeEdges)) inputNodeEdges.Remove(e); List outputNodeEdges; - if (m_NodeEdges.TryGetValue(e.outputSlot.node.id, out outputNodeEdges)) + if (m_NodeEdges.TryGetValue(e.outputSlot.node.objectId, out outputNodeEdges)) outputNodeEdges.Remove(e); m_RemovedEdges.Add(e); @@ -628,15 +629,15 @@ public T GetNodeFromId(string nodeId) where T : class public bool ContainsNode(AbstractMaterialNode node) { - return m_NodeDictionary.ContainsKey(node.id); + return m_NodeDictionary.ContainsKey(node.objectId); } public void GetEdges(SlotReference s, List foundEdges) { - ISlot slot = s.slot; + MaterialSlot slot = s.slot; List candidateEdges; - if (!m_NodeEdges.TryGetValue(s.node.id, out candidateEdges)) + if (!m_NodeEdges.TryGetValue(s.node.objectId, out candidateEdges)) return; foreach (var edge in candidateEdges) @@ -920,19 +921,19 @@ public void ValidateGraph() while (stack.Count > 0) { var node = stack.Pop(); - if (permanentMarks.Contains(node.id)) + if (permanentMarks.Contains(node.objectId)) { continue; } - if (temporaryMarks.Contains(node.id)) + if (temporaryMarks.Contains(node.objectId)) { node.ValidateNode(); - permanentMarks.Add(node.id); + permanentMarks.Add(node.objectId); } else { - temporaryMarks.Add(node.id); + temporaryMarks.Add(node.objectId); stack.Push(node); node.GetInputSlots(slots); foreach (var inputSlot in slots) @@ -961,7 +962,7 @@ public void ValidateGraph() { if (!ContainsNode(edge.outputSlot.node) || !ContainsNode(edge.inputSlot.node)) { - Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.node.id, edge.inputSlot.node.id, Environment.StackTrace); + Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.node.objectId, edge.inputSlot.node.objectId, Environment.StackTrace); m_AddedEdges.Remove(edge); } } @@ -1053,7 +1054,7 @@ public void ReplaceWith(GraphData other) using (var removedNodeIds = PooledList.Get()) { - removedNodeIds.AddRange(m_Nodes.Select(n => n.value.id)); + removedNodeIds.AddRange(m_Nodes.Select(n => n.value.objectId)); foreach (var nodeGuid in removedNodeIds) RemoveNodeNoValidate(m_NodeDictionary[nodeGuid]); } @@ -1241,17 +1242,33 @@ public override void OnAfterDeserialize(string json) var graphData0 = JsonUtility.FromJson(json); var nodeGuidMap = new Dictionary(); + var slotsField = typeof(AbstractMaterialNode).GetField("m_Slots", BindingFlags.Instance | BindingFlags.NonPublic); - foreach (var serializedElement in graphData0.m_SerializableNodes) + foreach (var serializedNode in graphData0.m_SerializableNodes) { - var node0 = JsonUtility.FromJson(serializedElement.JSONnodeData); - var node = (AbstractMaterialNode)DeserializeLegacy(serializedElement.typeInfo.fullName, serializedElement.JSONnodeData); + var node0 = JsonUtility.FromJson(serializedNode.JSONnodeData); + + var node = (AbstractMaterialNode)DeserializeLegacy(serializedNode.typeInfo.fullName, serializedNode.JSONnodeData); if (node == null) { continue; } nodeGuidMap.Add(node0.m_GuidSerialized, node); m_Nodes.Add(node); + + var slots = (List>)slotsField.GetValue(node); + slots.Clear(); + + foreach (var serializedSlot in node0.m_SerializableSlots) + { + var slot = (MaterialSlot)DeserializeLegacy(serializedSlot.typeInfo.fullName, serializedSlot.JSONnodeData); + if (slot == null) + { + continue; + } + + slots.Add(slot); + } } if (isSubGraph) @@ -1300,7 +1317,7 @@ public override void OnAfterMultiDeserialize(string json) { node.owner = this; node.UpdateNodeAfterDeserialization(); - m_NodeDictionary.Add(node.id, node); + m_NodeDictionary.Add(node.objectId, node); m_GroupItems[node.groupGuid].Add(node); } diff --git a/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs b/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs index 8a2ad0ea886..1f9292d0d6a 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/MaterialSlot.cs @@ -5,12 +5,13 @@ using UnityEngine; using UnityEditor.Graphing; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; using UnityEngine.UIElements; namespace UnityEditor.ShaderGraph { [Serializable] - abstract class MaterialSlot : ISlot + abstract class MaterialSlot : JsonObject { const string k_NotInit = "Not Initilaized"; @@ -289,16 +290,11 @@ public virtual void GetPreviewProperties(List properties, strin public abstract void CopyValuesFrom(MaterialSlot foundSlot); - bool Equals(MaterialSlot other) + public bool Equals(MaterialSlot other) { return m_Id == other.m_Id && owner == other.owner; } - public bool Equals(ISlot other) - { - return Equals(other as object); - } - public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; diff --git a/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs b/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs index 3f849b8849f..20e9665dac2 100644 --- a/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs +++ b/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs @@ -26,10 +26,10 @@ public static void SlotConfigurationExceptionIfBadConfiguration(AbstractMaterial var missingSlots = new List(); var inputSlots = expectedInputSlots as IList ?? expectedInputSlots.ToList(); - missingSlots.AddRange(inputSlots.Except(node.GetInputSlots().Select(x => x.id))); + missingSlots.AddRange(inputSlots.Except(node.GetInputSlots().Select(x => x.id))); var outputSlots = expectedOutputSlots as IList ?? expectedOutputSlots.ToList(); - missingSlots.AddRange(outputSlots.Except(node.GetOutputSlots().Select(x => x.id))); + missingSlots.AddRange(outputSlots.Except(node.GetOutputSlots().Select(x => x.id))); if (missingSlots.Count == 0) return; @@ -42,9 +42,9 @@ public static void SlotConfigurationExceptionIfBadConfiguration(AbstractMaterial public static IEnumerable GetAllEdges(AbstractMaterialNode node) { var result = new List(); - var validSlots = ListPool.Get(); + var validSlots = ListPool.Get(); - validSlots.AddRange(node.GetInputSlots()); + validSlots.AddRange(node.GetInputSlots()); for (int index = 0; index < validSlots.Count; index++) { var inputSlot = validSlots[index]; @@ -52,14 +52,14 @@ public static IEnumerable GetAllEdges(AbstractMaterialNode node) } validSlots.Clear(); - validSlots.AddRange(node.GetOutputSlots()); + validSlots.AddRange(node.GetOutputSlots()); for (int index = 0; index < validSlots.Count; index++) { var outputSlot = validSlots[index]; result.AddRange(node.owner.GetEdges(outputSlot.slotReference)); } - ListPool.Release(validSlots); + ListPool.Release(validSlots); return result; } @@ -104,11 +104,11 @@ public static void DepthFirstCollectNodesFromNode(List nod } else if (slotIds == null) { - ids = node.GetInputSlots().Select(x => x.id); + ids = node.GetInputSlots().Select(x => x.id); } else { - ids = node.GetInputSlots().Where(x => slotIds.Contains(x.id)).Select(x => x.id); + ids = node.GetInputSlots().Where(x => slotIds.Contains(x.id)).Select(x => x.id); } foreach (var slot in ids) @@ -165,7 +165,7 @@ public static void CollectNodesNodeFeedsInto(List nodeList if (nodeList.Contains(node)) return; - foreach (var slot in node.GetOutputSlots()) + foreach (var slot in node.GetOutputSlots()) { foreach (var edge in node.owner.GetEdges(slot.slotReference)) { diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/INode.cs b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/INode.cs index 6bcf12b2ddd..8b06959011e 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/INode.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/INode.cs @@ -17,21 +17,21 @@ enum ModificationScope static class NodeExtensions { - public static IEnumerable GetSlots(this AbstractMaterialNode node) where T : ISlot + public static IEnumerable GetSlots(this AbstractMaterialNode node) where T : MaterialSlot { var slots = new List(); node.GetSlots(slots); return slots; } - public static IEnumerable GetInputSlots(this AbstractMaterialNode node) where T : ISlot + public static IEnumerable GetInputSlots(this AbstractMaterialNode node) where T : MaterialSlot { var slots = new List(); node.GetInputSlots(slots); return slots; } - public static IEnumerable GetOutputSlots(this AbstractMaterialNode node) where T : ISlot + public static IEnumerable GetOutputSlots(this AbstractMaterialNode node) where T : MaterialSlot { var slots = new List(); node.GetOutputSlots(slots); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs deleted file mode 100644 index 318abe3a069..00000000000 --- a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using UnityEditor.ShaderGraph; - -namespace UnityEditor.Graphing -{ - interface ISlot : IEquatable - { - int id { get; } - string displayName { get; set; } - bool isInputSlot { get; } - bool isOutputSlot { get; } - int priority { get; set; } - SlotReference slotReference { get; } - AbstractMaterialNode owner { get; set; } - bool hidden { get; set; } - } -} diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs.meta b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs.meta deleted file mode 100644 index 757755f53c8..00000000000 --- a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/ISlot.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: c273d08d1dec8434583305f6cff41a08 -timeCreated: 1464264925 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs index 0c043c3689b..495d721bc5c 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/Graph/SlotReference.cs @@ -46,7 +46,7 @@ public override int GetHashCode() public int CompareTo(SlotReference other) { - var nodeIdComparison = m_Node.value.id.CompareTo(other.m_Node.value.id); + var nodeIdComparison = m_Node.value.objectId.CompareTo(other.m_Node.value.objectId); if (nodeIdComparison != 0) { return nodeIdComparison; diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireBitangent.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireBitangent.cs index a5e6bab3649..77ab47def4b 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireBitangent.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireBitangent.cs @@ -10,7 +10,7 @@ interface IMayRequireBitangent static class MayRequireBitangentExtensions { - public static NeededCoordinateSpace RequiresBitangent(this ISlot slot) + public static NeededCoordinateSpace RequiresBitangent(this MaterialSlot slot) { var mayRequireBitangent = slot as IMayRequireBitangent; return mayRequireBitangent != null ? mayRequireBitangent.RequiresBitangent() : NeededCoordinateSpace.None; diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireCameraOpaqueTexture.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireCameraOpaqueTexture.cs index d4628043230..a6ddbde06f6 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireCameraOpaqueTexture.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireCameraOpaqueTexture.cs @@ -9,7 +9,7 @@ interface IMayRequireCameraOpaqueTexture static class MayRequireCameraOpaqueTextureExtensions { - public static bool RequiresCameraOpaqueTexture(this ISlot slot) + public static bool RequiresCameraOpaqueTexture(this MaterialSlot slot) { var mayRequireCameraOpaqueTexture = slot as IMayRequireCameraOpaqueTexture; return mayRequireCameraOpaqueTexture != null && mayRequireCameraOpaqueTexture.RequiresCameraOpaqueTexture(); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireDepthTexture.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireDepthTexture.cs index 48f97ba8f70..31eb1189496 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireDepthTexture.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireDepthTexture.cs @@ -9,7 +9,7 @@ interface IMayRequireDepthTexture static class MayRequireDepthTextureExtensions { - public static bool RequiresDepthTexture(this ISlot slot) + public static bool RequiresDepthTexture(this MaterialSlot slot) { var mayRequireDepthTexture = slot as IMayRequireDepthTexture; return mayRequireDepthTexture != null && mayRequireDepthTexture.RequiresDepthTexture(); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs index 6eaac758f93..91aa568f50c 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs @@ -9,7 +9,7 @@ interface IMayRequireFaceSign static class IMayRequireFaceSignExtensions { - public static bool RequiresFaceSign(this ISlot slot) + public static bool RequiresFaceSign(this MaterialSlot slot) { var mayRequireFaceSign = slot as IMayRequireFaceSign; return mayRequireFaceSign != null && mayRequireFaceSign.RequiresFaceSign(); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireMeshUV.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireMeshUV.cs index d93153f80c6..291ac5f28d7 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireMeshUV.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireMeshUV.cs @@ -10,7 +10,7 @@ interface IMayRequireMeshUV static class MayRequireMeshUVExtensions { - public static bool RequiresMeshUV(this ISlot slot, UVChannel channel) + public static bool RequiresMeshUV(this MaterialSlot slot, UVChannel channel) { var mayRequireMeshUV = slot as IMayRequireMeshUV; return mayRequireMeshUV != null && mayRequireMeshUV.RequiresMeshUV(channel); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireNormal.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireNormal.cs index a1985f35569..e37cc80b0d1 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireNormal.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireNormal.cs @@ -10,7 +10,7 @@ interface IMayRequireNormal static class MayRequireNormalExtensions { - public static NeededCoordinateSpace RequiresNormal(this ISlot slot) + public static NeededCoordinateSpace RequiresNormal(this MaterialSlot slot) { var mayRequireNormal = slot as IMayRequireNormal; return mayRequireNormal != null ? mayRequireNormal.RequiresNormal() : NeededCoordinateSpace.None; diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequirePosition.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequirePosition.cs index 38c345c92a6..06611b1f15c 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequirePosition.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequirePosition.cs @@ -10,7 +10,7 @@ interface IMayRequirePosition static class MayRequirePositionExtensions { - public static NeededCoordinateSpace RequiresPosition(this ISlot slot) + public static NeededCoordinateSpace RequiresPosition(this MaterialSlot slot) { var mayRequirePosition = slot as IMayRequirePosition; return mayRequirePosition != null ? mayRequirePosition.RequiresPosition() : NeededCoordinateSpace.None; diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs index b5783da356c..cbd2a6bd24d 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs @@ -9,7 +9,7 @@ interface IMayRequireScreenPosition static class MayRequireScreenPositionExtensions { - public static bool RequiresScreenPosition(this ISlot slot) + public static bool RequiresScreenPosition(this MaterialSlot slot) { var mayRequireScreenPosition = slot as IMayRequireScreenPosition; return mayRequireScreenPosition != null && mayRequireScreenPosition.RequiresScreenPosition(); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireTangent.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireTangent.cs index f58278ff2e7..14d57eed68e 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireTangent.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireTangent.cs @@ -10,7 +10,7 @@ interface IMayRequireTangent static class MayRequireTangentExtensions { - public static NeededCoordinateSpace RequiresTangent(this ISlot slot) + public static NeededCoordinateSpace RequiresTangent(this MaterialSlot slot) { var mayRequireTangent = slot as IMayRequireTangent; return mayRequireTangent != null ? mayRequireTangent.RequiresTangent() : NeededCoordinateSpace.None; diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexColor.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexColor.cs index 953f08c11af..3040332e39c 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexColor.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexColor.cs @@ -9,7 +9,7 @@ interface IMayRequireVertexColor static class MayRequireVertexColorExtensions { - public static bool RequiresVertexColor(this ISlot slot) + public static bool RequiresVertexColor(this MaterialSlot slot) { var mayRequireVertexColor = slot as IMayRequireVertexColor; return mayRequireVertexColor != null && mayRequireVertexColor.RequiresVertexColor(); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexSkinning.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexSkinning.cs index bf1315f38b8..e5d98e7eca9 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexSkinning.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireVertexSkinning.cs @@ -9,7 +9,7 @@ interface IMayRequireVertexSkinning static class MayRequireVertexSkinningExtensions { - public static bool RequiresVertexSkinning(this ISlot slot) + public static bool RequiresVertexSkinning(this MaterialSlot slot) { var mayRequireVertexSkinning = slot as IMayRequireVertexSkinning; return mayRequireVertexSkinning != null && mayRequireVertexSkinning.RequiresVertexSkinning(); diff --git a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireViewDirection.cs b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireViewDirection.cs index 77565bc6bee..6abdc3ca36f 100644 --- a/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireViewDirection.cs +++ b/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireViewDirection.cs @@ -10,7 +10,7 @@ interface IMayRequireViewDirection static class MayRequireViewDirectionExtensions { - public static NeededCoordinateSpace RequiresViewDirection(this ISlot slot) + public static NeededCoordinateSpace RequiresViewDirection(this MaterialSlot slot) { var mayRequireViewDirection = slot as IMayRequireViewDirection; return mayRequireViewDirection != null ? mayRequireViewDirection.RequiresViewDirection() : NeededCoordinateSpace.None; diff --git a/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs index 3bc50200121..e4c9a329f99 100644 --- a/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs +++ b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using UnityEditor.Graphing; namespace UnityEditor.ShaderGraph.Legacy { @@ -6,5 +8,7 @@ namespace UnityEditor.ShaderGraph.Legacy class AbstractMaterialNode0 { public string m_GuidSerialized; + + public List m_SerializableSlots; } } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs index 0e4bcefacbf..9146064a7cc 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs @@ -30,11 +30,8 @@ abstract class AbstractMaterialNode : JsonObject, IGroupItem [NonSerialized] bool m_HasError; - [NonSerialized] - private List m_Slots = new List(); - [SerializeField] - List m_SerializableSlots = new List(); + List> m_Slots = new List>(); public GraphData owner { get; set; } @@ -164,7 +161,7 @@ string defaultVariableName { if (m_NameForDefaultVariableName != name) { - m_DefaultVariableName = string.Format("{0}_{1}", NodeUtils.GetHLSLSafeName(name ?? "node"), id); + m_DefaultVariableName = string.Format("{0}_{1}", NodeUtils.GetHLSLSafeName(name ?? "node"), objectId); m_NameForDefaultVariableName = name; } return m_DefaultVariableName; @@ -198,30 +195,34 @@ protected AbstractMaterialNode() version = 0; } - public void GetInputSlots(List foundSlots) where T : ISlot + public void GetInputSlots(List foundSlots) where T : MaterialSlot { - foreach (var slot in m_Slots) + foreach (var slot in m_Slots.SelectValue()) { if (slot.isInputSlot && slot is T) foundSlots.Add((T)slot); } } - public void GetOutputSlots(List foundSlots) where T : ISlot + public void GetOutputSlots(List foundSlots) where T : MaterialSlot { - foreach (var slot in m_Slots) + foreach (var slot in m_Slots.SelectValue()) { - if (slot.isOutputSlot && slot is T) - foundSlots.Add((T)slot); + if (slot.isOutputSlot && slot is T materialSlot) + { + foundSlots.Add(materialSlot); + } } } - public void GetSlots(List foundSlots) where T : ISlot + public void GetSlots(List foundSlots) where T : MaterialSlot { - foreach (var slot in m_Slots) + foreach (var slot in m_Slots.SelectValue()) { - if (slot is T) - foundSlots.Add((T)slot); + if (slot is T materialSlot) + { + foundSlots.Add(materialSlot); + } } } @@ -481,7 +482,7 @@ public virtual void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(id, errorMessage); + ((GraphData) owner).AddValidationError(objectId, errorMessage); } else { @@ -559,17 +560,20 @@ public virtual string GetVariableNameForNode() return defaultVariableName; } - public void AddSlot(ISlot slot) + public void AddSlot(MaterialSlot slot) { - if (!(slot is MaterialSlot)) - throw new ArgumentException(string.Format("Trying to add slot {0} to Material node {1}, but it is not a {2}", slot, this, typeof(MaterialSlot))); - - var addingSlot = (MaterialSlot)slot; var foundSlot = FindSlot(slot.id); + // Try to keep the existing instance to avoid unnecessary changes to file + if (foundSlot != null && slot.GetType() == foundSlot.GetType()) + { + return; + } + // this will remove the old slot and add a new one // if an old one was found. This allows updating values - m_Slots.RemoveAll(x => x.id == slot.id); + m_Slots.RemoveAll(x => x.value.id == slot.id); + m_Slots.Add(slot); slot.owner = this; @@ -578,7 +582,8 @@ public void AddSlot(ISlot slot) if (foundSlot == null) return; - addingSlot.CopyValuesFrom(foundSlot); + slot.CopyValuesFrom(foundSlot); + foundSlot.owner = null; } public void RemoveSlot(int slotId) @@ -595,7 +600,7 @@ public void RemoveSlot(int slotId) } //remove slots - m_Slots.RemoveAll(x => x.id == slotId); + m_Slots.RemoveAll(x => x.value.id == slotId); OnSlotsChanged(); } @@ -608,7 +613,7 @@ protected virtual void OnSlotsChanged() public void RemoveSlotsNameNotMatching(IEnumerable slotIds, bool supressWarnings = false) { - var invalidSlots = m_Slots.Select(x => x.id).Except(slotIds); + var invalidSlots = m_Slots.Select(x => x.value.id).Except(slotIds); foreach (var invalidSlot in invalidSlots.ToArray()) { @@ -620,15 +625,15 @@ public void RemoveSlotsNameNotMatching(IEnumerable slotIds, bool supressWar public SlotReference GetSlotReference(int slotId) { - var slot = FindSlot(slotId); + var slot = FindSlot(slotId); if (slot == null) throw new ArgumentException("Slot could not be found", "slotId"); return new SlotReference(this, slotId); } - public T FindSlot(int slotId) where T : ISlot + public T FindSlot(int slotId) where T : MaterialSlot { - foreach (var slot in m_Slots) + foreach (var slot in m_Slots.SelectValue()) { if (slot.id == slotId && slot is T) return (T)slot; @@ -636,9 +641,9 @@ public T FindSlot(int slotId) where T : ISlot return default(T); } - public T FindInputSlot(int slotId) where T : ISlot + public T FindInputSlot(int slotId) where T : MaterialSlot { - foreach (var slot in m_Slots) + foreach (var slot in m_Slots.SelectValue()) { if (slot.isInputSlot && slot.id == slotId && slot is T) return (T)slot; @@ -646,9 +651,9 @@ public T FindInputSlot(int slotId) where T : ISlot return default(T); } - public T FindOutputSlot(int slotId) where T : ISlot + public T FindOutputSlot(int slotId) where T : MaterialSlot { - foreach (var slot in m_Slots) + foreach (var slot in m_Slots.SelectValue()) { if (slot.isOutputSlot && slot.id == slotId && slot is T) return (T)slot; @@ -656,18 +661,17 @@ public T FindOutputSlot(int slotId) where T : ISlot return default(T); } - public virtual IEnumerable GetInputsWithNoConnection() + public virtual IEnumerable GetInputsWithNoConnection() { - return this.GetInputSlots().Where(x => !owner.GetEdges(GetSlotReference(x.id)).Any()); + return this.GetInputSlots().Where(x => !owner.GetEdges(GetSlotReference(x.id)).Any()); } public override void OnBeforeSerialize() { m_GroupGuidSerialized = m_GroupGuid.ToString(); - m_SerializableSlots = SerializationHelper.Serialize(m_Slots); } - public override void OnAfterDeserialize() + public override void OnAfterMultiDeserialize(string json) { if (m_NodeVersion != GetCompiledNodeVersion()) { @@ -680,12 +684,10 @@ public override void OnAfterDeserialize() else m_GroupGuid = Guid.Empty; - m_Slots = SerializationHelper.Deserialize(m_SerializableSlots, GraphUtil.GetLegacyTypeRemapping()); - m_SerializableSlots = null; - foreach (var s in m_Slots) + foreach (var s in m_Slots.SelectValue()) s.owner = this; - UpdateNodeAfterDeserialization(); + // UpdateNodeAfterDeserialization(); } public virtual void UpdateNodeAfterDeserialization() diff --git a/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs index 97e1172caac..4b7f3510b45 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs @@ -378,7 +378,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo private string GetFunctionName() { var function = GetFunctionToConvert(); - return function.Name + (function.IsStatic ? string.Empty : "_" + id) + "_" + concretePrecision.ToShaderString() + return function.Name + (function.IsStatic ? string.Empty : "_" + objectId) + "_" + concretePrecision.ToShaderString() + (this.GetSlots().Select(s => NodeUtils.GetSlotDimension(s.concreteValueType)).FirstOrDefault() ?? "") + (this.GetSlots().Select(s => NodeUtils.GetSlotDimension(s.concreteValueType)).FirstOrDefault() ?? ""); } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs index a4ae40982f9..e9f083ffbf4 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs @@ -251,7 +251,7 @@ public override void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(id, errorMessage); + ((GraphData) owner).AddValidationError(objectId, errorMessage); } else { diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs index 308b0e024be..05fd0b6f31e 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Math/Matrix/MatrixSplitNode.cs @@ -246,7 +246,7 @@ public override void ValidateNode() if (isInError) { - ((GraphData) owner).AddValidationError(id, errorMessage); + ((GraphData) owner).AddValidationError(objectId, errorMessage); } else { diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs index a7fc4bb12e9..da018bf7446 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs @@ -275,7 +275,7 @@ void ValidateSlotName() var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); if (error) { - owner.AddValidationError(id, errorMessage); + owner.AddValidationError(objectId, errorMessage); break; } } @@ -285,7 +285,7 @@ public override void ValidateNode() { if (!this.GetOutputSlots().Any()) { - owner.AddValidationError(id, k_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); + owner.AddValidationError(objectId, k_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); } if(sourceType == HlslSourceType.File) { @@ -297,7 +297,7 @@ public override void ValidateNode() string extension = path.Substring(path.LastIndexOf('.')); if(!s_ValidExtensions.Contains(extension)) { - owner.AddValidationError(id, k_InvalidFileType, ShaderCompilerMessageSeverity.Error); + owner.AddValidationError(objectId, k_InvalidFileType, ShaderCompilerMessageSeverity.Error); } } } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs index dda5ea8a085..ab162fe1ae8 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs @@ -430,11 +430,11 @@ public override void ValidateNode() var assetPath = string.IsNullOrEmpty(subGraphGuid) ? null : AssetDatabase.GUIDToAssetPath(assetGuid); if (string.IsNullOrEmpty(assetPath)) { - owner.AddValidationError(id, $"Could not find Sub Graph asset with GUID {assetGuid}."); + owner.AddValidationError(objectId, $"Could not find Sub Graph asset with GUID {assetGuid}."); } else { - owner.AddValidationError(id, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}."); + owner.AddValidationError(objectId, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}."); } return; @@ -443,12 +443,12 @@ public override void ValidateNode() if (asset.isRecursive || owner.isSubGraph && (asset.descendents.Contains(owner.assetGuid) || asset.assetGuid == owner.assetGuid)) { hasError = true; - owner.AddValidationError(id, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); + owner.AddValidationError(objectId, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); } else if (!asset.isValid) { hasError = true; - owner.AddValidationError(id, $"Invalid Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); + owner.AddValidationError(objectId, $"Invalid Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}."); } ValidateShaderStage(); diff --git a/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs b/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs index 8ff84d586e0..08e34b84bb8 100644 --- a/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs +++ b/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphOutputNode.cs @@ -56,7 +56,7 @@ void ValidateSlotName() var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); if (error) { - owner.AddValidationError(id, errorMessage); + owner.AddValidationError(objectId, errorMessage); break; } } @@ -68,7 +68,7 @@ public override void ValidateNode() if (!this.GetInputSlots().Any()) { - owner.AddValidationError(id, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); + owner.AddValidationError(objectId, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Warning); } base.ValidateNode(); @@ -82,7 +82,7 @@ protected override void OnSlotsChanged() public int AddSlot(ConcreteSlotValueType concreteValueType) { - var index = this.GetInputSlots().Count() + 1; + var index = this.GetInputSlots().Count() + 1; name = NodeUtils.GetDuplicateSafeNameForSlot(this, index, "Out_" + concreteValueType.ToString()); AddSlot(MaterialSlot.CreateMaterialSlot(concreteValueType.ToSlotValueType(), index, name, NodeUtils.GetHLSLSafeName(name), SlotType.Input, Vector4.zero)); diff --git a/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs b/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs index 15edea4e18e..69192b68cf1 100644 --- a/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs +++ b/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs @@ -187,9 +187,9 @@ public static bool IsShaderGraph(this Shader shader) static void Visit(List outputList, Dictionary unmarkedNodes, AbstractMaterialNode node) { - if (!unmarkedNodes.ContainsKey(node.id)) + if (!unmarkedNodes.ContainsKey(node.objectId)) return; - foreach (var slot in node.GetInputSlots()) + foreach (var slot in node.GetInputSlots()) { foreach (var edge in node.owner.GetEdges(slot.slotReference)) { @@ -197,7 +197,7 @@ static void Visit(List outputList, Dictionary 0) { - m_Messenger.AddOrAppendError(this, shaderData.node.id, messages[0]); + m_Messenger.AddOrAppendError(this, shaderData.node.objectId, messages[0]); } } } diff --git a/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs b/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs index 9eeaeb35554..71e9475b3b7 100644 --- a/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs +++ b/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs @@ -56,7 +56,7 @@ void OnDestroy() } List m_Ids; - List m_Slots = new List(); + List m_Slots = new List(); public void GenerateNodeEntries() { diff --git a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index 6e4a078d675..63ef75f8957 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -613,7 +613,7 @@ public void HandleGraphChanges() GraphElement graphElement = null; if (groupChange.groupItem is AbstractMaterialNode node) { - graphElement = m_GraphView.GetNodeByGuid(node.id); + graphElement = m_GraphView.GetNodeByGuid(node.objectId); } else if (groupChange.groupItem is StickyNoteData stickyNote) { @@ -735,7 +735,7 @@ void UpdateBadges() { var node = m_Graph.GetNodeFromId(messageData.Key); - if (!(m_GraphView.GetNodeByGuid(node.id) is MaterialNodeView nodeView)) + if (!(m_GraphView.GetNodeByGuid(node.objectId) is MaterialNodeView nodeView)) continue; if (messageData.Value.Count == 0) diff --git a/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs b/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs index 0a55e8fae33..ae76480c9b2 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs @@ -55,7 +55,7 @@ public void Initialize(AbstractMaterialNode inNode, PreviewManager previewManage m_ConnectorListener = connectorListener; node = inNode; - viewDataKey = node.id; + viewDataKey = node.objectId; UpdateTitle(); // Add controls container @@ -354,7 +354,7 @@ public void ShowGeneratedCode(DropdownMenuAction action) var mode = (GenerationMode)action.userData; string path = String.Format("Temp/GeneratedFromGraph-{0}-{1}-{2}{3}.shader", SanitizeName(name), - SanitizeName(node.name), node.id, mode == GenerationMode.Preview ? "-Preview" : ""); + SanitizeName(node.name), node.objectId, mode == GenerationMode.Preview ? "-Preview" : ""); if (GraphUtil.WriteToFile(path, ConvertToShader(mode))) GraphUtil.OpenFile(path); } diff --git a/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs b/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs index 6cadc513f7b..3f39b33ac6f 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/PropertyNodeView.cs @@ -16,7 +16,7 @@ public PropertyNodeView(PropertyNode node, EdgeConnectorListener edgeConnectorLi { styleSheets.Add(Resources.Load("Styles/PropertyNodeView")); this.node = node; - viewDataKey = node.id.ToString(); + viewDataKey = node.objectId.ToString(); userData = node; // Getting the generatePropertyBlock property to see if it is exposed or not diff --git a/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index d8ced564eb2..ca9f43a906d 100644 --- a/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -90,7 +90,7 @@ void BuildShader() if(m_GraphData.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit) { - m_GraphData.AddValidationError(m_OutputNode.id, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); + m_GraphData.AddValidationError(m_OutputNode.objectId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); m_ConfiguredTextures = shaderProperties.GetConfiguredTexutres(); m_Builder.AppendLines(ShaderGraphImporter.k_ErrorShader); diff --git a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index eb74427aa17..deaaccf35a8 100644 --- a/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -322,7 +322,7 @@ static ShaderGraphVfxAsset GenerateVfxShaderGraphAsset(VfxMasterNode masterNode) var message = new StringBuilder($"Precision mismatch for function {name}:"); foreach (var node in source.nodes) { - message.AppendLine($"{node.name} ({node.id}): {node.concretePrecision}"); + message.AppendLine($"{node.name} ({node.objectId}): {node.concretePrecision}"); } throw new InvalidOperationException(message.ToString()); } diff --git a/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs index b578213da9c..70c6e3ad6b8 100644 --- a/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs +++ b/com.unity.shadergraph/Editor/Serialization/FakeJsonObject.cs @@ -10,12 +10,12 @@ public class FakeJsonObject string m_Type; [SerializeField] - string m_Id; + string m_ObjectId; public string id { - get => m_Id; - set => m_Id = value; + get => m_ObjectId; + set => m_ObjectId = value; } public string type @@ -26,7 +26,7 @@ public string type public void Reset() { - m_Id = null; + m_ObjectId = null; m_Type = null; } } diff --git a/com.unity.shadergraph/Editor/Serialization/JsonData.cs b/com.unity.shadergraph/Editor/Serialization/JsonData.cs index 658b100f208..cb9ae5810c0 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonData.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonData.cs @@ -30,7 +30,14 @@ public void OnAfterDeserialize() { try { - m_Value = (T)MultiJsonInternal.valueMap[m_Id]; + if (MultiJsonInternal.valueMap.TryGetValue(m_Id, out var value)) + { + m_Value = (T)value; + } + else + { + Debug.LogError($"Missing {typeof(T).FullName} {m_Id}"); + } } catch (Exception e) { @@ -47,7 +54,7 @@ public static implicit operator T(JsonData jsonRef) public static implicit operator JsonData(T value) { - return new JsonData { m_Value = value, m_Id = value.id }; + return new JsonData { m_Value = value, m_Id = value.objectId }; } public bool Equals(JsonData other) diff --git a/com.unity.shadergraph/Editor/Serialization/JsonObject.cs b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs index 425098eb8ef..2c22dbd72cc 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonObject.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonObject.cs @@ -10,9 +10,9 @@ public class JsonObject : ISerializationCallbackReceiver string m_Type; [SerializeField] - string m_Id = Guid.NewGuid().ToString("N"); + string m_ObjectId = Guid.NewGuid().ToString("N"); - public string id => m_Id; + public string objectId => m_ObjectId; void ISerializationCallbackReceiver.OnBeforeSerialize() { diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs index 6ed3b33eb9b..b3057d319d9 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs @@ -43,7 +43,7 @@ public static implicit operator T(JsonRef jsonRef) public static implicit operator JsonRef(T value) { - return new JsonRef { m_Value = value, m_Id = value?.id }; + return new JsonRef { m_Value = value, m_Id = value?.objectId }; } public bool Equals(JsonRef other) diff --git a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs index d0664fdbe73..5c2d32cd2df 100644 --- a/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs +++ b/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs @@ -101,8 +101,8 @@ public static void Enqueue(JsonObject jsonObject, string json) throw new InvalidOperationException("Can only Enqueue during JsonObject.OnAfterDeserialize."); } - valueMap.Add(jsonObject.id, jsonObject); - s_Entries.Add(new MultiJsonEntry(jsonObject.GetType().FullName, jsonObject.id, json)); + valueMap.Add(jsonObject.objectId, jsonObject); + s_Entries.Add(new MultiJsonEntry(jsonObject.GetType().FullName, jsonObject.objectId, json)); } public static JsonObject CreateInstance(string typeString) @@ -133,7 +133,7 @@ public static JsonObject Deserialize(List entries) var value = CreateInstance(entry.type); if (entry.id == null) { - entries[index] = entry = new MultiJsonEntry(entry.type, value.id, entry.json); + entries[index] = entry = new MultiJsonEntry(entry.type, value.objectId, entry.json); } valueMap[entry.id] = value; @@ -200,7 +200,7 @@ public static string Serialize(JsonObject mainObject) { isSerializing = true; - serializedSet.Add(mainObject.id); + serializedSet.Add(mainObject.objectId); serializationQueue.Add(mainObject); var idJsonList = new List<(string, string)>(); @@ -210,18 +210,18 @@ public static string Serialize(JsonObject mainObject) { var value = serializationQueue[i]; var json = EditorJsonUtility.ToJson(value, true); - idJsonList.Add((value.id, json)); + idJsonList.Add((value.objectId, json)); } idJsonList.Sort((x, y) => // Main object needs to be placed first - x.Item1 == mainObject.id ? -1 : - y.Item1 == mainObject.id ? 1 : + x.Item1 == mainObject.objectId ? -1 : + y.Item1 == mainObject.objectId ? 1 : // We sort everything else by ID to consistently maintain positions in the output x.Item1.CompareTo(y.Item1)); var sb = new StringBuilder(); - foreach (var (_, json) in idJsonList) + foreach (var (id, json) in idJsonList) { sb.AppendLine(json); sb.AppendLine(); diff --git a/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs b/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs index 6ea0474b35b..a4eb2445cb5 100644 --- a/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs +++ b/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs @@ -74,7 +74,7 @@ public CopyPasteGraph(string sourceGraphGuid, IEnumerable groups, IEn { if (!node.canCopyNode) { - throw new InvalidOperationException($"Cannot copy node {node.name} ({node.id})."); + throw new InvalidOperationException($"Cannot copy node {node.name} ({node.objectId})."); } AddNode(node); foreach (var edge in NodeUtils.GetAllEdges(node)) diff --git a/com.unity.shadergraph/Editor/Util/MessageManager.cs b/com.unity.shadergraph/Editor/Util/MessageManager.cs index 77a089cc74d..72cbb69289b 100644 --- a/com.unity.shadergraph/Editor/Util/MessageManager.cs +++ b/com.unity.shadergraph/Editor/Util/MessageManager.cs @@ -109,7 +109,7 @@ public void ClearNodesFromProvider(object messageProvider, IEnumerable 0; messages.Clear(); diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs index f35daf9ba4f..28c2db1eeda 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/AbstractMaterialGraphTests.cs @@ -46,8 +46,8 @@ public void TestCanGetMaterialNodeFromMaterialGraph() Assert.AreEqual(0, graph.edges.Count()); Assert.AreEqual(1, graph.GetNodes().Count()); - Assert.AreEqual(node, graph.GetNodeFromId(node.id)); - Assert.AreEqual(node, graph.GetNodeFromId(node.id)); + Assert.AreEqual(node, graph.GetNodeFromId(node.objectId)); + Assert.AreEqual(node, graph.GetNodeFromId(node.objectId)); } /* [Test] diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/MaterialNodeTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/MaterialNodeTests.cs index 9b29dac2236..34ec91c1718 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/MaterialNodeTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/MaterialNodeTests.cs @@ -26,21 +26,19 @@ public TestNode() } } - class NotAMaterialSlot : ISlot + class NotAMaterialSlot : MaterialSlot { - public bool Equals(ISlot other) + public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode) { throw new NotImplementedException(); } - public int id { get; } - public string displayName { get; set; } - public bool isInputSlot { get; } - public bool isOutputSlot { get; } - public int priority { get; set; } - public SlotReference slotReference { get; } - public AbstractMaterialNode owner { get; set; } - public bool hidden { get; set; } + public override void CopyValuesFrom(MaterialSlot foundSlot) + { + throw new NotImplementedException(); + } + public override SlotValueType valueType { get; } + public override ConcreteSlotValueType concreteValueType { get; } } [OneTimeSetUp] diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs index 200eef4267c..8a99acb787a 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs @@ -40,13 +40,13 @@ public void Setup() m_EmptyMgr = new TestMessageManager(); m_ComplexMgr = new TestMessageManager(); - m_ComplexMgr.AddOrAppendError(p0, node0.id, e0); - m_ComplexMgr.AddOrAppendError(p0, node0.id, e1); - m_ComplexMgr.AddOrAppendError(p0, node1.id, e2); - m_ComplexMgr.AddOrAppendError(p1, node0.id, e1); - m_ComplexMgr.AddOrAppendError(p1, node1.id, e0); - m_ComplexMgr.AddOrAppendError(p1, node1.id, e1); - m_ComplexMgr.AddOrAppendError(p1, node2.id, e3); + m_ComplexMgr.AddOrAppendError(p0, node0.objectId, e0); + m_ComplexMgr.AddOrAppendError(p0, node0.objectId, e1); + m_ComplexMgr.AddOrAppendError(p0, node1.objectId, e2); + m_ComplexMgr.AddOrAppendError(p1, node0.objectId, e1); + m_ComplexMgr.AddOrAppendError(p1, node1.objectId, e0); + m_ComplexMgr.AddOrAppendError(p1, node1.objectId, e1); + m_ComplexMgr.AddOrAppendError(p1, node2.objectId, e3); } // Simple helper to avoid typing that ungodly generic type @@ -65,11 +65,11 @@ public void NewManager_IsEmpty() [Test] public void AddMessage_CreatesMessage() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.id, ret[0].Key); + Assert.AreEqual(node0.objectId, ret[0].Key); Assert.IsNotEmpty(ret[0].Value); Assert.AreEqual(e0, ret[0].Value[0]); } @@ -77,7 +77,7 @@ public void AddMessage_CreatesMessage() [Test] public void AddMessage_DirtiesManager() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); Assert.IsTrue(m_EmptyMgr.nodeMessagesChanged); } @@ -85,7 +85,7 @@ public void AddMessage_DirtiesManager() [Test] public void GettingMessages_ClearsDirtyFlag() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); GetListFrom(m_EmptyMgr); Assert.IsFalse(m_EmptyMgr.nodeMessagesChanged); @@ -94,26 +94,26 @@ public void GettingMessages_ClearsDirtyFlag() [Test] public void GettingMessages_DoesNotChangeLists() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.AddOrAppendError(p0, node0.id, e1); - m_EmptyMgr.AddOrAppendError(p1, node0.id, e2); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e1); + m_EmptyMgr.AddOrAppendError(p1, node0.objectId, e2); GetListFrom(m_EmptyMgr); - Assert.AreEqual(2, m_EmptyMgr.Messages[p0][node0.id].Count); - Assert.AreEqual(e0, m_EmptyMgr.Messages[p0][node0.id][0]); - Assert.AreEqual(e1, m_EmptyMgr.Messages[p0][node0.id][1]); - Assert.AreEqual(1, m_EmptyMgr.Messages[p1][node0.id].Count); - Assert.AreEqual(e2, m_EmptyMgr.Messages[p1][node0.id][0]); + Assert.AreEqual(2, m_EmptyMgr.Messages[p0][node0.objectId].Count); + Assert.AreEqual(e0, m_EmptyMgr.Messages[p0][node0.objectId][0]); + Assert.AreEqual(e1, m_EmptyMgr.Messages[p0][node0.objectId][1]); + Assert.AreEqual(1, m_EmptyMgr.Messages[p1][node0.objectId].Count); + Assert.AreEqual(e2, m_EmptyMgr.Messages[p1][node0.objectId][0]); } [Test] public void RemoveNode_DoesNotDirty_IfNodeDoesNotExist() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); GetListFrom(m_EmptyMgr); - m_EmptyMgr.RemoveNode(node1.id); + m_EmptyMgr.RemoveNode(node1.objectId); Assert.IsFalse(m_EmptyMgr.nodeMessagesChanged); } @@ -121,10 +121,10 @@ public void RemoveNode_DoesNotDirty_IfNodeDoesNotExist() [Test] public void RemoveNode_DirtiesList_IfNodeExists() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); GetListFrom(m_EmptyMgr); - m_EmptyMgr.RemoveNode(node0.id); + m_EmptyMgr.RemoveNode(node0.objectId); Assert.IsTrue(m_EmptyMgr.nodeMessagesChanged); } @@ -132,8 +132,8 @@ public void RemoveNode_DirtiesList_IfNodeExists() [Test] public void RemoveNode_RemovesNode() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.RemoveNode(node0.id); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.RemoveNode(node0.objectId); var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); @@ -142,9 +142,9 @@ public void RemoveNode_RemovesNode() [Test] public void RemoveNode_RemovesNode_FromAllProvides() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.AddOrAppendError(p1, node0.id, e1); - m_EmptyMgr.RemoveNode(node0.id); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.AddOrAppendError(p1, node0.objectId, e1); + m_EmptyMgr.RemoveNode(node0.objectId); var ret = GetListFrom(m_EmptyMgr); Assert.IsEmpty(ret); @@ -153,12 +153,12 @@ public void RemoveNode_RemovesNode_FromAllProvides() [Test] public void AppendMessage_AppendsMessage() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.AddOrAppendError(p0, node0.id, e1); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e1); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.id, ret[0].Key); + Assert.AreEqual(node0.objectId, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e1, ret[0].Value[1]); @@ -168,10 +168,10 @@ public void AppendMessage_AppendsMessage() public void Warnings_SortedAfterErrors() { var mixedMgr = new MessageManager(); - mixedMgr.AddOrAppendError(p0, node0.id, e0); - mixedMgr.AddOrAppendError(p0, node0.id, w0); - mixedMgr.AddOrAppendError(p0, node0.id, e1); - mixedMgr.AddOrAppendError(p0, node0.id, w1); + mixedMgr.AddOrAppendError(p0, node0.objectId, e0); + mixedMgr.AddOrAppendError(p0, node0.objectId, w0); + mixedMgr.AddOrAppendError(p0, node0.objectId, e1); + mixedMgr.AddOrAppendError(p0, node0.objectId, w1); var ret = GetListFrom(mixedMgr)[0].Value; Assert.AreEqual(e0, ret[0]); @@ -184,10 +184,10 @@ public void Warnings_SortedAfterErrors() public void Warnings_FromDifferentProviders_SortedAfterErrors() { var mixedMgr = new MessageManager(); - mixedMgr.AddOrAppendError(p0, node0.id, e0); - mixedMgr.AddOrAppendError(p0, node0.id, w0); - mixedMgr.AddOrAppendError(p1, node0.id, e1); - mixedMgr.AddOrAppendError(p1, node0.id, w1); + mixedMgr.AddOrAppendError(p0, node0.objectId, e0); + mixedMgr.AddOrAppendError(p0, node0.objectId, w0); + mixedMgr.AddOrAppendError(p1, node0.objectId, e1); + mixedMgr.AddOrAppendError(p1, node0.objectId, w1); var ret = GetListFrom(mixedMgr)[0].Value; Assert.AreEqual(e0, ret[0]); @@ -199,26 +199,26 @@ public void Warnings_FromDifferentProviders_SortedAfterErrors() [Test] public void MultipleNodes_RemainSeparate() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.AddOrAppendError(p0, node1.id, e1); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.AddOrAppendError(p0, node1.objectId, e1); var ret = GetListFrom(m_EmptyMgr); Assert.AreEqual(2, ret.Count); - Assert.AreEqual(node0.id, ret[0].Key); + Assert.AreEqual(node0.objectId, ret[0].Key); Assert.AreEqual(e0, ret[0].Value[0]); - Assert.AreEqual(node1.id, ret[1].Key); + Assert.AreEqual(node1.objectId, ret[1].Key); Assert.AreEqual(e1, ret[1].Value[0]); } [Test] public void MultipleCreators_AggregatePerNode() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.AddOrAppendError(p1, node0.id, e1); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.AddOrAppendError(p1, node0.objectId, e1); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.id, ret[0].Key); + Assert.AreEqual(node0.objectId, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e1, ret[0].Value[1]); @@ -227,12 +227,12 @@ public void MultipleCreators_AggregatePerNode() [Test] public void DuplicateEntries_AreNotIgnored() { - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); - m_EmptyMgr.AddOrAppendError(p0, node0.id, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); + m_EmptyMgr.AddOrAppendError(p0, node0.objectId, e0); var ret = GetListFrom(m_EmptyMgr); Assert.IsNotEmpty(ret); - Assert.AreEqual(node0.id, ret[0].Key); + Assert.AreEqual(node0.objectId, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); Assert.AreEqual(e0, ret[0].Value[0]); Assert.AreEqual(e0, ret[0].Value[1]); @@ -246,11 +246,11 @@ public void ClearAllFromProvider_ZerosMessageLists() var ret = GetListFrom(m_ComplexMgr); Assert.IsNotEmpty(ret); Assert.AreEqual(3, ret.Count); - Assert.AreEqual(node0.id, ret[0].Key); + Assert.AreEqual(node0.objectId, ret[0].Key); Assert.AreEqual(2, ret[0].Value.Count); - Assert.AreEqual(node1.id, ret[1].Key); + Assert.AreEqual(node1.objectId, ret[1].Key); Assert.AreEqual(1, ret[1].Value.Count); - Assert.AreEqual(node2.id, ret[2].Key); + Assert.AreEqual(node2.objectId, ret[2].Key); Assert.IsEmpty(ret[2].Value); } @@ -259,11 +259,11 @@ public void GetList_RemovesZeroLengthLists() { m_ComplexMgr.ClearAllFromProvider(p1); var ret = GetListFrom(m_ComplexMgr); - Assert.IsNotEmpty(ret.Where(kvp => kvp.Key.Equals(node2.id))); - Assert.IsEmpty(ret.First(kvp => kvp.Key.Equals(node2.id)).Value); + Assert.IsNotEmpty(ret.Where(kvp => kvp.Key.Equals(node2.objectId))); + Assert.IsEmpty(ret.First(kvp => kvp.Key.Equals(node2.objectId)).Value); ret = GetListFrom(m_ComplexMgr); - Assert.IsEmpty(ret.Where(kvp => kvp.Key.Equals(node2.id))); + Assert.IsEmpty(ret.Where(kvp => kvp.Key.Equals(node2.objectId))); } [Test] @@ -273,8 +273,8 @@ public void ClearNodesFromProvider_ClearsNodes() m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); - Assert.AreEqual(2, ret.Find(kpv => kpv.Key.Equals(node0.id)).Value.Count); - Assert.IsEmpty(ret.Find(kvp => kvp.Key.Equals(node2.id)).Value); + Assert.AreEqual(2, ret.Find(kpv => kpv.Key.Equals(node0.objectId)).Value.Count); + Assert.IsEmpty(ret.Find(kvp => kvp.Key.Equals(node2.objectId)).Value); } [Test] @@ -284,7 +284,7 @@ public void ClearNodesFromProvider_LeavesOtherNodes() m_ComplexMgr.ClearNodesFromProvider(p1, nodesToClear); var ret = GetListFrom(m_ComplexMgr); - Assert.AreEqual(3, ret.Find(kpv => kpv.Key.Equals(node1.id)).Value.Count); + Assert.AreEqual(3, ret.Find(kpv => kpv.Key.Equals(node1.objectId)).Value.Count); } } } diff --git a/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs b/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs index c1052ac336a..1010966f92e 100644 --- a/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs +++ b/com.unity.shadergraph/Tests/Editor/UnitTests/SerializedGraphTests.cs @@ -194,7 +194,7 @@ public void TestCanFindNodeInBaseMaterialGraph() graph.AddNode(node); Assert.AreEqual(1, graph.GetNodes().Count()); - Assert.IsNotNull(graph.GetNodeFromId(node.id)); + Assert.IsNotNull(graph.GetNodeFromId(node.objectId)); Assert.IsNull(graph.GetNodeFromId("asdfffsd")); } @@ -210,11 +210,11 @@ public void TestCanAddSlotToTestNode() Assert.AreEqual(1, graph.GetNodes().Count()); var found = graph.GetNodes().FirstOrDefault(); - Assert.AreEqual(1, found.GetInputSlots().Count()); - Assert.AreEqual(1, found.GetInputSlots().FirstOrDefault().id); - Assert.AreEqual(1, found.GetOutputSlots().Count()); - Assert.AreEqual(0, found.GetOutputSlots().FirstOrDefault().id); - Assert.AreEqual(2, found.GetSlots().Count()); + Assert.AreEqual(1, found.GetInputSlots().Count()); + Assert.AreEqual(1, found.GetInputSlots().FirstOrDefault().id); + Assert.AreEqual(1, found.GetOutputSlots().Count()); + Assert.AreEqual(0, found.GetOutputSlots().FirstOrDefault().id); + Assert.AreEqual(2, found.GetSlots().Count()); } [Test] @@ -233,15 +233,15 @@ public void TestCanRemoveSlotFromTestNode() node.AddSlot(new TestSlot(1, "input", SlotType.Input)); graph.AddNode(node); - Assert.AreEqual(2, node.GetSlots().Count()); - Assert.AreEqual(1, node.GetInputSlots().Count()); - Assert.AreEqual(1, node.GetOutputSlots().Count()); + Assert.AreEqual(2, node.GetSlots().Count()); + Assert.AreEqual(1, node.GetInputSlots().Count()); + Assert.AreEqual(1, node.GetOutputSlots().Count()); node.RemoveSlot(1); - Assert.AreEqual(1, node.GetSlots().Count()); - Assert.AreEqual(0, node.GetInputSlots().Count()); - Assert.AreEqual(1, node.GetOutputSlots().Count()); + Assert.AreEqual(1, node.GetSlots().Count()); + Assert.AreEqual(0, node.GetInputSlots().Count()); + Assert.AreEqual(1, node.GetOutputSlots().Count()); } [Test] @@ -251,19 +251,19 @@ public void TestCanRemoveSlotsWithNonMathingNameFromTestNode() var node = new TestableNode(); graph.AddNode(node); - Assert.AreEqual(6, node.GetSlots().Count()); - Assert.AreEqual(3, node.GetInputSlots().Count()); - Assert.AreEqual(3, node.GetOutputSlots().Count()); + Assert.AreEqual(6, node.GetSlots().Count()); + Assert.AreEqual(3, node.GetInputSlots().Count()); + Assert.AreEqual(3, node.GetOutputSlots().Count()); node.RemoveSlotsNameNotMatching(new[] {TestableNode.Input1}); - Assert.AreEqual(1, node.GetSlots().Count()); - Assert.AreEqual(1, node.GetInputSlots().Count()); - Assert.AreEqual(0, node.GetOutputSlots().Count()); + Assert.AreEqual(1, node.GetSlots().Count()); + Assert.AreEqual(1, node.GetInputSlots().Count()); + Assert.AreEqual(0, node.GetOutputSlots().Count()); - Assert.IsNull(node.FindInputSlot(TestableNode.Input0)); - Assert.IsNotNull(node.FindInputSlot(TestableNode.Input1)); - Assert.IsNull(node.FindInputSlot(TestableNode.Input2)); + Assert.IsNull(node.FindInputSlot(TestableNode.Input0)); + Assert.IsNotNull(node.FindInputSlot(TestableNode.Input1)); + Assert.IsNull(node.FindInputSlot(TestableNode.Input2)); } [Test] @@ -278,9 +278,9 @@ public void TestCanNotAddDuplicateSlotToTestNode() Assert.AreEqual(1, graph.GetNodes().Count()); var found = graph.GetNodes().FirstOrDefault(); - Assert.AreEqual(0, found.GetInputSlots().Count()); - Assert.AreEqual(1, found.GetOutputSlots().Count()); - Assert.AreEqual(1, found.GetSlots().Count()); + Assert.AreEqual(0, found.GetInputSlots().Count()); + Assert.AreEqual(1, found.GetOutputSlots().Count()); + Assert.AreEqual(1, found.GetSlots().Count()); } [Test] @@ -295,11 +295,11 @@ public void TestCanUpdateDisplaynameByReaddingSlotToTestNode() Assert.AreEqual(1, graph.GetNodes().Count()); var found = graph.GetNodes().FirstOrDefault(); - Assert.AreEqual(0, found.GetInputSlots().Count()); - Assert.AreEqual(1, found.GetOutputSlots().Count()); - Assert.AreEqual(1, found.GetSlots().Count()); + Assert.AreEqual(0, found.GetInputSlots().Count()); + Assert.AreEqual(1, found.GetOutputSlots().Count()); + Assert.AreEqual(1, found.GetSlots().Count()); - var slot = found.GetOutputSlots().FirstOrDefault(); + var slot = found.GetOutputSlots().FirstOrDefault(); Assert.AreEqual("output_updated(4)", slot.displayName); } @@ -314,11 +314,11 @@ public void TestCanUpdateSlotPriority() Assert.AreEqual(1, graph.GetNodes().Count()); var found = graph.GetNodes().FirstOrDefault(); - Assert.AreEqual(0, found.GetInputSlots().Count()); - Assert.AreEqual(1, found.GetOutputSlots().Count()); - Assert.AreEqual(1, found.GetSlots().Count()); + Assert.AreEqual(0, found.GetInputSlots().Count()); + Assert.AreEqual(1, found.GetOutputSlots().Count()); + Assert.AreEqual(1, found.GetSlots().Count()); - var slot = found.GetOutputSlots().FirstOrDefault(); + var slot = found.GetOutputSlots().FirstOrDefault(); Assert.AreEqual(0, slot.priority); slot.priority = 2; Assert.AreEqual(2, slot.priority); @@ -336,11 +336,11 @@ public void TestCanUpdateSlotPriorityByReaddingSlotToTestNode() Assert.AreEqual(1, graph.GetNodes().Count()); var found = graph.GetNodes().FirstOrDefault(); - Assert.AreEqual(0, found.GetInputSlots().Count()); - Assert.AreEqual(1, found.GetOutputSlots().Count()); - Assert.AreEqual(1, found.GetSlots().Count()); + Assert.AreEqual(0, found.GetInputSlots().Count()); + Assert.AreEqual(1, found.GetOutputSlots().Count()); + Assert.AreEqual(1, found.GetSlots().Count()); - var slot = found.GetOutputSlots().FirstOrDefault(); + var slot = found.GetOutputSlots().FirstOrDefault(); Assert.AreEqual(5, slot.priority); } @@ -351,11 +351,11 @@ public void TestCanUpdateSlotDisplayName() node.AddSlot(new TestSlot(0, "output", SlotType.Output)); node.name = "Test Node"; - Assert.AreEqual(0, node.GetInputSlots().Count()); - Assert.AreEqual(1, node.GetOutputSlots().Count()); - Assert.AreEqual(1, node.GetSlots().Count()); + Assert.AreEqual(0, node.GetInputSlots().Count()); + Assert.AreEqual(1, node.GetOutputSlots().Count()); + Assert.AreEqual(1, node.GetSlots().Count()); - var slot = node.GetOutputSlots().FirstOrDefault(); + var slot = node.GetOutputSlots().FirstOrDefault(); Assert.IsNotNull(slot); Assert.AreEqual("output(4)", slot.displayName); slot.displayName = "test"; @@ -367,15 +367,15 @@ public void TestCanFindSlotOnTestNode() { var node = new TestableNode(); - Assert.AreEqual(6, node.GetSlots().Count()); - Assert.IsNotNull(node.FindInputSlot(TestableNode.Input0)); - Assert.IsNull(node.FindInputSlot(TestableNode.Output0)); - Assert.IsNotNull(node.FindOutputSlot(TestableNode.Output0)); - Assert.IsNull(node.FindOutputSlot(TestableNode.Input0)); + Assert.AreEqual(6, node.GetSlots().Count()); + Assert.IsNotNull(node.FindInputSlot(TestableNode.Input0)); + Assert.IsNull(node.FindInputSlot(TestableNode.Output0)); + Assert.IsNotNull(node.FindOutputSlot(TestableNode.Output0)); + Assert.IsNull(node.FindOutputSlot(TestableNode.Input0)); - Assert.IsNotNull(node.FindSlot(TestableNode.Input0)); - Assert.IsNotNull(node.FindSlot(TestableNode.Output0)); - Assert.IsNull(node.FindSlot(555)); + Assert.IsNotNull(node.FindSlot(TestableNode.Input0)); + Assert.IsNotNull(node.FindSlot(TestableNode.Output0)); + Assert.IsNull(node.FindSlot(555)); } [Test] @@ -383,7 +383,7 @@ public void TestCanFindSlotReferenceOnTestNode() { var node = new TestableNode(); - Assert.AreEqual(6, node.GetSlots().Count()); + Assert.AreEqual(6, node.GetSlots().Count()); Assert.IsNotNull(node.GetSlotReference(TestableNode.Input0)); Assert.IsNotNull(node.GetSlotReference(TestableNode.Output0)); Assert.Throws(() => node.GetSlotReference(555)); @@ -411,12 +411,12 @@ public void TestCanConnectAndTraverseTwoNodesOnBaseMaterialGraph() Assert.AreEqual(createdEdge, edge); var foundOutputNode = edge.outputSlot.node; - var foundOutputSlot = foundOutputNode.FindOutputSlot(edge.outputSlot.slotId); + var foundOutputSlot = foundOutputNode.FindOutputSlot(edge.outputSlot.slotId); Assert.AreEqual(outputNode, foundOutputNode); Assert.IsNotNull(foundOutputSlot); var foundInputNode = edge.inputSlot.node; - var foundInputSlot = foundInputNode.FindInputSlot(edge.inputSlot.slotId); + var foundInputSlot = foundInputNode.FindInputSlot(edge.inputSlot.slotId); Assert.AreEqual(inputNode, foundInputNode); Assert.IsNotNull(foundInputSlot); } From 7b4d640cc53012a37fbf52375082345c9bbb3344 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Fri, 20 Mar 2020 11:10:34 +0100 Subject: [PATCH 21/64] Fix undo messing up previews --- .../Editor/Data/Graphs/GraphData.cs | 12 +++-- .../Editor/Drawing/PreviewManager.cs | 54 +++++++++++++++---- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 240cddbf25a..85c92002da1 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -629,7 +629,7 @@ public T GetNodeFromId(string nodeId) where T : class public bool ContainsNode(AbstractMaterialNode node) { - return m_NodeDictionary.ContainsKey(node.objectId); + return m_NodeDictionary.TryGetValue(node.objectId, out var foundNode) && node == foundNode; } public void GetEdges(SlotReference s, List foundEdges) @@ -1052,11 +1052,11 @@ public void ReplaceWith(GraphData other) RemoveEdgeNoValidate(edge); } - using (var removedNodeIds = PooledList.Get()) + using (var nodesToRemove = PooledList.Get()) { - removedNodeIds.AddRange(m_Nodes.Select(n => n.value.objectId)); - foreach (var nodeGuid in removedNodeIds) - RemoveNodeNoValidate(m_NodeDictionary[nodeGuid]); + nodesToRemove.AddRange(m_Nodes.SelectValue()); + foreach (var node in nodesToRemove) + RemoveNodeNoValidate(node); } ValidateGraph(); @@ -1073,7 +1073,9 @@ public void ReplaceWith(GraphData other) AddNodeNoValidate(node); foreach (var edge in other.edges) + { ConnectNoValidate(edge.outputSlot, edge.inputSlot); + } outputNode = other.outputNode; diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index e70a3aceab6..71ed3745c02 100644 --- a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -126,7 +126,7 @@ void AddPreview(AbstractMaterialNode node) onPrimaryMasterChanged(); } - m_NodesToUpdate.Add(node); + MarkNodeUpdate(node); } void OnNodeModified(AbstractMaterialNode node, ModificationScope scope) @@ -134,14 +134,50 @@ void OnNodeModified(AbstractMaterialNode node, ModificationScope scope) if (scope == ModificationScope.Topological || scope == ModificationScope.Graph) { - m_NodesToUpdate.Add(node); + MarkNodeUpdate(node); m_RefreshTimedNodes = true; } else if (scope == ModificationScope.Node) { - m_NodesToDraw.Add(node); + MarkNodeDraw(node); + } + } + + void MarkNodeUpdate(AbstractMaterialNode node) + { + if (!m_Graph.ContainsNode(node)) + { + return; + } + m_NodesToUpdate.Add(node); + } + + void UnmarkNodeUpdate(AbstractMaterialNode node) + { + if (!m_Graph.ContainsNode(node)) + { + return; + } + m_NodesToUpdate.Remove(node); + } + + void MarkNodeDraw(AbstractMaterialNode node) + { + if (!m_Graph.ContainsNode(node)) + { + return; + } + m_NodesToDraw.Add(node); + } + + void UnmarkNodeDraw(AbstractMaterialNode node) + { + if (!m_Graph.ContainsNode(node)) + { + return; } + m_NodesToDraw.Remove(node); } Stack m_NodeWave = new Stack(); @@ -215,8 +251,8 @@ public bool HandleGraphChanges() foreach (var node in m_Graph.removedNodes) { DestroyPreview(node.objectId); - m_NodesToUpdate.Remove(node); - m_NodesToDraw.Remove(node); + UnmarkNodeUpdate(node); + UnmarkNodeDraw(node); m_RefreshTimedNodes = true; } @@ -233,7 +269,7 @@ public bool HandleGraphChanges() var node = edge.inputSlot.node; if (node != null) { - m_NodesToUpdate.Add(node); + MarkNodeUpdate(node); m_RefreshTimedNodes = true; } } @@ -242,7 +278,7 @@ public bool HandleGraphChanges() var node = edge.inputSlot.node; if(node != null) { - m_NodesToUpdate.Add(node); + MarkNodeUpdate(node); m_RefreshTimedNodes = true; } } @@ -384,7 +420,7 @@ public void ForceShaderUpdate() { foreach (var data in m_RenderDatas.Values) { - m_NodesToUpdate.Add(data.shaderData.node); + MarkNodeUpdate(data.shaderData.node); } } @@ -415,7 +451,7 @@ void UpdateShaders() renderData.shaderData.isCompiling = false; CheckForErrors(renderData.shaderData); - m_NodesToDraw.Add(renderData.shaderData.node); + MarkNodeDraw(renderData.shaderData.node); var masterNode = renderData.shaderData.node as IMasterNode; masterNode?.ProcessPreviewMaterial(renderData.shaderData.mat); From 93eac8cf6fc66ec19f46bea9d9e9b9934294d548 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Fri, 20 Mar 2020 11:54:15 +0100 Subject: [PATCH 22/64] ShaderInput -> JsonObject --- .../Editor/Data/Graphs/GraphData.cs | 60 ++++++++++--------- .../Editor/Data/Graphs/ShaderInput.cs | 3 +- .../Editor/Data/Legacy/GraphData0.cs | 4 ++ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 85c92002da1..98f853ec282 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -30,27 +30,15 @@ sealed class GraphData : JsonObject #region Input data - [NonSerialized] - List m_Properties = new List(); - - public IEnumerable properties - { - get { return m_Properties; } - } - [SerializeField] - List m_SerializedProperties = new List(); - - [NonSerialized] - List m_Keywords = new List(); + List> m_Properties = new List>(); - public IEnumerable keywords - { - get { return m_Keywords; } - } + public DataValueEnumerable properties => m_Properties.SelectValue(); [SerializeField] - List m_SerializedKeywords = new List(); + List> m_Keywords = new List>(); + + public DataValueEnumerable keywords => m_Keywords.SelectValue(); [NonSerialized] List m_AddedInputs = new List(); @@ -815,8 +803,8 @@ public int GetGraphInputIndex(ShaderInput input) void RemoveGraphInputNoValidate(Guid guid) { - if (m_Properties.RemoveAll(x => x.guid == guid) > 0 || - m_Keywords.RemoveAll(x => x.guid == guid) > 0) + if (m_Properties.RemoveAll(x => x.value.guid == guid) > 0 || + m_Keywords.RemoveAll(x => x.value.guid == guid) > 0) { m_RemovedInputs.Add(guid); m_AddedInputs.RemoveAll(x => x.guid == guid); @@ -875,7 +863,7 @@ public void OnKeywordChangedNoValidate() public void ValidateGraph() { - var propertyNodes = GetNodes().Where(n => !m_Properties.Any(p => p.guid == n.propertyGuid)).ToArray(); + var propertyNodes = GetNodes().Where(n => !m_Properties.Any(p => p.value.guid == n.propertyGuid)).ToArray(); foreach (var pNode in propertyNodes) ReplacePropertyNodeWithConcreteNodeNoValidate(pNode); @@ -1000,9 +988,9 @@ public void ReplaceWith(GraphData other) using (var removedInputsPooledObject = ListPool.GetDisposable()) { var removedInputGuids = removedInputsPooledObject.value; - foreach (var property in m_Properties) + foreach (var property in m_Properties.SelectValue()) removedInputGuids.Add(property.guid); - foreach (var keyword in m_Keywords) + foreach (var keyword in m_Keywords.SelectValue()) removedInputGuids.Add(keyword.guid); foreach (var inputGuid in removedInputGuids) RemoveGraphInputNoValidate(inputGuid); @@ -1219,8 +1207,6 @@ internal void PasteGraph(CopyPasteGraph graphToPaste, List public override void OnBeforeSerialize() { m_Edges.Sort(); - m_SerializedProperties = SerializationHelper.Serialize(m_Properties); - m_SerializedKeywords = SerializationHelper.Serialize(m_Keywords); } static JsonObject DeserializeLegacy(string typeString, string json) @@ -1273,6 +1259,28 @@ public override void OnAfterDeserialize(string json) } } + foreach (var serializedProperty in graphData0.m_SerializedProperties) + { + var property = (AbstractShaderProperty)DeserializeLegacy(serializedProperty.typeInfo.fullName, serializedProperty.JSONnodeData); + if (property == null) + { + continue; + } + + m_Properties.Add(property); + } + + foreach (var serializedKeyword in graphData0.m_SerializedKeywords) + { + var keyword = (ShaderKeyword)DeserializeLegacy(serializedKeyword.typeInfo.fullName, serializedKeyword.JSONnodeData); + if (keyword == null) + { + continue; + } + + m_Keywords.Add(keyword); + } + if (isSubGraph) { m_OutputNode = GetNodes().FirstOrDefault(); @@ -1304,10 +1312,6 @@ public override void OnAfterDeserialize(string json) public override void OnAfterMultiDeserialize(string json) { - // have to deserialize 'globals' before nodes - m_Properties = SerializationHelper.Deserialize(m_SerializedProperties, GraphUtil.GetLegacyTypeRemapping()); - m_Keywords = SerializationHelper.Deserialize(m_SerializedKeywords, GraphUtil.GetLegacyTypeRemapping()); - m_NodeDictionary = new Dictionary(m_Nodes.Count); foreach (var group in m_Groups) diff --git a/com.unity.shadergraph/Editor/Data/Graphs/ShaderInput.cs b/com.unity.shadergraph/Editor/Data/Graphs/ShaderInput.cs index 10e21974830..35b22860a43 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/ShaderInput.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/ShaderInput.cs @@ -1,9 +1,10 @@ using System; +using UnityEditor.ShaderGraph.Serialization; using UnityEngine; namespace UnityEditor.ShaderGraph.Internal { - public abstract class ShaderInput + public abstract class ShaderInput : JsonObject { [SerializeField] SerializableGuid m_Guid = new SerializableGuid(); diff --git a/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs index ad3f8489b6d..aeef884c876 100644 --- a/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs +++ b/com.unity.shadergraph/Editor/Data/Legacy/GraphData0.cs @@ -12,5 +12,9 @@ class GraphData0 public List m_SerializableEdges; public string m_ActiveOutputNodeGuidSerialized; + + public List m_SerializedProperties; + + public List m_SerializedKeywords; } } From 94c8349067221b43fb8a1dc1ffedc8616fe7ef27 Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Fri, 20 Mar 2020 13:46:27 +0100 Subject: [PATCH 23/64] More equality members for JsonData and JsonRef --- .../Editor/Serialization/JsonData.cs | 57 ++++++++++++++++++- .../Editor/Serialization/JsonRef.cs | 37 +++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/com.unity.shadergraph/Editor/Serialization/JsonData.cs b/com.unity.shadergraph/Editor/Serialization/JsonData.cs index cb9ae5810c0..fb2489bf11d 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonData.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonData.cs @@ -62,14 +62,69 @@ public bool Equals(JsonData other) return EqualityComparer.Default.Equals(m_Value, other.m_Value); } + public bool Equals(T other) + { + return EqualityComparer.Default.Equals(m_Value, other); + } + public override bool Equals(object obj) { - return obj is JsonData other && Equals(other); + return obj is JsonData other && Equals(other) || obj is T otherValue && Equals(otherValue); } public override int GetHashCode() { return EqualityComparer.Default.GetHashCode(m_Value); } + + public static bool operator ==(JsonData left, JsonData right) + { + return left.value == right.value; + } + + public static bool operator !=(JsonData left, JsonData right) + { + return left.value != right.value; + } + + public static bool operator ==(JsonData left, T right) + { + return left.value == right; + } + + public static bool operator !=(JsonData left, T right) + { + return left.value != right; + } + + public static bool operator ==(T left, JsonData right) + { + return left == right.value; + } + + public static bool operator !=(T left, JsonData right) + { + return left != right.value; + } + + public static bool operator ==(JsonData left, JsonRef right) + { + return left.value == right.value; + } + + public static bool operator !=(JsonData left, JsonRef right) + { + return left.value != right.value; + } + + public static bool operator ==(JsonRef left, JsonData right) + { + return left.value == right.value; + } + + public static bool operator !=(JsonRef left, JsonData right) + { + return left.value != right.value; + } } } diff --git a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs index b3057d319d9..6aa68b9d088 100644 --- a/com.unity.shadergraph/Editor/Serialization/JsonRef.cs +++ b/com.unity.shadergraph/Editor/Serialization/JsonRef.cs @@ -51,14 +51,49 @@ public bool Equals(JsonRef other) return EqualityComparer.Default.Equals(m_Value, other.m_Value); } + public bool Equals(T other) + { + return EqualityComparer.Default.Equals(m_Value, other); + } + public override bool Equals(object obj) { - return obj is JsonRef other && Equals(other); + return obj is JsonRef other && Equals(other) || obj is T otherValue && Equals(otherValue); } public override int GetHashCode() { return EqualityComparer.Default.GetHashCode(m_Value); } + + public static bool operator ==(JsonRef left, JsonRef right) + { + return left.value == right.value; + } + + public static bool operator !=(JsonRef left, JsonRef right) + { + return left.value != right.value; + } + + public static bool operator ==(JsonRef left, T right) + { + return left.value == right; + } + + public static bool operator !=(JsonRef left, T right) + { + return left.value != right; + } + + public static bool operator ==(T left, JsonRef right) + { + return left == right.value; + } + + public static bool operator !=(T left, JsonRef right) + { + return left != right.value; + } } } From dfaed33a795feb35534617331e4a2de8681caedf Mon Sep 17 00:00:00 2001 From: Peter Bay Bastian Date: Thu, 2 Apr 2020 16:07:07 +0200 Subject: [PATCH 24/64] temp --- .../Editor/Data/Graphs/GraphData.cs | 118 ++++++++++-------- .../Editor/Data/Implementation/NodeUtils.cs | 2 +- .../Data/Legacy/AbstractMaterialNode0.cs | 4 + .../Editor/Data/Legacy/SerializableGuid.cs | 11 ++ .../Data/Legacy/SerializableGuid.cs.meta | 11 ++ .../Editor/Data/Legacy/ShaderInput0.cs | 10 ++ .../Editor/Data/Legacy/ShaderInput0.cs.meta | 3 + .../Editor/Data/Nodes/Input/PropertyNode.cs | 65 +++------- .../Editor/Data/Nodes/Utility/KeywordNode.cs | 49 ++------ .../Drawing/Blackboard/BlackboardProvider.cs | 30 ++--- .../Editor/Drawing/SearchWindowProvider.cs | 10 +- .../Editor/Drawing/Views/MaterialGraphView.cs | 28 ++--- .../Editor/Drawing/Views/MaterialNodeView.cs | 2 +- .../Editor/Drawing/Views/PropertyNodeView.cs | 6 +- .../Editor/Importers/ShaderGraphImporter.cs | 2 +- 15 files changed, 174 insertions(+), 177 deletions(-) create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs.meta create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs create mode 100644 com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs.meta diff --git a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 98f853ec282..6a87083d8af 100644 --- a/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -49,9 +49,9 @@ public IEnumerable addedInputs } [NonSerialized] - List m_RemovedInputs = new List(); + List m_RemovedInputs = new List(); - public IEnumerable removedInputs + public IEnumerable removedInputs { get { return m_RemovedInputs; } } @@ -698,10 +698,10 @@ public void SanitizeGraphInputName(ShaderInput input) switch(input) { case AbstractShaderProperty property: - input.displayName = GraphUtil.SanitizeName(properties.Where(p => p.guid != input.guid).Select(p => p.displayName), "{0} ({1})", input.displayName); + input.displayName = GraphUtil.SanitizeName(properties.Where(p => p != input).Select(p => p.displayName), "{0} ({1})", input.displayName); break; case ShaderKeyword keyword: - input.displayName = GraphUtil.SanitizeName(keywords.Where(p => p.guid != input.guid).Select(p => p.displayName), "{0} ({1})", input.displayName); + input.displayName = GraphUtil.SanitizeName(keywords.Where(p => p != input).Select(p => p.displayName), "{0} ({1})", input.displayName); break; default: throw new ArgumentOutOfRangeException(); @@ -721,10 +721,10 @@ public void SanitizeGraphInputReferenceName(ShaderInput input, string newName) switch(input) { case AbstractShaderProperty property: - property.overrideReferenceName = GraphUtil.SanitizeName(properties.Where(p => p.guid != property.guid).Select(p => p.referenceName), "{0}_{1}", name); + property.overrideReferenceName = GraphUtil.SanitizeName(properties.Where(p => p != property).Select(p => p.referenceName), "{0}_{1}", name); break; case ShaderKeyword keyword: - keyword.overrideReferenceName = GraphUtil.SanitizeName(keywords.Where(p => p.guid != input.guid).Select(p => p.referenceName), "{0}_{1}", name).ToUpper(); + keyword.overrideReferenceName = GraphUtil.SanitizeName(keywords.Where(p => p != input).Select(p => p.referenceName), "{0}_{1}", name).ToUpper(); break; default: throw new ArgumentOutOfRangeException(); @@ -736,13 +736,13 @@ public void RemoveGraphInput(ShaderInput input) switch(input) { case AbstractShaderProperty property: - var propetyNodes = GetNodes().Where(x => x.propertyGuid == input.guid).ToList(); - foreach (var propNode in propetyNodes) - ReplacePropertyNodeWithConcreteNodeNoValidate(propNode); + var propertyNodes = GetNodes().Where(x => x.property == input).ToList(); + foreach (var propertyNode in propertyNodes) + ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode); break; } - RemoveGraphInputNoValidate(input.guid); + RemoveGraphInputNoValidate(input); ValidateGraph(); } @@ -801,14 +801,14 @@ public int GetGraphInputIndex(ShaderInput input) } } - void RemoveGraphInputNoValidate(Guid guid) + void RemoveGraphInputNoValidate(ShaderInput shaderInput) { - if (m_Properties.RemoveAll(x => x.value.guid == guid) > 0 || - m_Keywords.RemoveAll(x => x.value.guid == guid) > 0) + if (shaderInput is AbstractShaderProperty property && m_Properties.Remove(property) || + shaderInput is ShaderKeyword keyword && m_Keywords.Remove(keyword)) { - m_RemovedInputs.Add(guid); - m_AddedInputs.RemoveAll(x => x.guid == guid); - m_MovedInputs.RemoveAll(x => x.guid == guid); + m_RemovedInputs.Add(shaderInput); + m_AddedInputs.Remove(shaderInput); + m_MovedInputs.Remove(shaderInput); } } @@ -822,7 +822,7 @@ public void ReplacePropertyNodeWithConcreteNode(PropertyNode propertyNode) void ReplacePropertyNodeWithConcreteNodeNoValidate(PropertyNode propertyNode) { - var property = properties.FirstOrDefault(x => x.guid == propertyNode.propertyGuid); + var property = properties.FirstOrDefault(x => x == propertyNode.property); if (property == null) return; @@ -863,7 +863,7 @@ public void OnKeywordChangedNoValidate() public void ValidateGraph() { - var propertyNodes = GetNodes().Where(n => !m_Properties.Any(p => p.value.guid == n.propertyGuid)).ToArray(); + var propertyNodes = GetNodes().Where(n => !m_Properties.Any(p => p == n.property)).ToArray(); foreach (var pNode in propertyNodes) ReplacePropertyNodeWithConcreteNodeNoValidate(pNode); @@ -985,25 +985,22 @@ public void ReplaceWith(GraphData other) if (other == null) throw new ArgumentException("Can only replace with another AbstractMaterialGraph", "other"); - using (var removedInputsPooledObject = ListPool.GetDisposable()) + using (var inputsToRemove = PooledList.Get()) { - var removedInputGuids = removedInputsPooledObject.value; foreach (var property in m_Properties.SelectValue()) - removedInputGuids.Add(property.guid); + inputsToRemove.Add(property); foreach (var keyword in m_Keywords.SelectValue()) - removedInputGuids.Add(keyword.guid); - foreach (var inputGuid in removedInputGuids) - RemoveGraphInputNoValidate(inputGuid); + inputsToRemove.Add(keyword); + foreach (var input in inputsToRemove) + RemoveGraphInputNoValidate(input); } foreach (var otherProperty in other.properties) { - if (!properties.Any(p => p.guid == otherProperty.guid)) - AddGraphInput(otherProperty); + AddGraphInput(otherProperty); } foreach (var otherKeyword in other.keywords) { - if (!keywords.Any(p => p.guid == otherKeyword.guid)) - AddGraphInput(otherKeyword); + AddGraphInput(otherKeyword); } other.ValidateGraph(); @@ -1230,7 +1227,39 @@ public override void OnAfterDeserialize(string json) var graphData0 = JsonUtility.FromJson(json); var nodeGuidMap = new Dictionary(); + var propertyGuidMap = new Dictionary(); + var keywordGuidMap = new Dictionary(); var slotsField = typeof(AbstractMaterialNode).GetField("m_Slots", BindingFlags.Instance | BindingFlags.NonPublic); + var propertyField = typeof(PropertyNode).GetField("m_Property", BindingFlags.Instance | BindingFlags.NonPublic); + var keywordField = typeof(KeywordNode).GetField("m_Keyword", BindingFlags.Instance | BindingFlags.NonPublic); + + foreach (var serializedProperty in graphData0.m_SerializedProperties) + { + var property = (AbstractShaderProperty)DeserializeLegacy(serializedProperty.typeInfo.fullName, serializedProperty.JSONnodeData); + if (property == null) + { + continue; + } + + m_Properties.Add(property); + + var input0 = JsonUtility.FromJson(serializedProperty.JSONnodeData); + propertyGuidMap[input0.m_Guid.m_GuidSerialized] = property; + } + + foreach (var serializedKeyword in graphData0.m_SerializedKeywords) + { + var keyword = (ShaderKeyword)DeserializeLegacy(serializedKeyword.typeInfo.fullName, serializedKeyword.JSONnodeData); + if (keyword == null) + { + continue; + } + + m_Keywords.Add(keyword); + + var input0 = JsonUtility.FromJson(serializedKeyword.JSONnodeData); + keywordGuidMap[input0.m_Guid.m_GuidSerialized] = keyword; + } foreach (var serializedNode in graphData0.m_SerializableNodes) { @@ -1241,9 +1270,20 @@ public override void OnAfterDeserialize(string json) { continue; } + nodeGuidMap.Add(node0.m_GuidSerialized, node); m_Nodes.Add(node); + if (!string.IsNullOrEmpty(node0.m_PropertyGuidSerialized) && propertyGuidMap.TryGetValue(node0.m_PropertyGuidSerialized, out var property)) + { + propertyField.SetValue(node, (JsonRef)property); + } + + if (!string.IsNullOrEmpty(node0.m_KeywordGuidSerialized) && keywordGuidMap.TryGetValue(node0.m_KeywordGuidSerialized, out var keyword)) + { + keywordField.SetValue(node, (JsonRef)keyword); + } + var slots = (List>)slotsField.GetValue(node); slots.Clear(); @@ -1259,28 +1299,6 @@ public override void OnAfterDeserialize(string json) } } - foreach (var serializedProperty in graphData0.m_SerializedProperties) - { - var property = (AbstractShaderProperty)DeserializeLegacy(serializedProperty.typeInfo.fullName, serializedProperty.JSONnodeData); - if (property == null) - { - continue; - } - - m_Properties.Add(property); - } - - foreach (var serializedKeyword in graphData0.m_SerializedKeywords) - { - var keyword = (ShaderKeyword)DeserializeLegacy(serializedKeyword.typeInfo.fullName, serializedKeyword.JSONnodeData); - if (keyword == null) - { - continue; - } - - m_Keywords.Add(keyword); - } - if (isSubGraph) { m_OutputNode = GetNodes().FirstOrDefault(); diff --git a/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs b/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs index 20e9665dac2..ac08b406733 100644 --- a/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs +++ b/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs @@ -99,7 +99,7 @@ public static void DepthFirstCollectNodesFromNode(List nod // The only valid port id is the port that corresponds to that keywords value in the active permutation if(node is KeywordNode keywordNode && keywordPermutation != null) { - var valueInPermutation = keywordPermutation.Where(x => x.Key.guid == keywordNode.keywordGuid).FirstOrDefault(); + var valueInPermutation = keywordPermutation.Where(x => x.Key == keywordNode.keyword).FirstOrDefault(); ids = new int[] { keywordNode.GetSlotIdForPermutation(valueInPermutation) }; } else if (slotIds == null) diff --git a/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs index e4c9a329f99..595a7fea64b 100644 --- a/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs +++ b/com.unity.shadergraph/Editor/Data/Legacy/AbstractMaterialNode0.cs @@ -10,5 +10,9 @@ class AbstractMaterialNode0 public string m_GuidSerialized; public List m_SerializableSlots; + + public string m_PropertyGuidSerialized; + + public string m_KeywordGuidSerialized; } } diff --git a/com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs b/com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs new file mode 100644 index 00000000000..c2a2661702b --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.Legacy +{ + [Serializable] + class SerializableGuid + { + public string m_GuidSerialized; + } +} diff --git a/com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs.meta b/com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs.meta new file mode 100644 index 00000000000..52c1ab4e0bb --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/SerializableGuid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24f07b05b5f6f4c2c8dffd53c3d22cb7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs b/com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs new file mode 100644 index 00000000000..965b77fec2a --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs @@ -0,0 +1,10 @@ +using System; + +namespace UnityEditor.ShaderGraph.Legacy +{ + [Serializable] + class ShaderInput0 + { + public SerializableGuid m_Guid; + } +} diff --git a/com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs.meta b/com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs.meta new file mode 100644 index 00000000000..96fd200e0d2 --- /dev/null +++ b/com.unity.shadergraph/Editor/Data/Legacy/ShaderInput0.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 57665dc19efe4f899fc58a777b490b07 +timeCreated: 1584700544 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Input/PropertyNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Input/PropertyNode.cs index 3cea338e511..86478a7e771 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Input/PropertyNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Input/PropertyNode.cs @@ -3,9 +3,11 @@ using UnityEngine; using UnityEditor.Graphing; using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; namespace UnityEditor.ShaderGraph { + [Serializable] [Title("Input", "Property")] class PropertyNode : AbstractMaterialNode, IGeneratesBodyCode, IOnAssetEnabled { @@ -14,43 +16,34 @@ public PropertyNode() name = "Property"; UpdateNodeAfterDeserialization(); } - - [SerializeField] - string m_PropertyGuidSerialized; - Guid m_PropertyGuid; + [SerializeField] + JsonRef m_Property; - public Guid propertyGuid + public AbstractShaderProperty property { - get { return m_PropertyGuid; } + get { return m_Property; } set - { - if (m_PropertyGuid == value) + { + if (m_Property == value) return; - m_PropertyGuid = value; - var property = owner.properties.FirstOrDefault(x => x.guid == value); - if (property == null) - return; - - AddOutputSlot(property); + m_Property = value; + AddOutputSlot(); Dirty(ModificationScope.Topological); + } } - } + public override bool canSetPrecision => false; public void OnEnable() { - var property = owner.properties.FirstOrDefault(x => x.guid == propertyGuid); - if (property == null) - return; - - AddOutputSlot(property); + AddOutputSlot(); } - + public const int OutputSlotId = 0; - void AddOutputSlot(AbstractShaderProperty property) + void AddOutputSlot() { switch(property.concreteShaderValueType) { @@ -117,10 +110,6 @@ void AddOutputSlot(AbstractShaderProperty property) public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - var property = owner.properties.FirstOrDefault(x => x.guid == propertyGuid); - if (property == null) - return; - switch(property.propertyType) { case PropertyType.Boolean: @@ -164,10 +153,6 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo public override string GetVariableNameForSlot(int slotId) { - var property = owner.properties.FirstOrDefault(x => x.guid == propertyGuid); - if (property == null) - throw new NullReferenceException(); - if (!(property is Texture2DShaderProperty) && !(property is Texture2DArrayShaderProperty) && !(property is Texture3DShaderProperty) && @@ -176,10 +161,10 @@ public override string GetVariableNameForSlot(int slotId) return property.referenceName; } - + protected override bool CalculateNodeHasError(ref string errorMessage) { - if (!propertyGuid.Equals(Guid.Empty) && !owner.properties.Any(x => x.guid == propertyGuid)) + if (property == null || !owner.properties.Any(x => x == property)) { errorMessage = "Property Node has no associated Blackboard property."; return true; @@ -191,7 +176,6 @@ protected override bool CalculateNodeHasError(ref string errorMessage) public override bool ValidateConcretePrecision(ref string errorMessage) { // Get precision from Property - var property = owner.properties.FirstOrDefault(x => x.guid == propertyGuid); if (property == null) return true; @@ -201,20 +185,7 @@ public override bool ValidateConcretePrecision(ref string errorMessage) concretePrecision = precision.ToConcrete(); else concretePrecision = owner.concretePrecision; - return false; - } - - public override void OnBeforeSerialize() - { - base.OnBeforeSerialize(); - m_PropertyGuidSerialized = m_PropertyGuid.ToString(); - } - - public override void OnAfterDeserialize() - { - base.OnAfterDeserialize(); - if (!string.IsNullOrEmpty(m_PropertyGuidSerialized)) - m_PropertyGuid = new Guid(m_PropertyGuidSerialized); + return false; } } } diff --git a/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs b/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs index d4ed64ccfa2..dbb9fb38c1d 100644 --- a/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs +++ b/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs @@ -3,11 +3,11 @@ using System.Linq; using UnityEngine; using UnityEditor.Graphing; -using UnityEngine.Serialization; -using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Serialization; namespace UnityEditor.ShaderGraph { + [Serializable] [Title("Utility", "Keyword")] class KeywordNode : AbstractMaterialNode, IOnAssetEnabled, IGeneratesBodyCode { @@ -20,19 +20,17 @@ public KeywordNode() } [SerializeField] - private string m_KeywordGuidSerialized; + JsonRef m_Keyword; - private Guid m_KeywordGuid; - - public Guid keywordGuid + public ShaderKeyword keyword { - get { return m_KeywordGuid; } + get { return m_Keyword; } set { - if (m_KeywordGuid == value) + if (m_Keyword == value) return; - m_KeywordGuid = value; + m_Keyword = value; UpdateNode(); Dirty(ModificationScope.Topological); } @@ -49,15 +47,11 @@ public void OnEnable() public void UpdateNode() { - var keyword = owner.keywords.FirstOrDefault(x => x.guid == keywordGuid); - if (keyword == null) - return; - name = keyword.displayName; - UpdatePorts(keyword); + UpdatePorts(); } - void UpdatePorts(ShaderKeyword keyword) + void UpdatePorts() { switch(keyword.keywordType) { @@ -129,10 +123,6 @@ void UpdatePorts(ShaderKeyword keyword) public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - var keyword = owner.keywords.FirstOrDefault(x => x.guid == keywordGuid); - if (keyword == null) - return; - var outputSlot = FindOutputSlot(OutputSlotId); switch(keyword.keywordType) { @@ -200,29 +190,10 @@ public int GetSlotIdForPermutation(KeyValuePair permutation) protected override bool CalculateNodeHasError(ref string errorMessage) { - if (!keywordGuid.Equals(Guid.Empty) && !owner.keywords.Any(x => x.guid == keywordGuid)) + if (keyword == null || !owner.keywords.Any(x => x == keyword)) return true; return false; } - - public override void OnBeforeSerialize() - { - base.OnBeforeSerialize(); - - // Handle keyword guid serialization - m_KeywordGuidSerialized = m_KeywordGuid.ToString(); - } - - public override void OnAfterDeserialize() - { - base.OnAfterDeserialize(); - - // Handle keyword guid serialization - if (!string.IsNullOrEmpty(m_KeywordGuidSerialized)) - { - m_KeywordGuid = new Guid(m_KeywordGuidSerialized); - } - } } } diff --git a/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs b/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs index 4ddcdb6db03..d67df7e6a53 100644 --- a/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs +++ b/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs @@ -13,7 +13,7 @@ class BlackboardProvider { readonly GraphData m_Graph; public static readonly Texture2D exposedIcon = Resources.Load("GraphView/Nodes/BlackboardFieldExposed"); - readonly Dictionary m_InputRows; + readonly Dictionary m_InputRows; readonly BlackboardSection m_PropertySection; readonly BlackboardSection m_KeywordSection; public Blackboard blackboard { get; private set; } @@ -22,9 +22,9 @@ class BlackboardProvider bool m_EditPathCancelled = false; List m_SelectedNodes = new List(); - Dictionary m_ExpandedInputs = new Dictionary(); + Dictionary m_ExpandedInputs = new Dictionary(); - public Dictionary expandedInputs + public Dictionary expandedInputs { get { return m_ExpandedInputs; } } @@ -41,7 +41,7 @@ public string assetName public BlackboardProvider(GraphData graph) { m_Graph = graph; - m_InputRows = new Dictionary(); + m_InputRows = new Dictionary(); blackboard = new Blackboard() { @@ -282,17 +282,17 @@ public void HandleGraphChanges() row.RemoveFromHierarchy(); foreach (var property in m_Graph.properties) - m_PropertySection.Add(m_InputRows[property.guid]); + m_PropertySection.Add(m_InputRows[property]); foreach (var keyword in m_Graph.keywords) - m_KeywordSection.Add(m_InputRows[keyword.guid]); + m_KeywordSection.Add(m_InputRows[keyword]); } m_ExpandedInputs.Clear(); } void AddInputRow(ShaderInput input, bool create = false, int index = -1) { - if (m_InputRows.ContainsKey(input.guid)) + if (m_InputRows.ContainsKey(input)) return; if (create) @@ -350,16 +350,16 @@ void AddInputRow(ShaderInput input, bool create = false, int index = -1) var expandButton = row.Q