Fixed shared_ptr cycle in TabFilament::add_filament_overrides_page(), TabFilament::build(), and TabFilament::build_fff(), which also caused a memory leak.

This commit is contained in:
Lukáš Hejl 2022-01-28 09:46:03 +01:00
parent dcecd96b39
commit c8d4eb5788
2 changed files with 44 additions and 38 deletions

View File

@ -18,6 +18,7 @@ namespace GUI {
class ConfigOptionsGroup;
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
using ConfigOptionsGroupWkp = std::weak_ptr<ConfigOptionsGroup>;
struct BedShape
{

View File

@ -1808,8 +1808,8 @@ bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode)
return !invalid;
}
static void validate_custom_gcode_cb(Tab* tab, ConfigOptionsGroupShp opt_group, const t_config_option_key& opt_key, const boost::any& value) {
tab->validate_custom_gcodes_was_shown = !Tab::validate_custom_gcode(opt_group->title, boost::any_cast<std::string>(value));
static void validate_custom_gcode_cb(Tab* tab, const wxString& title, const t_config_option_key& opt_key, const boost::any& value) {
tab->validate_custom_gcodes_was_shown = !Tab::validate_custom_gcode(title, boost::any_cast<std::string>(value));
tab->update_dirty();
tab->on_value_change(opt_key, value);
}
@ -1830,19 +1830,20 @@ void TabFilament::add_filament_overrides_page()
else
line = optgroup->create_single_option_line(optgroup->get_option(opt_key));
line.near_label_widget = [this, optgroup, opt_key, opt_index](wxWindow* parent) {
line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), opt_key, opt_index](wxWindow* parent) {
wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, "");
check_box->Bind(wxEVT_CHECKBOX, [optgroup, opt_key, opt_index](wxCommandEvent& evt) {
check_box->Bind(wxEVT_CHECKBOX, [optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) {
const bool is_checked = evt.IsChecked();
Field* field = optgroup->get_fieldc(opt_key, opt_index);
if (field != nullptr) {
if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) {
if (Field *field = optgroup_sh->get_fieldc(opt_key, opt_index); field != nullptr) {
field->toggle(is_checked);
if (is_checked)
field->set_last_meaningful_value();
else
field->set_na_value();
}
}
}, check_box->GetId());
m_overrides_options[opt_key] = check_box;
@ -1926,7 +1927,7 @@ void TabFilament::build()
optgroup->append_single_option_line("filament_cost");
optgroup->append_single_option_line("filament_spool_weight");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value)
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value)
{
update_dirty();
if (opt_key == "filament_spool_weight") {
@ -2038,8 +2039,8 @@ void TabFilament::build()
page = add_options_page(L("Custom G-code"), "cog");
optgroup = page->new_optgroup(L("Start G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("start_filament_gcode");
option.opt.full_width = true;
@ -2048,8 +2049,8 @@ void TabFilament::build()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("End G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("end_filament_gcode");
option.opt.full_width = true;
@ -2260,11 +2261,15 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup->append_single_option_line("single_extruder_multi_material");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) {
optgroup->m_on_change = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup)](t_config_option_key opt_key, boost::any value) {
auto optgroup_sh = optgroup_wk.lock();
if (!optgroup_sh)
return;
// optgroup->get_value() return int for def.type == coInt,
// Thus, there should be boost::any_cast<int> !
// Otherwise, boost::any_cast<size_t> causes an "unhandled unknown exception"
size_t extruders_count = size_t(boost::any_cast<int>(optgroup->get_value("extruders_count")));
size_t extruders_count = size_t(boost::any_cast<int>(optgroup_sh->get_value("extruders_count")));
wxTheApp->CallAfter([this, opt_key, value, extruders_count]() {
if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") {
extruders_count_changed(extruders_count);
@ -2323,7 +2328,7 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line("silent_mode");
optgroup->append_single_option_line("remaining_times");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) {
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
wxTheApp->CallAfter([this, opt_key, value]() {
if (opt_key == "silent_mode") {
bool val = boost::any_cast<bool>(value);
@ -2358,8 +2363,8 @@ void TabPrinter::build_fff()
const int notes_field_height = 25; // 250
page = add_options_page(L("Custom G-code"), "cog");
optgroup = page->new_optgroup(L("Start G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("start_gcode");
option.opt.full_width = true;
@ -2368,8 +2373,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("End G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("end_gcode");
option.opt.full_width = true;
@ -2378,8 +2383,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Before layer change G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("before_layer_gcode");
option.opt.full_width = true;
@ -2388,8 +2393,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("After layer change G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("layer_gcode");
option.opt.full_width = true;
@ -2398,8 +2403,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Tool change G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("toolchange_gcode");
option.opt.full_width = true;
@ -2408,8 +2413,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Between objects G-code (for sequential printing)"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("between_objects_gcode");
option.opt.full_width = true;
@ -2418,8 +2423,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Color Change G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("color_change_gcode");
option.opt.is_code = true;
@ -2427,8 +2432,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Pause Print G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("pause_print_gcode");
option.opt.is_code = true;
@ -2436,8 +2441,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Template Custom G-code"), 0);
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
option = optgroup->get_option("template_custom_gcode");
option.opt.is_code = true;
@ -4468,7 +4473,7 @@ void TabSLAMaterial::build()
optgroup->append_single_option_line("bottle_weight");
optgroup->append_single_option_line("material_density");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value)
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value)
{
if (opt_key == "material_colour") {
update_dirty();