A game about forced loneliness, made by TACStudios
at master 201 lines 7.3 kB view raw
1using System; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.Profiling; 5 6namespace UnityEditor.ShaderGraph 7{ 8 [GenerationAPI] 9 [InitializeOnLoad] 10 internal static class NodeClassCache 11 { 12 private class PostProcessor : AssetPostprocessor 13 { 14 static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) 15 { 16 if (m_KnownSubGraphLookupTable != null) 17 { 18 foreach (string str in deletedAssets) 19 { 20 var guid = AssetDatabase.AssetPathToGUID(str); 21 if (m_KnownSubGraphLookupTable.ContainsKey(guid)) 22 { 23 m_KnownSubGraphLookupTable.Remove(guid); 24 } 25 } 26 foreach (string str in movedFromAssetPaths) 27 { 28 var guid = AssetDatabase.AssetPathToGUID(str); 29 if (m_KnownSubGraphLookupTable.ContainsKey(guid)) 30 { 31 m_KnownSubGraphLookupTable.Remove(guid); 32 } 33 } 34 } 35 36 foreach (string str in importedAssets) 37 { 38 if (str.EndsWith(ShaderSubGraphImporter.Extension)) 39 { 40 UpdateSubGraphEntry(str); 41 } 42 } 43 foreach (string str in movedAssets) 44 { 45 if (str.EndsWith(ShaderSubGraphImporter.Extension)) 46 { 47 UpdateSubGraphEntry(str); 48 } 49 } 50 } 51 } 52 53 54 private static Dictionary<Type, List<ContextFilterableAttribute>> m_KnownTypeLookupTable; 55 private static Dictionary<Type, List<ContextFilterableAttribute>> KnownTypeLookupTable 56 { 57 get 58 { 59 EnsureKnownTypeLookupTable(); 60 return m_KnownTypeLookupTable; 61 } 62 } 63 64 public static IEnumerable<Type> knownNodeTypes 65 { 66 get => KnownTypeLookupTable.Keys; 67 } 68 69 70 private static Dictionary<string, SubGraphAsset> m_KnownSubGraphLookupTable; 71 private static Dictionary<string, SubGraphAsset> KnownSubGraphLookupTable 72 { 73 get 74 { 75 EnsureKnownSubGraphLookupTable(); 76 return m_KnownSubGraphLookupTable; 77 } 78 } 79 80 public static IEnumerable<SubGraphAsset> knownSubGraphAssets 81 { 82 get => KnownSubGraphLookupTable.Values; 83 } 84 85 public static void UpdateSubGraphEntry(string path) 86 { 87 string guid = AssetDatabase.AssetPathToGUID(path); 88 if (guid.Length == 0) 89 { 90 return; 91 } 92 var asset = AssetDatabase.LoadAssetAtPath<SubGraphAsset>(path); 93 94 bool valid = asset != null && asset.isValid; 95 if (KnownSubGraphLookupTable.TryGetValue(guid, out SubGraphAsset known)) 96 { 97 if (!valid) 98 { 99 KnownSubGraphLookupTable.Remove(guid); 100 } 101 else if (asset != known) 102 { 103 KnownSubGraphLookupTable[guid] = asset; 104 } 105 } 106 else if (valid) 107 { 108 KnownSubGraphLookupTable.Add(guid, asset); 109 } 110 } 111 112 public static IEnumerable<ContextFilterableAttribute> GetFilterableAttributesOnNodeType(Type nodeType) 113 { 114 if (nodeType == null) 115 { 116 throw new ArgumentNullException("Cannot get attributes on a null Type"); 117 } 118 119 if (KnownTypeLookupTable.TryGetValue(nodeType, out List<ContextFilterableAttribute> filterableAttributes)) 120 { 121 return filterableAttributes; 122 } 123 else 124 { 125 throw new ArgumentException($"The passed in Type {nodeType.FullName} was not found in the loaded assemblies as a child class of AbstractMaterialNode"); 126 } 127 } 128 129 public static T GetAttributeOnNodeType<T>(Type nodeType) where T : ContextFilterableAttribute 130 { 131 var filterableAttributes = GetFilterableAttributesOnNodeType(nodeType); 132 foreach (var attr in filterableAttributes) 133 { 134 if (attr is T searchTypeAttr) 135 { 136 return searchTypeAttr; 137 } 138 } 139 return null; 140 } 141 142 private static void EnsureKnownTypeLookupTable() 143 { 144 if (m_KnownTypeLookupTable == null) 145 { 146 Profiler.BeginSample("EnsureKnownTypeLookupTable"); 147 m_KnownTypeLookupTable = new Dictionary<Type, List<ContextFilterableAttribute>>(); 148 foreach (Type nodeType in TypeCache.GetTypesDerivedFrom<AbstractMaterialNode>()) 149 { 150 if (!nodeType.IsAbstract) 151 { 152 List<ContextFilterableAttribute> filterableAttributes = new List<ContextFilterableAttribute>(); 153 foreach (Attribute attribute in Attribute.GetCustomAttributes(nodeType)) 154 { 155 Type attributeType = attribute.GetType(); 156 if (!attributeType.IsAbstract && attribute is ContextFilterableAttribute contextFilterableAttribute) 157 { 158 filterableAttributes.Add(contextFilterableAttribute); 159 } 160 } 161 m_KnownTypeLookupTable.Add(nodeType, filterableAttributes); 162 } 163 } 164 Profiler.EndSample(); 165 } 166 } 167 168 private static void EnsureKnownSubGraphLookupTable() 169 { 170 if (m_KnownSubGraphLookupTable == null) 171 { 172 Profiler.BeginSample("EnsureKnownSubGraphLookupTable"); 173 m_KnownSubGraphLookupTable = new Dictionary<string, SubGraphAsset>(); 174 foreach (var guid in AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SubGraphAsset)))) 175 { 176 var asset = AssetDatabase.LoadAssetAtPath<SubGraphAsset>(AssetDatabase.GUIDToAssetPath(guid)); 177 if (asset != null && asset.isValid) 178 { 179 m_KnownSubGraphLookupTable.Add(guid, asset); 180 } 181 } 182 Profiler.EndSample(); 183 } 184 } 185 186 private static void DebugPrintKnownNodes() 187 { 188 foreach (var entry in KnownTypeLookupTable) 189 { 190 var nodeType = entry.Key; 191 var filterableAttributes = entry.Value; 192 String attrs = ""; 193 foreach (var filterable in filterableAttributes) 194 { 195 attrs += filterable.ToString() + ", "; 196 } 197 Debug.Log(nodeType.ToString() + $": [{attrs}]"); 198 } 199 } 200 } 201}