Files
2026-11-01 23:39:55 +02:00

90 lines
3.2 KiB
C#

using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using Unity.GraphAuthoring.Editor.ProviderSystem;
namespace UnityEditor.ShaderGraph.ProviderSystem
{
// Stateless filter that defers to ShaderGraph's keyword tables.
// Defined here rather than in com.unity.graph-authoring so it can reference NodeUtils,
// and serialized via [SerializeReference] in ExpressionProvider.
[Serializable]
sealed class ShaderGraphKeywordFilter : ExpressionProvider.IKeywordFilter
{
public bool IsReserved(string name)
=> NodeUtils.IsShaderLabKeyWord(name) || NodeUtils.IsShaderGraphKeyWord(name) || NodeUtils.IsHLSLKeyword(name);
}
[Serializable]
[ProviderModel(ExpressionProvider.kExpressionProviderKey)]
internal class ExpressionNode : ProviderNode
{
ExpressionProvider TypedProvider => Provider as ExpressionProvider;
string hlslFunctionName => $"ExpressionNode_{this.objectId}";
static readonly ShaderGraphKeywordFilter s_keywordFilter = new();
enum SupportedTypes { Vector1, Vector2, Vector3, Vector4 }
[EnumControl("Type")]
SupportedTypes SelectedType {
get => FromTypeName(TypedProvider.ShaderType);
set
{
TypedProvider.UpdateExpression(hlslFunctionName, Expression, ToTypeName(value), s_keywordFilter);
Refresh();
}
}
internal override bool requiresGeneration => true;
[TextControl(null, true)]
internal string Expression
{
get => TypedProvider.Expression;
set
{
if (value == null) // Text control can misbehave in undo redo scenarios; we'll need to visit that separately.
return;
TypedProvider.UpdateExpression(hlslFunctionName, value, TypedProvider.ShaderType, s_keywordFilter);
Refresh();
}
}
public ExpressionNode() { }
public override void UpdateNodeAfterDeserialization()
{
// Ensure the keyword filter is in place before base calls Refresh() → Provider.Reload().
// Handles fresh nodes and graphs saved before [SerializeReference] was introduced.
TypedProvider?.UpdateExpression(hlslFunctionName, TypedProvider.Expression, TypedProvider.ShaderType, s_keywordFilter);
base.UpdateNodeAfterDeserialization();
}
static SupportedTypes FromTypeName(string stype)
{
switch (stype)
{
default:
case "float": return SupportedTypes.Vector1;
case "float2": return SupportedTypes.Vector2;
case "float3": return SupportedTypes.Vector3;
case "float4": return SupportedTypes.Vector4;
}
}
static string ToTypeName(SupportedTypes etype)
{
switch (etype)
{
default:
case SupportedTypes.Vector1: return "float";
case SupportedTypes.Vector2: return "float2";
case SupportedTypes.Vector3: return "float3";
case SupportedTypes.Vector4: return "float4";
}
}
}
}