MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / startSession

Method startSession

pj_app/src/StreamingSourceManager.cpp:259–425  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

257}
258
259void StreamingSourceManager::startSession(const QString& plugin_id) {
260 const LoadedDataSource* source_ptr = resolveStreamSource(extensions_, plugin_id);
261 if (source_ptr == nullptr) {
262 qCWarning(lcStream) << "Stream plugin not found:" << plugin_id;
263 emit setupError(tr("Stream plugin '%1' not found.").arg(plugin_id));
264 return;
265 }
266 const LoadedDataSource& source = *source_ptr;
267 const QString source_name = QString::fromStdString(source.name);
268
269 DataSourceHandle handle = source.library.createHandle();
270 if (!handle.valid()) {
271 qCWarning(lcStream) << "createHandle failed for" << source_name;
272 emit setupError(tr("Plugin '%1': createHandle failed.").arg(source_name));
273 return;
274 }
275
276 DataEngine& engine = session_manager_.dataEngine();
277 const QString display_name = QStringLiteral("[stream] %1").arg(source_name);
278
279 // One TimeDomain per stream so each is independently time-shiftable on the
280 // Source Timeline. DUAL-ENGINE: the secondary (pause/tail buffer) must hold
281 // the SAME id, so force it explicitly — the two engines' counters drift
282 // whenever the primary gets a domain the secondary doesn't (e.g. a file load
283 // between streams). Relying on counter order would desync them.
284 auto td_or = engine.createTimeDomain(display_name.toStdString());
285 if (!td_or.has_value()) {
286 emit setupError(tr("Could not create the time domain."));
287 return;
288 }
289 const TimeDomainId td_id = *td_or;
290 auto mirrored_td = secondary_data_engine_->createTimeDomain(display_name.toStdString(), td_id);
291 if (!mirrored_td.has_value() || *mirrored_td != td_id) {
292 emit setupError(tr("secondary time domain lockstep failed."));
293 return;
294 }
295
296 auto dataset_or =
297 engine.createDataset(DatasetDescriptor{.source_name = display_name.toStdString(), .time_domain_id = td_id});
298 if (!dataset_or.has_value()) {
299 emit setupError(tr("createDataset failed: %1").arg(QString::fromStdString(dataset_or.error())));
300 return;
301 }
302 const DatasetId dataset_id = static_cast<DatasetId>(*dataset_or);
303 const PJ_data_source_handle_t source_handle{static_cast<uint32_t>(dataset_id)};
304
305 // Lockstep mirror onto the secondary engine. Topics are mirrored
306 // individually inside DataSourceRuntimeHost; the dataset has to exist here so
307 // cbEnsureParserBinding can use the same DatasetId on both engines without
308 // translation. Create it with the SAME id explicitly: the two engines'
309 // auto-increment counters drift whenever the primary gets a dataset the
310 // secondary doesn't (e.g. a file load between streams), so a plain
311 // createDataset() on the secondary would return a different id and the next
312 // stream would abort here. Forcing the id keeps them in lockstep regardless.
313 auto mirrored_dataset = secondary_data_engine_->createDataset(
314 DatasetDescriptor{.source_name = display_name.toStdString(), .time_domain_id = td_id}, dataset_id);
315 if (!mirrored_dataset.has_value()) {
316 emit setupError(tr("secondary createDataset failed: %1").arg(QString::fromStdString(mirrored_dataset.error())));

Callers

nothing calls this directly

Calls 15

resolveStreamSourceFunction · 0.85
trFunction · 0.85
parseFunction · 0.85
showDataSourceDialogFunction · 0.85
createTimeDomainMethod · 0.80
createDatasetMethod · 0.80
objectStoreMethod · 0.80
getMethod · 0.80
toStringMethod · 0.80
loadConfigMethod · 0.80
pluginConfigKeyFunction · 0.70

Tested by

no test coverage detected