Clean StopableJob and use inheritance instead of set lambda
This commit is contained in:
parent
86a60863bf
commit
456952325f
@ -14,18 +14,12 @@ using namespace Slic3r;
|
|||||||
using namespace GUI;
|
using namespace GUI;
|
||||||
|
|
||||||
namespace Priv {
|
namespace Priv {
|
||||||
|
|
||||||
static void process(std::unique_ptr<EmbossData> input, StopCondition is_stop);
|
|
||||||
static void finalize(const EmbossData &input, const indexed_triangle_set &result);
|
static void finalize(const EmbossData &input, const indexed_triangle_set &result);
|
||||||
|
// TODO: May be move to objec list utils
|
||||||
// TODO: move to objec list utils
|
|
||||||
static void select_volume(ModelVolume *volume);
|
static void select_volume(ModelVolume *volume);
|
||||||
|
|
||||||
} // namespace Priv
|
} // namespace Priv
|
||||||
|
|
||||||
EmbossJob::EmbossJob() : StopableJob<EmbossData>(Priv::process) {}
|
void EmbossJob::process(std::unique_ptr<EmbossData> input, StopCondition is_stop)
|
||||||
|
|
||||||
void Priv::process(std::unique_ptr<EmbossData> input, StopCondition is_stop)
|
|
||||||
{
|
{
|
||||||
// Changing cursor to busy
|
// Changing cursor to busy
|
||||||
wxBeginBusyCursor();
|
wxBeginBusyCursor();
|
||||||
|
@ -26,8 +26,8 @@ struct EmbossData
|
|||||||
|
|
||||||
class EmbossJob : public StopableJob<EmbossData>
|
class EmbossJob : public StopableJob<EmbossData>
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
EmbossJob();
|
void process(std::unique_ptr<EmbossData> input, StopCondition is_stop) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r::GUI
|
} // namespace Slic3r::GUI
|
||||||
|
@ -22,85 +22,137 @@ template<typename TIn> class StopableJob
|
|||||||
bool m_running = false;
|
bool m_running = false;
|
||||||
// faster interupt inside func, developer must add StopCondifion call
|
// faster interupt inside func, developer must add StopCondifion call
|
||||||
bool m_stop = false;
|
bool m_stop = false;
|
||||||
|
|
||||||
using Func = std::function<void(std::unique_ptr<TIn>, StopCondition)>;
|
|
||||||
Func m_func;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StopableJob(Func func) : m_func(func) {}
|
/// <summary>
|
||||||
virtual ~StopableJob() {
|
/// Stop and join thread
|
||||||
stop();
|
/// </summary>
|
||||||
try {
|
virtual ~StopableJob();
|
||||||
// thread join could throw exception
|
|
||||||
// https://en.cppreference.com/w/cpp/thread/thread/join
|
|
||||||
join();
|
|
||||||
} catch (std::system_error err) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
void run(std::unique_ptr<TIn> input)
|
/// <summary>
|
||||||
{
|
/// Restart processing of input
|
||||||
if (input == nullptr) return;
|
/// </summary>
|
||||||
{
|
/// <param name="input">Data needed to process</param>
|
||||||
// keep access to next input
|
void run(std::unique_ptr<TIn> input);
|
||||||
std::lock_guard lg(m_mutex);
|
|
||||||
if (m_running) {
|
|
||||||
// when runnig
|
|
||||||
m_stop = true;
|
|
||||||
m_input_next = std::move(input);
|
|
||||||
return; // on end of run will be used new input
|
|
||||||
}
|
|
||||||
m_running = true;
|
|
||||||
m_stop = false;
|
|
||||||
}
|
|
||||||
if (m_thread.joinable()) m_thread.join();
|
|
||||||
// at this moment is not running --> stoped
|
|
||||||
assert(m_input_next == nullptr);
|
|
||||||
try { // Execute the job
|
|
||||||
m_thread = std::thread(
|
|
||||||
[this](std::unique_ptr<TIn> input) {
|
|
||||||
do {
|
|
||||||
m_func(std::move(input), [this]() { return is_stoping(); });
|
|
||||||
|
|
||||||
std::lock_guard lg(m_mutex);
|
/// <summary>
|
||||||
m_stop = false;
|
/// Check if job processing input now
|
||||||
// this is not while (end)condition because of lock guard
|
/// </summary>
|
||||||
if (m_input_next == nullptr) {
|
/// <returns>True when run now otherwise False</returns>
|
||||||
m_running = false;
|
bool is_running(); // const; -- mutex
|
||||||
return;
|
|
||||||
}
|
|
||||||
input = std::move(m_input_next);
|
|
||||||
m_input_next = nullptr;
|
|
||||||
} while (true);
|
|
||||||
},
|
|
||||||
std::move(input));
|
|
||||||
} catch (std::exception &) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_running()
|
/// <summary>
|
||||||
{
|
/// Check if actual job is stopping now
|
||||||
std::lock_guard lg(m_mutex);
|
/// </summary>
|
||||||
return m_running;
|
/// <returns>True when at stop process otherwise False</returns>
|
||||||
}
|
bool is_stoping(); // const; -- mutex
|
||||||
bool is_stoping()
|
|
||||||
{
|
/// <summary>
|
||||||
std::lock_guard lg(m_mutex);
|
/// set flag to stop processing
|
||||||
return m_stop;
|
/// </summary>
|
||||||
}
|
void stop();
|
||||||
void stop() {
|
|
||||||
std::lock_guard lg(m_mutex);
|
/// <summary>
|
||||||
if (!m_running) return;
|
/// Free thread resources by join thread
|
||||||
m_input_next = nullptr;
|
/// Be Carefull, it is blocking until join
|
||||||
m_stop = true;
|
/// Suggest to call stop() before join
|
||||||
}
|
/// </summary>
|
||||||
// Be Carefull, blocking until join
|
void join();
|
||||||
// call stop when you not sure
|
protected:
|
||||||
void join(int timeout_ms = 0)
|
|
||||||
{
|
/// <summary>
|
||||||
if (m_thread.joinable()) m_thread.join();
|
/// Thread job of processing input data
|
||||||
assert(!m_running);
|
/// </summary>
|
||||||
}
|
/// <param name="input">input data to process</param>
|
||||||
|
/// <param name="stop_condition">When lambda is true, quit processing,
|
||||||
|
/// keep in mind check is under mutex so do it occasionally</param>
|
||||||
|
virtual void process(std::unique_ptr<TIn> input, StopCondition stop_condition) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//////
|
||||||
|
// Implementation
|
||||||
|
//////
|
||||||
|
template<typename TIn>
|
||||||
|
StopableJob<TIn>::~StopableJob()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
try {
|
||||||
|
// thread join could throw exception
|
||||||
|
// https://en.cppreference.com/w/cpp/thread/thread/join
|
||||||
|
join();
|
||||||
|
} catch (std::system_error err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TIn>
|
||||||
|
void StopableJob<TIn>::run(std::unique_ptr<TIn> input)
|
||||||
|
{
|
||||||
|
if (input == nullptr) return;
|
||||||
|
{
|
||||||
|
// keep access to next input
|
||||||
|
std::lock_guard lg(m_mutex);
|
||||||
|
if (m_running) {
|
||||||
|
// when runnig
|
||||||
|
m_stop = true;
|
||||||
|
m_input_next = std::move(input);
|
||||||
|
return; // on end of run will be used new input
|
||||||
|
}
|
||||||
|
m_running = true;
|
||||||
|
m_stop = false;
|
||||||
|
}
|
||||||
|
if (m_thread.joinable()) m_thread.join();
|
||||||
|
// at this moment is not running --> stoped
|
||||||
|
assert(m_input_next == nullptr);
|
||||||
|
try { // Execute the job
|
||||||
|
m_thread = std::thread(
|
||||||
|
[this](std::unique_ptr<TIn> input) {
|
||||||
|
do {
|
||||||
|
process(std::move(input), [this]() { return is_stoping(); });
|
||||||
|
|
||||||
|
std::lock_guard lg(m_mutex);
|
||||||
|
m_stop = false;
|
||||||
|
// this is not while (end)condition because of lock guard
|
||||||
|
if (m_input_next == nullptr) {
|
||||||
|
m_running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
input = std::move(m_input_next);
|
||||||
|
m_input_next = nullptr;
|
||||||
|
} while (true);
|
||||||
|
},
|
||||||
|
std::move(input));
|
||||||
|
} catch (std::exception &) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TIn>
|
||||||
|
bool StopableJob<TIn>::is_running()
|
||||||
|
{
|
||||||
|
std::lock_guard lg(m_mutex);
|
||||||
|
return m_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TIn>
|
||||||
|
bool StopableJob<TIn>::is_stoping()
|
||||||
|
{
|
||||||
|
std::lock_guard lg(m_mutex);
|
||||||
|
return m_stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TIn>
|
||||||
|
void StopableJob<TIn>::stop()
|
||||||
|
{
|
||||||
|
std::lock_guard lg(m_mutex);
|
||||||
|
if (!m_running) return;
|
||||||
|
m_input_next = nullptr;
|
||||||
|
m_stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TIn>
|
||||||
|
void StopableJob<TIn>::join()
|
||||||
|
{
|
||||||
|
if (m_thread.joinable()) m_thread.join();
|
||||||
|
assert(!m_running);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r::GUI
|
} // namespace Slic3r::GUI
|
||||||
|
|
||||||
#endif // slic3r_StopableJob_hpp_
|
#endif // slic3r_StopableJob_hpp_
|
||||||
|
Loading…
Reference in New Issue
Block a user