From 71d0380467c3ab5cfef11f4074e2404c8e42bbd1 Mon Sep 17 00:00:00 2001 From: Ian Chua Date: Tue, 14 Jul 2026 19:48:39 +0800 Subject: [PATCH] fix: preset resolution --- src/slic3r/CMakeLists.txt | 2 - .../plugin/CapabilityConfigDocument.cpp | 122 -------- src/slic3r/plugin/PluginConfig.cpp | 271 +++++++++++++++++- src/slic3r/plugin/PluginResolver.cpp | 30 -- src/slic3r/plugin/PluginResolver.hpp | 7 - src/slic3r/plugin/PresetPluginConfig.cpp | 170 ----------- src/slic3r/plugin/PresetPluginConfig.hpp | 6 +- .../test_plugin_capabilities_in_use.cpp | 15 - 8 files changed, 268 insertions(+), 355 deletions(-) delete mode 100644 src/slic3r/plugin/CapabilityConfigDocument.cpp delete mode 100644 src/slic3r/plugin/PresetPluginConfig.cpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index ede4077b43..b35c9ce643 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -615,11 +615,9 @@ set(SLIC3R_GUI_SOURCES plugin/CloudPluginService.hpp plugin/PluginFsUtils.cpp plugin/PluginFsUtils.hpp - plugin/CapabilityConfigDocument.cpp plugin/CapabilityConfigDocument.hpp plugin/PluginConfig.cpp plugin/PluginConfig.hpp - plugin/PresetPluginConfig.cpp plugin/PresetPluginConfig.hpp plugin/PythonJsonUtils.hpp plugin/PluginCatalog.cpp diff --git a/src/slic3r/plugin/CapabilityConfigDocument.cpp b/src/slic3r/plugin/CapabilityConfigDocument.cpp deleted file mode 100644 index 5114184445..0000000000 --- a/src/slic3r/plugin/CapabilityConfigDocument.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "CapabilityConfigDocument.hpp" - -namespace Slic3r { - -namespace { - -constexpr const char* KEY_PLUGIN = "plugin_key"; -constexpr const char* KEY_CAPABILITY = "capability"; -constexpr const char* KEY_VERSION = "plugin_version"; -constexpr const char* KEY_CAP_CONFIG = "cap_config"; - -std::string string_field(const nlohmann::json& entry, const char* key) -{ - const auto it = entry.find(key); - return it != entry.end() && it->is_string() ? it->get() : std::string(); -} - -bool is_recognized_entry(const nlohmann::json& entry, CapabilityConfigId& id) -{ - if (!entry.is_object()) - return false; - - id.plugin_key = string_field(entry, KEY_PLUGIN); - id.capability = string_field(entry, KEY_CAPABILITY); - return !id.plugin_key.empty() && !id.capability.empty(); -} - -CapabilityConfigEntry decode_entry(const CapabilityConfigId& id, const nlohmann::json& entry) -{ - CapabilityConfigEntry result; - result.id = id; - result.plugin_version = string_field(entry, KEY_VERSION); - const auto cap_it = entry.find(KEY_CAP_CONFIG); - result.cap_config = cap_it != entry.end() ? *cap_it : nlohmann::json::object(); - return result; -} - -} // namespace - -CapabilityConfigDocument CapabilityConfigDocument::from_entries(const nlohmann::json& entries) -{ - CapabilityConfigDocument document; - if (!entries.is_array()) - return document; - - for (const nlohmann::json& entry : entries) { - CapabilityConfigId id; - if (is_recognized_entry(entry, id)) - document.m_entries[id] = entry; - else - document.m_opaque_entries.push_back(entry); - } - - return document; -} - -CapabilityConfigDocument CapabilityConfigDocument::from_root_json(const nlohmann::json& root) -{ - const auto entries = root.find(KeyEntries); - return entries != root.end() ? from_entries(*entries) : CapabilityConfigDocument(); -} - -std::optional CapabilityConfigDocument::find(const CapabilityConfigId& id) const -{ - const auto it = m_entries.find(id); - if (it == m_entries.end()) - return std::nullopt; - return decode_entry(it->first, it->second); -} - -bool CapabilityConfigDocument::contains(const CapabilityConfigId& id) const -{ - return m_entries.find(id) != m_entries.end(); -} - -bool CapabilityConfigDocument::upsert(CapabilityConfigEntry entry) -{ - if (entry.id.plugin_key.empty() || entry.id.capability.empty()) - return false; - - nlohmann::json serialized = nlohmann::json::object(); - const auto existing = m_entries.find(entry.id); - if (existing != m_entries.end() && existing->second.is_object()) - serialized = existing->second; - - serialized[KEY_PLUGIN] = entry.id.plugin_key; - serialized[KEY_CAPABILITY] = entry.id.capability; - serialized[KEY_VERSION] = entry.plugin_version; - serialized[KEY_CAP_CONFIG] = entry.cap_config; - - m_entries[entry.id] = std::move(serialized); - return true; -} - -bool CapabilityConfigDocument::erase(const CapabilityConfigId& id) -{ - return m_entries.erase(id) != 0; -} - -bool CapabilityConfigDocument::empty() const -{ - return m_entries.empty() && m_opaque_entries.empty(); -} - -nlohmann::json CapabilityConfigDocument::serialize_entries() const -{ - nlohmann::json result = nlohmann::json::array(); - for (const auto& item : m_entries) - result.push_back(item.second); - for (const nlohmann::json& entry : m_opaque_entries) - result.push_back(entry); - return result; -} - -nlohmann::json CapabilityConfigDocument::root_json() const -{ - nlohmann::json root = nlohmann::json::object(); - root[KeyEntries] = serialize_entries(); - return root; -} - -} // namespace Slic3r diff --git a/src/slic3r/plugin/PluginConfig.cpp b/src/slic3r/plugin/PluginConfig.cpp index 7d2642ee36..c8b1a7b4f9 100644 --- a/src/slic3r/plugin/PluginConfig.cpp +++ b/src/slic3r/plugin/PluginConfig.cpp @@ -1,10 +1,14 @@ #include "PluginConfig.hpp" +#include #include #include #include +#include +#include #include +#include #include #include #include @@ -14,12 +18,44 @@ #include #include +#include #include namespace Slic3r { namespace { +constexpr const char* KEY_PLUGIN = "plugin_key"; +constexpr const char* KEY_CAPABILITY = "capability"; +constexpr const char* KEY_VERSION = "plugin_version"; +constexpr const char* KEY_CAP_CONFIG = "cap_config"; + +std::string string_field(const nlohmann::json& entry, const char* key) +{ + const auto it = entry.find(key); + return it != entry.end() && it->is_string() ? it->get() : std::string(); +} + +bool is_recognized_entry(const nlohmann::json& entry, CapabilityConfigId& id) +{ + if (!entry.is_object()) + return false; + + id.plugin_key = string_field(entry, KEY_PLUGIN); + id.capability = string_field(entry, KEY_CAPABILITY); + return !id.plugin_key.empty() && !id.capability.empty(); +} + +CapabilityConfigEntry decode_entry(const CapabilityConfigId& id, const nlohmann::json& entry) +{ + CapabilityConfigEntry result; + result.id = id; + result.plugin_version = string_field(entry, KEY_VERSION); + const auto cap_it = entry.find(KEY_CAP_CONFIG); + result.cap_config = cap_it != entry.end() ? *cap_it : nlohmann::json::object(); + return result; +} + // PluginDescriptor::version is overwritten with the latest cloud version on a cloud merge, so it can // name a version that is not the one on disk; installed_version is what actually loaded. std::string running_plugin_version(const std::string& plugin_key) @@ -30,6 +66,19 @@ std::string running_plugin_version(const std::string& plugin_key) return descriptor.installed_version.empty() ? descriptor.version : descriptor.installed_version; } +CapabilityConfigId make_id(const PluginCapabilityIdentifier& id) +{ + return CapabilityConfigId{id.plugin_key, id.name}; +} + +// Null wherever the plugin host runs without the GUI app (the unit tests). wxGetApp() dereferences +// the app unconditionally, so ask wxWidgets instead. +const PresetBundle* active_preset_bundle() +{ + const auto* app = dynamic_cast(wxApp::GetInstance()); + return app == nullptr ? nullptr : app->preset_bundle; +} + // PluginLoader stamps both halves onto the instance when it materializes the capability, so the // caller never supplies them and cannot name another capability's entry. Empty means the instance // was never materialized: refuse rather than read or clobber a wrong entry. @@ -42,11 +91,8 @@ std::pair capability_identity(const PluginCapabilityIn return id; } -// The identity above plus the type, which decides which preset may override the capability (see -// preset_type_for_capability). Taken from the instance, not the loader's registry: a capability -// calling get_config() from on_load() is not registered yet and must still see its preset's config. -// A raising get_type() costs it only the preset layer — Unknown names no preset, so the base config -// answers. +// The capability type identifies the preset that owns its override. If a plugin raises while +// reporting its type, resolve against the base config instead of failing the capability config API. PluginCapabilityIdentifier capability_full_identity(const PluginCapabilityInterface& capability, const char* api_name) { const auto [plugin_key, capability_name] = capability_identity(capability, api_name); @@ -63,6 +109,88 @@ PluginCapabilityIdentifier capability_full_identity(const PluginCapabilityInterf } // namespace +CapabilityConfigDocument CapabilityConfigDocument::from_entries(const nlohmann::json& entries) +{ + CapabilityConfigDocument document; + if (!entries.is_array()) + return document; + + for (const nlohmann::json& entry : entries) { + CapabilityConfigId id; + if (is_recognized_entry(entry, id)) + document.m_entries[id] = entry; + else + document.m_opaque_entries.push_back(entry); + } + + return document; +} + +CapabilityConfigDocument CapabilityConfigDocument::from_root_json(const nlohmann::json& root) +{ + const auto entries = root.find(KeyEntries); + return entries != root.end() ? from_entries(*entries) : CapabilityConfigDocument(); +} + +std::optional CapabilityConfigDocument::find(const CapabilityConfigId& id) const +{ + const auto it = m_entries.find(id); + if (it == m_entries.end()) + return std::nullopt; + return decode_entry(it->first, it->second); +} + +bool CapabilityConfigDocument::contains(const CapabilityConfigId& id) const +{ + return m_entries.find(id) != m_entries.end(); +} + +bool CapabilityConfigDocument::upsert(CapabilityConfigEntry entry) +{ + if (entry.id.plugin_key.empty() || entry.id.capability.empty()) + return false; + + nlohmann::json serialized = nlohmann::json::object(); + const auto existing = m_entries.find(entry.id); + if (existing != m_entries.end() && existing->second.is_object()) + serialized = existing->second; + + serialized[KEY_PLUGIN] = entry.id.plugin_key; + serialized[KEY_CAPABILITY] = entry.id.capability; + serialized[KEY_VERSION] = entry.plugin_version; + serialized[KEY_CAP_CONFIG] = entry.cap_config; + + m_entries[entry.id] = std::move(serialized); + return true; +} + +bool CapabilityConfigDocument::erase(const CapabilityConfigId& id) +{ + return m_entries.erase(id) != 0; +} + +bool CapabilityConfigDocument::empty() const +{ + return m_entries.empty() && m_opaque_entries.empty(); +} + +nlohmann::json CapabilityConfigDocument::serialize_entries() const +{ + nlohmann::json result = nlohmann::json::array(); + for (const auto& item : m_entries) + result.push_back(item.second); + for (const nlohmann::json& entry : m_opaque_entries) + result.push_back(entry); + return result; +} + +nlohmann::json CapabilityConfigDocument::root_json() const +{ + nlohmann::json root = nlohmann::json::object(); + root[KeyEntries] = serialize_entries(); + return root; +} + void PluginConfig::load() { const std::string path = plugin_config_file(); @@ -194,6 +322,139 @@ bool PluginConfig::dirty() const return m_dirty; } +std::string plugin_overrides_of(const Preset& preset) +{ + const auto* opt = dynamic_cast(preset.config.option(PLUGIN_OVERRIDES_OPTION_KEY)); + return opt == nullptr ? std::string() : opt->value; +} + +bool parse_plugin_overrides(const std::string& raw, CapabilityConfigDocument& document, std::string& error) +{ + document = CapabilityConfigDocument(); + error.clear(); + + if (raw.empty()) + return true; + + const nlohmann::json parsed = nlohmann::json::parse(raw, nullptr, /* allow_exceptions */ false); + if (parsed.is_discarded()) { + error = "The preset stores invalid plugin capability configuration JSON."; + return false; + } + if (!parsed.is_array()) { + error = "The preset's plugin capability configuration is not an array and cannot be edited."; + return false; + } + + document = CapabilityConfigDocument::from_entries(parsed); + return true; +} + +std::string serialize_plugin_overrides(const CapabilityConfigDocument& document) +{ + return document.empty() ? std::string() : document.serialize_entries().dump(); +} + +EffectiveCapabilityConfig PresetPluginConfigService::get_effective_config(const CapabilityConfigDocument& overrides, + const PluginCapabilityIdentifier& id) const +{ + EffectiveCapabilityConfig result; + result.id = make_id(id); + result.running_plugin_version = running_plugin_version(id.plugin_key); + + const BaseConfig base = PluginManager::instance().get_config().get_config(id.plugin_key, id.name); + result.has_base_config = !base.empty(); + + if (const auto entry = overrides.find(result.id)) { + result.has_preset_override = true; + result.config = entry->cap_config; + result.stored_plugin_version = entry->plugin_version; + return result; + } + + if (result.has_base_config) { + result.config = base.config; + result.stored_plugin_version = base.plugin_version; + } + return result; +} + +MutationResult PresetPluginConfigService::set_preset_override(CapabilityConfigDocument& overrides, + const PluginCapabilityIdentifier& id, + const nlohmann::json& value) const +{ + MutationResult result; + const CapabilityConfigId config_id = make_id(id); + const std::string version = running_plugin_version(id.plugin_key); + + // A no-op is a successful unchanged result: re-saving the displayed value must not mark the + // preset dirty. + const auto existing = overrides.find(config_id); + if (existing && existing->cap_config == value && existing->plugin_version == version) { + result.ok = true; + result.effective = get_effective_config(overrides, id); + return result; + } + + overrides.upsert({config_id, version, value}); + + result.ok = true; + result.changed = true; + result.effective = get_effective_config(overrides, id); + return result; +} + +MutationResult PresetPluginConfigService::remove_preset_override(CapabilityConfigDocument& overrides, + const PluginCapabilityIdentifier& id) const +{ + MutationResult result; + result.ok = true; + result.changed = overrides.erase(make_id(id)); + result.effective = get_effective_config(overrides, id); + return result; +} + +EffectiveCapabilityConfig active_capability_config(const PluginCapabilityIdentifier& id) +{ + const PresetPluginConfigService service; + + CapabilityConfigDocument overrides; + + const PresetBundle* bundle = active_preset_bundle(); + const Preset* preset = nullptr; + + if (bundle != nullptr) { + const std::string type_key = plugin_capability_type_to_string(id.type); + for (const auto& [key, def] : print_config_def.options) { + if (def.plugin_type != type_key) + continue; + + const auto& print_options = Preset::print_options(); + if (std::find(print_options.begin(), print_options.end(), key) != print_options.end()) { + preset = &bundle->prints.get_edited_preset(); + break; + } + + const auto& printer_options = Preset::printer_options(); + if (std::find(printer_options.begin(), printer_options.end(), key) != printer_options.end()) { + preset = &bundle->printers.get_edited_preset(); + break; + } + } + } + + if (preset != nullptr) { + std::string error; + if (!parse_plugin_overrides(plugin_overrides_of(*preset), overrides, error)) { + // Text we cannot read is not an override: log it and resolve against the base config. + BOOST_LOG_TRIVIAL(error) << "Preset \"" << preset->name << "\": " << error; + overrides = CapabilityConfigDocument(); + } + } + + return service.get_effective_config(overrides, id); +} + nlohmann::json capability_get_config(const PluginCapabilityInterface& capability) { // Shares its resolution with the dialogs, so a capability reads back exactly the config its UI diff --git a/src/slic3r/plugin/PluginResolver.cpp b/src/slic3r/plugin/PluginResolver.cpp index a164082b38..31c7cbd5e0 100644 --- a/src/slic3r/plugin/PluginResolver.cpp +++ b/src/slic3r/plugin/PluginResolver.cpp @@ -180,36 +180,6 @@ std::vector capabilities_in_use(Preset::Type type, c return result; } -Preset::Type preset_type_for_capability(PluginCapabilityType type) -{ - if (type == PluginCapabilityType::Unknown) - return Preset::TYPE_INVALID; - - // The three typed option lists are disjoint, so the first that holds the key names its owner. - const auto owner_of_option = [](const std::string& key) { - const auto holds = [&key](const std::vector& keys) { - return std::find(keys.begin(), keys.end(), key) != keys.end(); - }; - if (holds(Preset::print_options())) - return Preset::TYPE_PRINT; - if (holds(Preset::filament_options())) - return Preset::TYPE_FILAMENT; - if (holds(Preset::printer_options())) - return Preset::TYPE_PRINTER; - return Preset::TYPE_INVALID; - }; - - const std::string type_key = plugin_capability_type_to_string(type); - for (const auto& [key, def] : print_config_def.options) { - if (def.plugin_type != type_key) - continue; - const Preset::Type owner = owner_of_option(key); - if (owner != Preset::TYPE_INVALID) - return owner; - } - return Preset::TYPE_INVALID; -} - static std::string resolve_cloud_base_url() { std::string cloud_base_url = "https://cloud.orcaslicer.com"; diff --git a/src/slic3r/plugin/PluginResolver.hpp b/src/slic3r/plugin/PluginResolver.hpp index d4ab27b4f6..fd9c79a1b0 100644 --- a/src/slic3r/plugin/PluginResolver.hpp +++ b/src/slic3r/plugin/PluginResolver.hpp @@ -80,13 +80,6 @@ std::string resolve_recovery_url(const PluginCapabilityRef& ref); std::vector referenced_capabilities(Preset::Type type, const Preset& preset); std::vector capabilities_in_use(Preset::Type type, const Preset& preset); -// The preset type whose presets can reference capabilities of `type` and therefore carry their -// overrides. Derived from the ConfigDef rather than hardcoded: a plugin-backed option names the -// capability type it accepts (ConfigOptionDef::plugin_type) and belongs to exactly one preset type, -// so declaring the option is all it takes to map a new capability type. TYPE_INVALID when no option -// accepts the type — nothing can reference it, so no preset owns it. -Preset::Type preset_type_for_capability(PluginCapabilityType type); - // The referenced capabilities of the active preset(s) of `type` that are loaded right now: the set // that can actually be configured. Missing and broken refs are absent, having no instance to ask for // a config UI or defaults. A loaded-but-disabled capability IS listed — it still has stored config diff --git a/src/slic3r/plugin/PresetPluginConfig.cpp b/src/slic3r/plugin/PresetPluginConfig.cpp deleted file mode 100644 index ee7154cf11..0000000000 --- a/src/slic3r/plugin/PresetPluginConfig.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "PresetPluginConfig.hpp" - -#include "PluginManager.hpp" -#include "PluginResolver.hpp" - -#include - -#include -#include -#include - -namespace Slic3r { - -namespace { - -CapabilityConfigId make_id(const PluginCapabilityIdentifier& id) -{ - return CapabilityConfigId{id.plugin_key, id.name}; -} - -std::string running_plugin_version(const std::string& plugin_key) -{ - PluginDescriptor descriptor; - if (!PluginManager::instance().get_catalog().try_get_valid_plugin_descriptor(plugin_key, descriptor)) - return {}; - return descriptor.installed_version.empty() ? descriptor.version : descriptor.installed_version; -} - -// Null wherever the plugin host runs without the GUI app (the unit tests). wxGetApp() dereferences -// the app unconditionally, so ask wxWidgets instead. -const PresetBundle* active_preset_bundle() -{ - const auto* app = dynamic_cast(wxApp::GetInstance()); - return app == nullptr ? nullptr : app->preset_bundle; -} - -// The active preset that can carry an override for a capability of `type`. Edited, not selected: an -// override typed into the tab configures the next slice the same way every other unsaved setting does. -const Preset* active_preset_for(Preset::Type type) -{ - const PresetBundle* bundle = active_preset_bundle(); - if (bundle == nullptr) - return nullptr; - - switch (type) { - case Preset::TYPE_PRINT: return &bundle->prints.get_edited_preset(); - case Preset::TYPE_PRINTER: return &bundle->printers.get_edited_preset(); - - - // Deliberately unimplemented. We currently don't support any filament-based - // plugin capabilities. We will defer this to when we have filament-based plugins - // capabilities to have a clearer understanding on how to implement this. - case Preset::TYPE_FILAMENT: return nullptr; - - default: return nullptr; - } -} - -} // namespace - -std::string plugin_overrides_of(const Preset& preset) -{ - const auto* opt = dynamic_cast(preset.config.option(PLUGIN_OVERRIDES_OPTION_KEY)); - return opt == nullptr ? std::string() : opt->value; -} - -bool parse_plugin_overrides(const std::string& raw, CapabilityConfigDocument& document, std::string& error) -{ - document = CapabilityConfigDocument(); - error.clear(); - - if (raw.empty()) - return true; - - const nlohmann::json parsed = nlohmann::json::parse(raw, nullptr, /* allow_exceptions */ false); - if (parsed.is_discarded()) { - error = "The preset stores invalid plugin capability configuration JSON."; - return false; - } - if (!parsed.is_array()) { - error = "The preset's plugin capability configuration is not an array and cannot be edited."; - return false; - } - - document = CapabilityConfigDocument::from_entries(parsed); - return true; -} - -std::string serialize_plugin_overrides(const CapabilityConfigDocument& document) -{ - return document.empty() ? std::string() : document.serialize_entries().dump(); -} - -EffectiveCapabilityConfig PresetPluginConfigService::get_effective_config(const CapabilityConfigDocument& overrides, - const PluginCapabilityIdentifier& id) const -{ - EffectiveCapabilityConfig result; - result.id = make_id(id); - result.running_plugin_version = running_plugin_version(id.plugin_key); - - const BaseConfig base = PluginManager::instance().get_config().get_config(id.plugin_key, id.name); - result.has_base_config = !base.empty(); - - if (const auto entry = overrides.find(result.id)) { - result.has_preset_override = true; - result.config = entry->cap_config; - result.stored_plugin_version = entry->plugin_version; - return result; - } - - if (result.has_base_config) { - result.config = base.config; - result.stored_plugin_version = base.plugin_version; - } - return result; -} - -MutationResult PresetPluginConfigService::set_preset_override(CapabilityConfigDocument& overrides, - const PluginCapabilityIdentifier& id, - const nlohmann::json& value) const -{ - MutationResult result; - const CapabilityConfigId config_id = make_id(id); - const std::string version = running_plugin_version(id.plugin_key); - - // A no-op is a successful unchanged result: re-saving the displayed value must not mark the - // preset dirty. - const auto existing = overrides.find(config_id); - if (existing && existing->cap_config == value && existing->plugin_version == version) { - result.ok = true; - result.effective = get_effective_config(overrides, id); - return result; - } - - overrides.upsert({config_id, version, value}); - - result.ok = true; - result.changed = true; - result.effective = get_effective_config(overrides, id); - return result; -} - -MutationResult PresetPluginConfigService::remove_preset_override(CapabilityConfigDocument& overrides, - const PluginCapabilityIdentifier& id) const -{ - MutationResult result; - result.ok = true; - result.changed = overrides.erase(make_id(id)); - result.effective = get_effective_config(overrides, id); - return result; -} - -EffectiveCapabilityConfig active_capability_config(const PluginCapabilityIdentifier& id) -{ - const PresetPluginConfigService service; - - CapabilityConfigDocument overrides; - if (const Preset* preset = active_preset_for(preset_type_for_capability(id.type))) { - std::string error; - if (!parse_plugin_overrides(plugin_overrides_of(*preset), overrides, error)) { - // Text we cannot read is not an override: log it and resolve against the base config. - BOOST_LOG_TRIVIAL(error) << "Preset \"" << preset->name << "\": " << error; - overrides = CapabilityConfigDocument(); - } - } - - return service.get_effective_config(overrides, id); -} - -} // namespace Slic3r diff --git a/src/slic3r/plugin/PresetPluginConfig.hpp b/src/slic3r/plugin/PresetPluginConfig.hpp index ca3a978629..d5728de7e1 100644 --- a/src/slic3r/plugin/PresetPluginConfig.hpp +++ b/src/slic3r/plugin/PresetPluginConfig.hpp @@ -63,10 +63,8 @@ public: }; // The same resolution against the preset that is active right now, rather than a document the caller -// holds: this is what a running capability reads through the Python config API. Only one preset type -// can reference a given capability type (preset_type_for_capability), so there is exactly one preset -// to consult. Falls back to the base config for filament capabilities (see active_preset_for) and in -// a host with no preset bundle (the plugin unit tests). +// holds: this is what a running capability reads through the Python config API. It falls back to the +// base config when no active preset bundle is available. EffectiveCapabilityConfig active_capability_config(const PluginCapabilityIdentifier& id); } // namespace Slic3r diff --git a/tests/slic3rutils/test_plugin_capabilities_in_use.cpp b/tests/slic3rutils/test_plugin_capabilities_in_use.cpp index db50de68ec..16ba6e91ac 100644 --- a/tests/slic3rutils/test_plugin_capabilities_in_use.cpp +++ b/tests/slic3rutils/test_plugin_capabilities_in_use.cpp @@ -72,18 +72,3 @@ TEST_CASE("referenced_capabilities skips malformed manifest entries", "[PluginRe CHECK(capability_names(referenced_capabilities(Preset::TYPE_PRINT, preset)) == std::vector{"CapA"}); } - -TEST_CASE("preset_type_for_capability names the preset type whose options reference the capability", "[PluginResolver]") -{ - // Read out of the ConfigDef: declaring a plugin_type on an option is what puts its capability - // type on this map. - CHECK(preset_type_for_capability(PluginCapabilityType::SlicingPipeline) == Preset::TYPE_PRINT); - CHECK(preset_type_for_capability(PluginCapabilityType::PrinterConnection) == Preset::TYPE_PRINTER); -} - -TEST_CASE("preset_type_for_capability leaves capability types no option accepts unowned", "[PluginResolver]") -{ - // No option accepts them, so no preset can override them: they read config.json alone. - CHECK(preset_type_for_capability(PluginCapabilityType::Automation) == Preset::TYPE_INVALID); - CHECK(preset_type_for_capability(PluginCapabilityType::Unknown) == Preset::TYPE_INVALID); -}