From 6186436b236117af1e9700b2d00fc34119828a0e Mon Sep 17 00:00:00 2001 From: ExPikaPaka Date: Mon, 15 Jun 2026 08:31:33 +0200 Subject: [PATCH] Removing user\bundle serialization and keeping it only for system presets --- src/libslic3r/Preset.cpp | 3 - src/libslic3r/PresetBundle.cpp | 103 ++------ src/libslic3r/PresetBundleCache.cpp | 359 ++++------------------------ src/libslic3r/PresetBundleCache.hpp | 58 +---- 4 files changed, 70 insertions(+), 453 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6f165b7c55..8320559942 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -4,7 +4,6 @@ #include "Exception.hpp" #include "Preset.hpp" #include "PresetBundle.hpp" -#include "PresetBundleCache.hpp" #include "AppConfig.hpp" #ifdef _MSC_VER @@ -709,8 +708,6 @@ void Preset::save(DynamicPrintConfig* parent_config) this->save_info(idx_file.string()); } - // Update the per-file binary cache so the next startup skips JSON parsing. - PresetBundleCache::write_file_cache(*this); } void Preset::reload(Preset const &parent) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index af5742e2fd..aa146b0e48 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -959,16 +959,6 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For const auto user_load_t0 = std::chrono::steady_clock::now(); - // Helper: collect canonical names of presets in a collection that belong to a bundle. - auto collect_bundle_preset_names = [](const PresetCollection& coll, - const std::string& bundle_id, - std::vector& out) { - for (const Preset& p : coll()) { - if (p.bundle_id == bundle_id) - out.push_back(p.name); - } - }; - // Load bundle metadata from _local directory first fs::path local_dir(folder / PRESET_LOCAL_DIR); if (fs::exists(local_dir)) { @@ -987,34 +977,15 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For metadata.filament_presets.clear(); metadata.printer_presets.clear(); - const PresetOrigin origin(PresetOrigin::Kind::LocalBundle, metadata.id); - - // Pre-load from per-file caches; load_presets will skip these. - PresetBundleCache::preload_file_caches(prints, (fs::path(bundle_dir) / PRESET_PRINT_NAME).string(), origin); - PresetBundleCache::preload_file_caches(filaments, (fs::path(bundle_dir) / PRESET_FILAMENT_NAME).string(), origin); - PresetBundleCache::preload_file_caches(printers, (fs::path(bundle_dir) / PRESET_PRINTER_NAME).string(), origin); - - // Record names of preloaded presets in metadata. - collect_bundle_preset_names(prints, metadata.id, metadata.print_presets); - collect_bundle_preset_names(filaments, metadata.id, metadata.filament_presets); - collect_bundle_preset_names(printers, metadata.id, metadata.printer_presets); - - // Load any presets not covered by the cache (callback adds to metadata). this->prints.load_presets(bundle_dir, PRESET_PRINT_NAME, substitutions, substitution_rule, [&](Preset& preset) { metadata.print_presets.push_back(preset.name); - }, origin); + }, PresetOrigin(PresetOrigin::Kind::LocalBundle, metadata.id)); this->filaments.load_presets(bundle_dir, PRESET_FILAMENT_NAME, substitutions, substitution_rule, [&](Preset& preset) { metadata.filament_presets.push_back(preset.name); - }, origin); + }, PresetOrigin(PresetOrigin::Kind::LocalBundle, metadata.id)); this->printers.load_presets(bundle_dir, PRESET_PRINTER_NAME, substitutions, substitution_rule, [&](Preset& preset) { metadata.printer_presets.push_back(preset.name); - }, origin); - - // Persist any newly-loaded presets back to per-file caches. - PresetBundleCache::update_file_caches(prints, (fs::path(bundle_dir) / PRESET_PRINT_NAME).string()); - PresetBundleCache::update_file_caches(filaments, (fs::path(bundle_dir) / PRESET_FILAMENT_NAME).string()); - PresetBundleCache::update_file_caches(printers, (fs::path(bundle_dir) / PRESET_PRINTER_NAME).string()); - + }, PresetOrigin(PresetOrigin::Kind::LocalBundle, metadata.id)); metadata.bundle_type = BundleType::Local; metadata.path = metadata_file.string(); @@ -1042,33 +1013,15 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For metadata.printer_presets.clear(); metadata.is_subscribed = true; - const PresetOrigin origin(PresetOrigin::Kind::SubscribedBundle, metadata.id); - - // Pre-load from per-file caches; load_presets will skip these. - PresetBundleCache::preload_file_caches(prints, (fs::path(bundle_dir) / PRESET_PRINT_NAME).string(), origin); - PresetBundleCache::preload_file_caches(filaments, (fs::path(bundle_dir) / PRESET_FILAMENT_NAME).string(), origin); - PresetBundleCache::preload_file_caches(printers, (fs::path(bundle_dir) / PRESET_PRINTER_NAME).string(), origin); - - // Record names of preloaded presets in metadata. - collect_bundle_preset_names(prints, metadata.id, metadata.print_presets); - collect_bundle_preset_names(filaments, metadata.id, metadata.filament_presets); - collect_bundle_preset_names(printers, metadata.id, metadata.printer_presets); - - // Load any presets not covered by the cache (callback adds to metadata). this->prints.load_presets(bundle_dir, PRESET_PRINT_NAME, substitutions, substitution_rule, [&](Preset& preset) { metadata.print_presets.push_back(preset.name); - }, origin); + }, PresetOrigin(PresetOrigin::Kind::SubscribedBundle, metadata.id)); this->filaments.load_presets(bundle_dir, PRESET_FILAMENT_NAME, substitutions, substitution_rule, [&](Preset& preset) { metadata.filament_presets.push_back(preset.name); - }, origin); + }, PresetOrigin(PresetOrigin::Kind::SubscribedBundle, metadata.id)); this->printers.load_presets(bundle_dir, PRESET_PRINTER_NAME, substitutions, substitution_rule, [&](Preset& preset) { metadata.printer_presets.push_back(preset.name); - }, origin); - - // Persist any newly-loaded presets back to per-file caches. - PresetBundleCache::update_file_caches(prints, (fs::path(bundle_dir) / PRESET_PRINT_NAME).string()); - PresetBundleCache::update_file_caches(filaments, (fs::path(bundle_dir) / PRESET_FILAMENT_NAME).string()); - PresetBundleCache::update_file_caches(printers, (fs::path(bundle_dir) / PRESET_PRINTER_NAME).string()); + }, PresetOrigin(PresetOrigin::Kind::SubscribedBundle, metadata.id)); metadata.bundle_type = BundleType::Subscribed; metadata.path = metadata_file.string(); @@ -1083,46 +1036,28 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For // BBS do not load sla_print // BBS: change directories by design - // Regular user presets (process/filament/machine) — per-file cache approach. { - const PresetOrigin user_origin; // Kind::Auto → resolved to User by detect_origin_from_path - - // Pre-load from per-file .cache siblings; load_presets will skip pre-loaded names. - int cached_prints = PresetBundleCache::preload_file_caches(prints, (fs::path(dir_user_presets) / PRESET_PRINT_NAME).string(), user_origin); - int cached_filaments = PresetBundleCache::preload_file_caches(filaments, (fs::path(dir_user_presets) / PRESET_FILAMENT_NAME).string(), user_origin); - int cached_printers = PresetBundleCache::preload_file_caches(printers, (fs::path(dir_user_presets) / PRESET_PRINTER_NAME).string(), user_origin); - BOOST_LOG_TRIVIAL(info) << "PresetBundle: user presets from cache: " - << cached_prints << " process, " - << cached_filaments << " filament, " - << cached_printers << " machine"; - + const auto json_t0 = std::chrono::steady_clock::now(); try { - std::string print_selected_preset_name = prints.get_selected_preset().name; + std::string sel = prints.get_selected_preset().name; this->prints.load_presets(dir_user_presets, PRESET_PRINT_NAME, substitutions, substitution_rule); - prints.select_preset_by_name(print_selected_preset_name, false); - } catch (const std::runtime_error &err) { - errors_cummulative += err.what(); - } + prints.select_preset_by_name(sel, false); + } catch (const std::runtime_error& err) { errors_cummulative += err.what(); } try { - std::string filament_selected_preset_name = filaments.get_selected_preset().name; + std::string sel = filaments.get_selected_preset().name; this->filaments.load_presets(dir_user_presets, PRESET_FILAMENT_NAME, substitutions, substitution_rule); - filaments.select_preset_by_name(filament_selected_preset_name, false); - } catch (const std::runtime_error &err) { - errors_cummulative += err.what(); - } + filaments.select_preset_by_name(sel, false); + } catch (const std::runtime_error& err) { errors_cummulative += err.what(); } try { - std::string printer_selected_preset_name = printers.get_selected_preset().name; + std::string sel = printers.get_selected_preset().name; this->printers.load_presets(dir_user_presets, PRESET_PRINTER_NAME, substitutions, substitution_rule); - printers.select_preset_by_name(printer_selected_preset_name, false); - } catch (const std::runtime_error &err) { - errors_cummulative += err.what(); - } + printers.select_preset_by_name(sel, false); + } catch (const std::runtime_error& err) { errors_cummulative += err.what(); } if (!errors_cummulative.empty()) throw Slic3r::RuntimeError(errors_cummulative); - // Persist any newly-loaded presets back to per-file caches. - PresetBundleCache::update_file_caches(prints, (fs::path(dir_user_presets) / PRESET_PRINT_NAME).string()); - PresetBundleCache::update_file_caches(filaments, (fs::path(dir_user_presets) / PRESET_FILAMENT_NAME).string()); - PresetBundleCache::update_file_caches(printers, (fs::path(dir_user_presets) / PRESET_PRINTER_NAME).string()); + const auto json_ms = std::chrono::duration_cast( + std::chrono::steady_clock::now() - json_t0).count(); + BOOST_LOG_TRIVIAL(info) << "PresetBundle: user presets loaded from JSON in " << json_ms << " ms"; } { diff --git a/src/libslic3r/PresetBundleCache.cpp b/src/libslic3r/PresetBundleCache.cpp index eaa729847a..febba0e9f7 100644 --- a/src/libslic3r/PresetBundleCache.cpp +++ b/src/libslic3r/PresetBundleCache.cpp @@ -1,23 +1,17 @@ #include "PresetBundleCache.hpp" -#include #include #include #include #include #include - -#include -#include - #include #include #include #include #include -#include "Preset.hpp" #include "PresetBundle.hpp" #include "PrintConfig.hpp" #include "Semver.hpp" @@ -29,7 +23,6 @@ namespace PresetBundleCache { // ------------------------------------------------------------------------- // Binary cache file format: raw 20-byte header followed by cereal blob. // ------------------------------------------------------------------------- - static constexpr uint32_t CACHE_MAGIC = 0x4F52435A; // "ORCZ" static constexpr uint32_t CACHE_FILE_VERSION = 1; @@ -52,10 +45,8 @@ static void save_blob(const std::string& path, const T& obj) ar(obj); } const std::string blob = oss.str(); - boost::crc_32_type crc; crc.process_bytes(blob.data(), blob.size()); - try { boost::filesystem::create_directories(boost::filesystem::path(path).parent_path()); boost::nowide::ofstream ofs(path, std::ios::binary | std::ios::trunc); @@ -82,7 +73,6 @@ static bool load_blob(const std::string& path, T& obj) boost::nowide::ifstream ifs(path, std::ios::binary); if (!ifs.is_open()) return false; - CacheFileHeader hdr; if (!ifs.read(reinterpret_cast(&hdr), sizeof(hdr))) return false; @@ -90,18 +80,15 @@ static bool load_blob(const std::string& path, T& obj) return false; if (hdr.data_size == 0 || hdr.data_size > 512u * 1024u * 1024u) return false; - std::string blob(hdr.data_size, '\0'); if (!ifs.read(&blob[0], static_cast(hdr.data_size))) return false; - boost::crc_32_type crc; crc.process_bytes(blob.data(), blob.size()); if (crc.checksum() != hdr.crc32) { BOOST_LOG_TRIVIAL(warning) << "PresetBundleCache: CRC32 mismatch: " << path; return false; } - std::istringstream iss(blob, std::ios::in | std::ios::binary); cereal::BinaryInputArchive ar(iss); ar(obj); @@ -115,7 +102,6 @@ static bool load_blob(const std::string& path, T& obj) // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- - static std::string vendor_root_json(const std::string& system_dir, const std::string& vendor_id) { return (boost::filesystem::path(system_dir) / (vendor_id + ".json")).make_preferred().string(); @@ -124,7 +110,6 @@ static std::string vendor_root_json(const std::string& system_dir, const std::st // ------------------------------------------------------------------------- // SystemPresetsCache // ------------------------------------------------------------------------- - std::string SystemPresetsCache::cache_path() { return (boost::filesystem::path(data_dir()) / PRESET_SYSTEM_DIR / "system_presets_cache.cache") @@ -137,7 +122,6 @@ bool SystemPresetsCache::is_valid(const std::string& system_dir) const return false; if (config_options_count != print_config_def.options.size()) return false; - std::map current; try { for (const auto& entry : boost::filesystem::directory_iterator(system_dir)) { @@ -153,7 +137,6 @@ bool SystemPresetsCache::is_valid(const std::string& system_dir) const BOOST_LOG_TRIVIAL(warning) << "PresetBundleCache: directory scan failed: " << e.what(); return false; } - if (current.size() != vendor_versions.size()) return false; for (const auto& [name, ver] : current) { @@ -180,12 +163,11 @@ void SystemPresetsCache::capture(const PresetBundle& bundle, const std::string& for (const auto& [id, vp] : bundle.vendors) { CachedVendorProfile cvp; - cvp.id = vp.id; - cvp.name = vp.name; - cvp.config_version = vp.config_version.valid() ? vp.config_version.to_string() : ""; + cvp.id = vp.id; + cvp.name = vp.name; + cvp.config_version = vp.config_version.valid() ? vp.config_version.to_string() : ""; cvp.config_update_url = vp.config_update_url; - cvp.changelog_url = vp.changelog_url; - + cvp.changelog_url = vp.changelog_url; for (const auto& model : vp.models) { CachedPrinterModel cm; cm.id = model.id; @@ -195,26 +177,23 @@ void SystemPresetsCache::capture(const PresetBundle& bundle, const std::string& cm.technology = static_cast(model.technology); for (const auto& v : model.variants) cm.variants.push_back({v.name}); - cm.default_materials = model.default_materials; - cm.not_support_bed_types = model.not_support_bed_types; - cm.bed_model = model.bed_model; - cm.bed_texture = model.bed_texture; - cm.image_bed_type = model.image_bed_type; - cm.bottom_texture_end_name = model.bottom_texture_end_name; + cm.default_materials = model.default_materials; + cm.not_support_bed_types = model.not_support_bed_types; + cm.bed_model = model.bed_model; + cm.bed_texture = model.bed_texture; + cm.image_bed_type = model.image_bed_type; + cm.bottom_texture_end_name = model.bottom_texture_end_name; cm.use_double_extruder_default_texture = model.use_double_extruder_default_texture; - cm.bottom_texture_rect = model.bottom_texture_rect; - cm.middle_texture_rect = model.middle_texture_rect; - cm.hotend_model = model.hotend_model; + cm.bottom_texture_rect = model.bottom_texture_rect; + cm.middle_texture_rect = model.middle_texture_rect; + cm.hotend_model = model.hotend_model; cvp.models.push_back(std::move(cm)); } - for (const auto& f : vp.default_filaments) cvp.default_filaments.push_back(f); for (const auto& m : vp.default_sla_materials) cvp.default_sla_materials.push_back(m); - vendor_profiles.push_back(std::move(cvp)); - Semver ver = get_version_from_json(vendor_root_json(system_dir, id)); vendor_versions[id] = ver.valid() ? ver.to_string() : ""; } @@ -224,24 +203,23 @@ void SystemPresetsCache::capture(const PresetBundle& bundle, const std::string& if (!p.is_system) continue; CachedPreset cp; - cp.type = static_cast(p.type); - cp.name = p.name; - cp.alias = p.alias; - cp.file = p.file; - cp.version = p.version.valid() ? p.version.to_string() : ""; - cp.vendor_id = (p.vendor != nullptr) ? p.vendor->id : ""; - cp.filament_id = p.filament_id; - cp.setting_id = p.setting_id; - cp.description = p.description; - cp.renamed_from = p.renamed_from; - cp.is_system = p.is_system; - cp.is_visible = p.is_visible; + cp.type = static_cast(p.type); + cp.name = p.name; + cp.alias = p.alias; + cp.file = p.file; + cp.version = p.version.valid() ? p.version.to_string() : ""; + cp.vendor_id = (p.vendor != nullptr) ? p.vendor->id : ""; + cp.filament_id = p.filament_id; + cp.setting_id = p.setting_id; + cp.description = p.description; + cp.renamed_from = p.renamed_from; + cp.is_system = p.is_system; + cp.is_visible = p.is_visible; cp.m_from_orca_filament_lib = p.m_from_orca_filament_lib; - cp.config = p.config; + cp.config = p.config; out.push_back(std::move(cp)); } }; - capture_col(bundle.prints, print_presets); capture_col(bundle.filaments, filament_presets); capture_col(bundle.printers, printer_presets); @@ -252,7 +230,6 @@ void SystemPresetsCache::capture(const PresetBundle& bundle, const std::string& void SystemPresetsCache::apply(PresetBundle& bundle) const { bundle.reset(false); - for (const auto& cvp : vendor_profiles) { VendorProfile vp(cvp.id); vp.name = cvp.name; @@ -262,7 +239,6 @@ void SystemPresetsCache::apply(PresetBundle& bundle) const auto v = Semver::parse(cvp.config_version); if (v) vp.config_version = *v; } - for (const auto& cm : cvp.models) { VendorProfile::PrinterModel model; model.id = cm.id; @@ -272,24 +248,22 @@ void SystemPresetsCache::apply(PresetBundle& bundle) const model.technology = static_cast(cm.technology); for (const auto& v : cm.variants) model.variants.emplace_back(v.name); - model.default_materials = cm.default_materials; - model.not_support_bed_types = cm.not_support_bed_types; - model.bed_model = cm.bed_model; - model.bed_texture = cm.bed_texture; - model.image_bed_type = cm.image_bed_type; - model.bottom_texture_end_name = cm.bottom_texture_end_name; + model.default_materials = cm.default_materials; + model.not_support_bed_types = cm.not_support_bed_types; + model.bed_model = cm.bed_model; + model.bed_texture = cm.bed_texture; + model.image_bed_type = cm.image_bed_type; + model.bottom_texture_end_name = cm.bottom_texture_end_name; model.use_double_extruder_default_texture = cm.use_double_extruder_default_texture; - model.bottom_texture_rect = cm.bottom_texture_rect; - model.middle_texture_rect = cm.middle_texture_rect; - model.hotend_model = cm.hotend_model; + model.bottom_texture_rect = cm.bottom_texture_rect; + model.middle_texture_rect = cm.middle_texture_rect; + model.hotend_model = cm.hotend_model; vp.models.push_back(std::move(model)); } - for (const auto& f : cvp.default_filaments) vp.default_filaments.insert(f); for (const auto& m : cvp.default_sla_materials) vp.default_sla_materials.insert(m); - bundle.vendors.emplace(cvp.id, std::move(vp)); } @@ -304,26 +278,23 @@ void SystemPresetsCache::apply(PresetBundle& bundle) const } DynamicPrintConfig config = cp.config; Preset& p = coll.load_preset(cp.file, cp.name, std::move(config), /*select=*/false, version); - p.is_system = true; - p.is_visible = cp.is_visible; - p.alias = cp.alias; - p.renamed_from = cp.renamed_from; - p.filament_id = cp.filament_id; - p.setting_id = cp.setting_id; - p.description = cp.description; + p.is_system = true; + p.is_visible = cp.is_visible; + p.alias = cp.alias; + p.renamed_from = cp.renamed_from; + p.filament_id = cp.filament_id; + p.setting_id = cp.setting_id; + p.description = cp.description; p.m_from_orca_filament_lib = cp.m_from_orca_filament_lib; - if (!cp.vendor_id.empty()) { auto it = bundle.vendors.find(cp.vendor_id); if (it != bundle.vendors.end()) p.vendor = &it->second; } - if (is_filaments) coll.set_printer_hold_alias(p.alias, p); } }; - apply_col(print_presets, bundle.prints, false); apply_col(filament_presets, bundle.filaments, true); apply_col(printer_presets, bundle.printers, false); @@ -345,251 +316,5 @@ void SystemPresetsCache::save(const std::string& path) const save_blob(path, *this); } -// ------------------------------------------------------------------------- -// PresetFileCache -// ------------------------------------------------------------------------- - -std::string PresetFileCache::cache_path_for(const std::string& json_path) -{ - boost::filesystem::path p(json_path); - p.replace_extension(".cache"); - return p.string(); -} - -bool PresetFileCache::is_valid(const std::string& json_path) const -{ - if (format_version != FORMAT_VERSION) - return false; - if (config_options_count != print_config_def.options.size()) - return false; - - namespace fs = boost::filesystem; - const fs::path json(json_path); - if (!fs::exists(json)) - return false; - - int64_t cur_json_mtime = 0; - try { - cur_json_mtime = static_cast(fs::last_write_time(json)); - } catch (...) { return false; } - if (json_mtime != cur_json_mtime) - return false; - - fs::path info = json; - info.replace_extension(".info"); - int64_t cur_info_mtime = 0; - if (fs::exists(info)) { - try { - cur_info_mtime = static_cast(fs::last_write_time(info)); - } catch (...) { return false; } - } - return info_mtime == cur_info_mtime; -} - -// ------------------------------------------------------------------------- -// preload_file_caches / update_file_caches -// ------------------------------------------------------------------------- - -int preload_file_caches(PresetCollection& coll, const std::string& dir_path, - const PresetOrigin& origin) -{ - namespace fs = boost::filesystem; - const fs::path dir(dir_path); - if (!fs::exists(dir)) - return 0; - - // Step 1: collect .json paths (fast, sequential). - std::vector json_paths; - try { - for (const auto& entry : fs::directory_iterator(dir)) { - if (fs::is_regular_file(entry.path()) && - entry.path().extension().string() == ".json") - json_paths.push_back(entry.path().string()); - } - } catch (const std::exception& e) { - BOOST_LOG_TRIVIAL(warning) << "PresetBundleCache: dir scan failed (" - << dir_path << "): " << e.what(); - return 0; - } - - // Step 2: load + deserialize each .cache file in parallel. - // Each slot is independent - no shared state touched here. - struct LoadResult { - std::string json_path; - std::string canonical_name; - PresetFileCache pfc; - bool valid = false; - }; - std::vector results(json_paths.size()); - - tbb::parallel_for(tbb::blocked_range(0, json_paths.size()), - [&](const tbb::blocked_range& range) { - for (size_t i = range.begin(); i < range.end(); ++i) { - const std::string& json_path = json_paths[i]; - const std::string cache_path = PresetFileCache::cache_path_for(json_path); - - PresetFileCache pfc; - if (!load_blob(cache_path, pfc) || !pfc.is_valid(json_path)) - continue; - - const std::string stem = fs::path(json_path).stem().string(); - results[i].json_path = json_path; - results[i].canonical_name = get_preset_canonical_name(stem, origin); - results[i].pfc = std::move(pfc); - results[i].valid = true; - } - }); - - // Step 3: sequential merge into the collection (load_preset uses a lock). - const bool is_filaments = (coll.type() == Preset::TYPE_FILAMENT); - int loaded = 0; - for (auto& r : results) { - if (!r.valid) - continue; - - Semver version; - if (!r.pfc.preset.version.empty()) { - auto v = Semver::parse(r.pfc.preset.version); - if (v) version = *v; - } - - DynamicPrintConfig config = r.pfc.preset.config; - Preset& p = coll.load_preset(r.json_path, r.canonical_name, - std::move(config), /*select=*/false, version); - p.is_system = false; - p.is_visible = r.pfc.preset.is_visible; - p.alias = r.pfc.preset.alias; - p.filament_id = r.pfc.preset.filament_id; - p.setting_id = r.pfc.preset.setting_id; - p.description = r.pfc.preset.description; - p.base_id = r.pfc.preset.base_id; - p.user_id = r.pfc.preset.user_id; - p.sync_info = r.pfc.preset.sync_info; - p.updated_time = r.pfc.preset.updated_time; - p.renamed_from = r.pfc.preset.renamed_from; - p.bundle_id = origin.bundle_id; - - if (is_filaments) - coll.set_printer_hold_alias(p.alias, p); - - ++loaded; - } - return loaded; -} - -void update_file_caches(const PresetCollection& coll, const std::string& dir_path) -{ - namespace fs = boost::filesystem; - const std::string norm_dir = fs::path(dir_path).make_preferred().string(); - - // Step 1: collect candidate presets (sequential, fast). - std::vector candidates; - for (const Preset& p : coll()) { - if (p.is_system || p.is_default || p.file.empty()) - continue; - const std::string norm_file = fs::path(p.file).make_preferred().string(); - if (norm_file.rfind(norm_dir, 0) != 0) - continue; - candidates.push_back(&p); - } - - // Step 2: check + write each .cache file in parallel. - // Each write targets an independent file path - no shared state. - tbb::parallel_for(tbb::blocked_range(0, candidates.size()), - [&](const tbb::blocked_range& range) { - for (size_t i = range.begin(); i < range.end(); ++i) { - const Preset& p = *candidates[i]; - const std::string cache_path = PresetFileCache::cache_path_for(p.file); - - PresetFileCache existing; - if (load_blob(cache_path, existing) && existing.is_valid(p.file)) - continue; - - PresetFileCache pfc; - pfc.format_version = PresetFileCache::FORMAT_VERSION; - pfc.config_options_count = print_config_def.options.size(); - - try { - pfc.json_mtime = static_cast( - fs::last_write_time(fs::path(p.file))); - } catch (...) {} - - fs::path info_path = fs::path(p.file); - info_path.replace_extension(".info"); - if (fs::exists(info_path)) { - try { - pfc.info_mtime = static_cast( - fs::last_write_time(info_path)); - } catch (...) {} - } - - CachedPreset& cp = pfc.preset; - cp.type = static_cast(p.type); - cp.name = p.name; - cp.alias = p.alias; - cp.file = p.file; - cp.version = p.version.valid() ? p.version.to_string() : ""; - cp.filament_id = p.filament_id; - cp.setting_id = p.setting_id; - cp.description = p.description; - cp.base_id = p.base_id; - cp.user_id = p.user_id; - cp.sync_info = p.sync_info; - cp.updated_time = p.updated_time; - cp.renamed_from = p.renamed_from; - cp.is_system = false; - cp.is_visible = p.is_visible; - cp.config = p.config; - - save_blob(cache_path, pfc); - } - }); -} - -void write_file_cache(const Preset& preset) -{ - if (preset.is_system || preset.is_default || preset.is_project_embedded || preset.file.empty()) - return; - - namespace fs = boost::filesystem; - const std::string cache_path = PresetFileCache::cache_path_for(preset.file); - - PresetFileCache pfc; - pfc.format_version = PresetFileCache::FORMAT_VERSION; - pfc.config_options_count = print_config_def.options.size(); - - try { - pfc.json_mtime = static_cast(fs::last_write_time(fs::path(preset.file))); - } catch (...) {} - - fs::path info_path = fs::path(preset.file); - info_path.replace_extension(".info"); - if (fs::exists(info_path)) { - try { - pfc.info_mtime = static_cast(fs::last_write_time(info_path)); - } catch (...) {} - } - - CachedPreset& cp = pfc.preset; - cp.type = static_cast(preset.type); - cp.name = preset.name; - cp.alias = preset.alias; - cp.file = preset.file; - cp.version = preset.version.valid() ? preset.version.to_string() : ""; - cp.filament_id = preset.filament_id; - cp.setting_id = preset.setting_id; - cp.description = preset.description; - cp.base_id = preset.base_id; - cp.user_id = preset.user_id; - cp.sync_info = preset.sync_info; - cp.updated_time = preset.updated_time; - cp.renamed_from = preset.renamed_from; - cp.is_system = false; - cp.is_visible = preset.is_visible; - cp.config = preset.config; - - save_blob(cache_path, pfc); -} - } // namespace PresetBundleCache } // namespace Slic3r diff --git a/src/libslic3r/PresetBundleCache.hpp b/src/libslic3r/PresetBundleCache.hpp index a292072a4a..6e87adc7aa 100644 --- a/src/libslic3r/PresetBundleCache.hpp +++ b/src/libslic3r/PresetBundleCache.hpp @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -12,7 +12,6 @@ #include #include -#include "Preset.hpp" #include "PrintConfig.hpp" namespace Slic3r { @@ -30,7 +29,7 @@ struct CachedPrinterVariant { struct CachedPrinterModel { std::string id, name, model_id, family; - int technology = 0; // PrinterTechnology enum + int technology = 0; std::vector variants; std::vector default_materials; std::vector not_support_bed_types; @@ -62,12 +61,12 @@ struct CachedVendorProfile { } }; -// ---- Per-preset cache entry (shared by system and per-file caches) ---- +// ---- Per-preset cache entry ---- struct CachedPreset { - int type = 0; // Preset::Type + int type = 0; std::string name, alias, file, version; - std::string vendor_id; // reconstruct Preset::vendor pointer (system only) + std::string vendor_id; std::string filament_id, setting_id, description; std::string base_id, user_id, sync_info; long long updated_time = 0; @@ -87,7 +86,9 @@ struct CachedPreset { }; // ---- System preset cache ---- -// Stored next to vendor JSONs: /system/system_presets_cache.bin +// Single blob at /system/system_presets_cache.cache +// Covers all vendor profiles and system presets. +// Invalidated when any vendor version string changes or config option count changes. struct SystemPresetsCache { static constexpr uint32_t FORMAT_VERSION = 2; @@ -125,46 +126,5 @@ struct SystemPresetsCache { void save(const std::string& path) const; }; -// ---- Per-file preset cache ---- -// Each .json gets a sibling .cache file. -// Invalidated when json or info mtime changes, or when the app binary changes. - -struct PresetFileCache { - static constexpr uint32_t FORMAT_VERSION = 1; - - uint32_t format_version = FORMAT_VERSION; - size_t config_options_count = 0; - int64_t json_mtime = 0; // last_write_time of .json file - int64_t info_mtime = 0; // last_write_time of .info file (0 = doesn't exist) - CachedPreset preset; - - template - void serialize(Archive& ar) - { - ar(format_version, config_options_count, json_mtime, info_mtime, preset); - } - - // Returns the path of the .cache file sibling to json_path. - static std::string cache_path_for(const std::string& json_path); - - // Returns true when the stored mtimes still match the current filesystem state. - bool is_valid(const std::string& json_path) const; -}; - -// Pre-load cached presets from all valid .cache files found in dir_path. -// Presets are inserted into coll via load_preset() so that a subsequent -// load_presets() call will skip them. Returns the count of presets loaded. -int preload_file_caches(PresetCollection& coll, const std::string& dir_path, - const PresetOrigin& origin); - -// Write (or overwrite) .cache files for presets in coll whose json .file is -// inside dir_path and whose existing .cache (if any) is stale or missing. -void update_file_caches(const PresetCollection& coll, const std::string& dir_path); - -// Write (or overwrite) the .cache file for a single preset immediately after -// its .json has been written to disk. Safe to call from Preset::save(). -// Does nothing for system, default, or project-embedded presets. -void write_file_cache(const Preset& preset); - } // namespace PresetBundleCache -} // namespace Slic3r +} // namespace Slic3r \ No newline at end of file