diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 35e05f506..0227cc266 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -192,6 +192,7 @@ set(SLIC3R_GUI_SOURCES GUI/Jobs/BoostThreadWorker.cpp GUI/Jobs/UIThreadWorker.hpp GUI/Jobs/BusyCursorJob.hpp + GUI/Jobs/CancellableJob.hpp GUI/Jobs/PlaterWorker.hpp GUI/Jobs/ArrangeJob.hpp GUI/Jobs/ArrangeJob.cpp diff --git a/src/slic3r/GUI/Jobs/CancellableJob.hpp b/src/slic3r/GUI/Jobs/CancellableJob.hpp new file mode 100644 index 000000000..ea8d676cc --- /dev/null +++ b/src/slic3r/GUI/Jobs/CancellableJob.hpp @@ -0,0 +1,60 @@ +#ifndef CANCELLABLEJOB_HPP +#define CANCELLABLEJOB_HPP + +#include + +#include "Job.hpp" + +namespace Slic3r { namespace GUI { + +template +class CancellableJob: public Job { + JobSubclass m_job; + std::atomic_bool &m_flag; + +public: + template + CancellableJob(std::atomic_bool &flag, Args &&...args) + : m_job{std::forward(args)...}, m_flag{flag} + {} + + void process(Ctl &ctl) override + { + m_flag.store(false); + + struct CancelCtl : public Ctl + { + Ctl &basectl; + std::atomic_bool &cflag; + + CancelCtl (Ctl &c, std::atomic_bool &f): basectl{c}, cflag{f} {} + + void update_status(int st, const std::string &msg = "") override + { + basectl.update_status(st, msg); + } + + bool was_canceled() const override + { + return cflag.load() || basectl.was_canceled(); + } + + std::future call_on_main_thread( + std::function fn) override + { + return basectl.call_on_main_thread(fn); + } + } cctl(ctl, m_flag); + + m_job.process(cctl); + } + + void finalize(bool canceled, std::exception_ptr &eptr) override + { + m_job.finalize(m_flag.load() || canceled, eptr); + } +}; + +}} // namespace Slic3r::GUI + +#endif // CANCELLABLEJOB_HPP