Editor/ShaderGraphPlus/Nodes/Utility/Logic/EnumFeatureSwitchNode.cs
namespace ShaderGraphPlus.Nodes;
[Title( "Enum Combo Switch" ), Category( "Utility/Logic" ), Icon( "alt_route" )]
[InternalNode]
public sealed class EnumFeatureSwitchNode : ShaderNodePlus, BaseNodePlus.IInitializeNode, IParameterNode, IBlackboardNode, IErroringNode
{
[Hide, JsonIgnore, Browsable( false )]
public override Color NodeTitleColor { get; set; } = ShaderGraphPlusTheme.NodeHeaderColors.LogicNode;
[Hide, JsonIgnore, Browsable( false )]
public override string Title => $"F_{_lastName.ToUpper().Replace( " ", "_" )}";
[Hide, JsonIgnore, Browsable( false )]
public string Name => $"F_{Feature.Name.ToUpper().Replace( " ", "_" )}";
[Hide, Browsable( false )]
public Guid ParameterIdentifier { get; set; }
[Hide, JsonIgnore, Browsable( false )]
public ShaderFeatureEnum Feature
{
get => GetFeature();
}
[Hide]
private List<IPlugIn> InternalInputs = new();
[Hide]
public override IEnumerable<IPlugIn> Inputs => InternalInputs;
[Hide, JsonIgnore]
int _lastHashCodeInputs = 0;
[Hide, JsonIgnore]
string _lastName = "";
public override void OnFrame()
{
var hashCodeInput = new HashCode();
hashCodeInput.Add( Feature );
var hc = hashCodeInput.ToHashCode();
if ( hc != _lastHashCodeInputs )
{
_lastHashCodeInputs = hc;
_lastName = Feature.Name;
CreateInputs();
Update();
}
}
public void InitializeNode()
{
OnNodeCreated();
}
private void OnNodeCreated()
{
CreateInputs();
Update();
}
public void CreateInputs()
{
var plugs = new List<IPlugIn>();
if ( !Feature.IsValid )
return;
if ( Feature.Options == null )
{
InternalInputs = new();
}
else
{
foreach ( var option in Feature.Options )
{
if ( !option.IsValid ) continue;
var info = new PlugInfo()
{
Id = option.Id,
Name = option.Name,
Type = typeof( object ),
DisplayInfo = new()
{
Name = option.Name,
Fullname = typeof( object ).FullName,
Description = ""
}
};
var plug = new BasePlugIn( this, info, info.Type );
//var oldPlug = InternalInputs.FirstOrDefault( x => x is BasePlugIn plugIn && plugIn.Info.Name == info.Name ) as BasePlugIn;
var oldPlug = InternalInputs.FirstOrDefault( x => x is BasePlugIn plugIn && plugIn.Info.Id == info.Id ) as BasePlugIn;
if ( oldPlug is not null )
{
oldPlug.Info.Name = info.Name;
oldPlug.Info.Type = info.Type;
oldPlug.Info.DisplayInfo = info.DisplayInfo;
if ( oldPlug.Type != plug.Type )
{
plugs.Add( plug );
}
else
{
plugs.Add( oldPlug );
}
}
else
{
plugs.Add( plug );
}
}
InternalInputs = plugs;
}
}
private ShaderFeatureEnumParameter GetFeatureParameter()
{
if ( Graph is ShaderGraphPlus graph )
{
var parameter = graph.FindParameter<ShaderFeatureEnumParameter>( ParameterIdentifier );
return parameter;
}
return new ShaderFeatureEnumParameter();
}
private ShaderFeatureEnum GetFeature()
{
var parameter = GetFeatureParameter();
if ( parameter.IsValid )
{
var featureEnum = new ShaderFeatureEnum
{
Name = parameter.Name,
Description = parameter.Description,
HeaderName = parameter.HeaderName,
Options = parameter.Options,
};
return featureEnum;
}
return new ShaderFeatureEnum();
}
[Output, Hide]
public NodeResult.Func Result => ( GraphCompiler compiler ) =>
{
var inputs = new List<NodeInput>();
foreach ( var input in Inputs )
{
if ( input.ConnectedOutput is null )
{
NodeInput nodeInput = default;
inputs.Add( nodeInput );
}
else
{
NodeInput nodeInput = new NodeInput { Identifier = input.ConnectedOutput.Node.Identifier, Output = input.ConnectedOutput.Identifier };
inputs.Add( nodeInput );
}
}
var previewIndex = GetFeatureParameter().PreviewIndex;
var result = compiler.ResultFeatureSwitch( inputs, Feature, previewIndex );
return result.IsValid ? result : new NodeResult( ResultType.Float, $"1.0f" );
};
public List<string> GetErrors()
{
var errors = new List<string>();
//foreach ( var option in Feature.Options )
//{
// if ( string.IsNullOrWhiteSpace( option ) )
// {
// errors.Add( $"element \"{Feature.Options.IndexOf( option )}\" of feature \"{Feature.Name}\" cannot have a blank name!" );
// }
//}
return errors;
}
}