using System; using System.Collections.Generic; using UnityEditor; namespace AutoGroupGenerator { /// /// Graph of asset dependencies used by AutoGroupGenerator. /// public class DependencyGraph : Graph { #region Types /// /// Serializable payload for persisting dependency graphs. /// [Serializable] public class SerializedData { #region Fields /// /// The serialized graph representation. /// public Graph.SerializableData Graph = new(); /// /// Mapping of GUID strings to serialized indices. /// public List IndexEntries = new(); #endregion } /// /// Serializable mapping entry for GUID indices. /// [Serializable] public class SerializableKeyValue { /// /// GUID key string. /// public string Key; /// /// Integer index assigned to the GUID. /// public int Value; } #endregion #region Static Methods /// /// Rehydrates a from serialized data. /// /// Serialized graph payload. /// The deserialized dependency graph. public static DependencyGraph Deserialize(SerializedData serializedData) { var invertedDictionary = new Dictionary(); foreach (var entry in serializedData.IndexEntries) { invertedDictionary.Add(entry.Value, entry.Key); } Graph graph = Graph.FromSerializableData(serializedData.Graph) .ConvertNodeType(ConvertIndexToGuid); return new DependencyGraph(graph); AssetNode ConvertIndexToGuid(int nodeIndex) { var guidString = invertedDictionary[nodeIndex]; return AssetNode.FromGuidString(guidString); } } #endregion #region Methods /// /// Initializes an empty dependency graph. /// public DependencyGraph() { } /// /// Initializes the graph from an existing . /// /// Source graph to copy. public DependencyGraph(Graph graph) { FromGraph(graph); } /// /// Adds a dependency edge between two asset paths. /// /// Source asset path. /// Dependent asset path. public void AddEdge(string pathA, string pathB) { var guidA = AssetDatabase.GUIDFromAssetPath(pathA); var guidB = AssetDatabase.GUIDFromAssetPath(pathB); base.AddEdge(new AssetNode(guidA), new AssetNode(guidB)); } /// /// Adds a node for the asset path. /// /// Asset path to add. public void AddNode(string path) { var guid = AssetDatabase.GUIDFromAssetPath(path); base.AddNode(new AssetNode(guid)); } /// /// Counts outgoing edges from the specified node. /// /// Node to count edges for. /// The number of outgoing edges. public int CountOutgoingEdges(AssetNode node) { return GetNeighbors(node).Count; } private void FromGraph(Graph graph) { _adjacencyList = new Dictionary>(); foreach (var node in graph.GetAllNodes()) { _adjacencyList.Add(node, graph.GetNeighbors(node)); } } /// /// Serializes the graph into a persistable payload. /// /// The serialized graph data. public SerializedData Serialize() { var serializedData = new SerializedData(); int index = 0; serializedData.Graph = ConvertNodeType(ConvertGuidToIndex).ToSerializableData(); return serializedData; int ConvertGuidToIndex(AssetNode node) { var guidString = node.Guid.ToString(); var existingEntry = serializedData.IndexEntries.Find(kv => kv.Key == guidString); if (existingEntry != null) { return existingEntry.Value; } index++; serializedData.IndexEntries.Add(new SerializableKeyValue { Key = guidString, Value = index, }); return index; } } #endregion } }