Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
TaskGraphLoader.h
Go to the documentation of this file.
1/**
2 * @file TaskGraphLoader.h
3 * @brief Clean schema v4 parser for ATS Visual Script task graphs.
4 * @author Olympe Engine
5 * @date 2026-03-08
6 *
7 * @details
8 * TaskGraphLoader v4 is a ground-up rewrite of the legacy loader.
9 * It natively parses schema v4 ATS VisualScript JSON (flat structure).
10 * For schema v3, it delegates to TaskGraphMigrator_v3_to_v4 before parsing.
11 * For schema v2 and below, it retains minimal backward-compatible parsing
12 * so that existing BehaviorTree assets continue to load.
13 *
14 * Schema v4 (flat, ATS VisualScript):
15 * @code
16 * {
17 * "schema_version": 4,
18 * "id": "uuid-string",
19 * "name": "string",
20 * "graphType": "VisualScript",
21 * "blackboard": [ { "key": "k", "type": "Int|Float|Bool|String|Vector", "value": ... } ],
22 * "nodes": [
23 * { "id": 0, "type": "EntryPoint|AtomicTask|...", "label": "...",
24 * "position": { "x": 0, "y": 0 },
25 * "params": { "key": "value" },
26 * "taskType": "Task_Wait",
27 * "delaySeconds": 0.0,
28 * "bbKey": "scope:key",
29 * "subGraphPath": "path",
30 * "conditionKey": "scope:key",
31 * "conditionOp": "==/!=/</>/<=/>=" ,
32 * "conditionValue": any,
33 * "mathOp": "+|-|*|/",
34 * "mathInputA": "scope:key",
35 * "mathInputB": "scope:key",
36 * "mathOutput": "scope:key",
37 * "switchKey": "scope:key" }
38 * ],
39 * "execConnections": [ { "fromNode": 0, "fromPin": "Completed", "toNode": 1 } ],
40 * "dataConnections": [ { "fromNode": 0, "fromPin": "value", "toNode": 1, "toPin": "input" } ]
41 * }
42 * @endcode
43 *
44 * C++14 compliant - no std::filesystem, no C++17/20 features.
45 */
46
47#pragma once
48
49#include <string>
50#include <vector>
51
52#include "TaskGraphTemplate.h"
53#include "../json_helper.h"
54
55namespace Olympe {
56
57/**
58 * @class TaskGraphLoader
59 * @brief Static utility that loads TaskGraphTemplate from schema v4 JSON.
60 *
61 * @details
62 * All methods are static; do not instantiate this class.
63 * The caller owns the returned TaskGraphTemplate* and is responsible for deletion.
64 */
66public:
67
68 // -----------------------------------------------------------------------
69 // Public API
70 // -----------------------------------------------------------------------
71
72 /**
73 * @brief Loads a TaskGraphTemplate from a JSON file on disk.
74 *
75 * @param path Path to the JSON file (absolute or relative to working dir).
76 * @param outErrors Receives human-readable error messages if loading fails.
77 * @return Pointer to a newly allocated TaskGraphTemplate on success,
78 * or nullptr if the file cannot be read, parsed, or validated.
79 *
80 * @note The caller is responsible for deleting the returned pointer.
81 */
82 static TaskGraphTemplate* LoadFromFile(const std::string& path,
83 std::vector<std::string>& outErrors);
84
85 /**
86 * @brief Loads a TaskGraphTemplate from an already-parsed JSON object.
87 *
88 * Dispatch logic:
89 * - schema_version == 4: ParseSchemaV4 (flat ATS VS format).
90 * - schema_version == 3: run TaskGraphMigrator_v3_to_v4::MigrateJson(), then ParseSchemaV4.
91 * - schema_version <= 2 or absent: ParseSchemaV4 with nested data.nodes support.
92 *
93 * @param data Root JSON object.
94 * @param outErrors Receives human-readable error messages if loading fails.
95 * @return Pointer to a newly allocated TaskGraphTemplate on success,
96 * or nullptr if parsing or validation fails.
97 */
98 static TaskGraphTemplate* LoadFromJson(const json& data,
99 std::vector<std::string>& outErrors);
100
101 /**
102 * @brief Validates a JSON object against the expected task graph schema.
103 *
104 * For v4 flat format: checks for top-level "nodes" array.
105 * For v2/v3 nested format: checks for "data.nodes" array.
106 *
107 * @param data Root JSON object to validate.
108 * @param outErrors Receives human-readable messages for each validation issue.
109 * @return true if the JSON passes structural checks; false otherwise.
110 */
111 static bool ValidateJson(const json& data,
112 std::vector<std::string>& outErrors);
113
114 /**
115 * @brief Returns true if the given file path exists and can be opened.
116 *
117 * C++14 compatible implementation using std::ifstream.
118 *
119 * @param path File path to check.
120 * @return true if the file can be opened for reading.
121 */
122 static bool FileExists(const std::string& path);
123
124 /**
125 * @brief Recursively scans a directory for .ats task graph files.
126 *
127 * C++14 compatible — uses POSIX dirent.h on non-Windows, and Win32 API
128 * on Windows. Logs a warning if the directory does not exist.
129 *
130 * @param dir Directory to scan (absolute or relative to working dir).
131 * @return Sorted list of full paths to every .ats file found.
132 */
133 static std::vector<std::string> ScanTaskGraphDirectory(const std::string& dir);
134
135private:
136
137 // -----------------------------------------------------------------------
138 // v4 (flat ATS Visual Scripting format) – primary path
139 // -----------------------------------------------------------------------
140
141 /**
142 * @brief Parses a schema v4 flat JSON into a TaskGraphTemplate.
143 *
144 * Supports both the canonical flat format ("nodes", "execConnections",
145 * "dataConnections" at root) and the legacy nested format
146 * ("data.nodes", "data.exec_connections") for backward compatibility
147 * with existing JSON assets.
148 */
149 static TaskGraphTemplate* ParseSchemaV4(const json& data,
150 std::vector<std::string>& outErrors);
151
152 /**
153 * @brief Parses a single node JSON (v4 flat format) into a TaskNodeDefinition.
154 *
155 * Accepts both the new field names ("id", "type", "params", "label") and
156 * the legacy field names ("nodeID", "nodeType", "parameters", "nodeName").
157 */
159 const std::string& graphType,
160 std::vector<std::string>& outErrors);
161
162 /**
163 * @brief Parses the blackboard array (v4) and fills tmpl->Blackboard.
164 *
165 * Supports both "value" (new) and "default" (legacy) for the initial value.
166 * Supports both "key" (new) and "Key" (legacy PascalCase) field names.
167 */
168 static void ParseBlackboardV4(const json& root,
170 std::vector<std::string>& outErrors);
171
172 /**
173 * @brief Parses execConnections (v4) and fills tmpl->ExecConnections.
174 *
175 * Accepts "execConnections" (new camelCase), "ExecConnections" (PascalCase),
176 * and "data.exec_connections" (legacy nested).
177 */
178 static void ParseExecConnectionsV4(const json& root,
180
181 /**
182 * @brief Parses dataConnections (v4) and fills tmpl->DataConnections.
183 *
184 * Accepts "dataConnections" (new camelCase), "DataConnections" (PascalCase),
185 * and "data.data_connections" (legacy nested).
186 */
187 static void ParseDataConnectionsV4(const json& root,
189
190 // -----------------------------------------------------------------------
191 // Shared helpers
192 // -----------------------------------------------------------------------
193
194 static void ParseParameters(const json& paramsJson,
195 std::unordered_map<std::string, ParameterBinding>& outParams);
196
197 static TaskValue ParsePrimitiveValue(const json& val);
198 static bool GetChildValue(const json& obj, const std::string& key, json& outVal);
199 static int ResolveRootNodeId(const json& data, const json& dataSection);
200
201 static TaskNodeType StringToNodeType(const std::string& s,
202 const std::string& graphType,
203 bool& outOk);
204 static VariableType StringToVariableType(const std::string& s);
205 static DataPinDir StringToDataPinDir(const std::string& s);
206 static ExecPinRole StringToExecPinRole(const std::string& s);
207
208 // Prevent instantiation
210};
211
212} // namespace Olympe
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
Immutable asset structure shared by all task graph runners.
Static utility that loads TaskGraphTemplate from schema v4 JSON.
static ExecPinRole StringToExecPinRole(const std::string &s)
static DataPinDir StringToDataPinDir(const std::string &s)
static TaskNodeDefinition ParseNodeV4(const json &nodeJson, const std::string &graphType, std::vector< std::string > &outErrors)
Parses a single node JSON (v4 flat format) into a TaskNodeDefinition.
static TaskNodeType StringToNodeType(const std::string &s, const std::string &graphType, bool &outOk)
static bool ValidateJson(const json &data, std::vector< std::string > &outErrors)
Validates a JSON object against the expected task graph schema.
static void ParseDataConnectionsV4(const json &root, TaskGraphTemplate *tmpl)
Parses dataConnections (v4) and fills tmpl->DataConnections.
static VariableType StringToVariableType(const std::string &s)
static TaskGraphTemplate * LoadFromFile(const std::string &path, std::vector< std::string > &outErrors)
Loads a TaskGraphTemplate from a JSON file on disk.
static std::vector< std::string > ScanTaskGraphDirectory(const std::string &dir)
Recursively scans a directory for .ats task graph files.
static bool FileExists(const std::string &path)
Returns true if the given file path exists and can be opened.
static int ResolveRootNodeId(const json &data, const json &dataSection)
static TaskGraphTemplate * ParseSchemaV4(const json &data, std::vector< std::string > &outErrors)
Parses a schema v4 flat JSON into a TaskGraphTemplate.
static bool GetChildValue(const json &obj, const std::string &key, json &outVal)
static void ParseExecConnectionsV4(const json &root, TaskGraphTemplate *tmpl)
Parses execConnections (v4) and fills tmpl->ExecConnections.
static TaskValue ParsePrimitiveValue(const json &val)
static void ParseBlackboardV4(const json &root, TaskGraphTemplate *tmpl, std::vector< std::string > &outErrors)
Parses the blackboard array (v4) and fills tmpl->Blackboard.
static void ParseParameters(const json &paramsJson, std::unordered_map< std::string, ParameterBinding > &outParams)
static TaskGraphTemplate * LoadFromJson(const json &data, std::vector< std::string > &outErrors)
Loads a TaskGraphTemplate from an already-parsed JSON object.
Immutable, shareable task graph asset.
C++14-compliant type-safe value container for task parameters.
< Provides AssetID and INVALID_ASSET_ID
nlohmann::json json
VariableType
Type tags used by TaskValue to identify stored data.
TaskNodeType
Identifies the role of a node in the task graph.
DataPinDir
Direction of a data pin on a Visual Script node.
ExecPinRole
Role of an exec pin on a Visual Script node.
Full description of a single node in the task graph.