WIP: Fixed some issues with cancelation & restart of background processing.

This commit is contained in:
bubnikv 2018-10-30 09:27:31 +01:00
parent 6ae1517e13
commit f2b0904d12
4 changed files with 67 additions and 14 deletions

View file

@ -837,6 +837,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
enum Status {
Unknown,
Deleted,
Reused,
New
};
PrintObjectStatus(PrintObject *print_object, Status status = Unknown) :
@ -931,6 +932,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
{
std::vector<PrintObject*> print_objects_new;
print_objects_new.reserve(std::max(m_objects.size(), m_model.objects.size()));
bool new_objects = false;
// Walk over all new model objects and check, whether there are matching PrintObjects.
for (ModelObject *model_object : m_model.objects) {
auto range = print_object_status.equal_range(PrintObjectStatus(model_object->id()));
@ -953,7 +955,8 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
print_object->set_copies(print_instances.copies);
print_object->config_apply(config);
print_objects_new.emplace_back(print_object);
print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New));
// print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New));
new_objects = true;
}
continue;
}
@ -971,7 +974,10 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
print_object->set_copies(new_instances.copies);
print_object->config_apply(config);
print_objects_new.emplace_back(print_object);
print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New));
// print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New));
new_objects = true;
if (it_old != old.end())
const_cast<PrintObjectStatus*>(*it_old)->status = PrintObjectStatus::Deleted;
} else if ((*it_old)->print_object->copies() != new_instances.copies) {
// The PrintObject already exists and the copies differ.
if ((*it_old)->print_object->copies().size() != new_instances.copies.size())
@ -979,14 +985,26 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
update_apply_status(this->invalidate_step(psSkirt) || this->invalidate_step(psBrim) || this->invalidate_step(psGCodeExport));
(*it_old)->print_object->set_copies(new_instances.copies);
print_objects_new.emplace_back((*it_old)->print_object);
const_cast<PrintObjectStatus*>(*it_old)->status = PrintObjectStatus::Reused;
}
}
}
if (m_objects != print_objects_new) {
m_cancel_callback();
m_objects = print_objects_new;
update_apply_status(false);
// Delete the PrintObjects marked as Unknown or Deleted.
bool deleted_objects = false;
for (auto &pos : print_object_status)
if (pos.status == PrintObjectStatus::Unknown || pos.status == PrintObjectStatus::Deleted) {
// update_apply_status(pos.print_object->invalidate_all_steps());
delete pos.print_object;
deleted_objects = true;
}
if (deleted_objects)
update_apply_status(this->invalidate_step(psSkirt) || this->invalidate_step(psBrim) || this->invalidate_step(psWipeTower) || this->invalidate_step(psGCodeExport));
update_apply_status(new_objects);
}
print_object_status.clear();
}
// 5) Synchronize configs of ModelVolumes, synchronize AMF / 3MF materials (and their configs), refresh PrintRegions.

View file

@ -485,11 +485,22 @@ public:
// the state of the finished or running calculations.
void set_cancel_callback(cancel_callback_type cancel_callback) { m_cancel_callback = cancel_callback; }
// Has the calculation been canceled?
bool canceled() const { return m_canceled; }
enum CancelStatus {
// No cancelation, background processing should run.
NOT_CANCELED = 0,
// Canceled by user from the user interface (user pressed the "Cancel" button or user closed the application).
CANCELED_BY_USER = 1,
// Canceled internally from Print::apply() through the Print/PrintObject::invalidate_step() or ::invalidate_all_steps().
CANCELED_INTERNAL = 2
};
CancelStatus cancel_status() const { return m_cancel_status; }
// Has the calculation been canceled?
bool canceled() const { return m_cancel_status; }
// Cancel the running computation. Stop execution of all the background threads.
void cancel() { m_canceled = true; }
void cancel() { m_cancel_status = CANCELED_BY_USER; }
void cancel_internal() { m_cancel_status = CANCELED_INTERNAL; }
// Cancel the running computation. Stop execution of all the background threads.
void restart() { m_canceled = false; }
void restart() { m_cancel_status = NOT_CANCELED; }
// Accessed by SupportMaterial
const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; }
@ -513,7 +524,7 @@ private:
// If the background processing stop was requested, throw CanceledException.
// To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
void throw_if_canceled() const { if (m_canceled) throw CanceledException(); }
void throw_if_canceled() const { if (m_cancel_status) throw CanceledException(); }
void _make_skirt();
void _make_brim();
@ -526,8 +537,7 @@ private:
// while the data influencing the stage is modified.
mutable tbb::mutex m_mutex;
// Has the calculation been canceled?
tbb::atomic<bool> m_canceled;
tbb::atomic<CancelStatus> m_cancel_status;
// Callback to be evoked regularly to update state of the UI thread.
status_callback_type m_status_callback;