Fixed foreach loop connection input and output types
Some checks failed
Build / build (push) Has been cancelled
Some checks failed
Build / build (push) Has been cancelled
This commit is contained in:
@@ -39,6 +39,9 @@ namespace Nodify.Calculator
|
|||||||
|
|
||||||
// Dynamic Take node: adapt connectors when a list connects
|
// Dynamic Take node: adapt connectors when a list connects
|
||||||
if (!IsLoading) HandleTakeNodeConnected(c);
|
if (!IsLoading) HandleTakeNodeConnected(c);
|
||||||
|
|
||||||
|
// Dynamic ForEach node: adapt Current Item output based on list type
|
||||||
|
if (!IsLoading) HandleForEachNodeConnected(c);
|
||||||
})
|
})
|
||||||
.WhenRemoved(c =>
|
.WhenRemoved(c =>
|
||||||
{
|
{
|
||||||
@@ -68,6 +71,9 @@ namespace Nodify.Calculator
|
|||||||
|
|
||||||
// Dynamic Take node: reset on disconnect
|
// Dynamic Take node: reset on disconnect
|
||||||
HandleTakeNodeDisconnected(c);
|
HandleTakeNodeDisconnected(c);
|
||||||
|
|
||||||
|
// Dynamic ForEach node: reset Current Item output on disconnect
|
||||||
|
HandleForEachNodeDisconnected(c);
|
||||||
});
|
});
|
||||||
|
|
||||||
Operations.WhenAdded(x =>
|
Operations.WhenAdded(x =>
|
||||||
@@ -636,6 +642,115 @@ namespace Nodify.Calculator
|
|||||||
takeOp.Output.Remove(o);
|
takeOp.Output.Remove(o);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleForEachNodeConnected(ConnectionViewModel c)
|
||||||
|
{
|
||||||
|
// Find the ForEach node's Grid (List) input connector
|
||||||
|
ConnectorViewModel forEachListInput = null;
|
||||||
|
ConnectorViewModel sourceConnector = null;
|
||||||
|
|
||||||
|
if (c.Input.Shape == ConnectorShape.Grid && c.Input.IsInput && c.Input.Operation is ForEachOperationViewModel)
|
||||||
|
{
|
||||||
|
forEachListInput = c.Input;
|
||||||
|
sourceConnector = c.Output;
|
||||||
|
}
|
||||||
|
else if (c.Output.Shape == ConnectorShape.Grid && c.Output.IsInput && c.Output.Operation is ForEachOperationViewModel)
|
||||||
|
{
|
||||||
|
forEachListInput = c.Output;
|
||||||
|
sourceConnector = c.Input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forEachListInput == null || sourceConnector == null) return;
|
||||||
|
|
||||||
|
var forEachOp = (ForEachOperationViewModel)forEachListInput.Operation;
|
||||||
|
|
||||||
|
// Determine the element type from the source connector's DataType
|
||||||
|
var dataType = sourceConnector.DataType ?? "";
|
||||||
|
string elementType;
|
||||||
|
bool isList = dataType.StartsWith("List<") && dataType.EndsWith(">");
|
||||||
|
if (isList)
|
||||||
|
elementType = dataType.Substring(5, dataType.Length - 6);
|
||||||
|
else
|
||||||
|
elementType = dataType;
|
||||||
|
|
||||||
|
// Check if the element type is a model (custom class) or a primitive
|
||||||
|
var primitiveTypes = new[] { "string", "int", "double", "bool", "float", "decimal", "long", "object", "" };
|
||||||
|
bool isModel = !primitiveTypes.Contains(elementType.ToLower());
|
||||||
|
|
||||||
|
// Remove existing "Current Item" output (non-triangle, non-Index)
|
||||||
|
var currentItemOutputs = forEachOp.Output
|
||||||
|
.Where(o => o.Shape != ConnectorShape.Triangle && o.Title != "Index")
|
||||||
|
.ToList();
|
||||||
|
foreach (var o in currentItemOutputs)
|
||||||
|
{
|
||||||
|
DisconnectConnector(o);
|
||||||
|
forEachOp.Output.Remove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isModel)
|
||||||
|
{
|
||||||
|
// Model type: Square connector so it can connect to Split nodes
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = elementType,
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Square,
|
||||||
|
ConnectorColor = System.Drawing.Color.MediumPurple,
|
||||||
|
DataType = elementType
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Primitive type: Circle connector with type-appropriate color
|
||||||
|
var color = ConnectorViewModel.GetColorForType(elementType);
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = string.IsNullOrEmpty(elementType) ? "Current Item" : $"Item ({elementType})",
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Circle,
|
||||||
|
ConnectorColor = color,
|
||||||
|
DataType = elementType
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleForEachNodeDisconnected(ConnectionViewModel c)
|
||||||
|
{
|
||||||
|
ConnectorViewModel forEachListInput = null;
|
||||||
|
|
||||||
|
if (c.Input.Shape == ConnectorShape.Grid && c.Input.IsInput && c.Input.Operation is ForEachOperationViewModel)
|
||||||
|
forEachListInput = c.Input;
|
||||||
|
else if (c.Output.Shape == ConnectorShape.Grid && c.Output.IsInput && c.Output.Operation is ForEachOperationViewModel)
|
||||||
|
forEachListInput = c.Output;
|
||||||
|
|
||||||
|
if (forEachListInput == null) return;
|
||||||
|
|
||||||
|
var forEachOp = (ForEachOperationViewModel)forEachListInput.Operation;
|
||||||
|
|
||||||
|
// Check if input still has a connection
|
||||||
|
var stillConnected = Connections.Any(con => con.Input == forEachListInput || con.Output == forEachListInput);
|
||||||
|
if (stillConnected) return;
|
||||||
|
|
||||||
|
// Remove existing "Current Item" output (non-triangle, non-Index)
|
||||||
|
var currentItemOutputs = forEachOp.Output
|
||||||
|
.Where(o => o.Shape != ConnectorShape.Triangle && o.Title != "Index")
|
||||||
|
.ToList();
|
||||||
|
foreach (var o in currentItemOutputs)
|
||||||
|
{
|
||||||
|
DisconnectConnector(o);
|
||||||
|
forEachOp.Output.Remove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset to default Circle "Current Item" output
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = "Current Item",
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Circle,
|
||||||
|
ConnectorColor = System.Drawing.Color.MediumSpringGreen,
|
||||||
|
DataType = "object"
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user