using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor.Graphing; using UnityEngine; namespace UnityEditor.ShaderGraph { sealed partial class GraphData : ISerializationCallbackReceiver { public static class GraphValidation { public static void ValidateNode(AbstractMaterialNode node) { Type t = node.GetType(); node.ValidateNode(); if (!(node is BlockNode)) { bool disallowedByAnyTargets = false; bool disallowedByAllTargets = true; IEnumerable targets = node.owner.activeTargets; if (node.owner.isSubGraph) { targets = node.owner.allPotentialTargets; } foreach (var target in targets) { //if at least one target doesn't allow a node, it is considered invalid if (!target.IsNodeAllowedByTarget(t)) { disallowedByAnyTargets = true; node.isValid = false; node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by {target.displayName} implementation", Rendering.ShaderCompilerMessageSeverity.Warning); node.owner.m_UnsupportedTargets.Add(target); } //at least one target does allow node, not going to be explicitly set inactive else { disallowedByAllTargets = false; } } if (!disallowedByAnyTargets) { node.isValid = true; } //Set ActiveState based on if all targets disallow this node if (disallowedByAllTargets) { node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.ExplicitInactive); node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by any active targets, and will not be used in generation", Rendering.ShaderCompilerMessageSeverity.Warning); } else { node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.Implicit); } } } public static void ValidateGraph(GraphData graph) { graph.m_UnsupportedTargets.Clear(); GraphDataUtils.ApplyActionLeafFirst(graph, ValidateNode); } } } }