From e21123d8e982d26bd89277a63a8aa099abd54e8a Mon Sep 17 00:00:00 2001 From: Ian Chua Date: Wed, 15 Jul 2026 21:43:13 +0800 Subject: [PATCH] fix: trim configs --- src/slic3r/CMakeLists.txt | 2 - src/slic3r/GUI/PluginsConfigDialog.hpp | 2 +- .../plugin/CapabilityConfigDocument.hpp | 57 ---------- src/slic3r/plugin/PluginConfig.cpp | 1 - src/slic3r/plugin/PluginConfig.hpp | 105 +++++++++++++++++- src/slic3r/plugin/PresetPluginConfig.hpp | 70 ------------ 6 files changed, 105 insertions(+), 132 deletions(-) delete mode 100644 src/slic3r/plugin/CapabilityConfigDocument.hpp delete mode 100644 src/slic3r/plugin/PresetPluginConfig.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 0d344a2bcc..a5a26d84d3 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -619,10 +619,8 @@ set(SLIC3R_GUI_SOURCES plugin/CloudPluginService.hpp plugin/PluginFsUtils.cpp plugin/PluginFsUtils.hpp - plugin/CapabilityConfigDocument.hpp plugin/PluginConfig.cpp plugin/PluginConfig.hpp - plugin/PresetPluginConfig.hpp plugin/PythonJsonUtils.hpp plugin/PluginLoader.cpp plugin/PluginLoader.hpp diff --git a/src/slic3r/GUI/PluginsConfigDialog.hpp b/src/slic3r/GUI/PluginsConfigDialog.hpp index 1a7ae75980..08407faa9a 100644 --- a/src/slic3r/GUI/PluginsConfigDialog.hpp +++ b/src/slic3r/GUI/PluginsConfigDialog.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include diff --git a/src/slic3r/plugin/CapabilityConfigDocument.hpp b/src/slic3r/plugin/CapabilityConfigDocument.hpp deleted file mode 100644 index ebdd4abbeb..0000000000 --- a/src/slic3r/plugin/CapabilityConfigDocument.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -namespace Slic3r { - -struct CapabilityConfigId -{ - std::string plugin_key; - std::string capability; - - friend bool operator<(const CapabilityConfigId& lhs, const CapabilityConfigId& rhs) - { - return lhs.plugin_key < rhs.plugin_key || - (lhs.plugin_key == rhs.plugin_key && lhs.capability < rhs.capability); - } - - friend bool operator==(const CapabilityConfigId& lhs, const CapabilityConfigId& rhs) - { - return lhs.plugin_key == rhs.plugin_key && lhs.capability == rhs.capability; - } -}; - -struct CapabilityConfigEntry -{ - CapabilityConfigId id; - std::string plugin_version; - nlohmann::json cap_config = nlohmann::json::object(); -}; - -class CapabilityConfigDocument -{ -public: - static constexpr const char* KeyEntries = "config"; - - static CapabilityConfigDocument from_root_json(const nlohmann::json& root); - static CapabilityConfigDocument from_entries(const nlohmann::json& entries); - - std::optional find(const CapabilityConfigId& id) const; - bool contains(const CapabilityConfigId& id) const; - bool upsert(CapabilityConfigEntry entry); - bool erase(const CapabilityConfigId& id); - bool empty() const; - nlohmann::json serialize_entries() const; - nlohmann::json root_json() const; - -private: - std::map m_entries; - std::vector m_opaque_entries; -}; - -} // namespace Slic3r diff --git a/src/slic3r/plugin/PluginConfig.cpp b/src/slic3r/plugin/PluginConfig.cpp index d7421a6fa8..9acce3ed86 100644 --- a/src/slic3r/plugin/PluginConfig.cpp +++ b/src/slic3r/plugin/PluginConfig.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/src/slic3r/plugin/PluginConfig.hpp b/src/slic3r/plugin/PluginConfig.hpp index 6278e5be60..9056137124 100644 --- a/src/slic3r/plugin/PluginConfig.hpp +++ b/src/slic3r/plugin/PluginConfig.hpp @@ -3,11 +3,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -17,8 +17,54 @@ namespace Slic3r { class PluginCapabilityInterface; +class Preset; struct PluginCapabilityId; +struct CapabilityConfigId +{ + std::string plugin_key; + std::string capability; + + friend bool operator<(const CapabilityConfigId& lhs, const CapabilityConfigId& rhs) + { + return lhs.plugin_key < rhs.plugin_key || + (lhs.plugin_key == rhs.plugin_key && lhs.capability < rhs.capability); + } + + friend bool operator==(const CapabilityConfigId& lhs, const CapabilityConfigId& rhs) + { + return lhs.plugin_key == rhs.plugin_key && lhs.capability == rhs.capability; + } +}; + +struct CapabilityConfigEntry +{ + CapabilityConfigId id; + std::string plugin_version; + nlohmann::json cap_config = nlohmann::json::object(); +}; + +class CapabilityConfigDocument +{ +public: + static constexpr const char* KeyEntries = "config"; + + static CapabilityConfigDocument from_root_json(const nlohmann::json& root); + static CapabilityConfigDocument from_entries(const nlohmann::json& entries); + + std::optional find(const CapabilityConfigId& id) const; + bool contains(const CapabilityConfigId& id) const; + bool upsert(CapabilityConfigEntry entry); + bool erase(const CapabilityConfigId& id); + bool empty() const; + nlohmann::json serialize_entries() const; + nlohmann::json root_json() const; + +private: + std::map m_entries; + std::vector m_opaque_entries; +}; + /* Example config.json shape { @@ -44,6 +90,63 @@ struct BaseConfig { bool empty() const { return plugin_key.empty() || capability_name.empty(); } }; +// A preset keeps its plugin capability overrides as one raw JSON string in this ordinary +// ConfigOptionString, so the whole preset lifecycle — load, save, diff/dirty, inheritance, 3MF, +// sync — carries it for free. The plugin layer is the only thing that gives that string meaning. +inline constexpr const char* PLUGIN_OVERRIDES_OPTION_KEY = "plugin_preference_overrides"; + +// The preset's raw override text, or "" when it stores none. +std::string plugin_overrides_of(const Preset& preset); + +// An empty string is a valid, empty document. Returns false and fills `error` when the text is +// present but is not a JSON array of entries; the caller then shows it and edits nothing. +bool parse_plugin_overrides(const std::string& raw, CapabilityConfigDocument& document, std::string& error); + +// The document as compact JSON text, and "" once it holds no entries. Empty text — rather than a +// removed option — records "cleared here" against an inheriting parent that has overrides. +std::string serialize_plugin_overrides(const CapabilityConfigDocument& document); + +struct EffectiveCapabilityConfig +{ + CapabilityConfigId id; + nlohmann::json config = nlohmann::json::object(); + + bool has_preset_override = false; + bool has_base_config = false; + std::string stored_plugin_version; + std::string running_plugin_version; +}; + +struct MutationResult +{ + bool ok = false; + bool changed = false; + std::string error; + EffectiveCapabilityConfig effective; +}; + +// Resolves a capability's effective config as `preset override -> base config -> none`, and mutates +// the override layer. It works on a CapabilityConfigDocument the caller owns, never on a Preset and +// never on the base config file, which keeps the two layers from writing to each other: +// PluginConfigField holds the document and feeds the edited text back through the normal field/dirty +// pipeline, so the preset is written the way every other setting is. +class PresetPluginConfigService +{ +public: + EffectiveCapabilityConfig get_effective_config(const CapabilityConfigDocument& overrides, + const PluginCapabilityId& id) const; + MutationResult set_preset_override(CapabilityConfigDocument& overrides, + const PluginCapabilityId& id, + const nlohmann::json& value) const; + MutationResult remove_preset_override(CapabilityConfigDocument& overrides, + const PluginCapabilityId& id) const; +}; + +// 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. It falls +// back to the base config when no active preset bundle is available. +EffectiveCapabilityConfig active_capability_config(const PluginCapabilityId& id); + // Store for every plugin capability's configuration, persisted as a single config.json alongside the // installed plugins. The shape of `cap_config` belongs to the plugin; this class only round-trips it. // diff --git a/src/slic3r/plugin/PresetPluginConfig.hpp b/src/slic3r/plugin/PresetPluginConfig.hpp deleted file mode 100644 index e5c36c10ab..0000000000 --- a/src/slic3r/plugin/PresetPluginConfig.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "CapabilityConfigDocument.hpp" -#include "PluginConfig.hpp" - -#include -#include - -#include - -namespace Slic3r { - -// A preset keeps its plugin capability overrides as one raw JSON string in this ordinary -// ConfigOptionString, so the whole preset lifecycle — load, save, diff/dirty, inheritance, 3MF, -// sync — carries it for free. The plugin layer is the only thing that gives that string meaning. -inline constexpr const char* PLUGIN_OVERRIDES_OPTION_KEY = "plugin_preference_overrides"; - -// The preset's raw override text, or "" when it stores none. -std::string plugin_overrides_of(const Preset& preset); - -// An empty string is a valid, empty document. Returns false and fills `error` when the text is -// present but is not a JSON array of entries; the caller then shows it and edits nothing. -bool parse_plugin_overrides(const std::string& raw, CapabilityConfigDocument& document, std::string& error); - -// The document as compact JSON text, and "" once it holds no entries. Empty text — rather than a -// removed option — records "cleared here" against an inheriting parent that has overrides. -std::string serialize_plugin_overrides(const CapabilityConfigDocument& document); - -struct EffectiveCapabilityConfig -{ - CapabilityConfigId id; - nlohmann::json config = nlohmann::json::object(); - - bool has_preset_override = false; - bool has_base_config = false; - std::string stored_plugin_version; - std::string running_plugin_version; -}; - -struct MutationResult -{ - bool ok = false; - bool changed = false; - std::string error; - EffectiveCapabilityConfig effective; -}; - -// Resolves a capability's effective config as `preset override -> base config -> none`, and mutates -// the override layer. It works on a CapabilityConfigDocument the caller owns, never on a Preset and -// never on the base config file, which keeps the two layers from writing to each other: -// PluginConfigField holds the document and feeds the edited text back through the normal field/dirty -// pipeline, so the preset is written the way every other setting is. -class PresetPluginConfigService -{ -public: - EffectiveCapabilityConfig get_effective_config(const CapabilityConfigDocument& overrides, - const PluginCapabilityId& id) const; - MutationResult set_preset_override(CapabilityConfigDocument& overrides, - const PluginCapabilityId& id, - const nlohmann::json& value) const; - MutationResult remove_preset_override(CapabilityConfigDocument& overrides, - const PluginCapabilityId& id) const; -}; - -// 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. It falls back to the -// base config when no active preset bundle is available. -EffectiveCapabilityConfig active_capability_config(const PluginCapabilityId& id); - -} // namespace Slic3r