Make a PlaterWorker to handle PlaterJobs

This commit is contained in:
tamasmeszaros 2021-12-01 11:09:10 +01:00
parent 5c68340f2a
commit a12950c51a
3 changed files with 72 additions and 57 deletions

View File

@ -559,8 +559,8 @@ GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui,
imgui->disabled_begin(true);
if ( imgui->button(btn_txt) ) {
auto p = wxGetApp().plater();
replace_job<RotoptimizeJob>(*p);
replace_job(wxGetApp().plater()->get_ui_job_worker(),
std::make_unique<RotoptimizeJob>());
}
imgui->disabled_end();

View File

@ -13,60 +13,70 @@ namespace Slic3r { namespace GUI {
class Plater;
template<class JobSubclass>
class PlaterJob : public Job {
JobSubclass m_job;
Plater *m_plater;
template<class WorkerSubclass>
class PlaterWorker: public Worker {
WorkerSubclass m_w;
class PlaterJob : public Job {
std::unique_ptr<Job> 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<Job> 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<class ... WorkerArgs>
PlaterWorker(WorkerArgs &&...args) : m_w{std::forward<WorkerArgs>(args)...} {}
// Always package the job argument into a PlaterJob
bool start_next(std::unique_ptr<Job> job) override
{
CursorSetterRAII busycursor{c};
m_job.process(c);
return m_w.start_next(std::make_unique<PlaterJob>(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<class... Args>
PlaterJob(Args &&...args)
: m_job(std::forward<Args>(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<class JobSubclass, class ... Args>
void replace_job(Plater& p, Args && ...args)
{
replace_job(p.get_ui_job_worker(),
std::make_unique<PlaterJob<JobSubclass>>(
std::forward<Args>(args)...));
}
}} // namespace Slic3r::GUI
#endif // PLATERJOB_HPP

View File

@ -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<BoostThreadWorker> 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<SLAImportJob>(*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<SLAImportJob>(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<FillBedJob>(*this);
auto &w = get_ui_job_worker();
if (w.is_idle())
replace_job(w, std::make_unique<FillBedJob>());
}
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<ArrangeJob>(*this);
auto &w = get_ui_job_worker();
if (w.is_idle())
replace_job(w, std::make_unique<ArrangeJob>());
}
void Plater::set_current_canvas_as_dirty()