Major changes in the flow of code, implemented modularization of the code for maintainability
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
Ankitkumar Satapara
2026-04-22 15:03:20 +05:30
parent f9118a563c
commit b2fed489e2
9 changed files with 1224 additions and 873 deletions

View File

@@ -236,6 +236,22 @@ namespace Nodify.Calculator
}
public static OperationViewModel GetOperation(OperationInfoViewModel info)
{
// Route through the handler registry for all supported types
var handler = NodeHandlers.NodeHandlerRegistry.FindForCreate(info);
if (handler != null)
{
return handler.Create(info);
}
// Fallback for legacy types not yet migrated
return GetOperationLegacy(info);
}
/// <summary>
/// Legacy creation path — only used for Expression, Calculator, Group, Graph, and generic Normal types.
/// </summary>
internal static OperationViewModel GetOperationLegacy(OperationInfoViewModel info)
{
var input = info.Input.Select(i => new ConnectorViewModel
{
@@ -260,19 +276,6 @@ namespace Nodify.Calculator
Operation = info.Operation,
};
case OperationType.Expando:
var o = new ExpandoOperationViewModel
{
MaxInput = info.MaxInput,
MinInput = info.MinInput,
Title = info.Title,
Operation = info.Operation
};
o.Output.Add(new ConnectorViewModel { ConnectorColor = Color.DodgerBlue });
foreach (var ei in input) { ei.ConnectorColor = Color.DodgerBlue; }
o.Input.AddRange(input);
return o;
case OperationType.Group:
return new OperationGroupViewModel
{
@@ -286,476 +289,6 @@ namespace Nodify.Calculator
DesiredSize = new Size(420, 250)
};
case OperationType.API:
var _o = new APIOperationViewModel
{
Title = info.Title,
OperationType = info.OPType.ToUpper(),
ResponseModelClassName = info.ResponseModelClassName ?? string.Empty
};
var connectorViewModel = new ConnectorViewModel()
{
Title = "",
Shape = ConnectorShape.Triangle
};
var connectorViewModel2 = new ConnectorViewModel()
{
Title = "",
Shape = ConnectorShape.Triangle,
IsInput = false
};
_o.Output.Add(connectorViewModel2);
// Add typed response output based on ResponseModelClassName
if (!string.IsNullOrEmpty(info.ResponseModelClassName))
{
var responseClassName = info.ResponseModelClassName;
bool isList = responseClassName.StartsWith("List<") && responseClassName.EndsWith(">");
var innerType = isList ? responseClassName.Substring(5, responseClassName.Length - 6) : responseClassName;
// Use Grid shape for list/array types, Square for single model
_o.Output.Add(new ConnectorViewModel
{
Title = responseClassName,
IsInput = false,
Shape = isList ? ConnectorShape.Grid : ConnectorShape.Square,
ConnectorColor = isList ? Color.MediumSpringGreen : Color.MediumPurple,
DataType = responseClassName
});
}
else
{
// Default: generic object output
_o.Output.Add(new ConnectorViewModel
{
Title = "Response",
IsInput = false,
Shape = ConnectorShape.Circle,
ConnectorColor = Color.LimeGreen,
DataType = "object"
});
}
_o.Input.Add(connectorViewModel);
foreach (var item in input)
{
item.ConnectorColor = Color.LimeGreen;
_o.Input.Add(item);
}
return _o;
case OperationType.System:
if (info.sysOp == SystemOperations.FUNCTION)
{
var funcOp = new FunctionOperationViewModel
{
Title = info.Title,
FunctionName = info.Title
};
// Add flow connectors (triangle)
var funcFlowIn = new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle };
var funcFlowOut = new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false };
funcOp.Input.Add(funcFlowIn);
funcOp.Output.Add(funcFlowOut);
// Configure typed input/output parameters
funcOp.ConfigureParameters(info.FunctionInputs, info.FunctionOutputs);
return funcOp;
}
if (info.sysOp == SystemOperations.NEW_OBJECT)
{
var newObjOp = new SystemOperationViewModel
{
Title = info.Title,
SystemOperationType = SystemOperations.NEW_OBJECT
};
// Flow connectors
newObjOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
newObjOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
// Model class input (Square — user connects a model source)
foreach (var inp in input)
{
inp.Shape = ConnectorShape.Square;
inp.ConnectorColor = Color.MediumPurple;
newObjOp.Input.Add(inp);
}
// Model output (Square — returns the constructed object)
newObjOp.Output.Add(new ConnectorViewModel
{
Title = "Object",
IsInput = false,
Shape = ConnectorShape.Square,
ConnectorColor = Color.MediumPurple,
DataType = "object"
});
return newObjOp;
}
if (info.sysOp == SystemOperations.FOREACH)
{
var forEachOp = new ForEachOperationViewModel
{
Title = info.Title
};
// Flow connectors
forEachOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
forEachOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
// List data input (Grid shape for array/list types)
forEachOp.Input.Add(new ConnectorViewModel
{
Title = "List",
Shape = ConnectorShape.Grid,
ConnectorColor = Color.MediumSpringGreen
});
// "Loop Body" flow output — connects to nodes executed per iteration
forEachOp.Output.Add(new ConnectorViewModel
{
Title = "Loop Body",
IsInput = false,
Shape = ConnectorShape.Triangle,
ConnectorColor = Color.MediumSpringGreen
});
// "Current Item" data output — the element of the current iteration
forEachOp.Output.Add(new ConnectorViewModel
{
Title = "Current Item",
IsInput = false,
Shape = ConnectorShape.Circle,
ConnectorColor = Color.MediumSpringGreen,
DataType = "object"
});
// "Index" data output — current iteration index
forEachOp.Output.Add(new ConnectorViewModel
{
Title = "Index",
IsInput = false,
Shape = ConnectorShape.Circle,
ConnectorColor = Color.LightSkyBlue,
DataType = "int"
});
return forEachOp;
}
if (info.sysOp == SystemOperations.ASSERT)
{
var assertOp = new AssertOperationViewModel
{
Title = info.Title
};
// Flow connectors
assertOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
assertOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
// Data inputs
foreach (var inp in input)
{
inp.ConnectorColor = Color.Gold;
inp.Shape = ConnectorShape.Circle;
assertOp.Input.Add(inp);
}
// "Result" output — pass/fail boolean
assertOp.Output.Add(new ConnectorViewModel
{
Title = "Result",
IsInput = false,
Shape = ConnectorShape.Circle,
ConnectorColor = Color.Gold,
DataType = "bool"
});
return assertOp;
}
if (info.sysOp == SystemOperations.KNOT)
{
return new KnotOperationViewModel();
}
if (info.sysOp == SystemOperations.DEBUG)
{
var debugOp = new SystemOperationViewModel
{
Title = info.Title,
SystemOperationType = SystemOperations.DEBUG
};
// Flow connectors
debugOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
debugOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
// Data input
foreach (var inp in input)
{
inp.ConnectorColor = Color.LimeGreen;
debugOp.Input.Add(inp);
}
return debugOp;
}
if (info.sysOp == SystemOperations.AUTH)
{
var authOp = new AuthOperationViewModel
{
Title = info.Title,
SystemOperationType = SystemOperations.AUTH
};
// Add flow connectors (triangle)
var flowIn = new ConnectorViewModel()
{
Title = "",
Shape = ConnectorShape.Triangle
};
var flowOut = new ConnectorViewModel()
{
Title = "",
Shape = ConnectorShape.Triangle,
IsInput = false
};
authOp.Input.Add(flowIn);
authOp.Output.Add(flowOut);
// Add data input connectors
foreach (var inp in input)
{
inp.ConnectorColor = Color.Orange;
authOp.Input.Add(inp);
}
return authOp;
}
if (info.sysOp == SystemOperations.TAKE)
{
var takeOp = new TakeOperationViewModel
{
Title = info.Title,
SystemOperationType = SystemOperations.TAKE
};
// List input — accepts any shape but only list/array DataTypes
foreach (var item in input)
{
item.Shape = ConnectorShape.Circle;
item.ConnectorColor = Color.White;
item.IsCopyConnector = true;
item.IsTakeListConnector = true;
item.Title = "List";
takeOp.Input.Add(item);
}
// Nth index input (int type)
var nthConnector = new ConnectorViewModel
{
Title = "Nth",
Shape = ConnectorShape.Circle,
ConnectorColor = ConnectorViewModel.GetColorForType("int"),
DataType = "int"
};
takeOp.NthConnector = nthConnector;
takeOp.Input.Add(nthConnector);
return takeOp;
}
var sysOp = new SystemOperationViewModel
{
Title = info.Title,
SystemOperationType = info.sysOp,
IsSimpleVariable = info.IsSimpleVariable,
VariableType = info.VariableType ?? string.Empty,
ClassName = info.ClassName ?? string.Empty
};
if (info.sysOp == SystemOperations.COPY)
{
sysOp.Title = info.Title;
// Universal input — accepts any shape. Starts with no outputs.
foreach (var item in input)
{
item.Shape = ConnectorShape.Circle;
item.ConnectorColor = Color.White;
item.IsCopyConnector = true;
sysOp.Input.Add(item);
}
return sysOp;
}
if (info.sysOp == SystemOperations.SPLIT)
{
sysOp.Title = info.Title;
// Square input to accept model/class objects
foreach (var item in input)
{
item.Shape = ConnectorShape.Square;
item.ConnectorColor = Color.MediumPurple;
sysOp.Input.Add(item);
}
return sysOp;
}
if (info.sysOp == SystemOperations.GET_SET && info.IsModelNode && !info.IsSimpleVariable)
{
if (info.Title == "GET")
{
info.Output.Add("");
info.IsFlowNode = false;
}
else if (info.Title == "SET")
{
info.Input.Add("");
var customModelDir = System.IO.Path.Combine(ProjectManager.ProjectDirectory, "CustomModels");
Directory.CreateDirectory(customModelDir);
var flpath = System.IO.Path.Combine(customModelDir, info.ClassName + ".cs");
if (File.Exists(flpath))
{
var fileContent = File.ReadAllText(flpath);
var properties = GetPropertiesFromClass(fileContent);
Console.WriteLine("Properties found:");
foreach (var property in properties)
{
Console.WriteLine($"Property Name: {property.Name}, Type: {property.Type}");
}
info.IsFlowNode = true;
// Build the node with flow connectors first
var flTitle = $"{info.Title} {info.ClassName}";
sysOp.Title = flTitle;
// Flow connectors
sysOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
sysOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
// Input: Square connector for the class object
foreach (var item in input)
{
item.Shape = ConnectorShape.Square;
item.ConnectorColor = Color.MediumPurple;
sysOp.Input.Add(item);
}
// Outputs: Circle connectors per property, colored by type
foreach (var property in properties)
{
var propColor = ConnectorViewModel.GetColorForType(property.Type);
var propType = property.Type.ToLower();
sysOp.Output.Add(new ConnectorViewModel
{
Title = $"{property.Name} ({property.Type})",
IsInput = false,
Shape = ConnectorShape.Circle,
ConnectorColor = propColor,
DataType = propType
});
}
return sysOp;
}
info.IsFlowNode = true;
}
var flTitle2 = $"{info.Title} {info.ClassName}";
sysOp.Title = flTitle2;
}
if (info.sysOp == SystemOperations.GET_SET && info.IsSimpleVariable)
{
var varLabel = $"{info.Title} {info.ClassName} ({info.VariableType})";
sysOp.Title = varLabel;
var varType = info.VariableType.ToLower();
var varColor = ConnectorViewModel.GetColorForType(varType);
if (info.Title == "GET")
{
// GET variable: output the value, no flow needed
info.IsFlowNode = false;
// Flow connectors not needed, output connector with type color
sysOp.Output.Add(new ConnectorViewModel
{
Title = "Value",
IsInput = false,
Shape = ConnectorShape.Circle,
ConnectorColor = varColor,
DataType = varType
});
return sysOp;
}
else if (info.Title == "SET")
{
// SET variable: input connector for the value, flow node
info.IsFlowNode = true;
// Flow connectors
sysOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
sysOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
// Data input with type color
sysOp.Input.Add(new ConnectorViewModel
{
Title = "Value",
Shape = ConnectorShape.Circle,
ConnectorColor = varColor,
DataType = varType
});
return sysOp;
}
}
if (info.sysOp != SystemOperations.BEGIN &&
info.sysOp != SystemOperations.END &&
info.IsFlowNode)
{
var flowinputnode = new ConnectorViewModel()
{
Title = "",
Shape = ConnectorShape.Triangle
};
var flowoutputnode = new ConnectorViewModel()
{
Title = "",
Shape = ConnectorShape.Triangle,
IsInput = false
};
sysOp.Input.Add(flowinputnode);
sysOp.Output.Add(flowoutputnode);
}
// Determine connector shape & color based on system operation type
ConnectorShape dataShape;
System.Drawing.Color dataColor;
if (info.IsModelNode && !info.IsSimpleVariable)
{
dataShape = ConnectorShape.Square;
dataColor = Color.MediumPurple;
}
else if (info.IsSimpleVariable)
{
dataShape = ConnectorShape.Circle;
dataColor = Color.LightGreen;
}
else
{
dataShape = ConnectorShape.Circle;
dataColor = Color.Cyan;
}
foreach (var item in info.Output)
{
var isBeginEnd = info.sysOp == SystemOperations.BEGIN || info.sysOp == SystemOperations.END;
var out1 = new ConnectorViewModel()
{
Title = string.IsNullOrEmpty(item) ? "" : item,
IsInput = false,
Shape = isBeginEnd ? ConnectorShape.Triangle : dataShape,
ConnectorColor = isBeginEnd ? Color.DarkRed : dataColor,
};
sysOp.Output.Add(out1);
}
foreach (var item in input)
{
var isBeginEnd = info.sysOp == SystemOperations.BEGIN || info.sysOp == SystemOperations.END;
item.Shape = isBeginEnd ? ConnectorShape.Triangle : dataShape;
item.ConnectorColor = isBeginEnd ? Color.DarkRed : dataColor;
sysOp.Input.Add(item);
}
return sysOp;
default:
{
var op = new OperationViewModel