mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-19 03:13:39 +00:00
Async profile load on printer/filament selection screen (#9118)
The selection screen shows a loading indicator instead of frozen during the page loading process, during that time you will able to close the window if you want, instead of been stuck at this screen until it loaded:  Ported from BambuStudio, huge thanks to BambuLab!
This commit is contained in:
@@ -48,7 +48,7 @@ static wxString update_custom_filaments()
|
||||
json m_CustomFilaments = json::array();
|
||||
PresetBundle * preset_bundle = wxGetApp().preset_bundle;
|
||||
std::map<std::string, std::vector<Preset const *>> temp_filament_id_to_presets = preset_bundle->filaments.get_filament_presets();
|
||||
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> need_sort;
|
||||
bool need_delete_some_filament = false;
|
||||
for (std::pair<std::string, std::vector<Preset const *>> filament_id_to_presets : temp_filament_id_to_presets) {
|
||||
@@ -72,7 +72,7 @@ static wxString update_custom_filaments()
|
||||
auto filament_vendor = dynamic_cast<ConfigOptionStrings *>(const_cast<Preset *>(preset)->config.option("filament_vendor", false));
|
||||
if (filament_vendor && filament_vendor->values.size() && filament_vendor->values[0] == "Generic") not_need_show = true;
|
||||
}
|
||||
|
||||
|
||||
if (filament_name.empty()) {
|
||||
std::string preset_name = preset->name;
|
||||
size_t index_at = preset_name.find(" @");
|
||||
@@ -132,7 +132,7 @@ GuideFrame::GuideFrame(GUI_App *pGUI, long style)
|
||||
}
|
||||
m_browser->Hide();
|
||||
m_browser->SetSize(0, 0);
|
||||
|
||||
|
||||
SetSizer(topsizer);
|
||||
|
||||
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
|
||||
@@ -178,12 +178,6 @@ GuideFrame::GuideFrame(GUI_App *pGUI, long style)
|
||||
// Bind(wxEVT_IDLE, &GuideFrame::OnIdle, this);
|
||||
// Bind(wxEVT_CLOSE_WINDOW, &GuideFrame::OnClose, this);
|
||||
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
LoadProfile();
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ": LoadProfile() took " << duration.count() << " milliseconds";
|
||||
|
||||
// UI
|
||||
SetStartPage(BBL_REGION);
|
||||
|
||||
@@ -193,6 +187,12 @@ GuideFrame::GuideFrame(GUI_App *pGUI, long style)
|
||||
|
||||
GuideFrame::~GuideFrame()
|
||||
{
|
||||
m_destroy = true;
|
||||
if (m_load_task && m_load_task->joinable()) {
|
||||
m_load_task->join();
|
||||
delete m_load_task;
|
||||
m_load_task = nullptr;
|
||||
}
|
||||
if (m_browser) {
|
||||
delete m_browser;
|
||||
m_browser = nullptr;
|
||||
@@ -214,43 +214,43 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load)
|
||||
m_page = startpage;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" enter, load=%1%, start_page=%2%")%load%int(startpage);
|
||||
//wxLogMessage("GUIDE: webpage_1 %s", (boost::filesystem::path(resources_dir()) / "web\\guide\\1\\index.html").make_preferred().string().c_str() );
|
||||
wxString TargetUrl = from_u8( (boost::filesystem::path(resources_dir()) / "web/guide/1/index.html").make_preferred().string() );
|
||||
wxString TargetUrl = from_u8( (boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=1").make_preferred().string() );
|
||||
//wxLogMessage("GUIDE: webpage_2 %s", TargetUrl.mb_str());
|
||||
|
||||
if (startpage == BBL_WELCOME){
|
||||
SetTitle(_L("Setup Wizard"));
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/1/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=1").make_preferred().string());
|
||||
} else if (startpage == BBL_REGION) {
|
||||
SetTitle(_L("Setup Wizard"));
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/11/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=11").make_preferred().string());
|
||||
} else if (startpage == BBL_MODELS) {
|
||||
SetTitle(_L("Setup Wizard"));
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=21").make_preferred().string());
|
||||
} else if (startpage == BBL_FILAMENTS) {
|
||||
SetTitle(_L("Setup Wizard"));
|
||||
|
||||
int nSize = m_ProfileJson["model"].size();
|
||||
|
||||
if (nSize>0)
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/22/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=22").make_preferred().string());
|
||||
else
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=21").make_preferred().string());
|
||||
} else if (startpage == BBL_FILAMENT_ONLY) {
|
||||
SetTitle("");
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/23/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=23").make_preferred().string());
|
||||
} else if (startpage == BBL_MODELS_ONLY) {
|
||||
SetTitle("");
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/24/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=24").make_preferred().string());
|
||||
}
|
||||
else {
|
||||
SetTitle(_L("Setup Wizard"));
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string());
|
||||
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=21").make_preferred().string());
|
||||
}
|
||||
|
||||
wxString strlang = wxGetApp().current_language_code_safe();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(", strlang=%1%") % into_u8(strlang);
|
||||
if (strlang != "")
|
||||
TargetUrl = wxString::Format("%s?lang=%s", w2s(TargetUrl), strlang);
|
||||
TargetUrl = wxString::Format("%s&lang=%s", w2s(TargetUrl), strlang);
|
||||
|
||||
TargetUrl = "file://" + TargetUrl;
|
||||
if (load)
|
||||
@@ -301,9 +301,17 @@ void GuideFrame::OnNavigationRequest(wxWebViewEvent &evt)
|
||||
void GuideFrame::OnNavigationComplete(wxWebViewEvent &evt)
|
||||
{
|
||||
//wxLogMessage("%s", "Navigation complete; url='" + evt.GetURL() + "'");
|
||||
if (!bFirstComplete) {
|
||||
m_load_task = new boost::thread(boost::bind(&GuideFrame::LoadProfileData, this));
|
||||
// boost::thread LoadProfileThread(boost::bind(&GuideFrame::LoadProfileData, this));
|
||||
//LoadProfileThread.detach();
|
||||
|
||||
bFirstComplete = true;
|
||||
}
|
||||
|
||||
m_browser->Show();
|
||||
Layout();
|
||||
|
||||
|
||||
wxString NewUrl = evt.GetURL();
|
||||
|
||||
UpdateState();
|
||||
@@ -509,7 +517,7 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
|
||||
BOOST_LOG_TRIVIAL(trace) << "GuideFrame::OnScriptMessage;Error:" << e.what();
|
||||
}
|
||||
|
||||
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 GuideFrame::RunScript(const wxString &javascript)
|
||||
@@ -928,9 +936,9 @@ int GuideFrame::GetFilamentInfo( std::string VendorDirectory, json & pFilaList,
|
||||
if (jLocal.contains("inherits")) {
|
||||
std::string FName = jLocal["inherits"];
|
||||
|
||||
if (!pFilaList.contains(FName)) {
|
||||
if (!pFilaList.contains(FName)) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "pFilaList - Not Contains inherits filaments: " << FName;
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string FPath = pFilaList[FName]["sub_path"];
|
||||
@@ -976,8 +984,7 @@ int GuideFrame::GetFilamentInfo( std::string VendorDirectory, json & pFilaList,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int GuideFrame::LoadProfile()
|
||||
int GuideFrame::LoadProfileData()
|
||||
{
|
||||
try {
|
||||
m_ProfileJson = json::parse("{}");
|
||||
@@ -986,7 +993,7 @@ int GuideFrame::LoadProfile()
|
||||
m_ProfileJson["filament"] = json::object();
|
||||
m_ProfileJson["process"] = json::array();
|
||||
|
||||
vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR ).make_preferred();
|
||||
vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR).make_preferred();
|
||||
rsrc_vendor_dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred();
|
||||
|
||||
// Orca: add custom as default
|
||||
@@ -1028,6 +1035,8 @@ int GuideFrame::LoadProfile()
|
||||
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
||||
loaded_vendors.insert(w2s(strVendor));
|
||||
}
|
||||
if (m_destroy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
boost::filesystem::directory_iterator others_endIter;
|
||||
@@ -1043,10 +1052,37 @@ int GuideFrame::LoadProfile()
|
||||
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
||||
loaded_vendors.insert(w2s(strVendor));
|
||||
}
|
||||
if (m_destroy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//sync to web
|
||||
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: " << std::endl << strAll;
|
||||
json m_Res = json::object();
|
||||
m_Res["command"] = "userguide_profile_load_finish";
|
||||
m_Res["sequence_id"] = "10001";
|
||||
wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', true));
|
||||
if (!m_destroy)
|
||||
wxGetApp().CallAfter([this, strJS] { RunScript(strJS); });
|
||||
|
||||
//sync to appconfig
|
||||
if (!m_destroy)
|
||||
wxGetApp().CallAfter([this] { SaveProfileData(); });
|
||||
|
||||
} catch (std::exception& e) {
|
||||
// wxLogMessage("GUIDE: load_profile_error %s ", e.what());
|
||||
// wxMessageBox(e.what(), "", MB_OK);
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", error: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GuideFrame::SaveProfileData()
|
||||
{
|
||||
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>();
|
||||
m_appconfig_new.set_vendors(*wxGetApp().app_config);
|
||||
m_appconfig_new.set_section(AppConfig::SECTION_FILAMENTS, enabled_filaments);
|
||||
@@ -1119,9 +1155,6 @@ int GuideFrame::LoadProfile()
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", error: "<< e.what() <<std::endl;
|
||||
}
|
||||
|
||||
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: "<< std::endl<<strAll;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1169,6 +1202,8 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
|
||||
std::string s2 = OneModel["sub_path"];
|
||||
|
||||
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
||||
if (!boost::filesystem::exists(sub_path)) continue;
|
||||
|
||||
std::string sub_file = sub_path.string();
|
||||
|
||||
// wxLogMessage("GUIDE: json_path2 %s", w2s(ModelFilePath));
|
||||
@@ -1211,6 +1246,8 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
|
||||
|
||||
// wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
||||
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
||||
if (!boost::filesystem::exists(sub_path)) continue;
|
||||
|
||||
std::string sub_file = sub_path.string();
|
||||
LoadFile(sub_file, contents);
|
||||
json pm = json::parse(contents);
|
||||
@@ -1252,10 +1289,12 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
|
||||
if (!m_ProfileJson["filament"].contains(s1)) {
|
||||
// wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
||||
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
||||
if (!boost::filesystem::exists(sub_path)) continue;
|
||||
|
||||
std::string sub_file = sub_path.string();
|
||||
LoadFile(sub_file, contents);
|
||||
json pm = json::parse(contents);
|
||||
|
||||
|
||||
std::string strInstant = pm["instantiation"];
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Load Filament:" << s1 << ",Path:" << sub_file << ",instantiation?" << strInstant;
|
||||
|
||||
@@ -1264,9 +1303,9 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
|
||||
std::string sT;
|
||||
|
||||
int nRet = GetFilamentInfo(vendor_dir.string(),tFilaList, sub_file, sV, sT);
|
||||
if (nRet != 0) {
|
||||
if (nRet != 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Load Filament:" << s1 << ",GetFilamentInfo Failed, Vendor:" << sV << ",Type:"<< sT;
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
OneFF["vendor"] = sV;
|
||||
@@ -1312,6 +1351,8 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
|
||||
std::string s2 = OneProcess["sub_path"];
|
||||
// wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
||||
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
||||
if (!boost::filesystem::exists(sub_path)) continue;
|
||||
|
||||
std::string sub_file = sub_path.string();
|
||||
LoadFile(sub_file, contents);
|
||||
json pm = json::parse(contents);
|
||||
|
||||
@@ -73,7 +73,8 @@ public:
|
||||
bool IsFirstUse();
|
||||
|
||||
//Model - Machine - Filaments
|
||||
int LoadProfile();
|
||||
int LoadProfileData();
|
||||
int SaveProfileData();
|
||||
int LoadProfileFamily(std::string strVendor, std::string strFilePath);
|
||||
int SaveProfile();
|
||||
int GetFilamentInfo( std::string VendorDirectory,json & pFilaList, std::string filepath, std::string &sVendor, std::string &sType);
|
||||
@@ -107,6 +108,11 @@ private:
|
||||
boost::filesystem::path vendor_dir;
|
||||
boost::filesystem::path rsrc_vendor_dir;
|
||||
|
||||
//First Load
|
||||
bool bFirstComplete{false};
|
||||
bool m_destroy{false};
|
||||
boost::thread* m_load_task{ nullptr };
|
||||
|
||||
// User Config
|
||||
bool PrivacyUse;
|
||||
bool StealthMode;
|
||||
|
||||
Reference in New Issue
Block a user