A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Text;
4using UnityEditor.Rendering;
5using UnityEditor.ShaderGraph;
6using UnityEngine;
7using Object = UnityEngine.Object;
8
9namespace UnityEditor.Graphing.Util
10{
11 class MessageManager
12 {
13 public interface IErrorLog
14 {
15 void LogError(string message, Object context);
16 void LogWarning(string message, Object context);
17 }
18
19 protected Dictionary<object, Dictionary<string, List<ShaderMessage>>> m_Messages =
20 new Dictionary<object, Dictionary<string, List<ShaderMessage>>>();
21
22 Dictionary<string, List<ShaderMessage>> m_Combined = new Dictionary<string, List<ShaderMessage>>();
23
24 public bool nodeMessagesChanged { get; private set; }
25
26 Dictionary<string, List<ShaderMessage>> m_FoundMessages;
27
28 public void AddOrAppendError(object errorProvider, string nodeId, ShaderMessage error)
29 {
30 if (!m_Messages.TryGetValue(errorProvider, out var messages))
31 {
32 messages = new Dictionary<string, List<ShaderMessage>>();
33 m_Messages[errorProvider] = messages;
34 }
35
36 List<ShaderMessage> messageList;
37 if (messages.TryGetValue(nodeId, out messageList))
38 {
39 messageList.Add(error);
40 }
41 else
42 {
43 messages[nodeId] = new List<ShaderMessage>() { error };
44 }
45
46 nodeMessagesChanged = true;
47 }
48
49 // Sort messages so errors come before warnings in the list
50 static int CompareMessages(ShaderMessage m1, ShaderMessage m2)
51 {
52 return m1.severity > m2.severity ? 1 : m2.severity > m1.severity ? -1 : 0;
53 }
54
55 public IEnumerable<KeyValuePair<string, List<ShaderMessage>>> GetNodeMessages()
56 {
57 var fixedNodes = new List<string>();
58 m_Combined.Clear();
59 foreach (var messageMap in m_Messages)
60 {
61 foreach (var messageList in messageMap.Value)
62 {
63 if (!m_Combined.TryGetValue(messageList.Key, out var foundList))
64 {
65 foundList = new List<ShaderMessage>();
66 m_Combined.Add(messageList.Key, foundList);
67 }
68 foundList.AddRange(messageList.Value);
69
70 if (messageList.Value.Count == 0)
71 {
72 fixedNodes.Add(messageList.Key);
73 }
74 }
75
76 // If all the messages from a provider for a node are gone,
77 // we can now remove it from the list since that will be reported in m_Combined
78 fixedNodes.ForEach(nodeId => messageMap.Value.Remove(nodeId));
79 }
80
81 foreach (var nodeList in m_Combined)
82 {
83 nodeList.Value.Sort(CompareMessages);
84 }
85
86 nodeMessagesChanged = false;
87 return m_Combined;
88 }
89
90 public void RemoveNode(string nodeId)
91 {
92 foreach (var messageMap in m_Messages)
93 {
94 nodeMessagesChanged |= messageMap.Value.Remove(nodeId);
95 }
96 }
97
98 public void ClearAllFromProvider(object messageProvider)
99 {
100 if (m_Messages.TryGetValue(messageProvider, out m_FoundMessages))
101 {
102 foreach (var messageList in m_FoundMessages)
103 {
104 nodeMessagesChanged |= messageList.Value.Count > 0;
105 messageList.Value.Clear();
106 }
107
108 m_FoundMessages = null;
109 }
110 }
111
112 public void ClearNodesFromProvider(object messageProvider, IEnumerable<AbstractMaterialNode> nodes)
113 {
114 if (m_Messages.TryGetValue(messageProvider, out m_FoundMessages))
115 {
116 foreach (var node in nodes)
117 {
118 if (m_FoundMessages.TryGetValue(node.objectId, out var messages))
119 {
120 nodeMessagesChanged |= messages.Count > 0;
121 messages.Clear();
122 }
123 }
124 }
125 }
126
127 public void ClearAll()
128 {
129 m_Messages.Clear();
130 m_Combined.Clear();
131 nodeMessagesChanged = false;
132 }
133
134 void DebugPrint()
135 {
136 StringBuilder output = new StringBuilder("MessageMap:\n");
137 foreach (var messageMap in m_Messages)
138 {
139 output.AppendFormat("\tFrom Provider {0}:\n", messageMap.Key.GetType());
140 foreach (var messageList in messageMap.Value)
141 {
142 output.AppendFormat("\t\tNode {0} has {1} messages:\n", messageList.Key, messageList.Value.Count);
143 foreach (var message in messageList.Value)
144 {
145 output.AppendFormat("\t\t\t{0}\n", message.message);
146 }
147 }
148 }
149 Debug.Log(output.ToString());
150 }
151
152 public static void Log(string path, ShaderMessage message, Object context, IErrorLog log)
153 {
154 var errString = $"{message.severity} in Graph at {path} on line {message.line}: {message.message}";
155 if (message.severity == ShaderCompilerMessageSeverity.Error)
156 {
157 log.LogError(errString, context);
158 }
159 else
160 {
161 log.LogWarning(errString, context);
162 }
163 }
164
165 public bool AnyError(Func<string, bool> nodeFilter = null)
166 {
167 if (m_Messages == null)
168 return false;
169
170 foreach (var kvp in m_Messages)
171 {
172 var errorProvider = kvp.Key;
173 var messageMap = kvp.Value;
174 foreach (var kvp2 in messageMap)
175 {
176 var nodeId = kvp2.Key;
177 List<ShaderMessage> messageList = kvp2.Value;
178 if ((nodeFilter == null) || nodeFilter(nodeId))
179 {
180 foreach (var message in messageList)
181 {
182 if (message.severity == ShaderCompilerMessageSeverity.Error)
183 {
184 return true;
185 }
186 }
187 }
188 }
189 }
190 return false;
191 }
192
193 public IEnumerable<string> ErrorStrings(Func<string, bool> nodeFilter = null, ShaderCompilerMessageSeverity severity = ShaderCompilerMessageSeverity.Error)
194 {
195 if (m_Messages == null)
196 yield break;
197
198 foreach (var kvp in m_Messages)
199 {
200 var errorProvider = kvp.Key;
201 var messageMap = kvp.Value;
202 foreach (var kvp2 in messageMap)
203 {
204 var nodeId = kvp2.Key;
205 if ((nodeFilter == null) || nodeFilter(nodeId))
206 {
207 List<ShaderMessage> messageList = kvp2.Value;
208 foreach (var message in messageList)
209 {
210 if (message.severity == severity)
211 {
212 yield return message.message;
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220}