diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 25bb122f67..ac23f754c9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -559,8 +559,8 @@ GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui, imgui->disabled_begin(true); if ( imgui->button(btn_txt) ) { - auto p = wxGetApp().plater(); - replace_job(*p); + replace_job(wxGetApp().plater()->get_ui_job_worker(), + std::make_unique()); } imgui->disabled_end(); diff --git a/src/slic3r/GUI/Jobs/PlaterJob.hpp b/src/slic3r/GUI/Jobs/PlaterJob.hpp index 8c8d2e3787..c20075f0e7 100644 --- a/src/slic3r/GUI/Jobs/PlaterJob.hpp +++ b/src/slic3r/GUI/Jobs/PlaterJob.hpp @@ -13,60 +13,70 @@ namespace Slic3r { namespace GUI { class Plater; -template -class PlaterJob : public Job { - JobSubclass m_job; - Plater *m_plater; +template +class PlaterWorker: public Worker { + WorkerSubclass m_w; + + class PlaterJob : public Job { + std::unique_ptr m_job; + Plater *m_plater; + + public: + void process(Ctl &c) override + { + CursorSetterRAII busycursor{c}; + m_job->process(c); + } + + void finalize(bool canceled, std::exception_ptr &eptr) override + { + m_job->finalize(canceled, eptr); + + if (eptr) try { + std::rethrow_exception(eptr); + } catch (std::exception &e) { + show_error(m_plater, _L("An unexpected error occured: ") + e.what()); + eptr = nullptr; + } + } + + PlaterJob(std::unique_ptr j) + : m_job{std::move(j)}, m_plater{wxGetApp().plater()} + { + // TODO: decide if disabling slice button during UI job is what we want. + // if (m_plater) + // m_plater->sidebar().enable_buttons(false); + } + + ~PlaterJob() override + { + // TODO: decide if disabling slice button during UI job is what we want. + + // Reload scene ensures that the slice button gets properly + // enabled or disabled after the job finishes, depending on the + // state of slicing. This might be an overkill but works for now. + // if (m_plater) + // m_plater->canvas3D()->reload_scene(false); + } + }; public: - void process(Ctl &c) override + template + PlaterWorker(WorkerArgs &&...args) : m_w{std::forward(args)...} {} + + // Always package the job argument into a PlaterJob + bool start_next(std::unique_ptr job) override { - CursorSetterRAII busycursor{c}; - m_job.process(c); + return m_w.start_next(std::make_unique(std::move(job))); } - void finalize(bool canceled, std::exception_ptr &eptr) override - { - m_job.finalize(canceled, eptr); - - if (eptr) try { - std::rethrow_exception(eptr); - } catch (std::exception &e) { - show_error(m_plater, _L("An unexpected error occured: ") + e.what()); - eptr = nullptr; - } - } - - template - PlaterJob(Args &&...args) - : m_job(std::forward(args)...), m_plater{wxGetApp().plater()} - { - // TODO: decide if disabling slice button during UI job is what we want. -// if (m_plater) -// m_plater->sidebar().enable_buttons(false); - } - - ~PlaterJob() override - { - // TODO: decide if disabling slice button during UI job is what we want. - - // Reload scene ensures that the slice button gets properly - // enabled or disabled after the job finishes, depending on the - // state of slicing. This might be an overkill but works for now. -// if (m_plater) -// m_plater->canvas3D()->reload_scene(false); - } + bool is_idle() const override { return m_w.is_idle(); } + void cancel() override { m_w.cancel(); } + void cancel_all() override { m_w.cancel_all(); } + void process_events() override { m_w.process_events(); } }; -template -void replace_job(Plater& p, Args && ...args) -{ - replace_job(p.get_ui_job_worker(), - std::make_unique>( - std::forward(args)...)); -} - }} // namespace Slic3r::GUI #endif // PLATERJOB_HPP diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3dfac576e6..caaa4a4c89 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1637,8 +1637,8 @@ struct Plater::priv // objects would be frozen for the user. In case of arrange, an animation // could be shown, or with the optimize orientations, partial results // could be displayed. - BoostThreadWorker m_worker; - SLAImportDialog * m_sla_import_dlg; + PlaterWorker m_worker; + SLAImportDialog * m_sla_import_dlg; bool delayed_scene_refresh; std::string delayed_error_message; @@ -2176,7 +2176,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // Ensure that messages from the worker thread to the UI thread are processed // continuously. - main_frame->Bind(wxEVT_IDLE, [this](const wxIdleEvent &){ m_worker.process_events(); }); + main_frame->Bind(wxEVT_IDLE, [this](const wxIdleEvent &) { + m_worker.process_events(); + }); } Plater::priv::~priv() @@ -5048,8 +5050,9 @@ void Plater::add_model(bool imperial_units/* = false*/) void Plater::import_sl1_archive() { - if (get_ui_job_worker().is_idle() && p->m_sla_import_dlg->ShowModal() == wxID_OK) { - replace_job(*this, p->m_sla_import_dlg); + auto &w = get_ui_job_worker(); + if (w.is_idle() && p->m_sla_import_dlg->ShowModal() == wxID_OK) { + replace_job(w, std::make_unique(p->m_sla_import_dlg)); } } @@ -5484,8 +5487,9 @@ void Plater::set_number_of_copies(/*size_t num*/) void Plater::fill_bed_with_instances() { - if (get_ui_job_worker().is_idle()) - replace_job(*this); + auto &w = get_ui_job_worker(); + if (w.is_idle()) + replace_job(w, std::make_unique()); } bool Plater::is_selection_empty() const @@ -6365,8 +6369,9 @@ GLCanvas3D* Plater::get_current_canvas3D() void Plater::arrange() { - if (get_ui_job_worker().is_idle()) - replace_job(*this); + auto &w = get_ui_job_worker(); + if (w.is_idle()) + replace_job(w, std::make_unique()); } void Plater::set_current_canvas_as_dirty()