Fix Crash when using m_ProfileJson (#79)

* Recover: Packaging Process

* Update: Flutter 1222

* Fix: crash when recreate GUI

* Fix Crash when using m_profile_json
This commit is contained in:
xiaoyeliu
2025-12-22 16:24:48 +08:00
committed by GitHub
parent f6899b277f
commit f729c53b20
4 changed files with 161 additions and 91 deletions

View File

@@ -698,7 +698,7 @@ std::string AppConfig::load()
auto it_app = m_storage.find("app"); auto it_app = m_storage.find("app");
if (it_app != m_storage.end()) { if (it_app != m_storage.end()) {
auto it_region = it_app->second.find("region"); auto it_region = it_app->second.find("region");
if (it_region != it_app->second.end() && it_region->second == "China") { if (it_region != it_app->second.end() && (it_region->second == "China" || it_region->second == "")) {
it_region->second = "Chinese Mainland"; it_region->second = "Chinese Mainland";
m_dirty = true; m_dirty = true;
} }

View File

@@ -28,6 +28,7 @@
#include "MoonRaker.hpp" #include "MoonRaker.hpp"
#include "slic3r/GUI/WebPresetDialog.hpp" #include "slic3r/GUI/WebPresetDialog.hpp"
#include <mutex>
#include "slic3r/GUI/SMPhysicalPrinterDialog.hpp" #include "slic3r/GUI/SMPhysicalPrinterDialog.hpp"
#include "slic3r/GUI/WebUrlDialog.hpp" #include "slic3r/GUI/WebUrlDialog.hpp"
@@ -184,6 +185,7 @@ WCP_Logger::~WCP_Logger()
} }
extern json m_ProfileJson; extern json m_ProfileJson;
extern std::mutex m_ProfileJson_mutex;
std::vector<std::string> load_thumbnails(const std::string& file, size_t image_count) std::vector<std::string> load_thumbnails(const std::string& file, size_t image_count)
{ {
@@ -5236,6 +5238,8 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
m_dialog->m_device_id = ip; m_dialog->m_device_id = ip;
// 检查是否该预设已经选入系统 // 检查是否该预设已经选入系统
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
int nModel = m_ProfileJson["model"].size(); int nModel = m_ProfileJson["model"].size();
bool isFind = false; bool isFind = false;
for (int m = 0; m < nModel; m++) { for (int m = 0; m < nModel; m++) {
@@ -5261,6 +5265,7 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
new_item["nozzle_selected"] = nozzle_diameters[0]; new_item["nozzle_selected"] = nozzle_diameters[0];
m_ProfileJson["model"].push_back(new_item); m_ProfileJson["model"].push_back(new_item);
} }
}
wxGetApp().mainframe->plater()->sidebar().update_all_preset_comboboxes(false); wxGetApp().mainframe->plater()->sidebar().update_all_preset_comboboxes(false);

View File

@@ -33,12 +33,14 @@
#include <libslic3r/miniz_extension.hpp> #include <libslic3r/miniz_extension.hpp>
#include <libslic3r/Utils.hpp> #include <libslic3r/Utils.hpp>
#include "CreatePresetsDialog.hpp" #include "CreatePresetsDialog.hpp"
#include <mutex>
using namespace nlohmann; using namespace nlohmann;
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
json m_ProfileJson; json m_ProfileJson;
std::mutex m_ProfileJson_mutex;
static wxString update_custom_filaments() static wxString update_custom_filaments()
{ {
@@ -229,7 +231,11 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load)
} else if (startpage == BBL_FILAMENTS) { } else if (startpage == BBL_FILAMENTS) {
SetTitle(_L("Setup Wizard")); SetTitle(_L("Setup Wizard"));
int nSize = m_ProfileJson["model"].size(); int nSize;
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
nSize = m_ProfileJson["model"].size();
}
if (nSize>0) if (nSize>0)
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=22").make_preferred().string()); TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=22").make_preferred().string());
@@ -403,7 +409,10 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
json m_Res = json::object(); json m_Res = json::object();
m_Res["command"] = "response_userguide_profile"; m_Res["command"] = "response_userguide_profile";
m_Res["sequence_id"] = "10001"; m_Res["sequence_id"] = "10001";
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
m_Res["response"] = m_ProfileJson; m_Res["response"] = m_ProfileJson;
}
//wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', false, json::error_handler_t::ignore)); //wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', false, json::error_handler_t::ignore));
wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', true)); wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', true));
@@ -426,6 +435,8 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
{ {
json MSelected = j["data"]; json MSelected = j["data"];
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
int nModel = m_ProfileJson["model"].size(); int nModel = m_ProfileJson["model"].size();
for (int m = 0; m < nModel; m++) { for (int m = 0; m < nModel; m++) {
json TmpModel = m_ProfileJson["model"][m]; json TmpModel = m_ProfileJson["model"][m];
@@ -443,7 +454,10 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
} }
} }
} }
}
else if (strCmd == "save_userguide_filaments") { else if (strCmd == "save_userguide_filaments") {
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
//reset //reset
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it)
{ {
@@ -459,10 +473,15 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
m_ProfileJson["filament"][fName]["selected"] = 1; m_ProfileJson["filament"][fName]["selected"] = 1;
} }
} }
}
else if (strCmd == "user_guide_finish") { else if (strCmd == "user_guide_finish") {
SaveProfile(); SaveProfile();
std::string oldregion = m_ProfileJson["region"]; std::string oldregion;
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
oldregion = m_ProfileJson["region"];
}
bool bLogin = false; bool bLogin = false;
if (m_Region != oldregion) { if (m_Region != oldregion) {
AppConfig* config = GUI::wxGetApp().app_config; AppConfig* config = GUI::wxGetApp().app_config;
@@ -492,8 +511,11 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
this->Close(); this->Close();
} else if (strCmd == "save_region") { } else if (strCmd == "save_region") {
m_Region = j["region"]; m_Region = j["region"];
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
m_ProfileJson["region"] = m_Region; m_ProfileJson["region"] = m_Region;
} }
}
else if (strCmd == "common_openurl") { else if (strCmd == "common_openurl") {
std::string url = j["url"]; std::string url = j["url"];
@@ -635,7 +657,11 @@ int GuideFrame::SaveProfile()
m_MainPtr->app_config->save(); m_MainPtr->app_config->save();
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore); std::string strAll;
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "before save to app_config: "<< std::endl<<strAll; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "before save to app_config: "<< std::endl<<strAll;
@@ -643,16 +669,21 @@ int GuideFrame::SaveProfile()
const std::string &section_name = AppConfig::SECTION_FILAMENTS; const std::string &section_name = AppConfig::SECTION_FILAMENTS;
std::map<std::string, std::string> section_new; std::map<std::string, std::string> section_new;
m_appconfig_new.clear_section(section_name); m_appconfig_new.clear_section(section_name);
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) { for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
if (it.value()["selected"] == 1){ if (it.value()["selected"] == 1){
section_new[it.key()] = "true"; section_new[it.key()] = "true";
} }
} }
}
m_appconfig_new.set_section(section_name, section_new); m_appconfig_new.set_section(section_name, section_new);
//set vendors to app_config //set vendors to app_config
Slic3r::AppConfig::VendorMap empty_vendor_map; Slic3r::AppConfig::VendorMap empty_vendor_map;
m_appconfig_new.set_vendors(empty_vendor_map); m_appconfig_new.set_vendors(empty_vendor_map);
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
for (auto it = m_ProfileJson["model"].begin(); it != m_ProfileJson["model"].end(); ++it) for (auto it = m_ProfileJson["model"].begin(); it != m_ProfileJson["model"].end(); ++it)
{ {
if (it.value().is_object()) { if (it.value().is_object()) {
@@ -997,6 +1028,7 @@ int GuideFrame::GetFilamentInfo( std::string VendorDirectory, json & pFilaList,
int GuideFrame::LoadProfileData() int GuideFrame::LoadProfileData()
{ {
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
try { try {
m_ProfileJson = json::parse("{}"); m_ProfileJson = json::parse("{}");
m_ProfileJson["model"] = json::array(); m_ProfileJson["model"] = json::array();
@@ -1068,7 +1100,7 @@ int GuideFrame::LoadProfileData()
} }
//sync to web //sync to web
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore); std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore); // Already locked at function start
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: " << std::endl << strAll; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: " << std::endl << strAll;
json m_Res = json::object(); json m_Res = json::object();
@@ -1093,6 +1125,7 @@ int GuideFrame::LoadProfileData()
int GuideFrame::SaveProfileData() int GuideFrame::SaveProfileData()
{ {
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
try { try {
const auto enabled_filaments = wxGetApp().app_config->has_section(AppConfig::SECTION_FILAMENTS) ? wxGetApp().app_config->get_section(AppConfig::SECTION_FILAMENTS) : std::map<std::string, std::string>(); const auto enabled_filaments = wxGetApp().app_config->has_section(AppConfig::SECTION_FILAMENTS) ? wxGetApp().app_config->get_section(AppConfig::SECTION_FILAMENTS) : std::map<std::string, std::string>();
m_appconfig_new.set_vendors(*wxGetApp().app_config); m_appconfig_new.set_vendors(*wxGetApp().app_config);

View File

@@ -30,12 +30,14 @@
#include <libslic3r/Utils.hpp> #include <libslic3r/Utils.hpp>
#include "CreatePresetsDialog.hpp" #include "CreatePresetsDialog.hpp"
#include "slic3r/GUI/Tab.hpp" #include "slic3r/GUI/Tab.hpp"
#include <mutex>
using namespace nlohmann; using namespace nlohmann;
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
extern json m_ProfileJson; extern json m_ProfileJson;
extern std::mutex m_ProfileJson_mutex;
extern void StringReplace(string& strBase, string strSrc, string strDes); extern void StringReplace(string& strBase, string strSrc, string strDes);
static wxString update_custom_filaments() static wxString update_custom_filaments()
@@ -112,7 +114,7 @@ static wxString update_custom_filaments()
} }
WebPresetDialog::WebPresetDialog(GUI_App* pGUI, long style) WebPresetDialog::WebPresetDialog(GUI_App* pGUI, long style)
: DPIDialog((wxWindow*) (pGUI->mainframe), wxID_ANY, "Snapmaker Orca", wxDefaultPosition, wxDefaultSize, style), m_appconfig_new() : DPIDialog((wxWindow*) (nullptr), wxID_ANY, "Snapmaker Orca", wxDefaultPosition, wxDefaultSize, style), m_appconfig_new()
{ {
SetBackgroundColour(*wxWHITE); SetBackgroundColour(*wxWHITE);
// INI // INI
@@ -424,7 +426,11 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
m_Res["command"] = "response_userguide_profile"; m_Res["command"] = "response_userguide_profile";
m_Res["sequence_id"] = "10001"; m_Res["sequence_id"] = "10001";
json res_json = m_ProfileJson; json res_json;
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
res_json = m_ProfileJson;
}
// 把所有的选中信息取消,换成当前连接的机器 // 把所有的选中信息取消,换成当前连接的机器
std::string model_name = ""; std::string model_name = "";
@@ -491,6 +497,8 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
} else if (strCmd == "save_userguide_models") { } else if (strCmd == "save_userguide_models") {
json MSelected = j["data"]; json MSelected = j["data"];
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
int nModel = m_ProfileJson["model"].size(); int nModel = m_ProfileJson["model"].size();
bool isFind = false; bool isFind = false;
for (int m = 0; m < nModel; m++) { for (int m = 0; m < nModel; m++) {
@@ -513,6 +521,7 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
new_item["nozzle_selected"] = MSelected.begin().value()["nozzle_diameter"]; new_item["nozzle_selected"] = MSelected.begin().value()["nozzle_diameter"];
m_ProfileJson["model"].push_back(new_item); m_ProfileJson["model"].push_back(new_item);
} }
}
DeviceInfo info; DeviceInfo info;
if (wxGetApp().app_config->get_device_info(m_device_id, info)) { if (wxGetApp().app_config->get_device_info(m_device_id, info)) {
@@ -548,6 +557,8 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
} }
} else if (strCmd == "save_userguide_filaments") { } else if (strCmd == "save_userguide_filaments") {
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
// reset // reset
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) { for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
m_ProfileJson["filament"][it.key()]["selected"] = 0; m_ProfileJson["filament"][it.key()]["selected"] = 0;
@@ -560,10 +571,15 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
m_ProfileJson["filament"][fName]["selected"] = 1; m_ProfileJson["filament"][fName]["selected"] = 1;
} }
}
} else if (strCmd == "user_guide_finish") { } else if (strCmd == "user_guide_finish") {
SaveProfile(); SaveProfile();
std::string oldregion = m_ProfileJson["region"]; std::string oldregion;
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
oldregion = m_ProfileJson["region"];
}
bool bLogin = false; bool bLogin = false;
if (m_Region != oldregion) { if (m_Region != oldregion) {
AppConfig* config = GUI::wxGetApp().app_config; AppConfig* config = GUI::wxGetApp().app_config;
@@ -590,8 +606,11 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
this->Close(); this->Close();
} else if (strCmd == "save_region") { } else if (strCmd == "save_region") {
m_Region = j["region"]; m_Region = j["region"];
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
m_ProfileJson["region"] = m_Region; m_ProfileJson["region"] = m_Region;
} }
}
else if (strCmd == "common_openurl") { else if (strCmd == "common_openurl") {
std::string url = j["url"]; std::string url = j["url"];
@@ -622,7 +641,10 @@ void WebPresetDialog::OnScriptMessage(wxWebViewEvent& evt)
BOOST_LOG_TRIVIAL(trace) << "WebPresetDialog::OnScriptMessage;Error:" << e.what(); BOOST_LOG_TRIVIAL(trace) << "WebPresetDialog::OnScriptMessage;Error:" << e.what();
} }
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
wxString strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore); wxString strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
}
} }
void WebPresetDialog::RunScript(const wxString& javascript) void WebPresetDialog::RunScript(const wxString& javascript)
@@ -754,7 +776,11 @@ int WebPresetDialog::SaveProfile()
m_MainPtr->app_config->save(); m_MainPtr->app_config->save();
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore); std::string strAll;
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "before save to app_config: " << std::endl << strAll; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "before save to app_config: " << std::endl << strAll;
@@ -762,16 +788,21 @@ int WebPresetDialog::SaveProfile()
const std::string& section_name = AppConfig::SECTION_FILAMENTS; const std::string& section_name = AppConfig::SECTION_FILAMENTS;
std::map<std::string, std::string> section_new; std::map<std::string, std::string> section_new;
m_appconfig_new.clear_section(section_name); m_appconfig_new.clear_section(section_name);
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) { for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
if (it.value()["selected"] == 1) { if (it.value()["selected"] == 1) {
section_new[it.key()] = "true"; section_new[it.key()] = "true";
} }
} }
}
m_appconfig_new.set_section(section_name, section_new); m_appconfig_new.set_section(section_name, section_new);
// set vendors to app_config // set vendors to app_config
Slic3r::AppConfig::VendorMap empty_vendor_map; Slic3r::AppConfig::VendorMap empty_vendor_map;
m_appconfig_new.set_vendors(empty_vendor_map); m_appconfig_new.set_vendors(empty_vendor_map);
{
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
for (auto it = m_ProfileJson["model"].begin(); it != m_ProfileJson["model"].end(); ++it) { for (auto it = m_ProfileJson["model"].begin(); it != m_ProfileJson["model"].end(); ++it) {
if (it.value().is_object()) { if (it.value().is_object()) {
json temp_model = it.value(); json temp_model = it.value();
@@ -1121,6 +1152,7 @@ int WebPresetDialog::GetFilamentInfo(std::string VendorDirectory, json& pFilaLis
int WebPresetDialog::LoadProfile() int WebPresetDialog::LoadProfile()
{ {
std::lock_guard<std::mutex> lock(m_ProfileJson_mutex);
try { try {
// wxString ExePath = boost::dll::program_location().parent_path().string(); // wxString ExePath = boost::dll::program_location().parent_path().string();
// wxString TargetFolder = ExePath + "\\resources\\profiles\\"; // wxString TargetFolder = ExePath + "\\resources\\profiles\\";