mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-07 10:07:38 +00:00
Merge branch 'main' into fix/plugin-install-state
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
|
||||
#include <libslic3r/Config.hpp>
|
||||
#include <libslic3r/PresetBundle.hpp>
|
||||
#include <libslic3r/PrintConfig.hpp>
|
||||
#include <slic3r/GUI/GUI.hpp>
|
||||
@@ -164,6 +165,20 @@ bool CapabilityConfigDocument::erase(const PluginCapabilityId& id)
|
||||
return erased;
|
||||
}
|
||||
|
||||
bool CapabilityConfigDocument::prune_unreferenced(const std::set<std::pair<PluginCapabilityType, std::string>>& referenced)
|
||||
{
|
||||
bool changed = false;
|
||||
for (auto it = m_entries.begin(); it != m_entries.end();) {
|
||||
if (referenced.count({it->first.type, it->first.name}) != 0) {
|
||||
++it;
|
||||
} else {
|
||||
it = m_entries.erase(it);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool CapabilityConfigDocument::empty() const
|
||||
{
|
||||
return m_entries.empty() && m_opaque_entries.empty();
|
||||
@@ -342,6 +357,50 @@ std::string serialize_plugin_overrides(const CapabilityConfigDocument& document)
|
||||
return document.empty() ? std::string() : document.serialize_entries().dump();
|
||||
}
|
||||
|
||||
bool prune_stale_plugin_overrides(DynamicConfig& config)
|
||||
{
|
||||
const auto* overrides_opt = dynamic_cast<const ConfigOptionString*>(config.option(PLUGIN_OVERRIDES_OPTION_KEY));
|
||||
if (overrides_opt == nullptr || overrides_opt->value.empty())
|
||||
return false;
|
||||
|
||||
CapabilityConfigDocument overrides;
|
||||
std::string error;
|
||||
if (!parse_plugin_overrides(overrides_opt->value, overrides, error)) {
|
||||
// Malformed text is not ours to fix up here: leave it untouched rather than risk
|
||||
// discarding data the user might still be able to recover.
|
||||
BOOST_LOG_TRIVIAL(error) << "prune_stale_plugin_overrides: " << error;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Capability names currently referenced by a plugin-backed option's value(s) — e.g.
|
||||
// slicing_pipeline_plugin's ConfigOptionStrings entries name SlicingPipeline capabilities
|
||||
// directly, the same raw values save_plugin_collection() resolves into the "plugins" manifest.
|
||||
std::set<std::pair<PluginCapabilityType, std::string>> referenced;
|
||||
const ConfigDef* def = config.def();
|
||||
for (const std::string& opt_key : config.keys()) {
|
||||
const ConfigOptionDef* opt_def = def != nullptr ? def->get(opt_key) : nullptr;
|
||||
if (opt_def == nullptr || !opt_def->is_plugin_backed())
|
||||
continue;
|
||||
|
||||
const ConfigOption* opt = config.option(opt_key);
|
||||
const PluginCapabilityType type = plugin_capability_type_from_string(opt_def->plugin_type);
|
||||
if (const auto* string_opt = dynamic_cast<const ConfigOptionString*>(opt)) {
|
||||
if (!string_opt->value.empty())
|
||||
referenced.emplace(type, string_opt->value);
|
||||
} else if (const auto* vector_opt = dynamic_cast<const ConfigOptionVectorBase*>(opt)) {
|
||||
for (const std::string& value : vector_opt->vserialize())
|
||||
if (!value.empty())
|
||||
referenced.emplace(type, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!overrides.prune_unreferenced(referenced))
|
||||
return false;
|
||||
|
||||
config.set_key_value(PLUGIN_OVERRIDES_OPTION_KEY, new ConfigOptionString(serialize_plugin_overrides(overrides)));
|
||||
return true;
|
||||
}
|
||||
|
||||
EffectiveCapabilityConfig PresetPluginConfigService::get_effective_config(const CapabilityConfigDocument& overrides,
|
||||
const PluginCapabilityId& id) const
|
||||
{
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#define PLUGIN_CONFIG_DIR "config.json"
|
||||
@@ -16,6 +18,7 @@
|
||||
namespace Slic3r {
|
||||
|
||||
class Preset;
|
||||
class DynamicConfig;
|
||||
struct CapabilityConfigEntry
|
||||
{
|
||||
PluginCapabilityId id;
|
||||
@@ -35,6 +38,9 @@ public:
|
||||
bool contains(const PluginCapabilityId& id) const;
|
||||
bool upsert(CapabilityConfigEntry entry);
|
||||
bool erase(const PluginCapabilityId& id);
|
||||
// Drops every entry whose (type, name) is not in `referenced`, e.g. capabilities a preset's
|
||||
// plugin-backed options no longer name. Returns true if anything was removed.
|
||||
bool prune_unreferenced(const std::set<std::pair<PluginCapabilityType, std::string>>& referenced);
|
||||
bool empty() const;
|
||||
nlohmann::json serialize_entries() const;
|
||||
nlohmann::json root_json() const;
|
||||
@@ -50,6 +56,14 @@ std::string plugin_overrides_of(const Preset& preset);
|
||||
bool parse_plugin_overrides(const std::string& raw, CapabilityConfigDocument& document, std::string& error);
|
||||
std::string serialize_plugin_overrides(const CapabilityConfigDocument& document);
|
||||
|
||||
// Drops plugin_config_overrides entries for capabilities no longer named by any plugin-backed
|
||||
// option's current value in `config` (e.g. slicing_pipeline_plugin cleared or switched to a
|
||||
// different capability), and writes the result back if anything changed. Called wherever a
|
||||
// plugin-backed option's value changes, so a saved preset never carries configuration for a
|
||||
// capability it no longer references. Returns true if `config` was modified, so a caller holding a
|
||||
// GUI field over PLUGIN_OVERRIDES_OPTION_KEY knows it must refresh that field's displayed value.
|
||||
bool prune_stale_plugin_overrides(DynamicConfig& config);
|
||||
|
||||
struct EffectiveCapabilityConfig
|
||||
{
|
||||
PluginCapabilityId id;
|
||||
|
||||
@@ -54,7 +54,7 @@ struct PluginDescriptor
|
||||
std::string description; // Plugin description
|
||||
std::string author; // Plugin author from manifest, if available
|
||||
std::string version; // Selected plugin version
|
||||
std::string latest_version; // Latest available cloud version fallback when changelog is unavailable.
|
||||
std::string latest_version; // Authoritative latest available cloud version.
|
||||
std::string installed_version; // Locally installed package version. Preserved across cloud merges, which overwrite `version` with the latest cloud version. Empty when not installed.
|
||||
std::vector<std::string> display_types; // Display-only "compatibility" labels (cloud: raw service labels; local: from real capabilities). Never used for dispatch.
|
||||
std::string plugin_root; // Installed plugin directory, even when entry_path is invalid or ambiguous.
|
||||
@@ -117,10 +117,6 @@ struct PluginDescriptor
|
||||
bool is_unauthorized() const { return get_update_status() == PluginUpdateStatus::Unauthorized; }
|
||||
std::string latest_available_version() const
|
||||
{
|
||||
for (const PluginChangelog& entry : changelog) {
|
||||
if (!entry.version.empty())
|
||||
return entry.version;
|
||||
}
|
||||
if (!latest_version.empty())
|
||||
return latest_version;
|
||||
return version;
|
||||
|
||||
Reference in New Issue
Block a user