Merge branch 'tm_ui_job_rethrow'

This commit is contained in:
tamasmeszaros 2021-01-19 15:01:36 +01:00
commit 7cd218a4ee
11 changed files with 112 additions and 51 deletions

View file

@ -158,6 +158,8 @@ set(SLIC3R_GUI_SOURCES
GUI/PrintHostDialogs.hpp GUI/PrintHostDialogs.hpp
GUI/Jobs/Job.hpp GUI/Jobs/Job.hpp
GUI/Jobs/Job.cpp GUI/Jobs/Job.cpp
GUI/Jobs/PlaterJob.hpp
GUI/Jobs/PlaterJob.cpp
GUI/Jobs/ArrangeJob.hpp GUI/Jobs/ArrangeJob.hpp
GUI/Jobs/ArrangeJob.cpp GUI/Jobs/ArrangeJob.cpp
GUI/Jobs/RotoptimizeJob.hpp GUI/Jobs/RotoptimizeJob.hpp

View file

@ -7,6 +7,8 @@
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/GUI.hpp"
#include "libnest2d/common.hpp"
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
// Cache the wti info // Cache the wti info
@ -140,6 +142,19 @@ void ArrangeJob::prepare()
wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all(); wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all();
} }
void ArrangeJob::on_exception(const std::exception_ptr &eptr)
{
try {
if (eptr)
std::rethrow_exception(eptr);
} catch (libnest2d::GeometryException &) {
show_error(m_plater, _(L("Could not arrange model objects! "
"Some geometries may be invalid.")));
} catch (std::exception &e) {
PlaterJob::on_exception(eptr);
}
}
void ArrangeJob::process() void ArrangeJob::process()
{ {
static const auto arrangestr = _(L("Arranging")); static const auto arrangestr = _(L("Arranging"));
@ -151,30 +166,23 @@ void ArrangeJob::process()
params.allow_rotations = settings.enable_rotation; params.allow_rotations = settings.enable_rotation;
params.min_obj_distance = scaled(settings.distance); params.min_obj_distance = scaled(settings.distance);
auto count = unsigned(m_selected.size() + m_unprintable.size()); auto count = unsigned(m_selected.size() + m_unprintable.size());
Points bedpts = get_bed_shape(*m_plater->config()); Points bedpts = get_bed_shape(*m_plater->config());
params.stopcondition = [this]() { return was_canceled(); }; params.stopcondition = [this]() { return was_canceled(); };
try { params.progressind = [this, count](unsigned st) {
params.progressind = [this, count](unsigned st) { st += m_unprintable.size();
st += m_unprintable.size(); if (st > 0) update_status(int(count - st), arrangestr);
if (st > 0) update_status(int(count - st), arrangestr); };
};
arrangement::arrange(m_selected, m_unselected, bedpts, params);
arrangement::arrange(m_selected, m_unselected, bedpts, params);
params.progressind = [this, count](unsigned st) {
params.progressind = [this, count](unsigned st) { if (st > 0) update_status(int(count - st), arrangestr);
if (st > 0) update_status(int(count - st), arrangestr); };
};
arrangement::arrange(m_unprintable, {}, bedpts, params);
arrangement::arrange(m_unprintable, {}, bedpts, params);
} catch (std::exception & /*e*/) {
GUI::show_error(m_plater,
_(L("Could not arrange model objects! "
"Some geometries may be invalid.")));
}
// finalize just here. // finalize just here.
update_status(int(count), update_status(int(count),

View file

@ -1,17 +1,13 @@
#ifndef ARRANGEJOB_HPP #ifndef ARRANGEJOB_HPP
#define ARRANGEJOB_HPP #define ARRANGEJOB_HPP
#include "Job.hpp" #include "PlaterJob.hpp"
#include "libslic3r/Arrange.hpp" #include "libslic3r/Arrange.hpp"
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class Plater; class ArrangeJob : public PlaterJob
class ArrangeJob : public Job
{ {
Plater *m_plater;
using ArrangePolygon = arrangement::ArrangePolygon; using ArrangePolygon = arrangement::ArrangePolygon;
using ArrangePolygons = arrangement::ArrangePolygons; using ArrangePolygons = arrangement::ArrangePolygons;
@ -30,10 +26,12 @@ class ArrangeJob : public Job
protected: protected:
void prepare() override; void prepare() override;
void on_exception(const std::exception_ptr &) override;
public: public:
ArrangeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) ArrangeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: Job{std::move(pri)}, m_plater{plater} : PlaterJob{std::move(pri), plater}
{} {}
int status_range() const override int status_range() const override

View file

@ -7,9 +7,8 @@ namespace Slic3r { namespace GUI {
class Plater; class Plater;
class FillBedJob : public Job class FillBedJob : public PlaterJob
{ {
Plater *m_plater;
int m_object_idx = -1; int m_object_idx = -1;
using ArrangePolygon = arrangement::ArrangePolygon; using ArrangePolygon = arrangement::ArrangePolygon;
@ -28,7 +27,7 @@ protected:
public: public:
FillBedJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) FillBedJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: Job{std::move(pri)}, m_plater{plater} : PlaterJob{std::move(pri), plater}
{} {}
int status_range() const override int status_range() const override

View file

@ -1,4 +1,5 @@
#include <algorithm> #include <algorithm>
#include <exception>
#include "Job.hpp" #include "Job.hpp"
#include <libslic3r/Thread.hpp> #include <libslic3r/Thread.hpp>
@ -6,10 +7,15 @@
namespace Slic3r { namespace Slic3r {
void GUI::Job::run() void GUI::Job::run(std::exception_ptr &eptr)
{ {
m_running.store(true); m_running.store(true);
process(); try {
process();
} catch (...) {
eptr = std::current_exception();
}
m_running.store(false); m_running.store(false);
// ensure to call the last status to finalize the job // ensure to call the last status to finalize the job
@ -27,22 +33,29 @@ void GUI::Job::update_status(int st, const wxString &msg)
GUI::Job::Job(std::shared_ptr<ProgressIndicator> pri) GUI::Job::Job(std::shared_ptr<ProgressIndicator> pri)
: m_progress(std::move(pri)) : m_progress(std::move(pri))
{ {
Bind(wxEVT_THREAD, [this](const wxThreadEvent &evt) { Bind(wxEVT_THREAD, [this](const wxThreadEvent &evt) {
auto msg = evt.GetString(); auto msg = evt.GetString();
if (!msg.empty()) if (!msg.empty() && !m_worker_error)
m_progress->set_status_text(msg.ToUTF8().data()); m_progress->set_status_text(msg.ToUTF8().data());
if (m_finalized) return; if (m_finalized) return;
m_progress->set_progress(evt.GetInt()); m_progress->set_progress(evt.GetInt());
if (evt.GetInt() == status_range()) { if (evt.GetInt() == status_range() || m_worker_error) {
// set back the original range and cancel callback // set back the original range and cancel callback
m_progress->set_range(m_range); m_progress->set_range(m_range);
m_progress->set_cancel_callback(); m_progress->set_cancel_callback();
wxEndBusyCursor(); wxEndBusyCursor();
finalize(); if (m_worker_error) {
m_finalized = true;
m_progress->set_status_text("");
m_progress->set_progress(m_range);
on_exception(m_worker_error);
}
else
finalize();
// dont do finalization again for the same process // dont do finalization again for the same process
m_finalized = true; m_finalized = true;
} }
@ -69,7 +82,8 @@ void GUI::Job::start()
wxBeginBusyCursor(); wxBeginBusyCursor();
try { // Execute the job try { // Execute the job
m_thread = create_thread([this] { this->run(); }); m_worker_error = nullptr;
m_thread = create_thread([this] { this->run(m_worker_error); });
} catch (std::exception &) { } catch (std::exception &) {
update_status(status_range(), update_status(status_range(),
_(L("ERROR: not enough resources to " _(L("ERROR: not enough resources to "

View file

@ -2,6 +2,7 @@
#define JOB_HPP #define JOB_HPP
#include <atomic> #include <atomic>
#include <exception>
#include "libslic3r/libslic3r.h" #include "libslic3r/libslic3r.h"
@ -32,8 +33,9 @@ class Job : public wxEvtHandler
std::atomic<bool> m_running{false}, m_canceled{false}; std::atomic<bool> m_running{false}, m_canceled{false};
bool m_finalized = false; bool m_finalized = false;
std::shared_ptr<ProgressIndicator> m_progress; std::shared_ptr<ProgressIndicator> m_progress;
std::exception_ptr m_worker_error = nullptr;
void run(); void run(std::exception_ptr &);
protected: protected:
// status range for a particular job // status range for a particular job
@ -49,6 +51,8 @@ protected:
// Launched when the job is finished. It refreshes the 3Dscene by def. // Launched when the job is finished. It refreshes the 3Dscene by def.
virtual void finalize() { m_finalized = true; } virtual void finalize() { m_finalized = true; }
virtual void on_exception(const std::exception_ptr &) {}
public: public:
Job(std::shared_ptr<ProgressIndicator> pri); Job(std::shared_ptr<ProgressIndicator> pri);

View file

@ -0,0 +1,17 @@
#include "PlaterJob.hpp"
#include "slic3r/GUI/GUI.hpp"
#include "slic3r/GUI/Plater.hpp"
namespace Slic3r { namespace GUI {
void PlaterJob::on_exception(const std::exception_ptr &eptr)
{
try {
if (eptr)
std::rethrow_exception(eptr);
} catch (std::exception &e) {
show_error(m_plater, _(L("An unexpected error occured: ")) + e.what());
}
}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,24 @@
#ifndef PLATERJOB_HPP
#define PLATERJOB_HPP
#include "Job.hpp"
namespace Slic3r { namespace GUI {
class Plater;
class PlaterJob : public Job {
protected:
Plater *m_plater;
void on_exception(const std::exception_ptr &) override;
public:
PlaterJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater):
Job{std::move(pri)}, m_plater{plater} {}
};
}} // namespace Slic3r::GUI
#endif // PLATERJOB_HPP

View file

@ -1,18 +1,15 @@
#ifndef ROTOPTIMIZEJOB_HPP #ifndef ROTOPTIMIZEJOB_HPP
#define ROTOPTIMIZEJOB_HPP #define ROTOPTIMIZEJOB_HPP
#include "Job.hpp" #include "PlaterJob.hpp"
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class Plater; class RotoptimizeJob : public PlaterJob
class RotoptimizeJob : public Job
{ {
Plater *m_plater;
public: public:
RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: Job{std::move(pri)}, m_plater{plater} : PlaterJob{std::move(pri), plater}
{} {}
void process() override; void process() override;

View file

@ -124,7 +124,7 @@ public:
}; };
SLAImportJob::SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater) SLAImportJob::SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: Job{std::move(pri)}, p{std::make_unique<priv>(plater)} : PlaterJob{std::move(pri), plater}, p{std::make_unique<priv>(plater)}
{} {}
SLAImportJob::~SLAImportJob() = default; SLAImportJob::~SLAImportJob() = default;

View file

@ -1,13 +1,11 @@
#ifndef SLAIMPORTJOB_HPP #ifndef SLAIMPORTJOB_HPP
#define SLAIMPORTJOB_HPP #define SLAIMPORTJOB_HPP
#include "Job.hpp" #include "PlaterJob.hpp"
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class Plater; class SLAImportJob : public PlaterJob {
class SLAImportJob : public Job {
class priv; class priv;
std::unique_ptr<priv> p; std::unique_ptr<priv> p;