Major changes in the flow of code, implemented modularization of the code for maintainability
Some checks failed
Build / build (push) Has been cancelled
Some checks failed
Build / build (push) Has been cancelled
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user