10#include "../TaskSystem/TaskGraphTypes.h"
11#include "../system/system_utils.h"
29 std::vector<ValidationError> errors;
34 if (!
options.initialBlackboardJson.empty())
40 if (
tmpl.EntryPointID < 0)
44 outTracer.RecordError(-1,
"",
"No entry point defined",
"Critical");
45 outTracer.RecordExecutionCompleted(
false,
"Graph has no entry point");
55 outTracer.RecordNodeEntered(currentNodeId,
"EntryPoint",
"EntryPoint");
65 std::string
msg =
"Node " + std::to_string(currentNodeId) +
" not found";
76 std::string
msg =
"Potential infinite loop detected at node " +
77 (
nodeDef->NodeName.empty() ? std::to_string(currentNodeId) :
nodeDef->NodeName);
91 outTracer.RecordNodeEntered(currentNodeId,
"EntryPoint",
"EntryPoint");
96 outTracer.RecordExecutionBlocked(currentNodeId,
"EntryPoint has no outgoing connection");
98 "EntryPoint has no outgoing execution link",
122 outTracer.RecordNodeEntered(currentNodeId,
nodeDef->NodeName,
"AtomicTask");
126 outTracer.RecordExecutionBlocked(currentNodeId,
"No outgoing link from AtomicTask");
167 auto it =
nodeDef->Parameters.find(
"subgraph_path");
177 outTracer.RecordError(currentNodeId,
nodeDef->NodeName,
"SubGraph path is empty");
194 std::string
msg =
"Maximum simulation steps exceeded - possible infinite loop";
200 if (
options.validateBranchPaths)
213 outTracer.RecordExecutionCompleted(errors.empty(),
214 std::to_string(
stepCount) +
" steps executed, " +
215 std::to_string(errors.size()) +
" validation issues found");
230 tracer.RecordNodeEntered(currentNodeId,
node->NodeName,
"");
243 tracer.RecordNodeEntered(nodeId,
node->NodeName,
"Branch");
247 bool conditionResult =
true;
248 tracer.RecordConditionEvaluated(nodeId,
"condition", conditionResult);
252 tracer.RecordBranchTaken(nodeId,
"True", -1);
257 tracer.RecordBranchTaken(nodeId,
"False", -1);
271 tracer.RecordNodeEntered(nodeId,
node->NodeName,
"Switch");
286 tracer.RecordNodeEntered(nodeId,
node->NodeName,
"VSSequence");
299 tracer.RecordNodeEntered(nodeId,
node->NodeName,
"While");
300 tracer.RecordBranchTaken(nodeId,
"Loop", -1);
307 const std::string& pinName)
314 for (
const auto&
link :
tmpl.ExecConnections)
316 if (
link.SourceNodeID == nodeId &&
link.SourcePinName == pinName)
318 return link.TargetNodeID;
341 "Branch node missing 'Then' connection",
349 "Branch node missing 'Else' connection",
364 for (
const auto&
link :
tmpl.DataConnections)
372 "Data connection references non-existent node",
391 if (
tmpl.EntryPointID >= 0)
399 if (!
pair.second &&
pair.first != -1)
407 "Node is unreachable from entry point",
426 for (
const auto&
link :
tmpl.ExecConnections)
428 if (
link.SourceNodeID == nodeId)
450 "While loop has no 'Completed' exit path",
478 if (
tmpl.EntryPointID >= 0)
509 std::string
indent(depth * 2,
' ');
510 std::string
depthMarker = (depth > 0) ? (
"<- [EVAL] ") :
"";
516 tracer.RecordDataPinResolved(nodeId,
"Value",
518 " (Key: " +
node->BBKey +
")");
525 tracer.RecordDataPinResolved(nodeId,
"Result",
527 " (Operator: " +
node->MathOperator +
")");
533 for (
const auto&
conn :
tmpl.DataConnections)
535 if (
conn.TargetNodeID == nodeId)
537 if (
conn.TargetPinName ==
"A")
544 else if (
conn.TargetPinName ==
"B")
558 tracer.RecordDataPinResolved(nodeId,
"Input",
560 " (Key: " +
node->BBKey +
")");
563 for (
const auto&
conn :
tmpl.DataConnections)
565 if (
conn.TargetNodeID == nodeId &&
conn.TargetPinName ==
"Value")
581 for (
const auto&
conn :
tmpl.DataConnections)
583 if (
conn.TargetNodeID == nodeId)
586 conn.TargetNodeID,
conn.TargetPinName,
ComponentTypeID GetComponentTypeID_Static()
Simulates graph execution without runtime side effects.
void TraceDataPinEvaluation(int32_t nodeId, const TaskGraphTemplate &tmpl, GraphExecutionTracer &tracer, int32_t depth=0)
Recursively traces data pin evaluation for pure data nodes.
int32_t GetNextNodeId(const TaskGraphTemplate &tmpl, int32_t nodeId, const std::string &pinName)
Gets the next node ID from an execution link.
std::set< int32_t > m_tracedDataNodes
Track data nodes already traced to prevent infinite recursion.
int32_t HandleWhileSimulation(const TaskGraphTemplate &tmpl, int32_t nodeId, LocalBlackboard &blackboard, GraphExecutionTracer &tracer)
Simulates a While loop execution.
void TraceDataConnection(int32_t sourceNodeId, const std::string &sourcePinName, int32_t targetNodeId, const std::string &targetPinName, const TaskGraphTemplate &tmpl, GraphExecutionTracer &tracer, int32_t depth)
Traces evaluation of a single data connection.
std::vector< int32_t > m_pathStack
Current execution path.
std::map< int32_t, int32_t > m_visitCount
Track visits per node to detect loops.
void BuildNodeReachabilityMap(const TaskGraphTemplate &tmpl, std::map< int32_t, bool > &reachable)
bool DetectPotentialInfiniteLoops(const TaskGraphTemplate &tmpl, std::vector< ValidationError > &outErrors)
Checks for potential infinite loops or cycles.
int32_t HandleSequenceSimulation(const TaskGraphTemplate &tmpl, int32_t nodeId, LocalBlackboard &blackboard, GraphExecutionTracer &tracer)
Simulates a Sequence node execution.
std::vector< ValidationError > SimulateExecution(const TaskGraphTemplate &tmpl, const SimulationOptions &options, GraphExecutionTracer &outTracer)
Simulates execution of a graph template.
int32_t SimulateStep(const TaskGraphTemplate &tmpl, int32_t currentNodeId, LocalBlackboard &blackboard, const SimulationOptions &options, GraphExecutionTracer &tracer)
int32_t HandleBranchSimulation(const TaskGraphTemplate &tmpl, int32_t nodeId, LocalBlackboard &blackboard, GraphExecutionTracer &tracer)
Simulates a Branch node execution.
bool ValidateAllBranches(const TaskGraphTemplate &tmpl, std::vector< ValidationError > &outErrors)
Validates all branch nodes in a graph.
int32_t HandleSwitchSimulation(const TaskGraphTemplate &tmpl, int32_t nodeId, LocalBlackboard &blackboard, GraphExecutionTracer &tracer)
Simulates a Switch node execution.
void MarkReachableNodes(const TaskGraphTemplate &tmpl, int32_t nodeId, std::map< int32_t, bool > &reachable)
GraphExecutionSimulator()
~GraphExecutionSimulator()
bool ValidateConditionExpression(int32_t nodeId, const std::string &expression)
Validates a condition expression.
bool ValidateDataConnections(const TaskGraphTemplate &tmpl, std::vector< ValidationError > &outErrors)
Validates all data connections in a graph.
std::vector< int32_t > FindUnreachableNodes(const TaskGraphTemplate &tmpl, std::vector< ValidationError > &outErrors)
Checks for unreachable nodes.
Records execution trace during graph simulation.
Simple map-based blackboard for task graph runtime state.
Immutable, shareable task graph asset.
< Provides AssetID and INVALID_ASSET_ID
@ Literal
Value is embedded directly in the template.
@ AtomicTask
Leaf node that executes a single atomic task.
@ While
Conditional loop (Loop / Completed exec outputs)
@ SubGraph
Sub-graph call (SubTask)
@ DoOnce
Single-fire execution (reset via Reset pin)
@ Delay
Timer (Completed exec output after N seconds)
@ GetBBValue
Data node – reads a Blackboard key.
@ MathOp
Data node – arithmetic operation (+, -, *, /)
@ SetBBValue
Data node – writes a Blackboard key.
@ Switch
Multi-branch on value (N exec outputs)
@ EntryPoint
Unique entry node for VS graphs (replaces Root)
@ Branch
If/Else conditional (Then / Else exec outputs)
@ VSSequence
Execute N outputs in order ("VS" prefix avoids collision with BT Sequence=1)
constexpr int32_t NODE_INDEX_NONE
Sentinel value for "no node" in node index / ID fields.
Configuration options for graph simulation.
Full description of a single node in the task graph.