mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-14 04:27:36 +00:00
fix: crash on windows
This commit is contained in:
@@ -1110,6 +1110,8 @@ void MainFrame::update_edge_panels()
|
|||||||
void MainFrame::shutdown()
|
void MainFrame::shutdown()
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "MainFrame::shutdown enter";
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "MainFrame::shutdown enter";
|
||||||
|
if (m_project != nullptr)
|
||||||
|
m_project->shutdown();
|
||||||
m_plugin_pages.shutdown();
|
m_plugin_pages.shutdown();
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// Edge panels are child windows — wxWidgets destroys them automatically.
|
// Edge panels are child windows — wxWidgets destroys them automatically.
|
||||||
|
|||||||
@@ -74,7 +74,18 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos,
|
|||||||
Fit();
|
Fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectPanel::~ProjectPanel() {}
|
ProjectPanel::~ProjectPanel()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectPanel::shutdown()
|
||||||
|
{
|
||||||
|
m_reload_cancel_token->store(true, std::memory_order_release);
|
||||||
|
if (m_reload_task && m_reload_task->joinable())
|
||||||
|
m_reload_task->join();
|
||||||
|
m_reload_task.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to convert newlines to <br>
|
// Helper to convert newlines to <br>
|
||||||
static std::string convert_newlines_to_br(const std::string& text) {
|
static std::string convert_newlines_to_br(const std::string& text) {
|
||||||
@@ -101,7 +112,17 @@ void ProjectPanel::onWebNavigating(wxWebViewEvent& evt)
|
|||||||
|
|
||||||
void ProjectPanel::on_reload(wxCommandEvent& evt)
|
void ProjectPanel::on_reload(wxCommandEvent& evt)
|
||||||
{
|
{
|
||||||
boost::thread reload = boost::thread([this] {
|
if (wxTheApp == nullptr || wxGetApp().is_closing() ||
|
||||||
|
m_reload_cancel_token->load(std::memory_order_acquire))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_reload_task && m_reload_task->joinable())
|
||||||
|
m_reload_task->join();
|
||||||
|
|
||||||
|
const auto cancel_token = m_reload_cancel_token;
|
||||||
|
m_reload_task = std::make_unique<boost::thread>([this, cancel_token] {
|
||||||
|
if (cancel_token->load(std::memory_order_acquire) || wxTheApp == nullptr || wxGetApp().is_closing())
|
||||||
|
return;
|
||||||
std::string update_type;
|
std::string update_type;
|
||||||
std::string license;
|
std::string license;
|
||||||
std::string model_name;
|
std::string model_name;
|
||||||
@@ -115,6 +136,9 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
|
|||||||
|
|
||||||
std::map<std::string, std::vector<json>> files;
|
std::map<std::string, std::vector<json>> files;
|
||||||
|
|
||||||
|
if (wxGetApp().plater() == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
Model model = wxGetApp().plater()->model();
|
Model model = wxGetApp().plater()->model();
|
||||||
|
|
||||||
auto model_info = model.model_info;
|
auto model_info = model.model_info;
|
||||||
@@ -156,7 +180,14 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
|
|||||||
std::string file_path = encode_path(wxGetApp().plater()->model().get_auxiliary_file_temp_path().c_str());
|
std::string file_path = encode_path(wxGetApp().plater()->model().get_auxiliary_file_temp_path().c_str());
|
||||||
if (!file_path.empty()) {
|
if (!file_path.empty()) {
|
||||||
files = Reload(file_path);
|
files = Reload(file_path);
|
||||||
wxGetApp().CallAfter([this, file_path, files] { m_auxiliary->Reload(file_path, files); });
|
if (cancel_token->load(std::memory_order_acquire) || wxTheApp == nullptr || wxGetApp().is_closing())
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxGetApp().CallAfter([this, cancel_token, file_path, files] {
|
||||||
|
if (cancel_token->load(std::memory_order_acquire) || wxTheApp == nullptr || wxGetApp().is_closing())
|
||||||
|
return;
|
||||||
|
m_auxiliary->Reload(file_path, files);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
clear_model_info();
|
clear_model_info();
|
||||||
return;
|
return;
|
||||||
@@ -215,15 +246,18 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
|
|||||||
|
|
||||||
json m_Res = json::object();
|
json m_Res = json::object();
|
||||||
m_Res["command"] = "show_3mf_info";
|
m_Res["command"] = "show_3mf_info";
|
||||||
m_Res["sequence_id"] = std::to_string(ProjectPanel::m_sequence_id++);
|
m_Res["sequence_id"] = std::to_string(ProjectPanel::m_sequence_id.fetch_add(1, std::memory_order_relaxed));
|
||||||
m_Res["model"] = j;
|
m_Res["model"] = j;
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
if (m_web_init_completed) {
|
if (m_web_init_completed.load(std::memory_order_acquire) &&
|
||||||
wxGetApp().CallAfter([this, strJS] {
|
!cancel_token->load(std::memory_order_acquire) && wxTheApp != nullptr && !wxGetApp().is_closing()) {
|
||||||
|
wxGetApp().CallAfter([this, cancel_token, strJS] {
|
||||||
|
if (cancel_token->load(std::memory_order_acquire) || wxTheApp == nullptr || wxGetApp().is_closing())
|
||||||
|
return;
|
||||||
RunScript(strJS.ToStdString());
|
RunScript(strJS.ToStdString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -264,7 +298,7 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strCmd == "request_3mf_info") {
|
else if (strCmd == "request_3mf_info") {
|
||||||
m_web_init_completed = true;
|
m_web_init_completed.store(true, std::memory_order_release);
|
||||||
}
|
}
|
||||||
else if (strCmd == "edit_project_info") {
|
else if (strCmd == "edit_project_info") {
|
||||||
show_info_editor(true);
|
show_info_editor(true);
|
||||||
@@ -307,13 +341,20 @@ void ProjectPanel::update_model_data()
|
|||||||
|
|
||||||
void ProjectPanel::clear_model_info()
|
void ProjectPanel::clear_model_info()
|
||||||
{
|
{
|
||||||
|
if (wxTheApp == nullptr || wxGetApp().is_closing() ||
|
||||||
|
m_reload_cancel_token->load(std::memory_order_acquire))
|
||||||
|
return;
|
||||||
|
|
||||||
json m_Res = json::object();
|
json m_Res = json::object();
|
||||||
m_Res["command"] = "clear_3mf_info";
|
m_Res["command"] = "clear_3mf_info";
|
||||||
m_Res["sequence_id"] = std::to_string(ProjectPanel::m_sequence_id++);
|
m_Res["sequence_id"] = std::to_string(ProjectPanel::m_sequence_id.fetch_add(1, std::memory_order_relaxed));
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
wxGetApp().CallAfter([this, strJS] {
|
const auto cancel_token = m_reload_cancel_token;
|
||||||
|
wxGetApp().CallAfter([this, cancel_token, strJS] {
|
||||||
|
if (cancel_token->load(std::memory_order_acquire) || wxTheApp == nullptr || wxGetApp().is_closing())
|
||||||
|
return;
|
||||||
RunScript(strJS.ToStdString());
|
RunScript(strJS.ToStdString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,11 @@
|
|||||||
#include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
#include "slic3r/Utils/json_diff.hpp"
|
#include "slic3r/Utils/json_diff.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <boost/thread.hpp>
|
||||||
#include "Event.hpp"
|
#include "Event.hpp"
|
||||||
#include "libslic3r/ProjectTask.hpp"
|
#include "libslic3r/ProjectTask.hpp"
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
@@ -60,14 +62,17 @@ struct project_file{
|
|||||||
class ProjectPanel : public wxPanel
|
class ProjectPanel : public wxPanel
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool m_web_init_completed = {false};
|
std::atomic<bool> m_web_init_completed{false};
|
||||||
bool m_reload_already = {false};
|
bool m_reload_already = {false};
|
||||||
|
|
||||||
|
std::shared_ptr<std::atomic<bool>> m_reload_cancel_token{std::make_shared<std::atomic<bool>>(false)};
|
||||||
|
std::unique_ptr<boost::thread> m_reload_task;
|
||||||
|
|
||||||
wxWebView* m_browser = {nullptr};
|
wxWebView* m_browser = {nullptr};
|
||||||
AuxiliaryPanel* m_auxiliary{nullptr};
|
AuxiliaryPanel* m_auxiliary{nullptr};
|
||||||
wxString m_project_home_url;
|
wxString m_project_home_url;
|
||||||
wxString m_root_dir;
|
wxString m_root_dir;
|
||||||
static inline int m_sequence_id = 8000;
|
static inline std::atomic<int> m_sequence_id{8000};
|
||||||
|
|
||||||
void show_info_editor(bool show);
|
void show_info_editor(bool show);
|
||||||
|
|
||||||
@@ -75,6 +80,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
ProjectPanel(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
|
ProjectPanel(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
|
||||||
~ProjectPanel();
|
~ProjectPanel();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
|
||||||
void onWebNavigating(wxWebViewEvent& evt);
|
void onWebNavigating(wxWebViewEvent& evt);
|
||||||
|
|||||||
@@ -8477,8 +8477,12 @@ void Page::activate(ConfigOptionMode mode, std::function<void()> throw_if_cancel
|
|||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
// BBS: fix field control position
|
// BBS: fix field control position
|
||||||
wxTheApp->CallAfter([this]() {
|
wxTheApp->CallAfter([wp = std::weak_ptr<Page>(shared_from_this())]() {
|
||||||
for (auto group : m_optgroups) {
|
auto page = wp.lock();
|
||||||
|
if (!page)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto group : page->m_optgroups) {
|
||||||
if (group->custom_ctrl)
|
if (group->custom_ctrl)
|
||||||
group->custom_ctrl->fixup_items_positions();
|
group->custom_ctrl->fixup_items_positions();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user