Implemented generic mechanism for executing tasks on UI thread synchronously

from the background slicing thread, that supports cancellation.
The generic mechanism is used for generating thumbnails into G-code and
Fixes Fix deadlock when canceling the slicing while gcode is creating thumbnails #6476
Thanks @supermerill for pointing out the issue.
This commit is contained in:
Vojtech Bubnik 2021-05-04 16:07:25 +02:00
parent 5f5d0df47e
commit 1aef86f650
5 changed files with 126 additions and 46 deletions

View file

@ -1684,7 +1684,7 @@ struct Plater::priv
bool can_split(bool to_objects) const;
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background);
void generate_thumbnails(ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background);
ThumbnailsList generate_thumbnails(const ThumbnailsParams& params);
void bring_instance_forward() const;
@ -1760,15 +1760,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
background_process.set_fff_print(&fff_print);
background_process.set_sla_print(&sla_print);
background_process.set_gcode_result(&gcode_result);
background_process.set_thumbnail_cb([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background)
{
std::packaged_task<void(ThumbnailsList&, const Vec2ds&, bool, bool, bool, bool)> task([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) {
generate_thumbnails(thumbnails, sizes, printable_only, parts_only, show_bed, transparent_background);
});
std::future<void> result = task.get_future();
wxTheApp->CallAfter([&]() { task(thumbnails, sizes, printable_only, parts_only, show_bed, transparent_background); });
result.wait();
});
background_process.set_thumbnail_cb([this](const ThumbnailsParams& params) { return this->generate_thumbnails(params); });
background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED);
background_process.set_finished_event(EVT_PROCESS_COMPLETED);
background_process.set_export_began_event(EVT_EXPORT_BEGAN);
@ -3812,17 +3804,17 @@ void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsig
view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only, show_bed, transparent_background);
}
void Plater::priv::generate_thumbnails(ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background)
ThumbnailsList Plater::priv::generate_thumbnails(const ThumbnailsParams& params)
{
thumbnails.clear();
for (const Vec2d& size : sizes)
{
ThumbnailsList thumbnails;
for (const Vec2d& size : params.sizes) {
thumbnails.push_back(ThumbnailData());
Point isize(size); // round to ints
generate_thumbnail(thumbnails.back(), isize.x(), isize.y(), printable_only, parts_only, show_bed, transparent_background);
generate_thumbnail(thumbnails.back(), isize.x(), isize.y(), params.printable_only, params.parts_only, params.show_bed, params.transparent_background);
if (!thumbnails.back().is_valid())
thumbnails.pop_back();
}
return thumbnails;
}
wxString Plater::priv::get_project_filename(const wxString& extension) const