10#include <unordered_map>
11#include <unordered_set>
21 std::vector<ValidationMessage>
messages;
26 "Graph pointer is null.",
27 "Ensure a valid graph is loaded before validation.");
44 std::vector<ValidationMessage>
messages;
49 "Node pointer is null.",
"");
57 "SubGraph node '" +
node->NodeName +
"' has no SubGraphPath.",
58 "Set the SubGraphPath field to a valid .json blueprint file.");
69 std::vector<ValidationMessage>&
messages)
73 for (
size_t i = 0;
i <
graph->ExecConnections.size(); ++
i)
76 for (
size_t i = 0;
i <
graph->Nodes.size(); ++
i)
87 "Node '" +
node.NodeName +
"' has no outgoing exec connection.",
88 "Connect the node's output pin or remove it if unused.");
98 std::vector<ValidationMessage>&
messages)
100 for (
size_t i = 0;
i <
graph->Nodes.size(); ++
i)
107 if (
node.SubGraphPath.empty())
110 "SubGraph node '" +
node.NodeName +
"' has an empty SubGraphPath.",
111 "Set the SubGraphPath field to a valid .json blueprint file.");
124 const std::unordered_map<
int32_t, std::vector<int32_t>>&
adj,
125 std::unordered_set<int32_t>&
visited,
126 std::unordered_set<int32_t>&
inStack)
155 std::vector<ValidationMessage>&
messages)
158 std::unordered_map<int32_t, std::vector<int32_t>>
adj;
159 for (
size_t i = 0;
i <
graph->ExecConnections.size(); ++
i)
162 adj[
conn.SourceNodeID].push_back(
conn.TargetNodeID);
165 std::unordered_set<int32_t>
visited;
166 std::unordered_set<int32_t>
inStack;
168 for (
size_t i = 0;
i <
graph->Nodes.size(); ++
i)
176 "Cycle detected in exec flow involving node '"
177 +
graph->Nodes[
i].NodeName +
"'.",
178 "Break the circular connection to allow the graph to terminate.");
194 const std::string&
msg,
195 const std::string& hint)
199 m.severity = severity;
ComponentTypeID GetComponentTypeID_Static()
Real-time node and graph validation (Phase 9).
static void AddMessage(std::vector< ValidationMessage > &messages, int nodeId, NVSeverity severity, const std::string &msg, const std::string &hint="")
static void CheckUnconnectedNodes(const TaskGraphTemplate *graph, std::vector< ValidationMessage > &messages)
Flags non-EntryPoint/ExitPoint nodes with no outgoing exec connections.
static std::vector< ValidationMessage > ValidateNode(const TaskNodeDefinition *node)
Validates a single node definition.
static void CheckInfiniteLoops(const TaskGraphTemplate *graph, std::vector< ValidationMessage > &messages)
Flags cycles detected via DFS over ExecPinConnections.
static void CheckMissingSubGraphPaths(const TaskGraphTemplate *graph, std::vector< ValidationMessage > &messages)
Flags SubGraph nodes that have an empty SubGraphPath.
static std::vector< ValidationMessage > ValidateGraph(const TaskGraphTemplate *graph)
Validates every node in the graph and returns all findings.
Immutable, shareable task graph asset.
bool DFSHasCycle(int32_t current, const std::unordered_map< int32_t, std::vector< int32_t > > &adj, std::unordered_set< int32_t > &visited, std::unordered_set< int32_t > &inStack)
DFS helper: returns true if a cycle is found starting from startId.
< Provides AssetID and INVALID_ASSET_ID
NVSeverity
Indicates how serious a NodeValidator finding is.
@ Warning
May cause unexpected behaviour.
@ Error
Will prevent correct execution.
@ SubGraph
Sub-graph call (SubTask)
@ EntryPoint
Unique entry node for VS graphs (replaces Root)
@ Root
Entry point of the graph (exactly one per template)
Explicit connection between a named exec-out pin of a source node and the exec-in pin of a target nod...
Full description of a single node in the task graph.
A single finding produced by NodeValidator.
int nodeId
Offending node ID; -1 for graph-level messages.