Avoid issue with invisible status indication.

This commit is contained in:
tamasmeszaros 2021-12-01 12:47:14 +01:00
parent a12950c51a
commit fb93166c64
8 changed files with 57 additions and 31 deletions

View File

@ -173,7 +173,7 @@ set(SLIC3R_GUI_SOURCES
GUI/Jobs/BoostThreadWorker.hpp
GUI/Jobs/BoostThreadWorker.cpp
GUI/Jobs/BusyCursorJob.hpp
GUI/Jobs/PlaterJob.hpp
GUI/Jobs/PlaterWorker.hpp
GUI/Jobs/ArrangeJob.hpp
GUI/Jobs/ArrangeJob.cpp
GUI/Jobs/RotoptimizeJob.hpp

View File

@ -11,7 +11,6 @@
#include "libslic3r/PresetBundle.hpp"
#include "slic3r/GUI/Jobs/RotoptimizeJob.hpp"
#include "slic3r/GUI/Jobs/PlaterJob.hpp"
namespace Slic3r {
namespace GUI {

View File

@ -164,10 +164,11 @@ void ArrangeJob::prepare()
void ArrangeJob::process(Ctl &ctl)
{
ctl.call_on_main_thread([this]{ prepare(); }).wait();
static const auto arrangestr = _u8L("Arranging");
ctl.update_status(0, arrangestr);
ctl.call_on_main_thread([this]{ prepare(); }).wait();;
arrangement::ArrangeParams params = get_arrange_params(m_plater);
auto count = unsigned(m_selected.size() + m_unprintable.size());
@ -196,7 +197,7 @@ void ArrangeJob::process(Ctl &ctl)
_u8L("Arranging done."));
}
ArrangeJob::ArrangeJob() : m_plater{wxGetApp().plater()} { }
ArrangeJob::ArrangeJob() : m_plater{wxGetApp().plater()} {}
static std::string concat_strings(const std::set<std::string> &strings,
const std::string &delim = "\n")

View File

@ -29,7 +29,7 @@ void BoostThreadWorker::WorkerMessage::deliver(BoostThreadWorker &runner)
case MainThreadCall: {
MainThreadCallData &calldata = std::get<MainThreadCall>(m_data);
calldata.fn();
calldata.barrier.set_value();
calldata.promise.set_value();
break;
}
@ -69,7 +69,7 @@ void BoostThreadWorker::update_status(int st, const std::string &msg)
std::future<void> BoostThreadWorker::call_on_main_thread(std::function<void ()> fn)
{
MainThreadCallData cbdata{std::move(fn), {}};
std::future<void> future = cbdata.barrier.get_future();
std::future<void> future = cbdata.promise.get_future();
m_output_queue.push(std::move(cbdata));
@ -77,8 +77,8 @@ std::future<void> BoostThreadWorker::call_on_main_thread(std::function<void ()>
}
BoostThreadWorker::BoostThreadWorker(std::shared_ptr<ProgressIndicator> pri,
boost::thread::attributes &attribs,
const char * name)
boost::thread::attributes &attribs,
const char * name)
: m_progress(std::move(pri)), m_name{name}
{
if (m_progress)

View File

@ -39,7 +39,7 @@ class BoostThreadWorker : public Worker, private Job::Ctl
struct MainThreadCallData
{
std::function<void()> fn;
std::promise<void> barrier;
std::promise<void> promise;
};
class WorkerMessage
@ -55,6 +55,8 @@ class BoostThreadWorker : public Worker, private Job::Ctl
WorkerMessage(JobEntry &&entry) : m_data{std::move(entry)} {}
WorkerMessage(MainThreadCallData fn) : m_data{std::move(fn)} {}
int get_type () const { return m_data.index(); }
void deliver(BoostThreadWorker &runner);
};

View File

@ -105,7 +105,9 @@ void FillBedJob::prepare()
void FillBedJob::process(Ctl &ctl)
{
ctl.call_on_main_thread([this]{ prepare(); }).wait();
auto statustxt = _u8L("Filling bed");
ctl.call_on_main_thread([this] { prepare(); }).wait();
ctl.update_status(0, statustxt);
if (m_object_idx == -1 || m_selected.empty()) return;
@ -121,10 +123,6 @@ void FillBedJob::process(Ctl &ctl)
return ctl.was_canceled() || do_stop;
};
auto statustxt = _u8L("Filling bed");
ctl.update_status(0, statustxt);
params.progressind = [this, &ctl, &statustxt](unsigned st) {
if (st > 0)
ctl.update_status(int(m_status_range - st) * 100 / status_range(), statustxt);

View File

@ -1,5 +1,5 @@
#ifndef PLATERJOB_HPP
#define PLATERJOB_HPP
#ifndef PLATERWORKER_HPP
#define PLATERWORKER_HPP
#include "BusyCursorJob.hpp"
@ -24,8 +24,32 @@ class PlaterWorker: public Worker {
public:
void process(Ctl &c) override
{
CursorSetterRAII busycursor{c};
m_job->process(c);
// Ensure that wxWidgets processing wakes up to handle outgoing
// messages in plater's wxIdle handler. Otherwise it might happen
// that the message will only be processed when an event like mouse
// move comes along which might be too late.
struct WakeUpCtl: Ctl {
Ctl &ctl;
WakeUpCtl(Ctl &c) : ctl{c} {}
void update_status(int st, const std::string &msg = "") override
{
wxWakeUpIdle();
ctl.update_status(st, msg);
}
bool was_canceled() const override { return ctl.was_canceled(); }
std::future<void> call_on_main_thread(std::function<void()> fn) override
{
wxWakeUpIdle();
return ctl.call_on_main_thread(std::move(fn));
}
} wctl{c};
CursorSetterRAII busycursor{wctl};
m_job->process(wctl);
}
void finalize(bool canceled, std::exception_ptr &eptr) override
@ -60,10 +84,18 @@ class PlaterWorker: public Worker {
}
};
public:
template<class ... WorkerArgs>
PlaterWorker(WorkerArgs &&...args) : m_w{std::forward<WorkerArgs>(args)...} {}
public:
template<class... WorkerArgs>
PlaterWorker(Plater *plater, WorkerArgs &&...args)
: m_w{std::forward<WorkerArgs>(args)...}
{
// Ensure that messages from the worker thread to the UI thread are
// processed continuously.
plater->Bind(wxEVT_IDLE, [this](wxIdleEvent &) {
m_w.process_events();
});
}
// Always package the job argument into a PlaterJob
bool start_next(std::unique_ptr<Job> job) override
@ -74,7 +106,7 @@ public:
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(); }
void process_events() override {}
};
}} // namespace Slic3r::GUI

View File

@ -75,7 +75,7 @@
#include "Jobs/SLAImportJob.hpp"
#include "Jobs/SLAImportDialog.hpp"
#include "Jobs/NotificationProgressIndicator.hpp"
#include "Jobs/PlaterJob.hpp"
#include "Jobs/PlaterWorker.hpp"
#include "Jobs/BoostThreadWorker.hpp"
#include "BackgroundSlicingProcess.hpp"
#include "PrintHostDialogs.hpp"
@ -1943,7 +1943,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
}))
, sidebar(new Sidebar(q))
, notification_manager(std::make_unique<NotificationManager>(q))
, m_worker{std::make_unique<NotificationProgressIndicator>(notification_manager.get()), "ui_worker"}
, m_worker{q, std::make_unique<NotificationProgressIndicator>(notification_manager.get()), "ui_worker"}
, m_sla_import_dlg{new SLAImportDialog{q}}
, delayed_scene_refresh(false)
, view_toolbar(GLToolbar::Radio, "View")
@ -2173,12 +2173,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
sidebar->collapse(is_collapsed);
}
// 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();
});
}
Plater::priv::~priv()