using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEditor.ShaderGraph; namespace UnityEditor.Graphing.Util { [Serializable] sealed class CopyPasteGraph : ISerializationCallbackReceiver { [NonSerialized] HashSet m_Edges = new HashSet(); [NonSerialized] HashSet m_Nodes = new HashSet(); [SerializeField] List m_Groups = new List(); [SerializeField] List m_StickyNotes = new List(); [NonSerialized] HashSet m_Inputs = new HashSet(); // The meta properties are properties that are not copied into the target graph // but sent along to allow property nodes to still hvae the data from the original // property present. [NonSerialized] HashSet m_MetaProperties = new HashSet(); // The meta keywords are keywords that are required by keyword nodes // These are copied into the target graph when there is no collision [NonSerialized] HashSet m_MetaKeywords = new HashSet(); [SerializeField] string m_SourceGraphGuid; [SerializeField] List m_SerializableNodes = new List(); [SerializeField] List m_SerializableEdges = new List(); [SerializeField] List m_SerilaizeableInputs = new List(); [SerializeField] List m_SerializableMetaProperties = new List(); [SerializeField] List m_SerializableMetaKeywords = new List(); public CopyPasteGraph() {} public CopyPasteGraph(string sourceGraphGuid, IEnumerable groups, IEnumerable nodes, IEnumerable edges, IEnumerable inputs, IEnumerable metaProperties, IEnumerable metaKeywords, IEnumerable notes) { m_SourceGraphGuid = sourceGraphGuid; foreach (var groupData in groups) { AddGroup(groupData); } foreach (var stickyNote in notes) { AddNote(stickyNote); } foreach (var node in nodes) { if (!node.canCopyNode) { throw new InvalidOperationException($"Cannot copy node {node.name} ({node.guid})."); } AddNode(node); foreach (var edge in NodeUtils.GetAllEdges(node)) AddEdge(edge); } foreach (var edge in edges) AddEdge(edge); foreach (var input in inputs) AddInput(input); foreach (var metaProperty in metaProperties) AddMetaProperty(metaProperty); foreach (var metaKeyword in metaKeywords) AddMetaKeyword(metaKeyword); } public void AddGroup(GroupData group) { m_Groups.Add(group); } public void AddNote(StickyNoteData stickyNote) { m_StickyNotes.Add(stickyNote); } public void AddNode(AbstractMaterialNode node) { m_Nodes.Add(node); } public void AddEdge(IEdge edge) { m_Edges.Add(edge); } public void AddInput(ShaderInput input) { m_Inputs.Add(input); } public void AddMetaProperty(AbstractShaderProperty metaProperty) { m_MetaProperties.Add(metaProperty); } public void AddMetaKeyword(ShaderKeyword metaKeyword) { m_MetaKeywords.Add(metaKeyword); } public IEnumerable GetNodes() { return m_Nodes.OfType(); } public IEnumerable groups { get { return m_Groups; } } public IEnumerable stickyNotes => m_StickyNotes; public IEnumerable edges { get { return m_Edges; } } public IEnumerable inputs { get { return m_Inputs; } } public IEnumerable metaProperties { get { return m_MetaProperties; } } public IEnumerable metaKeywords { get { return m_MetaKeywords; } } public string sourceGraphGuid { get { return m_SourceGraphGuid; } } public void OnBeforeSerialize() { m_SerializableNodes = SerializationHelper.Serialize(m_Nodes); m_SerializableEdges = SerializationHelper.Serialize(m_Edges); m_SerilaizeableInputs = SerializationHelper.Serialize(m_Inputs); m_SerializableMetaProperties = SerializationHelper.Serialize(m_MetaProperties); m_SerializableMetaKeywords = SerializationHelper.Serialize(m_MetaKeywords); } public void OnAfterDeserialize() { var nodes = SerializationHelper.Deserialize(m_SerializableNodes, GraphUtil.GetLegacyTypeRemapping()); m_Nodes.Clear(); foreach (var node in nodes) m_Nodes.Add(node); m_SerializableNodes = null; var edges = SerializationHelper.Deserialize(m_SerializableEdges, GraphUtil.GetLegacyTypeRemapping()); m_Edges.Clear(); foreach (var edge in edges) m_Edges.Add(edge); m_SerializableEdges = null; var inputs = SerializationHelper.Deserialize(m_SerilaizeableInputs, GraphUtil.GetLegacyTypeRemapping()); m_Inputs.Clear(); foreach (var input in inputs) m_Inputs.Add(input); m_SerilaizeableInputs = null; var metaProperties = SerializationHelper.Deserialize(m_SerializableMetaProperties, GraphUtil.GetLegacyTypeRemapping()); m_MetaProperties.Clear(); foreach (var metaProperty in metaProperties) { m_MetaProperties.Add(metaProperty); } m_SerializableMetaProperties = null; var metaKeywords = SerializationHelper.Deserialize(m_SerializableMetaKeywords, GraphUtil.GetLegacyTypeRemapping()); m_MetaKeywords.Clear(); foreach (var metaKeyword in metaKeywords) { m_MetaKeywords.Add(metaKeyword); } m_SerializableMetaKeywords = null; } internal static CopyPasteGraph FromJson(string copyBuffer) { try { return JsonUtility.FromJson(copyBuffer); } catch { // ignored. just means copy buffer was not a graph :( return null; } } } }