NodePipeline/NodePipeline.Engine/obj/Generated/NodePipeline.Engine.Analyzers/NodePipeline.Engine.Analyzers.CodeGeneration.NodeProviderGenerator/GeneratedNodeFactory.g.cs
2026-01-02 20:55:25 +03:00

278 lines
12 KiB
C#

using System.Globalization;
using NodePipeline.Abstractions;
using NodePipeline.Abstractions.Exceptions.NodeFactory;
using NodePipeline.Abstractions.Interfaces;
using NodePipeline.Abstractions.Interfaces.Nodes;
using NodePipeline.Configuration.Abstractions.Models.Execute;
using NodePipeline.Engine.Abstractions;
using NodePipeline.Engine.NodeFields;
using NodePipeline.Engine.Utils;
using NodePipeline.Engine.Abstractions.Validation;
// ReSharper disable CheckNamespace
// ReSharper disable ConvertTypeCheckPatternToNullCheck
// ReSharper disable RedundantCast
// ReSharper disable RedundantNameQualifier
// ReSharper disable ReturnTypeCanBeNotNullable
// ReSharper disable UnusedMember.Local
// ReSharper disable UnusedParameter.Local
#nullable enable
namespace NodePipeline.Engine.Generated;
public sealed class GeneratedNodeFactory : INodeFactory
{
public Dictionary<string, Func<INode>> NodeFactories { get; set; } = new();
public IPipelineLocalizationProvider PipelineLocalizationProvider { get; set; } = new PipelineLocalizationProvider();
public INode CreateNode(string pipelineId, NodeConfig config)
{
INode? node;
if (NodeFactories.TryGetValue(config.Type, out var f))
{
node = f();
InitializeNodeFields(pipelineId, node, config.Id);
return node;
}
switch (config.Type)
{
default:
throw new NodeNotFoundException(pipelineId, config.Type, config.Id);
}
InitializeNodeFields(pipelineId, node, config.Id);
return node ?? throw new NodeWasNotInitializedException(pipelineId, config.Type, config.Id);
}
private void InitializeNodeFields(string pipelineId, INode node, string nodeId)
{
switch (node)
{
default:
throw new NodeNotFoundException(pipelineId, node.GetType().Name, nodeId);
}
}
public IEnumerable<string> GetParameterCodes(string nodeType)
{
switch (nodeType)
{
default:
throw new NodeTypeNotFoundException(nodeType);
}
}
public object? ReadParameterValue(string pipelineId, string nodeId, string nodeType, string parameterName, string? valueString)
{
switch (nodeType)
{
default:
throw new NodeTypeNotFoundException(nodeType);
}
}
public Dictionary<NodePortKey, NodePortInfo> GetAllPorts(string pipelineId, HashSet<string> nodeTypes, Dictionary<string, IEnumerable<string>> nodeList)
{
var result = new Dictionary<NodePortKey, NodePortInfo>();
foreach (var nodeType in nodeTypes)
{
if (!nodeList.TryGetValue(nodeType, out var ids)) continue;
foreach (var nodeId in ids)
{
var ports = GetNodePorts(pipelineId, nodeType, nodeId);
foreach (var kv in ports) result.Add(kv.Key, kv.Value);
}
}
return result;
}
public IEnumerable<NodePortInfo> GetNodeInputPorts(string pipelineId, string nodeType, string nodeId)
{
var ports = GetNodePorts(pipelineId, nodeType, nodeId);
foreach (var kv in ports) if (kv.Key.Input) yield return kv.Value;
}
private Dictionary<NodePortKey, NodePortInfo> GetNodePorts(string pipelineId, string nodeType, string nodeId)
{
switch (nodeType)
{
default:
throw new NodeNotFoundException(pipelineId, nodeType, nodeId);
}
}
private IReadOnlyDictionary<string, object> GetNodeOutputs(string pipelineId, string nodeId, INode node)
{
switch (node)
{
default:
throw new NodeNotFoundException(pipelineId, node.GetType().Name, nodeId);
}
}
public void ConnectPorts<TNode>(string pipelineId, TNode node, string nodeId, Dictionary<string, InputSource> inputs, IReadOnlyDictionary<string, INode> createdNodes) where TNode : INode
{
switch (node)
{
default:
throw new NodeNotFoundException(pipelineId, node.GetType().Name, nodeId);
}
}
private PortConnectionInfo? TryConnectPorts<T>(string pipelineId, string nodeId, string nodeType, INodeField<T>? nodeInput, string nodeInputName, Dictionary<string, InputSource> inputs, string inputKey, IReadOnlyDictionary<string, INode> createdNodes, bool isRequired = false) where T : notnull
{
if (!inputs.TryGetValue(inputKey, out var connection))
return !isRequired ? null : throw new InputPortHasNoRequiredConnectionException(pipelineId, inputKey, nodeId, nodeType);
var fromNodeId = connection.NodeId;
var fromPortName = connection.OutputName;
if (nodeInput == null) throw new InputPortNotFoundException(pipelineId, inputKey, nodeId, nodeType);
if (!createdNodes.TryGetValue(fromNodeId, out var fromNode)) throw new OutputPortNodeNotFoundException(pipelineId, fromNodeId, nodeId);
var outputs = GetNodeOutputs(pipelineId, fromNodeId, fromNode);
var outputFieldKey = NodeFieldCodeGenerator.GenerateFieldCode(fromNodeId, fromPortName, FieldDirection.Output);
if (!outputs.TryGetValue(outputFieldKey, out var outputFieldObj)) throw new OutputPortNotFoundException(pipelineId, fromPortName, fromNodeId, nodeId);
var fromNodeType = GetNodeType(pipelineId, fromNodeId, fromNode);
if (outputFieldObj is INodeField<T> outStrict && nodeInput is INodeField<T> inStrict)
{
PortConnector.ConnectStatic(outStrict, inStrict);
return new PortConnectionInfo(true, outputFieldObj, fromPortName, fromNodeType, fromNodeId);
}
return new PortConnectionInfo(false, outputFieldObj, fromPortName, fromNodeType, fromNodeId);
}
private void ConnectPortsStruct<T>(string pipelineId, string nodeId,string nodeType, INodeField<T>? nodeInput, string nodeInputName, Dictionary<string, InputSource> inputs,
string inputKey, IReadOnlyDictionary<string, INode> createdNodes, bool disallowNullableOutput = false, bool isRequired = false)
where T : struct
{
var portConnectionInfo = TryConnectPorts(pipelineId, nodeId, nodeType, nodeInput, nodeInputName, inputs, inputKey, createdNodes, isRequired);
if (portConnectionInfo is null || portConnectionInfo.Connected) return;
if (typeof(T).IsValueType && portConnectionInfo.OutputFieldObj is INodeField<T?> outputField)
{
PortConnector.ConnectRuntimeFromNullableStruct(outputField, nodeInput!,
nodeId, inputKey, portConnectionInfo.FromNodeId, portConnectionInfo.FromPortName);
return;
}
if (portConnectionInfo.OutputFieldObj is INodeField<T?> outNullable && nodeInput is INodeField<T?> inNullable)
{
PortConnector.ConnectRuntimeBothNullable(outNullable, inNullable);
return;
}
if (portConnectionInfo.OutputFieldObj is INodeField<T?> outNToStrict && nodeInput != null)
{
if (disallowNullableOutput)
{
throw new NonNullableInputRestrictsConnectionToNullableOutputException(pipelineId, nodeId, nodeType, inputKey, portConnectionInfo.FromPortName, portConnectionInfo.FromNodeId);
}
PortConnector.ConnectRuntimeFromNullableStruct(outNToStrict, nodeInput, currentNodeId: nodeId,
inputPortName: inputKey, sourceNodeId: portConnectionInfo.FromNodeId, outputPortName: portConnectionInfo.FromPortName);
return;
}
if (portConnectionInfo.OutputFieldObj is INodeField<T> outStrictToN && nodeInput is INodeField<T?> inNullable2)
{
PortConnector.ConnectRuntimeToNullableStruct(outStrictToN, inNullable2);
return;
}
throw new PortsTypeMismatchException(pipelineId, inputKey, nodeType, nodeId,
portConnectionInfo.FromPortName, portConnectionInfo.FromNodeType, portConnectionInfo.FromNodeId);
}
private void ConnectPortsClass<T>(string pipelineId, string nodeId,string nodeType, INodeField<T>? nodeInput, string nodeInputName, Dictionary<string, InputSource> inputs,
string inputKey, IReadOnlyDictionary<string, INode> createdNodes, bool disallowNullableOutput = false, bool isRequired = false)
where T : class
{
var portConnectionInfo = TryConnectPorts(pipelineId, nodeId, nodeType, nodeInput, nodeInputName, inputs, inputKey, createdNodes, isRequired);
if (portConnectionInfo is null || portConnectionInfo.Connected) return;
if (!typeof(T).IsValueType && portConnectionInfo.OutputFieldObj is INodeField<T?> outputField)
{
PortConnector.ConnectRuntimeFromNullableClass(outputField, nodeInput!,
nodeId, inputKey, portConnectionInfo.FromNodeId, portConnectionInfo.FromPortName);
return;
}
if (portConnectionInfo.OutputFieldObj is INodeField<T?> outNullable && nodeInput is INodeField<T?> inNullable)
{
PortConnector.ConnectRuntimeBothNullable(outNullable, (INodeField<T?>)inNullable);
return;
}
if (portConnectionInfo.OutputFieldObj is INodeField<T?> outNToStrict && nodeInput != null)
{
if (disallowNullableOutput)
{
throw new NonNullableInputRestrictsConnectionToNullableOutputException(pipelineId, nodeId, nodeType, inputKey, portConnectionInfo.FromPortName, portConnectionInfo.FromNodeId);
}
PortConnector.ConnectRuntimeFromNullableClass(outNToStrict, nodeInput, currentNodeId: nodeId,
inputPortName: inputKey, sourceNodeId: portConnectionInfo.FromNodeId, outputPortName: portConnectionInfo.FromPortName);
return;
}
if (portConnectionInfo.OutputFieldObj is INodeField<T> outStrictToN && nodeInput is INodeField<T?> inNullable2)
{
PortConnector.ConnectRuntimeToNullableClass(outStrictToN, (INodeField<T?>)inNullable2);
return;
}
throw new PortsTypeMismatchException(pipelineId, inputKey, nodeType, nodeId,
portConnectionInfo.FromPortName, portConnectionInfo.FromNodeType, portConnectionInfo.FromNodeId);
}
private static T? ParseParameter<T>(string? valueString)
{
var type = typeof(T);
if (type == typeof(string)) return valueString is not null ? (T)(object)valueString : default;
if (string.IsNullOrEmpty(valueString)) return default;
if (type == typeof(int)) return (T)(object)int.Parse(valueString);
if (type == typeof(double)) return (T)(object)double.Parse(valueString, CultureInfo.InvariantCulture);
if (type == typeof(bool)) return (T)(object)bool.Parse(valueString);
throw new NotSupportedException(type.Name);
}
public object GetParameterDefaultValue(string nodeType, string parameterName)
{
switch (nodeType)
{
default:
throw new NodeParameterNotFoundException(parameterName, nodeType);
}
}
private static T? GetDefaultValue<T>()
{
var type = typeof(T);
if (type == typeof(string)) return (T)(object)string.Empty;
if (type == typeof(int)) return (T)(object)0;
if (type == typeof(double)) return (T)(object)0d;
if (type == typeof(decimal)) return (T)(object)0m;
if (type == typeof(bool)) return (T)(object)false;
if (type == typeof(Guid)) return (T)(object)Guid.Empty;
if (type.IsEnum) return default;
throw new NotSupportedException(type.Name);
}
public void SetNodeParametersValues<TNode>(string pipelineId, TNode node, string nodeId, Dictionary<string, object?> parameters) where TNode : INode
{
switch (node)
{
default:
throw new NodeNotFoundException(pipelineId, node.GetType().Name, nodeId);
}
}
private static string GetNodeType(string pipelineId, string nodeId, INode node)
{
switch (node)
{
default:
throw new NodeNotFoundException(pipelineId, node.GetType().Name, nodeId);
}
}
private record PortConnectionInfo(bool Connected, object? OutputFieldObj, string FromPortName, string FromNodeType, string FromNodeId);
}
#nullable restore