Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
GraphExecutionSimulator.h
Go to the documentation of this file.
1/**
2 * @file GraphExecutionSimulator.h
3 * @brief Simulates graph execution without runtime side effects.
4 * @author Olympe Engine
5 * @date 2026-03-24
6 *
7 * @details
8 * GraphExecutionSimulator simulates the execution of a blueprint graph without
9 * actually performing runtime operations. It tracks the execution path,
10 * evaluates conditions, and detects logic errors. Used during blueprint
11 * validation to ensure graphs are executable and to find logic issues.
12 *
13 * Phase 24.3 — Integration with blueprint validation system.
14 * C++14 compliant.
15 */
16
17#pragma once
18
19#include <string>
20#include <vector>
21#include <memory>
22#include <map>
23#include <set>
24#include <cstdint>
25
26#include "../TaskSystem/TaskGraphTemplate.h"
27#include "../TaskSystem/LocalBlackboard.h"
29#include "BlueprintValidator.h"
30
31namespace Olympe {
32
33/**
34 * @struct SimulationOptions
35 * @brief Configuration options for graph simulation.
36 */
38 int32_t maxStepsPerFrame = 1000; ///< Maximum steps to prevent infinite loops
39 int32_t maxSubGraphDepth = 10; ///< Maximum nesting depth for subgraphs
40 bool validateConditions = true; ///< Check condition syntax
41 bool validateDataFlow = true; ///< Check data connections
42 bool validateBranchPaths = true; ///< Verify all branches lead somewhere
43 std::string initialBlackboardJson; ///< Optional initial blackboard values
44};
45
46/**
47 * @class GraphExecutionSimulator
48 * @brief Simulates blueprint graph execution for validation purposes.
49 *
50 * @details
51 * Simulates graph execution to detect:
52 * - Unreachable nodes (orphaned branches)
53 * - Infinite loops or circular paths
54 * - Invalid condition expressions
55 * - Data flow mismatches
56 * - Blocked execution paths (conditions that always fail)
57 * - Missing connections
58 *
59 * The simulator does NOT execute actual AtomicTasks or modify runtime state.
60 */
62public:
63
66
67 /**
68 * @brief Simulates execution of a graph template.
69 * @param tmpl The TaskGraphTemplate to simulate.
70 * @param options Simulation configuration options.
71 * @param outTracer [out] The execution tracer containing results.
72 * @return Vector of validation errors found during simulation.
73 */
74 std::vector<ValidationError> SimulateExecution(const TaskGraphTemplate& tmpl,
77
78 /**
79 * @brief Validates all branch nodes in a graph.
80 * @param tmpl The TaskGraphTemplate to validate.
81 * @param outErrors [out] Vector to append validation errors to.
82 * @return true if all branches are valid.
83 */
85 std::vector<ValidationError>& outErrors);
86
87 /**
88 * @brief Validates all data connections in a graph.
89 * @param tmpl The TaskGraphTemplate to validate.
90 * @param outErrors [out] Vector to append validation errors to.
91 * @return true if all data connections are valid.
92 */
94 std::vector<ValidationError>& outErrors);
95
96 /**
97 * @brief Checks for unreachable nodes.
98 * @param tmpl The TaskGraphTemplate to check.
99 * @param outErrors [out] Vector to append validation errors to.
100 * @return Vector of unreachable node IDs.
101 */
102 std::vector<int32_t> FindUnreachableNodes(const TaskGraphTemplate& tmpl,
103 std::vector<ValidationError>& outErrors);
104
105 /**
106 * @brief Checks for potential infinite loops or cycles.
107 * @param tmpl The TaskGraphTemplate to check.
108 * @param outErrors [out] Vector to append validation errors to.
109 * @return true if potential infinite loops were found.
110 */
112 std::vector<ValidationError>& outErrors);
113
114private:
115
116 // Execution simulation helpers
118 int32_t currentNodeId,
122
123 /**
124 * @brief Simulates a Branch node execution.
125 * @return ID of the node to execute next, or NODE_INDEX_NONE.
126 */
128 int32_t nodeId,
131
132 /**
133 * @brief Simulates a Switch node execution.
134 */
136 int32_t nodeId,
139
140 /**
141 * @brief Simulates a Sequence node execution.
142 */
144 int32_t nodeId,
147
148 /**
149 * @brief Simulates a While loop execution.
150 */
152 int32_t nodeId,
155
156 /**
157 * @brief Gets the next node ID from an execution link.
158 * @param tmpl The template.
159 * @param nodeId Source node ID.
160 * @param pinName Execution output pin name.
161 * @return ID of target node, or NODE_INDEX_NONE.
162 */
164 int32_t nodeId,
165 const std::string& pinName);
166
167 /**
168 * @brief Validates a condition expression.
169 * @param nodeId Node containing the condition.
170 * @param expression Condition text to validate.
171 * @return true if valid.
172 */
174 const std::string& expression);
175
176 /**
177 * @brief Recursively traces data pin evaluation for pure data nodes.
178 * @details Evaluates and traces all incoming data pins of a node,
179 * and recursively traces their source nodes.
180 * @param nodeId Node to trace data pins for.
181 * @param tmpl The task graph template.
182 * @param tracer Execution tracer to record events.
183 * @param depth Current recursion depth.
184 */
186 const TaskGraphTemplate& tmpl,
188 int32_t depth = 0);
189
190 /**
191 * @brief Traces evaluation of a single data connection.
192 * @param sourceNodeId Node providing the data.
193 * @param sourcePinName Name of the output pin.
194 * @param targetNodeId Node receiving the data.
195 * @param targetPinName Name of the input pin.
196 * @param tmpl The task graph template.
197 * @param tracer Execution tracer to record events.
198 * @param depth Current recursion depth.
199 */
201 const std::string& sourcePinName,
203 const std::string& targetPinName,
204 const TaskGraphTemplate& tmpl,
206 int32_t depth);
207
208 // Graph analysis helpers
210 std::map<int32_t, bool>& reachable);
211
213 int32_t nodeId,
214 std::map<int32_t, bool>& reachable);
215
216 // Data structures
217 std::map<int32_t, int32_t> m_visitCount; ///< Track visits per node to detect loops
218 std::vector<int32_t> m_pathStack; ///< Current execution path
219 std::set<int32_t> m_tracedDataNodes; ///< Track data nodes already traced to prevent infinite recursion
220};
221
222} // namespace Olympe
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
Graph execution tracing for simulation and validation.
Simulates blueprint graph execution for validation purposes.
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)
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
Configuration options for graph simulation.
bool validateConditions
Check condition syntax.
int32_t maxStepsPerFrame
Maximum steps to prevent infinite loops.
bool validateDataFlow
Check data connections.
bool validateBranchPaths
Verify all branches lead somewhere.
std::string initialBlackboardJson
Optional initial blackboard values.
int32_t maxSubGraphDepth
Maximum nesting depth for subgraphs.