mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-05 01:02:08 +00:00
feat: plugins config APIs
This commit is contained in:
@@ -3,10 +3,13 @@
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "PythonPluginInterface.hpp"
|
||||
#include "PythonInterpreter.hpp"
|
||||
#include "PythonJsonUtils.hpp"
|
||||
#include "PluginAuditManager.hpp"
|
||||
|
||||
// Trampoline variants of pybind11's override macros. Every C++->Python plugin call
|
||||
@@ -90,6 +93,40 @@ public:
|
||||
get_config_ui);
|
||||
}
|
||||
|
||||
// Hand-rolled rather than PYBIND11_OVERRIDE: the macro casts the Python result to the return
|
||||
// type, and nlohmann::json has no pybind caster (config crosses this boundary through the
|
||||
// explicit py_to_json/json_to_py helpers instead). Otherwise identical — same audit scope, and
|
||||
// a Python exception is logged with its traceback and rethrown for the caller to handle.
|
||||
//
|
||||
// The hook is optional, and "not implemented" must mean an EMPTY config, never a null or a
|
||||
// stray scalar landing in cap_config. Two ways to not implement it, both resolved here:
|
||||
// - no override at all -> the base's empty object
|
||||
// - an override that returns None, or any -> likewise. `def get_default_config(self): pass`
|
||||
// non-object (a list, a string, a number) is the easy mistake, and it must not be able to
|
||||
// write `"cap_config": null` to config.json.
|
||||
nlohmann::json get_default_config() const override
|
||||
{
|
||||
ORCA_PY_AUDIT_SCOPE(::Slic3r::PluginAuditManager::AuditMode::Loading);
|
||||
try {
|
||||
pybind11::gil_scoped_acquire gil;
|
||||
pybind11::function override = pybind11::get_override(static_cast<const Base*>(this), "get_default_config");
|
||||
if (!override)
|
||||
return Base::get_default_config();
|
||||
|
||||
nlohmann::json config = ::Slic3r::py_to_json(override());
|
||||
if (!config.is_object()) {
|
||||
BOOST_LOG_TRIVIAL(warning)
|
||||
<< "Plugin capability '" << this->audit_capability_name() << "' of plugin '" << this->audit_plugin_key()
|
||||
<< "': get_default_config() returned " << config.type_name() << ", not an object; restoring an empty config";
|
||||
return Base::get_default_config();
|
||||
}
|
||||
return config;
|
||||
} catch (pybind11::error_already_set& err) {
|
||||
::Slic3r::log_python_exception_keep(err);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// All plugins may define their own on_load/unload functions.
|
||||
void on_load() override
|
||||
{
|
||||
|
||||
@@ -339,6 +339,16 @@ void bind_python_api(pybind11::module_& m)
|
||||
"Override to return the custom configuration UI as an HTML string. Only called when\n"
|
||||
"has_config_ui() is True; an empty result falls back to the default JSON editor.\n"
|
||||
"Inside the page, use window.orca.getConfig()/saveConfig() to reach this same config.")
|
||||
.def(
|
||||
"get_default_config",
|
||||
[](const PluginCapabilityInterface& self) {
|
||||
nlohmann::json config = self.get_default_config();
|
||||
return json_to_py(config); // GIL held (binding body)
|
||||
},
|
||||
"Override to return the config that the Config tab's \"Restore defaults\" action writes\n"
|
||||
"back. Optional: without it the action stores an empty dict, which already restores the\n"
|
||||
"defaults of a capability that keeps its stored config sparse and applies its own\n"
|
||||
"defaults on read. Override it to write an explicit starting config instead.")
|
||||
.def(
|
||||
"get_config",
|
||||
[](const PluginCapabilityInterface& self) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <pybind11/embed.h>
|
||||
|
||||
namespace Slic3r {
|
||||
@@ -116,6 +117,16 @@ public:
|
||||
// treated as "no custom UI" and falls back to the default JSON editor.
|
||||
virtual std::string get_config_ui() const { return ""; }
|
||||
|
||||
// The config the Config tab's "Restore defaults" action writes back. Optional.
|
||||
//
|
||||
// Not overridden -> an empty object, which is the right answer for a capability that keeps
|
||||
// its stored config sparse and applies its own defaults on read: clearing the overrides
|
||||
// *is* restoring the defaults, and it keeps a later release free to change them.
|
||||
// Override it to write an explicit starting config instead (e.g. to seed a form UI with
|
||||
// every field present). The host neither invents nor validates this value; it only stores
|
||||
// whatever comes back, so a throwing override leaves the stored config untouched.
|
||||
virtual nlohmann::json get_default_config() const { return nlohmann::json::object(); }
|
||||
|
||||
virtual void on_load() {}
|
||||
virtual void on_unload() {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user