// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include #include #include #include #include #include "../process/JFJochProcess.h" #include "../common/DiffractionExperiment.h" #include "../common/PixelMask.h" #include "../reader/JFJochReaderDataset.h" Q_DECLARE_METATYPE(ProcessResult) // Runs one JFJochProcess job off the GUI thread and reports back via queued Qt signals. The job // opens its own private JFJochHDF5Reader on the file (HDF5 access is globally serialized, so this // is safe alongside the interactive reader), so the viewer becomes a processing frontend without // blocking the UI. Cancel() is forwarded to JFJochProcess::Cancel() (atomic) and works from any // thread / at any point of the run. class JFJochProcessController : public QObject, private JFJochProcessObserver { Q_OBJECT public: explicit JFJochProcessController(QObject *parent = nullptr); ~JFJochProcessController() override; bool running() const { return running_; } public slots: // Start a job over `file_path` with the given (fully configured) experiment + mask + config. // Ignored if a job is already running. void start(const QString &file_path, DiffractionExperiment experiment, PixelMask pixel_mask, ProcessConfig config); void cancel(); signals: void started(); void phaseChanged(QString phase); void progress(quint64 done, quint64 total); void finished(ProcessResult result); void failed(QString error); // Per-image results accumulated so far, for live dataset-info plots while a job runs (throttled). void liveDataset(std::shared_ptr dataset); private: // JFJochProcessObserver - called from worker threads, forwarded as queued signals. void OnPhase(const std::string &phase) override; void OnProgress(uint64_t done, uint64_t total) override; void OnImageProcessed(const DataMessage &msg) override; void run_(QString file_path, DiffractionExperiment experiment, PixelMask pixel_mask, ProcessConfig config); void joinWorker_(); std::thread worker_; std::atomic active_{nullptr}; std::atomic running_{false}; std::atomic cancel_pending_{false}; // Live per-image results, accumulated by OnImageProcessed (worker threads) and emitted as // immutable copies. live_mutex_ guards both the dataset and the throttle timestamp. std::mutex live_mutex_; std::shared_ptr live_dataset_; std::chrono::steady_clock::time_point last_live_emit_; };