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
}
}