ExplorationWorkerWrapper.hpp
1 #pragma once
2 #include "ExplorationWorker.hpp"
3 
4 #include <Device/Protocol/DeviceInterface.hpp>
5 
6 #include <Explorer/Explorer/DeviceExplorerWidget.hpp>
7 
8 #include <score/widgets/MessageBox.hpp>
9 
10 #include <QApplication>
11 #include <QThread>
12 
13 namespace Explorer
14 {
15 class DeviceExplorerWidget;
16 
20 template <typename OnSuccess>
21 class ExplorationWorkerWrapper final : public QObject
22 {
23  QThread* thread = new QThread;
24  ExplorationWorker* worker{};
25  DeviceExplorerWidget& m_widget;
26 
27  OnSuccess m_success;
28 
29 public:
30  template <typename OnSuccess_t>
32  OnSuccess_t&& success, DeviceExplorerWidget& widg, Device::DeviceInterface& dev)
33  : worker{new ExplorationWorker{dev}}
34  , m_widget{widg}
35  , m_success{std::move(success)}
36  {
37  QObject::connect(
38  thread, &QThread::started, worker,
39  [&]() { on_start(); }, // so that it runs on thread.
40  Qt::QueuedConnection);
41 
42  QObject::connect(
43  worker, &ExplorationWorker::finished, this, &ExplorationWorkerWrapper::on_finish,
44  Qt::QueuedConnection);
45 
46  QObject::connect(
47  worker, &ExplorationWorker::failed, this, &ExplorationWorkerWrapper::on_fail,
48  Qt::QueuedConnection);
49  }
50 
51  void start()
52  {
53  m_widget.blockGUI(true);
54  worker->moveToThread(thread);
55  thread->start();
56  }
57 
59  {
60  thread->quit();
61  thread->wait();
62  delete thread;
63  }
64 
65 private:
66  void on_start()
67  {
68  try
69  {
70  worker->node = worker->dev.refresh();
71  worker->finished();
72  }
73  catch(std::runtime_error& e)
74  {
75  worker->failed(e.what());
76  }
77  }
78 
79  void on_finish()
80  {
81  m_widget.blockGUI(false);
82  m_success(std::move(worker->node));
83 
84  cleanup();
85  }
86 
87  void on_fail(const QString& str)
88  {
89  score::warning(
90  QApplication::activeWindow(), QObject::tr("Unable to refresh the device"),
91  QObject::tr("Unable to refresh the device: ") + worker->dev.settings().name
92  + QObject::tr(".\nCause: ") + str);
93 
94  m_widget.blockGUI(false);
95  cleanup();
96  }
97 
98  void cleanup()
99  {
100  thread->quit();
101  worker->deleteLater();
102  this->deleteLater();
103  }
104 };
105 
106 template <typename OnSuccess_t>
107 static auto make_worker(
108  OnSuccess_t&& success, DeviceExplorerWidget& widg, Device::DeviceInterface& dev)
109 {
110  return new ExplorationWorkerWrapper<OnSuccess_t>{std::move(success), widg, dev};
111 }
112 }
Definition: DeviceInterface.hpp:66
Definition: DeviceExplorerWidget.hpp:44
The ExplorationWorker class.
Definition: ExplorationWorker.hpp:23
Definition: ExplorationWorkerWrapper.hpp:22