Added logs to track the issues, started doing changes based on the school api project
Some checks failed
Build / build (push) Has been cancelled
Some checks failed
Build / build (push) Has been cancelled
This commit is contained in:
@@ -198,7 +198,7 @@ namespace Nodify.Calculator.Execution.Handlers
|
||||
|
||||
var bodyNode = loopBodyConnection?.Input?.Operation;
|
||||
if (bodyNode != null)
|
||||
ctx.Executor.TraverseChainPublic(bodyNode, "end", ctx.Connections, new HashSet<string>(), true);
|
||||
ctx.Executor.ExecuteLinearChain(bodyNode, ctx.Connections);
|
||||
}
|
||||
ctx.Log($"[FOREACH] Loop completed. {array.Count} iterations executed.");
|
||||
}
|
||||
|
||||
@@ -56,13 +56,35 @@ namespace Nodify.Calculator.Execution.Resolvers
|
||||
{
|
||||
// Split's model input is the Square-shaped connector
|
||||
var modelInput = node.Input.FirstOrDefault(i => i.Shape == ConnectorShape.Square);
|
||||
if (modelInput == null) return null;
|
||||
if (modelInput == null)
|
||||
{
|
||||
ctx.Log("[SPLIT] No Square input connector found.", logType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
var modelJson = ctx.Read(modelInput);
|
||||
ctx.Log($"[SPLIT] Input JSON: {(modelJson?.Length > 120 ? modelJson.Substring(0, 120) + "..." : modelJson ?? "(null)")}");
|
||||
if (string.IsNullOrWhiteSpace(modelJson)) return null;
|
||||
|
||||
var propName = ResolverUtils.NormalizeConnectorName(outputConnector.Title);
|
||||
return ResolverUtils.ExtractJsonProperty(modelJson, propName);
|
||||
ctx.Log($"[SPLIT] Looking for property: \"{propName}\"");
|
||||
|
||||
// Try direct property extraction first
|
||||
var result = ResolverUtils.ExtractJsonProperty(modelJson, propName);
|
||||
|
||||
// If not found at top level, try unwrapping a "data" envelope
|
||||
if (result == null)
|
||||
{
|
||||
var dataInner = ResolverUtils.ExtractJsonProperty(modelJson, "data");
|
||||
if (!string.IsNullOrWhiteSpace(dataInner))
|
||||
{
|
||||
ctx.Log("[SPLIT] Property not found at top level, unwrapping \"data\" envelope...");
|
||||
result = ResolverUtils.ExtractJsonProperty(dataInner, propName);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Log($"[SPLIT] Resolved \"{propName}\" = {result ?? "(null)"}");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -208,24 +208,51 @@ namespace Nodify.Calculator
|
||||
var sourceOp = sourceConnector?.Operation;
|
||||
var srcNodeId = sourceOp?.NodeId;
|
||||
|
||||
OnLogMe?.Invoke($"[RESOLVE] Reading input \"{input.Title}\" ? source node \"{sourceOp?.Title}\" (connector \"{sourceConnector?.Title}\")");
|
||||
|
||||
// 1. Flow-executed nodes record their result in outputs[nodeId].
|
||||
if (srcNodeId != null && outputs.TryGetValue(srcNodeId, out var producedVal))
|
||||
{
|
||||
OnLogMe?.Invoke($"[RESOLVE] Found in outputs[{sourceOp?.Title}]: {(producedVal?.Length > 80 ? producedVal.Substring(0, 80) + "..." : producedVal)}");
|
||||
return producedVal;
|
||||
}
|
||||
|
||||
// 2. Generic dispatch for non-flow (sideband) nodes.
|
||||
if (sourceOp != null && sourceConnector != null)
|
||||
{
|
||||
OnLogMe?.Invoke($"[RESOLVE] No cached output for \"{sourceOp.Title}\", trying value resolvers...");
|
||||
var resCtx = new ValueResolutionContext(this, connections);
|
||||
foreach (var resolver in _valueResolvers)
|
||||
{
|
||||
if (!resolver.CanResolve(sourceOp, sourceConnector)) continue;
|
||||
OnLogMe?.Invoke($"[RESOLVE] Matched resolver: {resolver.GetType().Name}");
|
||||
var resolved = resolver.Resolve(sourceOp, sourceConnector, resCtx);
|
||||
if (!string.IsNullOrEmpty(resolved))
|
||||
{
|
||||
OnLogMe?.Invoke($"[RESOLVE] Resolver returned: {(resolved.Length > 80 ? resolved.Substring(0, 80) + "..." : resolved)}");
|
||||
return resolved;
|
||||
}
|
||||
OnLogMe?.Invoke($"[RESOLVE] Resolver returned null/empty, trying next...", logType.Warning);
|
||||
}
|
||||
OnLogMe?.Invoke($"[RESOLVE] No resolver produced a value for \"{sourceOp.Title}\"", logType.Warning);
|
||||
|
||||
// 2b. Fallback: if no resolver handled this non-flow node, try to recursively
|
||||
// resolve its first data input and pass the value through (generic passthrough).
|
||||
var fallbackInput = sourceOp.Input.FirstOrDefault(i => i.Shape != ConnectorShape.Triangle);
|
||||
if (fallbackInput != null)
|
||||
{
|
||||
OnLogMe?.Invoke($"[RESOLVE] Attempting generic passthrough for \"{sourceOp.Title}\"...");
|
||||
var passthrough = TryReadInputValue(fallbackInput, connections);
|
||||
if (!string.IsNullOrEmpty(passthrough))
|
||||
{
|
||||
OnLogMe?.Invoke($"[RESOLVE] Passthrough returned: {(passthrough.Length > 80 ? passthrough.Substring(0, 80) + "..." : passthrough)}");
|
||||
return passthrough;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3/4. Fall back to connector/default values.
|
||||
OnLogMe?.Invoke($"[RESOLVE] Falling back to connector Value: {sourceConnector?.Value}", logType.Warning);
|
||||
if (sourceConnector?.Value != null)
|
||||
return sourceConnector.Value.ToString();
|
||||
return input.Value.ToString();
|
||||
@@ -479,10 +506,43 @@ namespace Nodify.Calculator
|
||||
internal string GetResponsePublic(string url, string type) => GetResponse(url, type);
|
||||
|
||||
internal bool TraverseChainPublic(OperationViewModel node, string endNodeTitle,
|
||||
ICollection<ConnectionViewModel> connections,
|
||||
HashSet<string> visited, bool isExecute)
|
||||
ICollection<ConnectionViewModel> connections,
|
||||
HashSet<string> visited, bool isExecute)
|
||||
=> TraverseChain(node, endNodeTitle, connections, visited, isExecute);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a linear chain of nodes without requiring an "End" node.
|
||||
/// Used for loop bodies where the chain simply terminates at the last node.
|
||||
/// </summary>
|
||||
internal void ExecuteLinearChain(OperationViewModel startNode,
|
||||
ICollection<ConnectionViewModel> connections)
|
||||
{
|
||||
var visited = new HashSet<string>();
|
||||
var current = startNode;
|
||||
while (current != null)
|
||||
{
|
||||
if (visited.Contains(current.NodeId))
|
||||
break;
|
||||
visited.Add(current.NodeId);
|
||||
|
||||
SetNodeState(current, ExecutionState.Running);
|
||||
System.Threading.Thread.Sleep(AnimationDelayMs / 2);
|
||||
StartExecution(current, connections);
|
||||
SetNodeState(current, ExecutionState.Completed);
|
||||
|
||||
// Find next node via outgoing Triangle connection
|
||||
var outConn = connections.FirstOrDefault(c => c.Output?.Operation == current && c.Output.Shape == ConnectorShape.Triangle);
|
||||
if (outConn?.Input?.Operation == null)
|
||||
break;
|
||||
|
||||
SetConnectionActive(outConn, true);
|
||||
System.Threading.Thread.Sleep(AnimationDelayMs);
|
||||
SetConnectionActive(outConn, false);
|
||||
|
||||
current = outConn.Input.Operation;
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddNewModelPublic(OperationInfoViewModel model)
|
||||
=> editorViewModel.Calculator.OperationsMenu.AddNewModel(model);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user