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