/
klischa
/
AstraScanner2
Обзор
Документация
Войти
/
klischa
/
AstraScanner2
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/controllers/ProcessingController.cpp
192 строки
8 KB
k k
fix(critical): harden destructor and ProcessingController against queued events
13 июл 2026, 23:27
13 июл 2026, 23:27
7e996d2
Код
Авторство
О чём код?
#include "ProcessingController.h" #include "../filters/PointCloudFilters.h" #include <QFutureWatcher> #include <QPointer> #include <QtConcurrent/QtConcurrent> ProcessingController::ProcessingController(QObject *parent) : QObject(parent) { m_filters = new PointCloudFilters(this); connect(m_filters, &PointCloudFilters::progressUpdated, this, &ProcessingController::progressUpdated); connect(m_filters, &PointCloudFilters::filterCompleted, this, &ProcessingController::filterCompleted); } void ProcessingController::runCloudOperation( QObject *receiver, const CloudOperation &operation, const std::function<void(pcl::PointCloud<pcl::PointXYZRGB>::Ptr)> &onFinished, const std::function<void()> &onCanceled) { auto *watcher = new QFutureWatcher<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>(this); QPointer<QObject> safeReceiver(receiver); connect(watcher, &QFutureWatcher<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::finished, receiver, [watcher, onFinished, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } onFinished(watcher->result()); watcher->deleteLater(); }); connect(watcher, &QFutureWatcher<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::canceled, receiver, [watcher, onCanceled, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } if (onCanceled) onCanceled(); watcher->deleteLater(); }); m_pendingCloudFuture = QtConcurrent::run([this, operation, watcher]() { try { if (watcher->isCanceled()) return pcl::PointCloud<pcl::PointXYZRGB>::Ptr(); PointCloudFilters localFilters; return operation(&localFilters); } catch (const std::exception& e) { qCritical() << "[ProcessingController] Cloud operation failed:" << e.what(); return pcl::PointCloud<pcl::PointXYZRGB>::Ptr(); } catch (...) { qCritical() << "[ProcessingController] Cloud operation failed: unknown exception"; return pcl::PointCloud<pcl::PointXYZRGB>::Ptr(); } }); watcher->setFuture(m_pendingCloudFuture); } void ProcessingController::runMeshOperation( QObject *receiver, const MeshOperation &operation, const std::function<void(const pcl::PolygonMesh &)> &onFinished, const std::function<void()> &onCanceled) { auto *watcher = new QFutureWatcher<pcl::PolygonMesh>(this); QPointer<QObject> safeReceiver(receiver); connect(watcher, &QFutureWatcher<pcl::PolygonMesh>::finished, receiver, [watcher, onFinished, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } onFinished(watcher->result()); watcher->deleteLater(); }); connect(watcher, &QFutureWatcher<pcl::PolygonMesh>::canceled, receiver, [watcher, onCanceled, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } if (onCanceled) onCanceled(); watcher->deleteLater(); }); m_pendingMeshFuture = QtConcurrent::run([this, operation, watcher]() { try { if (watcher->isCanceled()) return pcl::PolygonMesh(); PointCloudFilters localFilters; return operation(&localFilters); } catch (const std::exception& e) { qCritical() << "[ProcessingController] Mesh operation failed:" << e.what(); return pcl::PolygonMesh(); } catch (...) { qCritical() << "[ProcessingController] Mesh operation failed: unknown exception"; return pcl::PolygonMesh(); } }); watcher->setFuture(m_pendingMeshFuture); } void ProcessingController::runReconstruction( QObject *receiver, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &snapshot, const AstraPoissonParams ¶ms, const std::function<void(const pcl::PolygonMesh &)> &onFinished, const std::function<void()> &onCanceled) { auto *watcher = new QFutureWatcher<pcl::PolygonMesh>(this); QPointer<QObject> safeReceiver(receiver); connect(watcher, &QFutureWatcher<pcl::PolygonMesh>::finished, receiver, [watcher, onFinished, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } onFinished(watcher->result()); watcher->deleteLater(); }); connect(watcher, &QFutureWatcher<pcl::PolygonMesh>::canceled, receiver, [watcher, onCanceled, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } if (onCanceled) onCanceled(); watcher->deleteLater(); }); m_reconstructionFuture = QtConcurrent::run([this, snapshot, params, watcher]() { try { if (watcher->isCanceled()) return pcl::PolygonMesh(); PointCloudFilters localFilters; return localFilters.reconstructPoissonMesh(snapshot, params); } catch (const std::exception& e) { qCritical() << "[ProcessingController] Reconstruction failed:" << e.what(); return pcl::PolygonMesh(); } catch (...) { qCritical() << "[ProcessingController] Reconstruction failed: unknown exception"; return pcl::PolygonMesh(); } }); watcher->setFuture(m_reconstructionFuture); } void ProcessingController::runMergeScans( QObject *receiver, const std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> &scans, const AstraMergeParams ¶ms, const std::function<void(pcl::PointCloud<pcl::PointXYZRGB>::Ptr)> &onFinished, const std::function<void()> &onCanceled) { auto *watcher = new QFutureWatcher<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>(this); QPointer<QObject> safeReceiver(receiver); connect(watcher, &QFutureWatcher<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::finished, receiver, [watcher, onFinished, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } onFinished(watcher->result()); watcher->deleteLater(); }); connect(watcher, &QFutureWatcher<pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::canceled, receiver, [watcher, onCanceled, safeReceiver]() { if (!safeReceiver) { watcher->deleteLater(); return; } if (onCanceled) onCanceled(); watcher->deleteLater(); }); m_mergeFuture = QtConcurrent::run([this, scans, params, watcher]() { try { if (watcher->isCanceled()) return pcl::PointCloud<pcl::PointXYZRGB>::Ptr(); PointCloudFilters localFilters; return localFilters.mergeScans(scans, params); } catch (const std::exception& e) { qCritical() << "[ProcessingController] Merge failed:" << e.what(); return pcl::PointCloud<pcl::PointXYZRGB>::Ptr(); } catch (...) { qCritical() << "[ProcessingController] Merge failed: unknown exception"; return pcl::PointCloud<pcl::PointXYZRGB>::Ptr(); } }); watcher->setFuture(m_mergeFuture); } void ProcessingController::cancelAll() { m_pendingCloudFuture.cancel(); m_pendingMeshFuture.cancel(); m_reconstructionFuture.cancel(); m_mergeFuture.cancel(); for (auto *w : findChildren<QFutureWatcherBase*>()) { w->cancel(); w->disconnect(); } } void ProcessingController::waitForOperations() { if (m_pendingCloudFuture.isRunning()) { m_pendingCloudFuture.waitForFinished(); } if (m_pendingMeshFuture.isRunning()) { m_pendingMeshFuture.waitForFinished(); } if (m_reconstructionFuture.isRunning()) { m_reconstructionFuture.waitForFinished(); } if (m_mergeFuture.isRunning()) { m_mergeFuture.waitForFinished(); } }