aboutsummaryrefslogtreecommitdiff
path: root/libs/plugin_python/src/mobase/pybind11_all.h
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
commit7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch)
tree27fb39be241fdb5ac2734c574de678977d1856d0 /libs/plugin_python/src/mobase/pybind11_all.h
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/plugin_python/src/mobase/pybind11_all.h')
-rw-r--r--libs/plugin_python/src/mobase/pybind11_all.h146
1 files changed, 146 insertions, 0 deletions
diff --git a/libs/plugin_python/src/mobase/pybind11_all.h b/libs/plugin_python/src/mobase/pybind11_all.h
new file mode 100644
index 0000000..c92d7ff
--- /dev/null
+++ b/libs/plugin_python/src/mobase/pybind11_all.h
@@ -0,0 +1,146 @@
+#ifndef PYTHON_PYBIND11_ALL_H
+#define PYTHON_PYBIND11_ALL_H
+
+#include <filesystem>
+
+#include <QDir>
+
+#include <pybind11/operators.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+#include <pybind11/stl/filesystem.h>
+
+#include "pybind11_qt/pybind11_qt.h"
+
+#include "pybind11_utils/functional.h"
+#include "pybind11_utils/generator.h"
+#include "pybind11_utils/shared_cpp_owner.h"
+#include "pybind11_utils/smart_variant_wrapper.h"
+
+#include <uibase/game_features/game_feature.h>
+#include <uibase/isavegame.h>
+#include <uibase/pluginrequirements.h>
+
+namespace mo2::python {
+
+ namespace detail {
+
+ template <>
+ struct smart_variant_converter<QString> {
+
+ static QString from(std::filesystem::path const& path)
+ {
+ return QString::fromStdString(path.string());
+ }
+
+ static QString from(QFileInfo const& fileInfo)
+ {
+ return fileInfo.filePath();
+ }
+
+ static QString from(QDir const& dir) { return dir.path(); }
+ };
+
+ template <>
+ struct smart_variant_converter<std::filesystem::path> {
+
+ static std::filesystem::path from(QString const& value)
+ {
+ return {value.toStdWString()};
+ }
+
+ static std::filesystem::path from(QFileInfo const& fileInfo)
+ {
+ return fileInfo.filesystemFilePath();
+ }
+
+ static std::filesystem::path from(QDir const& dir)
+ {
+ return dir.filesystemPath();
+ }
+ };
+
+ // we do not need specialization for QFileInfo and QDir because both of them can
+ // be constructed from std::filesystem::path and QString already
+
+ } // namespace detail
+
+ using FileWrapper = smart_variant<QString, std::filesystem::path, QFileInfo>;
+ using DirectoryWrapper = smart_variant<QString, std::filesystem::path, QDir>;
+
+ // wrap the given function to accept FileWrapper (str | PathLike | QFileInfo) at the
+ // given argument positions (or any valid positions if Is... is empty)
+ //
+ template <std::size_t... Is, class Fn>
+ auto wrap_for_filepath(Fn&& fn)
+ {
+ return mo2::python::wrap_arguments<FileWrapper, Is...>(std::forward<Fn>(fn));
+ }
+
+ // wrap the given function to accept DirectoryWrapper (str | PathLike | QDir)
+ // at the given argument positions (or any valid positions if Is... is empty)
+ //
+ template <std::size_t... Is, class Fn>
+ auto wrap_for_directory(Fn&& fn)
+ {
+ return mo2::python::wrap_arguments<DirectoryWrapper, Is...>(
+ std::forward<Fn>(fn));
+ }
+
+ // wrap a function-like object to return a FileWrapper instead of its return type,
+ // useful to generate proper typing in Python
+ //
+ // note that QFileInfo has a __fspath__ in Python, so it is quite easy to convert
+ // from "FileWrapper", a.k.a., str | os.PathLike | QFileInfo to Path by simply
+ // calling Path() on the return type if necessary
+ //
+ // this should be combined with custom return-value in PYBIND11_OVERRIDE(_PURE), see
+ // ISaveGame binding for an example
+ //
+ template <class Fn>
+ auto wrap_return_for_filepath(Fn&& fn)
+ {
+ return mo2::python::wrap_return<FileWrapper>(std::forward<Fn>(fn));
+ }
+
+ // similar to wrap_return_for_filepath, except it returns a DirectoryWrapper instead
+ // of its return type
+ //
+ // this is much less practical than wrap_return_for_filepath since QDir does not
+ // expose __fspath__, so more complex things need to be done in Python, which is why
+ // this should be used carefully (e.g., should not be used if the return type is
+ // already QDir)
+ //
+ template <class Fn>
+ auto wrap_return_for_directory(Fn&& fn)
+ {
+ return mo2::python::wrap_return<DirectoryWrapper>(std::forward<Fn>(fn));
+ }
+
+ // convert a QList to QStringList - QString must be constructible from QString
+ //
+ template <class T>
+ QStringList toQStringList(QList<T> const& list)
+ {
+ static_assert(std::is_constructible_v<QString, T>,
+ "QString must be constructible from T.");
+ return {list.begin(), list.end()};
+ }
+
+ // convert a QStringList to a QList - T must be constructible from QString
+ //
+ template <class T>
+ QList<T> toQList(QStringList const& list)
+ {
+ static_assert(std::is_constructible_v<T, QString>,
+ "T must be constructible from QString.");
+ return {list.begin(), list.end()};
+ }
+
+} // namespace mo2::python
+
+MO2_PYBIND11_SHARED_CPP_HOLDER(MOBase::IPluginRequirement)
+MO2_PYBIND11_SHARED_CPP_HOLDER(MOBase::ISaveGame)
+MO2_PYBIND11_SHARED_CPP_HOLDER(MOBase::GameFeature)
+
+#endif