v2.0.0
Loading...
Searching...
No Matches
mna_node.cpp
Go to the documentation of this file.
1//=============================================================================================================
24
25//=============================================================================================================
26// INCLUDES
27//=============================================================================================================
28
29#include "mna_node.h"
30
31#include <QJsonArray>
32#include <QCborArray>
33
34//=============================================================================================================
35// USED NAMESPACES
36//=============================================================================================================
37
38using namespace MNALIB;
39
40//=============================================================================================================
41// STATIC HELPERS
42//=============================================================================================================
43
44static QString execModeToString(MnaNodeExecMode mode)
45{
46 switch (mode) {
48 return QStringLiteral("batch");
50 return QStringLiteral("stream");
52 return QStringLiteral("ipc");
54 return QStringLiteral("script");
55 }
56 return QStringLiteral("batch");
57}
58
59//=============================================================================================================
60
61static MnaNodeExecMode execModeFromString(const QString& str)
62{
63 if (str == QLatin1String("stream"))
65 if (str == QLatin1String("ipc"))
67 if (str == QLatin1String("script"))
70}
71
72//=============================================================================================================
73// DEFINE MEMBER METHODS
74//=============================================================================================================
75
76QJsonObject MnaNode::toJson() const
77{
78 QJsonObject json = extras;
79 json[QLatin1String("id")] = id;
80 json[QLatin1String("op_type")] = opType;
81 json[QLatin1String("exec_mode")] = execModeToString(execMode);
82
83 // Attributes
84 json[QLatin1String("attributes")] = QJsonObject::fromVariantMap(attributes);
85
86 // Ports
87 QJsonArray inputArr;
88 for (const MnaPort& p : inputs)
89 inputArr.append(p.toJson());
90 json[QLatin1String("inputs")] = inputArr;
91
92 QJsonArray outputArr;
93 for (const MnaPort& p : outputs)
94 outputArr.append(p.toJson());
95 json[QLatin1String("outputs")] = outputArr;
96
97 // IPC config
99 json[QLatin1String("ipc_command")] = ipcCommand;
100 QJsonArray argsArr;
101 for (const QString& arg : ipcArgs)
102 argsArr.append(arg);
103 json[QLatin1String("ipc_args")] = argsArr;
104 json[QLatin1String("ipc_work_dir")] = ipcWorkDir;
105 json[QLatin1String("ipc_transport")] = ipcTransport;
106 }
107
108 // Script config
110 json[QLatin1String("script")] = script.toJson();
111 }
112
113 // Verification & provenance
114 QJsonObject verObj = verification.toJson();
115 if (!verObj.isEmpty()) {
116 json[QLatin1String("verification")] = verObj;
117 }
118
119 // Metadata
120 if (!toolVersion.isEmpty())
121 json[QLatin1String("tool_version")] = toolVersion;
122 if (executedAt.isValid())
123 json[QLatin1String("executed_at")] = executedAt.toString(Qt::ISODate);
124 json[QLatin1String("dirty")] = dirty;
125
126 return json;
127}
128
129//=============================================================================================================
130
131MnaNode MnaNode::fromJson(const QJsonObject& json)
132{
133 MnaNode node;
134 node.id = json[QLatin1String("id")].toString();
135 node.opType = json[QLatin1String("op_type")].toString();
136 node.execMode = execModeFromString(json[QLatin1String("exec_mode")].toString());
137
138 node.attributes = json[QLatin1String("attributes")].toObject().toVariantMap();
139
140 // Ports
141 QJsonArray inputArr = json[QLatin1String("inputs")].toArray();
142 for (const QJsonValue& v : inputArr)
143 node.inputs.append(MnaPort::fromJson(v.toObject()));
144
145 QJsonArray outputArr = json[QLatin1String("outputs")].toArray();
146 for (const QJsonValue& v : outputArr)
147 node.outputs.append(MnaPort::fromJson(v.toObject()));
148
149 // IPC
150 node.ipcCommand = json[QLatin1String("ipc_command")].toString();
151 QJsonArray argsArr = json[QLatin1String("ipc_args")].toArray();
152 for (const QJsonValue& v : argsArr)
153 node.ipcArgs.append(v.toString());
154 node.ipcWorkDir = json[QLatin1String("ipc_work_dir")].toString();
155 node.ipcTransport = json[QLatin1String("ipc_transport")].toString();
156
157 // Script
158 if (json.contains(QLatin1String("script"))) {
159 node.script = MnaScript::fromJson(json[QLatin1String("script")].toObject());
160 }
161
162 // Verification
163 if (json.contains(QLatin1String("verification"))) {
164 node.verification = MnaVerification::fromJson(json[QLatin1String("verification")].toObject());
165 }
166
167 // Metadata
168 node.toolVersion = json[QLatin1String("tool_version")].toString();
169 QString execStr = json[QLatin1String("executed_at")].toString();
170 if (!execStr.isEmpty())
171 node.executedAt = QDateTime::fromString(execStr, Qt::ISODate);
172 node.dirty = json[QLatin1String("dirty")].toBool(true);
173
174 static const QSet<QString> knownKeys = {
175 QStringLiteral("id"), QStringLiteral("op_type"),
176 QStringLiteral("exec_mode"), QStringLiteral("attributes"),
177 QStringLiteral("inputs"), QStringLiteral("outputs"),
178 QStringLiteral("ipc_command"), QStringLiteral("ipc_args"),
179 QStringLiteral("ipc_work_dir"), QStringLiteral("ipc_transport"),
180 QStringLiteral("script"), QStringLiteral("verification"),
181 QStringLiteral("tool_version"), QStringLiteral("executed_at"),
182 QStringLiteral("dirty")};
183 for (auto it = json.constBegin(); it != json.constEnd(); ++it) {
184 if (!knownKeys.contains(it.key()))
185 node.extras.insert(it.key(), it.value());
186 }
187
188 return node;
189}
190
191//=============================================================================================================
192
193QCborMap MnaNode::toCbor() const
194{
195 QCborMap cbor = QCborMap::fromJsonObject(extras);
196 cbor[QLatin1String("id")] = id;
197 cbor[QLatin1String("op_type")] = opType;
198 cbor[QLatin1String("exec_mode")] = execModeToString(execMode);
199
200 cbor[QLatin1String("attributes")] = QCborMap::fromJsonObject(QJsonObject::fromVariantMap(attributes));
201
202 QCborArray inputArr;
203 for (const MnaPort& p : inputs)
204 inputArr.append(p.toCbor());
205 cbor[QLatin1String("inputs")] = inputArr;
206
207 QCborArray outputArr;
208 for (const MnaPort& p : outputs)
209 outputArr.append(p.toCbor());
210 cbor[QLatin1String("outputs")] = outputArr;
211
213 cbor[QLatin1String("ipc_command")] = ipcCommand;
214 QCborArray argsArr;
215 for (const QString& arg : ipcArgs)
216 argsArr.append(arg);
217 cbor[QLatin1String("ipc_args")] = argsArr;
218 cbor[QLatin1String("ipc_work_dir")] = ipcWorkDir;
219 cbor[QLatin1String("ipc_transport")] = ipcTransport;
220 }
221
223 cbor[QLatin1String("script")] = script.toCbor();
224 }
225
226 QCborMap verCbor = verification.toCbor();
227 if (!verCbor.isEmpty()) {
228 cbor[QLatin1String("verification")] = verCbor;
229 }
230
231 if (!toolVersion.isEmpty())
232 cbor[QLatin1String("tool_version")] = toolVersion;
233 if (executedAt.isValid())
234 cbor[QLatin1String("executed_at")] = executedAt.toString(Qt::ISODate);
235 cbor[QLatin1String("dirty")] = dirty;
236
237 return cbor;
238}
239
240//=============================================================================================================
241
242MnaNode MnaNode::fromCbor(const QCborMap& cbor)
243{
244 MnaNode node;
245 node.id = cbor[QLatin1String("id")].toString();
246 node.opType = cbor[QLatin1String("op_type")].toString();
247 node.execMode = execModeFromString(cbor[QLatin1String("exec_mode")].toString());
248
249 QCborMap attrCbor = cbor[QLatin1String("attributes")].toMap();
250 node.attributes = attrCbor.toJsonObject().toVariantMap();
251
252 QCborArray inputArr = cbor[QLatin1String("inputs")].toArray();
253 for (const QCborValue& v : inputArr)
254 node.inputs.append(MnaPort::fromCbor(v.toMap()));
255
256 QCborArray outputArr = cbor[QLatin1String("outputs")].toArray();
257 for (const QCborValue& v : outputArr)
258 node.outputs.append(MnaPort::fromCbor(v.toMap()));
259
260 node.ipcCommand = cbor[QLatin1String("ipc_command")].toString();
261 QCborArray argsArr = cbor[QLatin1String("ipc_args")].toArray();
262 for (const QCborValue& v : argsArr)
263 node.ipcArgs.append(v.toString());
264 node.ipcWorkDir = cbor[QLatin1String("ipc_work_dir")].toString();
265 node.ipcTransport = cbor[QLatin1String("ipc_transport")].toString();
266
267 if (cbor.contains(QLatin1String("script"))) {
268 node.script = MnaScript::fromCbor(cbor[QLatin1String("script")].toMap());
269 }
270 if (cbor.contains(QLatin1String("verification"))) {
271 node.verification = MnaVerification::fromCbor(cbor[QLatin1String("verification")].toMap());
272 }
273
274 node.toolVersion = cbor[QLatin1String("tool_version")].toString();
275 QString execStr = cbor[QLatin1String("executed_at")].toString();
276 if (!execStr.isEmpty())
277 node.executedAt = QDateTime::fromString(execStr, Qt::ISODate);
278 node.dirty = cbor[QLatin1String("dirty")].toBool(true);
279
280 static const QSet<QString> knownKeys = {
281 QStringLiteral("id"), QStringLiteral("op_type"),
282 QStringLiteral("exec_mode"), QStringLiteral("attributes"),
283 QStringLiteral("inputs"), QStringLiteral("outputs"),
284 QStringLiteral("ipc_command"), QStringLiteral("ipc_args"),
285 QStringLiteral("ipc_work_dir"), QStringLiteral("ipc_transport"),
286 QStringLiteral("script"), QStringLiteral("verification"),
287 QStringLiteral("tool_version"), QStringLiteral("executed_at"),
288 QStringLiteral("dirty")};
289 QJsonObject cborJson = cbor.toJsonObject();
290 for (auto it = cborJson.constBegin(); it != cborJson.constEnd(); ++it) {
291 if (!knownKeys.contains(it.key()))
292 node.extras.insert(it.key(), it.value());
293 }
294
295 return node;
296}
One operation in an MNA graph — opType, typed I/O ports, attributes, execution mode (Batch / Stream /...
MNE Analysis Container Format (mna/mnx).
MnaNodeExecMode
Definition mna_types.h:128
@ Batch
Runs once on static file-based inputs (default).
Definition mna_types.h:129
@ Ipc
Delegates to an external process via inter-process communication.
Definition mna_types.h:131
@ Stream
Runs continuously on real-time data (MNE Scan mode).
Definition mna_types.h:130
@ Script
Inline code executed via interpreter (Python, shell, R, …).
Definition mna_types.h:132
Single executable step in an MNA pipeline graph, with attributes, typed ports, exec mode,...
Definition mna_node.h:77
MnaNodeExecMode execMode
Execution mode.
Definition mna_node.h:85
QString toolVersion
Version of tool that last executed this node.
Definition mna_node.h:100
QString ipcCommand
External executable command.
Definition mna_node.h:88
QStringList ipcArgs
Command-line arguments (supports {{placeholder}} tokens).
Definition mna_node.h:89
bool dirty
Whether node needs re-execution.
Definition mna_node.h:102
MnaScript script
Inline source code, interpreter, language.
Definition mna_node.h:94
QList< MnaPort > inputs
Input ports.
Definition mna_node.h:82
QCborMap toCbor() const
Definition mna_node.cpp:193
QVariantMap attributes
Operation parameters.
Definition mna_node.h:80
QDateTime executedAt
Timestamp of last execution.
Definition mna_node.h:101
static MnaNode fromJson(const QJsonObject &json)
Definition mna_node.cpp:131
QString opType
Operation type (looked up in MnaOpRegistry).
Definition mna_node.h:79
MnaVerification verification
Explanation, checks, results, and provenance snapshot.
Definition mna_node.h:97
QString ipcWorkDir
Working directory for external process.
Definition mna_node.h:90
QString ipcTransport
"stdio", "tcp", "shm", "file"
Definition mna_node.h:91
static MnaNode fromCbor(const QCborMap &cbor)
Definition mna_node.cpp:242
QList< MnaPort > outputs
Output ports.
Definition mna_node.h:83
QJsonObject toJson() const
Definition mna_node.cpp:76
QString id
Unique node identifier.
Definition mna_node.h:78
QJsonObject extras
Unknown keys preserved for lossless round-trip.
Definition mna_node.h:103
Named, typed port on an MNA graph node with upstream link and optional real-time stream binding.
Definition mna_port.h:65
static MnaPort fromJson(const QJsonObject &json)
Definition mna_port.cpp:165
static MnaPort fromCbor(const QCborMap &cbor)
Definition mna_port.cpp:221
static MnaScript fromJson(const QJsonObject &json)
static MnaScript fromCbor(const QCborMap &cbor)
static MnaVerification fromJson(const QJsonObject &json)
static MnaVerification fromCbor(const QCborMap &cbor)