Represents the result of compiling a shader graph node. Stores generated code, component count, constant flag, errors, and provides helpers to cast between float vector sizes and produce error/missing-input results.
namespace Editor.ShaderGraphExtras;
public enum NodeResultType
{
Bool,
Float,
Vector2,
Vector3,
Color,
Sampler,
Texture2DObject,
TextureCubemapObject
}
public struct NodeResult : IValid
{
public delegate NodeResult Func( GraphCompiler compiler );
public string Code { get; private set; }
public int Components { get; private set; }
public bool Constant { get; set; }
public string[] Errors { get; private init; }
public readonly bool IsValid => Components >= 0 && !string.IsNullOrWhiteSpace( Code );
public readonly string TypeName => Components > 1 ? $"float{Components}" : Components == 0 ? "bool" : "float";
public readonly Type ComponentType => Components switch
{
1 => typeof( float ),
2 => typeof( Vector2 ),
3 => typeof( Vector3 ),
4 => typeof( Color ),
_ => null,
};
public NodeResult( int components, string code, bool constant = false )
{
Components = components;
Code = code;
Constant = constant;
}
public NodeResult( NodeResultType type, string code, bool constant = false )
{
Components = type switch
{
NodeResultType.Bool => 1,
NodeResultType.Float => 1,
NodeResultType.Vector2 => 2,
NodeResultType.Vector3 => 3,
NodeResultType.Color => 4,
NodeResultType.Sampler => 0,
NodeResultType.Texture2DObject => 0,
NodeResultType.TextureCubemapObject => 0,
_ => 1
};
Code = code;
Constant = constant;
}
public static NodeResult Error( params string[] errors ) => new() { Errors = errors };
public static NodeResult MissingInput( string name ) => Error( $"Missing required input '{name}'." );
/// <summary>
/// "Cast" this result to different float types
/// </summary>
public string Cast( int components, float defaultValue = 0.0f )
{
if ( Components == components )
return Code;
if ( Components > components )
{
return $"{Code}.{"xyzw"[..components]}";
}
else if ( Components == 1 )
{
return $"float{components}( {string.Join( ", ", Enumerable.Repeat( Code, components ) )} )";
}
else
{
if ( !string.IsNullOrWhiteSpace( Code ) )
return $"float{components}( {Code}, {string.Join( ", ", Enumerable.Repeat( $"{defaultValue}", components - Components ) )} )";
return $"float{components}( {string.Join( ", ", Enumerable.Repeat( $"{defaultValue}", components ) )} )";
}
}
public override readonly string ToString()
{
return Code;
}
}