fix: merge pythonjsonutils into pluginfsutils

This commit is contained in:
Ian Chua
2026-07-17 13:35:51 +08:00
parent 74ffc46bbc
commit 96182e778a
6 changed files with 71 additions and 79 deletions

View File

@@ -621,7 +621,6 @@ set(SLIC3R_GUI_SOURCES
plugin/PluginFsUtils.hpp
plugin/PluginConfig.cpp
plugin/PluginConfig.hpp
plugin/PythonJsonUtils.hpp
plugin/PluginLoader.cpp
plugin/PluginLoader.hpp
plugin/PluginDescriptor.hpp

View File

@@ -2,8 +2,12 @@
#include "PluginDescriptor.hpp"
#include <nlohmann/json.hpp>
#include <pybind11/pybind11.h>
#include <boost/filesystem/path.hpp>
#include <cstdint>
#include <string>
#include <vector>
@@ -13,6 +17,70 @@ namespace Slic3r {
extern const char* const INSTALL_STATE_FILE;
// JSON <-> Python conversion shared by the plugin bindings. The caller must hold the GIL.
// Plugin config and orca.host.ui payloads both cross the boundary as plain JSON-compatible
// values, so both go through these.
inline pybind11::object json_to_py(const nlohmann::json& j)
{
namespace py = pybind11;
using json = nlohmann::json;
switch (j.type()) {
case json::value_t::null: return py::none();
case json::value_t::boolean: return py::bool_(j.get<bool>());
case json::value_t::number_integer: return py::int_(j.get<std::int64_t>());
case json::value_t::number_unsigned: return py::int_(j.get<std::uint64_t>());
case json::value_t::number_float: return py::float_(j.get<double>());
case json::value_t::string: return py::str(j.get<std::string>());
case json::value_t::array: {
py::list lst;
for (const auto& e : j)
lst.append(json_to_py(e));
return lst;
}
case json::value_t::object: {
py::dict d;
for (auto it = j.begin(); it != j.end(); ++it)
d[py::str(it.key())] = json_to_py(it.value());
return d;
}
default: return py::none();
}
}
inline nlohmann::json py_to_json(const pybind11::handle& o)
{
namespace py = pybind11;
using json = nlohmann::json;
if (o.is_none())
return json(nullptr);
if (py::isinstance<py::bool_>(o)) // bool before int (bool subclasses int in Python)
return o.cast<bool>();
if (py::isinstance<py::int_>(o))
return o.cast<std::int64_t>();
if (py::isinstance<py::float_>(o))
return o.cast<double>();
if (py::isinstance<py::str>(o))
return o.cast<std::string>();
if (py::isinstance<py::bytes>(o))
return o.cast<std::string>();
if (py::isinstance<py::dict>(o)) {
json obj = json::object();
for (auto item : py::reinterpret_borrow<py::dict>(o))
obj[py::str(item.first).cast<std::string>()] = py_to_json(item.second);
return obj;
}
if (py::isinstance<py::list>(o) || py::isinstance<py::tuple>(o)) {
json arr = json::array();
for (auto e : o)
arr.push_back(py_to_json(e));
return arr;
}
return py::str(o).cast<std::string>(); // fallback: str()
}
// Returns the cloud plugin install/scan directory for a given user_id.
// Path: {data_dir}/orca_plugins/_subscribed/{user_id}/
std::string get_cloud_plugin_dir(const std::string& user_id);

View File

@@ -10,7 +10,7 @@
#include "PythonPluginInterface.hpp"
#include "PythonInterpreter.hpp"
#include "PythonJsonUtils.hpp"
#include "PluginFsUtils.hpp"
#include "PluginAuditManager.hpp"
// Trampoline variants of pybind11's override macros. Every C++->Python plugin call crosses a

View File

@@ -1,75 +0,0 @@
#pragma once
#include <nlohmann/json.hpp>
#include <pybind11/pybind11.h>
#include <cstdint>
#include <string>
namespace Slic3r {
// JSON <-> Python conversion shared by the plugin bindings. The caller must hold the GIL.
// Plugin config and orca.host.ui payloads both cross the boundary as plain JSON-compatible
// values, so both go through these.
inline pybind11::object json_to_py(const nlohmann::json& j)
{
namespace py = pybind11;
using json = nlohmann::json;
switch (j.type()) {
case json::value_t::null: return py::none();
case json::value_t::boolean: return py::bool_(j.get<bool>());
case json::value_t::number_integer: return py::int_(j.get<std::int64_t>());
case json::value_t::number_unsigned: return py::int_(j.get<std::uint64_t>());
case json::value_t::number_float: return py::float_(j.get<double>());
case json::value_t::string: return py::str(j.get<std::string>());
case json::value_t::array: {
py::list lst;
for (const auto& e : j)
lst.append(json_to_py(e));
return lst;
}
case json::value_t::object: {
py::dict d;
for (auto it = j.begin(); it != j.end(); ++it)
d[py::str(it.key())] = json_to_py(it.value());
return d;
}
default: return py::none();
}
}
inline nlohmann::json py_to_json(const pybind11::handle& o)
{
namespace py = pybind11;
using json = nlohmann::json;
if (o.is_none())
return json(nullptr);
if (py::isinstance<py::bool_>(o)) // bool before int (bool subclasses int in Python)
return o.cast<bool>();
if (py::isinstance<py::int_>(o))
return o.cast<std::int64_t>();
if (py::isinstance<py::float_>(o))
return o.cast<double>();
if (py::isinstance<py::str>(o))
return o.cast<std::string>();
if (py::isinstance<py::bytes>(o))
return o.cast<std::string>();
if (py::isinstance<py::dict>(o)) {
json obj = json::object();
for (auto item : py::reinterpret_borrow<py::dict>(o))
obj[py::str(item.first).cast<std::string>()] = py_to_json(item.second);
return obj;
}
if (py::isinstance<py::list>(o) || py::isinstance<py::tuple>(o)) {
json arr = json::array();
for (auto e : o)
arr.push_back(py_to_json(e));
return arr;
}
return py::str(o).cast<std::string>(); // fallback: str()
}
} // namespace Slic3r

View File

@@ -13,7 +13,7 @@
#include <pybind11/stl.h>
#include "PythonInterpreter.hpp"
#include "PythonJsonUtils.hpp"
#include "PluginFsUtils.hpp"
#include "PluginConfig.hpp"
#include "host/PluginHost.hpp"
#include "PyPluginPackage.hpp"

View File

@@ -2,7 +2,7 @@
#include "slic3r/plugin/PluginAuditManager.hpp"
#include "slic3r/plugin/PythonInterpreter.hpp" // PythonGILState
#include "slic3r/plugin/PythonJsonUtils.hpp" // json_to_py / py_to_json
#include "slic3r/plugin/PluginFsUtils.hpp" // json_to_py / py_to_json
#include <slic3r/GUI/GUI_App.hpp>
#include <slic3r/GUI/MainFrame.hpp>