A game about forced loneliness, made by TACStudios
at master 4.2 kB view raw
1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Reflection; 5using System.Text; 6using UnityEditor.Graphing; 7using UnityEditor.ShaderGraph.Legacy; 8using UnityEditor.ShaderGraph.Serialization; 9using UnityEngine; 10 11namespace UnityEditor.ShaderGraph 12{ 13 /// <summary> 14 /// Minimal version of <see cref="GraphData"/> used for gathering dependencies. This allows us to not deserialize 15 /// all the nodes, ports, edges, groups etc., which is important as we cannot share data between 16 /// <see cref="ShaderSubGraphImporter.GatherDependenciesFromSourceFile"/> and 17 /// <see cref="ShaderSubGraphImporter.OnImportAsset"/>. The latter must always import fully, but for the former we 18 /// want to avoid the extra GC pressure. 19 /// </summary> 20 [Serializable] 21 class MinimalGraphData 22 { 23 static Dictionary<string, Type> s_MinimalTypeMap = CreateMinimalTypeMap(); 24 25 static Dictionary<string, Type> CreateMinimalTypeMap() 26 { 27 var types = new Dictionary<string, Type>(); 28 foreach (var type in TypeCache.GetTypesWithAttribute<HasDependenciesAttribute>()) 29 { 30 var dependencyAttribute = (HasDependenciesAttribute)type.GetCustomAttributes(typeof(HasDependenciesAttribute), false)[0]; 31 if (!typeof(IHasDependencies).IsAssignableFrom(dependencyAttribute.minimalType)) 32 { 33 Debug.LogError($"{type} must implement {typeof(IHasDependencies)} to be used in {typeof(HasDependenciesAttribute)}"); 34 continue; 35 } 36 37 types.Add(type.FullName, dependencyAttribute.minimalType); 38 39 var formerNameAttributes = (FormerNameAttribute[])type.GetCustomAttributes(typeof(FormerNameAttribute), false); 40 foreach (var formerNameAttribute in formerNameAttributes) 41 { 42 types.Add(formerNameAttribute.fullName, dependencyAttribute.minimalType); 43 } 44 } 45 46 return types; 47 } 48 49 [SerializeField] 50 List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>(); 51 52 // gather all asset dependencies declared by nodes in the given (shadergraph or shadersubgraph) asset 53 // by reading the source file from disk, and doing a minimal parse 54 // returns true if it successfully gathered the dependencies, false if there was an error 55 public static bool GatherMinimalDependenciesFromFile(string assetPath, AssetCollection assetCollection) 56 { 57 var textGraph = FileUtilities.SafeReadAllText(assetPath); 58 59 // if we can't read the file, no dependencies can be gathered 60 if (string.IsNullOrEmpty(textGraph)) 61 return false; 62 63 var entries = MultiJsonInternal.Parse(textGraph); 64 65 if (string.IsNullOrWhiteSpace(entries[0].type)) 66 { 67 var minimalGraphData = JsonUtility.FromJson<MinimalGraphData>(textGraph); 68 entries.Clear(); 69 foreach (var node in minimalGraphData.m_SerializableNodes) 70 { 71 entries.Add(new MultiJsonEntry(node.typeInfo.fullName, null, node.JSONnodeData)); 72 AbstractMaterialNode0 amn = new AbstractMaterialNode0(); 73 JsonUtility.FromJsonOverwrite(node.JSONnodeData, amn); 74 foreach (var slot in amn.m_SerializableSlots) 75 { 76 entries.Add(new MultiJsonEntry(slot.typeInfo.fullName, null, slot.JSONnodeData)); 77 } 78 } 79 } 80 81 foreach (var entry in entries) 82 { 83 if (s_MinimalTypeMap.TryGetValue(entry.type, out var minimalType)) 84 { 85 var instance = (IHasDependencies)Activator.CreateInstance(minimalType); 86 JsonUtility.FromJsonOverwrite(entry.json, instance); 87 instance.GetSourceAssetDependencies(assetCollection); 88 } 89 } 90 91 return true; 92 } 93 } 94}