initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,21 @@
using UnityEngine.Assertions;
namespace UnityEditor.ShaderGraph
{
static class AssertHelpers
{
public static void IsNotNull(object anObject, string message)
{
#if SG_ASSERTIONS
Assert.IsNotNull(anObject, message);
#endif
}
public static void Fail(string message)
{
#if SG_ASSERTIONS
throw new AssertionException(message, null);
#endif
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 67a39d09a4be41f686550822af7da95e
timeCreated: 1615243771

View file

@ -0,0 +1,51 @@
using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.ShaderGraph.Drawing
{
static class CompatibilityExtensions
{
#if !UNITY_2018_3_OR_NEWER
public static void MarkDirtyRepaint(this VisualElement element)
{
element.Dirty(ChangeType.Repaint);
}
#endif
#if !UNITY_2018_3_OR_NEWER
public static void CaptureMouse(this VisualElement element)
{
element.TakeMouseCapture();
}
public static void ReleaseMouse(this VisualElement element)
{
element.ReleaseMouseCapture();
}
#endif
public static void OnToggleChanged(this Toggle toggle, EventCallback<ChangeEvent<bool>> callback)
{
#if UNITY_2018_3_OR_NEWER
toggle.RegisterValueChangedCallback(callback);
#else
toggle.OnToggle(() => callback(ChangeEvent<bool>.GetPooled(!toggle.value, toggle.value)));
#endif
}
}
static class TrickleDownEnum
{
#if UNITY_2018_3_OR_NEWER
public static readonly TrickleDown NoTrickleDown = TrickleDown.NoTrickleDown;
public static readonly TrickleDown TrickleDown = TrickleDown.TrickleDown;
#else
public static readonly Capture NoTrickleDown = Capture.NoCapture;
public static readonly Capture TrickleDown = Capture.Capture;
#endif
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7c1717b624ad45ccbb3fa6bec28af711
timeCreated: 1519741123

View file

@ -0,0 +1,304 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
using UnityEngine;
using UnityEditor.ShaderGraph;
using UnityEditor.ShaderGraph.Internal;
using UnityEditor.ShaderGraph.Serialization;
namespace UnityEditor.ShaderGraph
{
enum CopyPasteGraphSource
{
Default,
Duplicate
}
[Serializable]
sealed class CopyPasteGraph : JsonObject
{
CopyPasteGraphSource m_CopyPasteGraphSource;
[SerializeField]
List<Edge> m_Edges = new List<Edge>();
[SerializeField]
List<JsonData<AbstractMaterialNode>> m_Nodes = new List<JsonData<AbstractMaterialNode>>();
[SerializeField]
List<JsonData<GroupData>> m_Groups = new List<JsonData<GroupData>>();
[SerializeField]
List<JsonData<StickyNoteData>> m_StickyNotes = new List<JsonData<StickyNoteData>>();
[SerializeField]
List<JsonRef<ShaderInput>> m_Inputs = new List<JsonRef<ShaderInput>>();
[SerializeField]
List<JsonData<CategoryData>> m_Categories = new List<JsonData<CategoryData>>();
// The meta properties are properties that are not copied into the target graph
// but sent along to allow property nodes to still hvae the data from the original
// property present.
[SerializeField]
List<JsonData<AbstractShaderProperty>> m_MetaProperties = new List<JsonData<AbstractShaderProperty>>();
[SerializeField]
List<string> m_MetaPropertyIds = new List<string>();
// The meta keywords are keywords that are required by keyword nodes
// These are copied into the target graph when there is no collision
[SerializeField]
List<JsonData<ShaderKeyword>> m_MetaKeywords = new List<JsonData<ShaderKeyword>>();
[SerializeField]
List<string> m_MetaKeywordIds = new List<string>();
[SerializeField]
List<JsonData<ShaderDropdown>> m_MetaDropdowns = new List<JsonData<ShaderDropdown>>();
[SerializeField]
List<string> m_MetaDropdownIds = new List<string>();
public CopyPasteGraph() { }
public CopyPasteGraph(IEnumerable<GroupData> groups,
IEnumerable<AbstractMaterialNode> nodes,
IEnumerable<Edge> edges,
IEnumerable<ShaderInput> inputs,
IEnumerable<CategoryData> categories,
IEnumerable<AbstractShaderProperty> metaProperties,
IEnumerable<ShaderKeyword> metaKeywords,
IEnumerable<ShaderDropdown> metaDropdowns,
IEnumerable<StickyNoteData> notes,
bool keepOutputEdges = false,
bool removeOrphanEdges = true,
CopyPasteGraphSource copyPasteGraphSource = CopyPasteGraphSource.Default)
{
m_CopyPasteGraphSource = copyPasteGraphSource;
if (groups != null)
{
foreach (var groupData in groups)
AddGroup(groupData);
}
if (notes != null)
{
foreach (var stickyNote in notes)
AddNote(stickyNote);
}
var nodeSet = new HashSet<AbstractMaterialNode>();
if (nodes != null)
{
foreach (var node in nodes.Distinct())
{
if (!node.canCopyNode)
{
throw new InvalidOperationException($"Cannot copy node {node.name} ({node.objectId}).");
}
nodeSet.Add(node);
AddNode(node);
foreach (var edge in NodeUtils.GetAllEdges(node))
AddEdge((Edge)edge);
}
}
if (edges != null)
{
foreach (var edge in edges)
AddEdge(edge);
}
if (inputs != null)
{
foreach (var input in inputs)
AddInput(input);
}
if (categories != null)
{
foreach (var category in categories)
AddCategory(category);
}
if (metaProperties != null)
{
foreach (var metaProperty in metaProperties.Distinct())
AddMetaProperty(metaProperty);
}
if (metaKeywords != null)
{
foreach (var metaKeyword in metaKeywords.Distinct())
AddMetaKeyword(metaKeyword);
}
if (metaDropdowns != null)
{
foreach (var metaDropdown in metaDropdowns.Distinct())
AddMetaDropdown(metaDropdown);
}
var distinct = m_Edges.Distinct();
if (removeOrphanEdges)
{
distinct = distinct.Where(edge => nodeSet.Contains(edge.inputSlot.node) || (keepOutputEdges && nodeSet.Contains(edge.outputSlot.node)));
}
m_Edges = distinct.ToList();
}
public bool IsInputCategorized(ShaderInput shaderInput)
{
foreach (var category in categories)
{
if (category.IsItemInCategory(shaderInput))
return true;
}
return false;
}
// The only situation in which an input has an identical reference name to another input in a category, while not being the same instance, is if they are duplicates
public bool IsInputDuplicatedFromCategory(ShaderInput shaderInput, CategoryData inputCategory, GraphData targetGraphData)
{
foreach (var child in inputCategory.Children)
{
if (child.referenceName.Equals(shaderInput.referenceName, StringComparison.Ordinal) && child.objectId != shaderInput.objectId)
{
return true;
}
}
// Need to check if they share same graph owner as well, if not then we can early out
bool inputBelongsToTargetGraph = targetGraphData.ContainsInput(shaderInput);
if (inputBelongsToTargetGraph == false)
return false;
return false;
}
void AddGroup(GroupData group)
{
m_Groups.Add(group);
}
void AddNote(StickyNoteData stickyNote)
{
m_StickyNotes.Add(stickyNote);
}
void AddNode(AbstractMaterialNode node)
{
m_Nodes.Add(node);
}
void AddEdge(Edge edge)
{
m_Edges.Add(edge);
}
void AddInput(ShaderInput input)
{
m_Inputs.Add(input);
}
void AddCategory(CategoryData category)
{
m_Categories.Add(category);
}
void AddMetaProperty(AbstractShaderProperty metaProperty)
{
m_MetaProperties.Add(metaProperty);
m_MetaPropertyIds.Add(metaProperty.objectId);
}
void AddMetaKeyword(ShaderKeyword metaKeyword)
{
m_MetaKeywords.Add(metaKeyword);
m_MetaKeywordIds.Add(metaKeyword.objectId);
}
void AddMetaDropdown(ShaderDropdown metaDropdown)
{
m_MetaDropdowns.Add(metaDropdown);
m_MetaDropdownIds.Add(metaDropdown.objectId);
}
public IEnumerable<T> GetNodes<T>()
{
return m_Nodes.SelectValue().OfType<T>();
}
public DataValueEnumerable<GroupData> groups => m_Groups.SelectValue();
public DataValueEnumerable<StickyNoteData> stickyNotes => m_StickyNotes.SelectValue();
public IEnumerable<Edge> edges
{
get { return m_Edges; }
}
public RefValueEnumerable<ShaderInput> inputs
{
get { return m_Inputs.SelectValue(); }
}
public DataValueEnumerable<CategoryData> categories
{
get { return m_Categories.SelectValue(); }
}
public DataValueEnumerable<AbstractShaderProperty> metaProperties
{
get { return m_MetaProperties.SelectValue(); }
}
public DataValueEnumerable<ShaderKeyword> metaKeywords
{
get { return m_MetaKeywords.SelectValue(); }
}
public DataValueEnumerable<ShaderDropdown> metaDropdowns
{
get { return m_MetaDropdowns.SelectValue(); }
}
public IEnumerable<string> metaPropertyIds => m_MetaPropertyIds;
public IEnumerable<string> metaKeywordIds => m_MetaKeywordIds;
public CopyPasteGraphSource copyPasteGraphSource => m_CopyPasteGraphSource;
public override void OnAfterMultiDeserialize(string json)
{
// should we add support for versioning old CopyPasteGraphs from old versions of Unity?
// so you can copy from old paste to new
foreach (var node in m_Nodes.SelectValue())
{
node.UpdateNodeAfterDeserialization();
node.SetupSlots();
}
}
internal static CopyPasteGraph FromJson(string copyBuffer, GraphData targetGraph)
{
try
{
var graph = new CopyPasteGraph();
MultiJson.Deserialize(graph, copyBuffer, targetGraph, true);
return graph;
}
catch
{
// ignored. just means copy buffer was not a graph :(
return null;
}
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 187365d075d49dc46a3e09b81f0d6fdd
timeCreated: 1483699278
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,3 @@
namespace UnityEditor.Graphing
{
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2a64b792c8859f74281b897c2a1d659c
timeCreated: 1464601236
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,22 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.Tests")]
namespace UnityEngine.Rendering.ShaderGraph
{
//Need to live in Runtime as Attribute of documentation is on Runtime classes \o/
class Documentation : DocumentationInfo
{
//This must be used like
//[HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "some-page" + Documentation.endURL)]
//It cannot support String.Format nor string interpolation
internal const string baseURL = "https://docs.unity3d.com/Packages/com.unity.shadergraph@";
internal const string subURL = "/manual/";
internal const string endURL = ".html";
internal static string GetPageLink(string pageName)
{
return baseURL + version + subURL + pageName + endURL;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a567520c18010479aaafcdc0b5a358b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,105 @@
using System;
using System.IO;
using UnityEditor.ShaderGraph.Serialization;
using Debug = UnityEngine.Debug;
using UnityEditor.VersionControl;
using System.Text;
namespace UnityEditor.ShaderGraph
{
static class FileUtilities
{
// if successfully written to disk, returns the serialized file contents as a string
// on failure, returns null
public static string WriteShaderGraphToDisk(string path, GraphData data)
{
if (data == null)
{
// Returning false may be better than throwing this exception, in terms of preserving data.
// But if GraphData is null, it's likely we don't have any data to preserve anyways.
// So this exception seems fine for now.
throw new ArgumentNullException(nameof(data));
}
var text = MultiJson.Serialize(data);
if (WriteToDisk(path, text))
return text;
else
return null;
}
// returns true if successfully written to disk
public static bool WriteToDisk(string path, string text)
{
CheckoutIfValid(path);
while (true)
{
try
{
File.WriteAllText(path, text);
}
catch (Exception e)
{
if (e.GetBaseException() is UnauthorizedAccessException &&
(File.GetAttributes(path) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
if (EditorUtility.DisplayDialog("File is Read-Only", path, "Make Writeable", "Cancel Save"))
{
// make writeable
FileInfo fileInfo = new FileInfo(path);
fileInfo.IsReadOnly = false;
continue; // retry save
}
else
return false;
}
Debug.LogException(e);
if (EditorUtility.DisplayDialog("Exception While Saving", e.ToString(), "Retry", "Cancel"))
continue; // retry save
else
return false;
}
break; // no exception, file save success!
}
return true;
}
// returns contents of the asset file as a string, or null if any error or exception occurred
public static string SafeReadAllText(string assetPath)
{
string result = null;
try
{
result = File.ReadAllText(assetPath, Encoding.UTF8);
}
catch
{
result = null;
}
return result;
}
static void CheckoutIfValid(string path)
{
if (VersionControl.Provider.enabled && VersionControl.Provider.isActive)
{
var asset = VersionControl.Provider.GetAssetByPath(path);
if (asset != null)
{
if (!VersionControl.Provider.IsOpenForEdit(asset))
{
var task = VersionControl.Provider.Checkout(asset, VersionControl.CheckoutMode.Asset);
task.Wait();
if (!task.success)
Debug.Log(task.text + " " + task.resultCode);
}
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0970d6d44fd28864389bbdd8dbddbf03
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,356 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace UnityEditor.ShaderGraph.Drawing
{
sealed class IndexSet : ICollection<int>
{
List<uint> m_Masks = new List<uint>();
public IndexSet() { }
public IndexSet(IEnumerable<int> indices)
{
foreach (var index in indices)
Add(index);
}
public IEnumerator<int> GetEnumerator()
{
for (var i = 0; i < m_Masks.Count; i++)
{
var mask = m_Masks[i];
if (mask == 0)
continue;
for (var j = 0; j < 32; j++)
{
if ((mask & (1 << j)) > 0)
yield return i * 32 + j;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void UnionWith(IEnumerable<int> other)
{
var otherSet = other as IndexSet;
if (otherSet != null)
{
UnionWith(otherSet);
}
else
{
foreach (var index in other)
Add(index);
}
}
public void UnionWith(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
m_Masks[i] |= other.m_Masks[i];
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
m_Masks.Add(other.m_Masks[i]);
}
public void IntersectWith(IEnumerable<int> other)
{
IntersectWith(other as IndexSet ?? new IndexSet(other));
}
public void IntersectWith(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
m_Masks[i] &= other.m_Masks[i];
}
public void ExceptWith(IEnumerable<int> other)
{
var otherSet = other as IndexSet;
if (otherSet != null)
{
ExceptWith(otherSet);
}
else
{
foreach (var index in other)
Remove(index);
}
}
public void ExceptWith(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
m_Masks[i] &= ~other.m_Masks[i];
}
public void SymmetricExceptWith(IEnumerable<int> other)
{
SymmetricExceptWith(other as IndexSet ?? new IndexSet(other));
}
public void SymmetricExceptWith(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
m_Masks[i] ^= other.m_Masks[i];
}
public bool IsSubsetOf(IEnumerable<int> other)
{
return IsSubsetOf(other as IndexSet ?? new IndexSet(other));
}
public bool IsSubsetOf(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
{
var mask = m_Masks[i];
var otherMask = other.m_Masks[i];
if ((mask & otherMask) != mask)
return false;
}
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
{
if (m_Masks[i] > 0)
return false;
}
return true;
}
public bool IsSupersetOf(IEnumerable<int> other)
{
return IsSupersetOf(other as IndexSet ?? new IndexSet(other));
}
public bool IsSupersetOf(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
{
var otherMask = other.m_Masks[i];
var mask = m_Masks[i];
if ((otherMask & mask) != otherMask)
return false;
}
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
{
if (other.m_Masks[i] > 0)
return false;
}
return true;
}
public bool IsProperSupersetOf(IEnumerable<int> other)
{
return IsProperSupersetOf(other as IndexSet ?? new IndexSet(other));
}
public bool IsProperSupersetOf(IndexSet other)
{
var isProper = false;
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
{
var mask = m_Masks[i];
var otherMask = other.m_Masks[i];
if ((otherMask & mask) != otherMask)
return false;
if ((~otherMask & mask) > 0)
isProper = true;
}
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
{
if (other.m_Masks[i] > 0)
return false;
}
if (!isProper)
{
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
{
if (m_Masks[i] > 0)
return true;
}
}
return isProper;
}
public bool IsProperSubsetOf(IEnumerable<int> other)
{
return IsProperSubsetOf(other as IndexSet ?? new IndexSet(other));
}
public bool IsProperSubsetOf(IndexSet other)
{
var isProper = false;
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
{
var mask = m_Masks[i];
var otherMask = other.m_Masks[i];
if ((mask & otherMask) != mask)
return false;
if ((~mask & otherMask) > 0)
isProper = true;
}
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
{
if (m_Masks[i] > 0)
return false;
}
if (!isProper)
{
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
{
if (other.m_Masks[i] > 0)
return true;
}
}
return isProper;
}
public bool Overlaps(IEnumerable<int> other)
{
var otherSet = other as IndexSet;
if (otherSet != null)
return Overlaps(otherSet);
foreach (var index in other)
{
if (Contains(index))
return true;
}
return false;
}
public bool Overlaps(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
{
if ((m_Masks[i] & other.m_Masks[i]) > 0)
return true;
}
return false;
}
public bool SetEquals(IEnumerable<int> other)
{
var otherSet = other as IndexSet;
if (otherSet != null)
return SetEquals(otherSet);
foreach (var index in other)
{
if (!Contains(index))
return false;
}
return true;
}
public bool SetEquals(IndexSet other)
{
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
{
if (m_Masks[i] != other.m_Masks[i])
return false;
}
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
{
if (m_Masks[i] > 0)
return false;
}
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
{
if (other.m_Masks[i] > 0)
return false;
}
return true;
}
public bool Add(int index)
{
var maskIndex = index >> 5;
var bitIndex = index & 31;
for (var i = m_Masks.Count; i <= maskIndex; i++)
m_Masks.Add(0);
var mask = (uint)1 << bitIndex;
var isNew = (m_Masks[maskIndex] & mask) == 0;
m_Masks[maskIndex] |= mask;
return isNew;
}
void ICollection<int>.Add(int index)
{
Add(index);
}
public void Clear()
{
m_Masks.Clear();
}
public bool Contains(int index)
{
var maskIndex = index >> 5;
var bitIndex = index & 31;
return maskIndex < m_Masks.Count && (m_Masks[maskIndex] & ((uint)1 << bitIndex)) > 0;
}
public void CopyTo(int[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(int index)
{
var maskIndex = index >> 5;
var bitIndex = index & 31;
if (maskIndex >= m_Masks.Count)
return false;
var mask = (uint)1 << bitIndex;
var exists = (m_Masks[maskIndex] & mask) > 0;
m_Masks[maskIndex] &= ~mask;
return exists;
}
public int Count
{
get
{
var count = 0;
foreach (var mask in m_Masks)
{
for (var j = 0; j < 32; j++)
{
if ((mask & (1 << j)) > 0)
count++;
}
}
return count;
}
}
public bool IsReadOnly
{
get { return false; }
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 41c67c52dd54464fa78d8ab286eb501b
timeCreated: 1514376310

View file

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
namespace UnityEditor.ShaderGraph
{
static class ListUtilities
{
// Ideally, we should build a non-yield return, struct version of Slice
public static IEnumerable<T> Slice<T>(this List<T> list, int start, int end)
{
for (int i = start; i < end; i++)
yield return list[i];
}
public static int RemoveAllFromRange<T>(this List<T> list, Predicate<T> match, int startIndex, int count)
{
// match behavior of RemoveRange
if ((startIndex < 0) || (count < 0))
throw new ArgumentOutOfRangeException();
int endIndex = startIndex + count;
if (endIndex > list.Count)
throw new ArgumentException();
int readIndex = startIndex;
int writeIndex = startIndex;
while (readIndex < endIndex)
{
T element = list[readIndex];
bool remove = match(element);
if (!remove)
{
// skip some work if nothing removed (especially if T is a large struct)
if (writeIndex < readIndex)
list[writeIndex] = element;
writeIndex++;
}
readIndex++;
}
// once we're done, we can remove the entries at the end in one operation
int numberRemoved = readIndex - writeIndex;
if (numberRemoved > 0)
{
list.RemoveRange(writeIndex, numberRemoved);
}
return numberRemoved;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8c48f9c41990b0242bcf63d2db521237
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,220 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEditor.Rendering;
using UnityEditor.ShaderGraph;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityEditor.Graphing.Util
{
class MessageManager
{
public interface IErrorLog
{
void LogError(string message, Object context);
void LogWarning(string message, Object context);
}
protected Dictionary<object, Dictionary<string, List<ShaderMessage>>> m_Messages =
new Dictionary<object, Dictionary<string, List<ShaderMessage>>>();
Dictionary<string, List<ShaderMessage>> m_Combined = new Dictionary<string, List<ShaderMessage>>();
public bool nodeMessagesChanged { get; private set; }
Dictionary<string, List<ShaderMessage>> m_FoundMessages;
public void AddOrAppendError(object errorProvider, string nodeId, ShaderMessage error)
{
if (!m_Messages.TryGetValue(errorProvider, out var messages))
{
messages = new Dictionary<string, List<ShaderMessage>>();
m_Messages[errorProvider] = messages;
}
List<ShaderMessage> messageList;
if (messages.TryGetValue(nodeId, out messageList))
{
messageList.Add(error);
}
else
{
messages[nodeId] = new List<ShaderMessage>() { error };
}
nodeMessagesChanged = true;
}
// Sort messages so errors come before warnings in the list
static int CompareMessages(ShaderMessage m1, ShaderMessage m2)
{
return m1.severity > m2.severity ? 1 : m2.severity > m1.severity ? -1 : 0;
}
public IEnumerable<KeyValuePair<string, List<ShaderMessage>>> GetNodeMessages()
{
var fixedNodes = new List<string>();
m_Combined.Clear();
foreach (var messageMap in m_Messages)
{
foreach (var messageList in messageMap.Value)
{
if (!m_Combined.TryGetValue(messageList.Key, out var foundList))
{
foundList = new List<ShaderMessage>();
m_Combined.Add(messageList.Key, foundList);
}
foundList.AddRange(messageList.Value);
if (messageList.Value.Count == 0)
{
fixedNodes.Add(messageList.Key);
}
}
// If all the messages from a provider for a node are gone,
// we can now remove it from the list since that will be reported in m_Combined
fixedNodes.ForEach(nodeId => messageMap.Value.Remove(nodeId));
}
foreach (var nodeList in m_Combined)
{
nodeList.Value.Sort(CompareMessages);
}
nodeMessagesChanged = false;
return m_Combined;
}
public void RemoveNode(string nodeId)
{
foreach (var messageMap in m_Messages)
{
nodeMessagesChanged |= messageMap.Value.Remove(nodeId);
}
}
public void ClearAllFromProvider(object messageProvider)
{
if (m_Messages.TryGetValue(messageProvider, out m_FoundMessages))
{
foreach (var messageList in m_FoundMessages)
{
nodeMessagesChanged |= messageList.Value.Count > 0;
messageList.Value.Clear();
}
m_FoundMessages = null;
}
}
public void ClearNodesFromProvider(object messageProvider, IEnumerable<AbstractMaterialNode> nodes)
{
if (m_Messages.TryGetValue(messageProvider, out m_FoundMessages))
{
foreach (var node in nodes)
{
if (m_FoundMessages.TryGetValue(node.objectId, out var messages))
{
nodeMessagesChanged |= messages.Count > 0;
messages.Clear();
}
}
}
}
public void ClearAll()
{
m_Messages.Clear();
m_Combined.Clear();
nodeMessagesChanged = false;
}
void DebugPrint()
{
StringBuilder output = new StringBuilder("MessageMap:\n");
foreach (var messageMap in m_Messages)
{
output.AppendFormat("\tFrom Provider {0}:\n", messageMap.Key.GetType());
foreach (var messageList in messageMap.Value)
{
output.AppendFormat("\t\tNode {0} has {1} messages:\n", messageList.Key, messageList.Value.Count);
foreach (var message in messageList.Value)
{
output.AppendFormat("\t\t\t{0}\n", message.message);
}
}
}
Debug.Log(output.ToString());
}
public static void Log(string path, ShaderMessage message, Object context, IErrorLog log)
{
var errString = $"{message.severity} in Graph at {path} on line {message.line}: {message.message}";
if (message.severity == ShaderCompilerMessageSeverity.Error)
{
log.LogError(errString, context);
}
else
{
log.LogWarning(errString, context);
}
}
public bool AnyError(Func<string, bool> nodeFilter = null)
{
if (m_Messages == null)
return false;
foreach (var kvp in m_Messages)
{
var errorProvider = kvp.Key;
var messageMap = kvp.Value;
foreach (var kvp2 in messageMap)
{
var nodeId = kvp2.Key;
List<ShaderMessage> messageList = kvp2.Value;
if ((nodeFilter == null) || nodeFilter(nodeId))
{
foreach (var message in messageList)
{
if (message.severity == ShaderCompilerMessageSeverity.Error)
{
return true;
}
}
}
}
}
return false;
}
public IEnumerable<string> ErrorStrings(Func<string, bool> nodeFilter = null, ShaderCompilerMessageSeverity severity = ShaderCompilerMessageSeverity.Error)
{
if (m_Messages == null)
yield break;
foreach (var kvp in m_Messages)
{
var errorProvider = kvp.Key;
var messageMap = kvp.Value;
foreach (var kvp2 in messageMap)
{
var nodeId = kvp2.Key;
if ((nodeFilter == null) || nodeFilter(nodeId))
{
List<ShaderMessage> messageList = kvp2.Value;
foreach (var message in messageList)
{
if (message.severity == severity)
{
yield return message.message;
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3536b8f2543044f72bb45c2e5dd889e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.Graphing.Util
{
class TypeMapper : IEnumerable<TypeMapping>
{
readonly Type m_FromBaseType;
readonly Type m_ToBaseType;
readonly Type m_FallbackType;
readonly Dictionary<Type, Type> m_Mappings = new Dictionary<Type, Type>();
public TypeMapper(Type fromBaseType = null, Type toBaseType = null, Type fallbackType = null)
{
if (fallbackType != null && toBaseType != null && !toBaseType.IsAssignableFrom(fallbackType))
throw new ArgumentException(string.Format("{0} does not implement or derive from {1}.", fallbackType.Name, toBaseType.Name), "fallbackType");
m_FromBaseType = fromBaseType ?? typeof(object);
m_ToBaseType = toBaseType;
m_FallbackType = fallbackType;
}
public void Add(TypeMapping mapping)
{
Add(mapping.fromType, mapping.toType);
}
public void Add(Type fromType, Type toType)
{
if (m_FromBaseType != typeof(object) && !m_FromBaseType.IsAssignableFrom(fromType))
{
throw new ArgumentException(string.Format("{0} does not implement or derive from {1}.", fromType.Name, m_FromBaseType.Name), "fromType");
}
if (m_ToBaseType != null && !m_ToBaseType.IsAssignableFrom(toType))
{
throw new ArgumentException(string.Format("{0} does not derive from {1}.", toType.Name, m_ToBaseType.Name), "toType");
}
m_Mappings[fromType] = toType;
}
public Type MapType(Type fromType)
{
Type toType = null;
while (toType == null && fromType != null && fromType != m_FromBaseType)
{
if (!m_Mappings.TryGetValue(fromType, out toType))
fromType = fromType.BaseType;
}
return toType ?? m_FallbackType;
}
public IEnumerator<TypeMapping> GetEnumerator()
{
return m_Mappings.Select(kvp => new TypeMapping(kvp.Key, kvp.Value)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f9c0c57b328abb94982f26ec960996d2
timeCreated: 1485161458
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,16 @@
using System;
namespace UnityEditor.Graphing.Util
{
class TypeMapping
{
public Type fromType { get; private set; }
public Type toType { get; private set; }
public TypeMapping(Type fromType, Type toType)
{
this.fromType = fromType;
this.toType = toType;
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 53ba6b433697da6468377c205573f728
timeCreated: 1485164640
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.Graphing.Util
{
static class UIUtilities
{
public static bool ItemsReferenceEquals<T>(this IList<T> first, IList<T> second)
{
if (first.Count != second.Count)
{
return false;
}
for (int i = 0; i < first.Count; i++)
{
if (!ReferenceEquals(first[i], second[i]))
{
return false;
}
}
return true;
}
public static int GetHashCode(params object[] objects)
{
return GetHashCode(objects.AsEnumerable());
}
public static int GetHashCode<T>(IEnumerable<T> objects)
{
var hashCode = 17;
foreach (var @object in objects)
{
hashCode = hashCode * 31 + (@object == null ? 79 : @object.GetHashCode());
}
return hashCode;
}
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
yield return item;
}
public static void Add<T>(this VisualElement visualElement, T elementToAdd, Action<T> action)
where T : VisualElement
{
visualElement.Add(elementToAdd);
action(elementToAdd);
}
public static IEnumerable<Type> GetTypesOrNothing(this Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch
{
return Enumerable.Empty<Type>();
}
}
public static Vector2 CalculateCentroid(IEnumerable<Vector2> nodePositions)
{
Vector2 centroid = Vector2.zero;
int count = 1;
foreach (var position in nodePositions)
{
centroid = centroid + (position - centroid) / count;
++count;
}
return centroid;
}
}
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 60ebb16e194464bce8a4975da8fd215a
timeCreated: 1476782702
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,56 @@
using System;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.ShaderGraph
{
static class ValueUtilities
{
public static string ToShaderString(this ShaderValueType type, string precisionToken = PrecisionUtil.Token)
{
switch (type)
{
case ShaderValueType.Boolean:
return precisionToken;
case ShaderValueType.Float:
return precisionToken;
case ShaderValueType.Float2:
return $"{precisionToken}2";
case ShaderValueType.Float3:
return $"{precisionToken}3";
case ShaderValueType.Float4:
return $"{precisionToken}4";
case ShaderValueType.Matrix2:
return $"{precisionToken}2x2";
case ShaderValueType.Matrix3:
return $"{precisionToken}3x3";
case ShaderValueType.Matrix4:
return $"{precisionToken}4x4";
case ShaderValueType.Integer:
return "int";
case ShaderValueType.Uint:
return "uint";
case ShaderValueType.Uint4:
return "uint4";
default:
return "Error";
}
}
public static int GetVectorCount(this ShaderValueType type)
{
switch (type)
{
case ShaderValueType.Float:
return 1;
case ShaderValueType.Float2:
return 2;
case ShaderValueType.Float3:
return 3;
case ShaderValueType.Float4:
return 4;
default:
return 0;
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9e9a618319be6a04bada8d206987f1e4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: