diff --git a/src/proxy/plugin_python_en.ts b/src/proxy/plugin_python_en.ts
index e4e2f66..99302dd 100644
--- a/src/proxy/plugin_python_en.ts
+++ b/src/proxy/plugin_python_en.ts
@@ -14,48 +14,48 @@
-
+
ModOrganizer path contains a semicolon
-
+
Python DLL not found
-
+
Invalid Python DLL
-
+
Initializing Python failed
-
-
+
+
invalid problem key %1
-
+
The path to Mod Organizer (%1) contains a semicolon. <br>While this is legal on NTFS drives, many softwares do not handle it correctly.<br>Unfortunately MO depends on libraries that seem to fall into that group.<br>As a result the python plugin cannot be loaded, and the only solution we canoffer is to remove the semicolon or move MO to a path without a semicolon.
-
+
The Python plugin DLL was not found, maybe your antivirus deleted it. Re-installing MO2 might fix the problem.
-
+
The Python plugin DLL is invalid, maybe your antivirus is blocking it. Re-installing MO2 and adding exclusions for it to your AV might fix the problem.
-
+
The initialization of the Python plugin DLL failed, unfortunately without any details.
diff --git a/src/proxy/proxypython.cpp b/src/proxy/proxypython.cpp
index 377d277..035063c 100644
--- a/src/proxy/proxypython.cpp
+++ b/src/proxy/proxypython.cpp
@@ -153,15 +153,11 @@ QStringList ProxyPython::pluginList(const QDir& pluginPath) const
QString name = iter.next();
QFileInfo info = iter.fileInfo();
- if (info.fileName() == "pyCfg.py" || info.fileName() == "installer_wizard") {
+ if (info.isFile() && name.endsWith(".py")) {
result.append(name);
}
-
- if (info.isFile() && name.endsWith(".py")) {
- // result.append(name);
- }
else if (info.isDir() && QDir(info.absoluteFilePath()).exists("__init__.py")) {
- // result.append(name);
+ result.append(name);
}
}
diff --git a/src/proxy/proxypython.h b/src/proxy/proxypython.h
index 249d198..9da1b9d 100644
--- a/src/proxy/proxypython.h
+++ b/src/proxy/proxypython.h
@@ -25,59 +25,56 @@ along with python proxy plugin. If not, see .
#include
-#include
#include
+#include
#include
-
-class ProxyPython : public QObject, public MOBase::IPluginProxy, public MOBase::IPluginDiagnose
-{
- Q_OBJECT
- Q_INTERFACES(MOBase::IPlugin MOBase::IPluginProxy MOBase::IPluginDiagnose)
-#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
- Q_PLUGIN_METADATA(IID "org.tannin.ProxyPython" FILE "proxypython.json")
+class ProxyPython : public QObject,
+ public MOBase::IPluginProxy,
+ public MOBase::IPluginDiagnose {
+ Q_OBJECT
+ Q_INTERFACES(MOBase::IPlugin MOBase::IPluginProxy MOBase::IPluginDiagnose)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org.mo2.ProxyPython")
#endif
public:
- ProxyPython();
+ ProxyPython();
- virtual bool init(MOBase::IOrganizer *moInfo);
- virtual QString name() const override;
- virtual QString localizedName() const override;
- virtual QString author() const override;
- virtual QString description() const override;
- virtual MOBase::VersionInfo version() const override;
- virtual QList settings() const override;
+ virtual bool init(MOBase::IOrganizer* moInfo);
+ virtual QString name() const override;
+ virtual QString localizedName() const override;
+ virtual QString author() const override;
+ virtual QString description() const override;
+ virtual MOBase::VersionInfo version() const override;
+ virtual QList settings() const override;
- QStringList pluginList(const QDir& pluginPath) const override;
- QList load(const QString& identifier) override;
- void unload(const QString& identifier) override;
+ QStringList pluginList(const QDir& pluginPath) const override;
+ QList load(const QString& identifier) override;
+ void unload(const QString& identifier) override;
-public: // IPluginDiagnose
-
- virtual std::vector activeProblems() const override;
- virtual QString shortDescription(unsigned int key) const override;
- virtual QString fullDescription(unsigned int key) const override;
- virtual bool hasGuidedFix(unsigned int key) const override;
- virtual void startGuidedFix(unsigned int key) const override;
+public: // IPluginDiagnose
+ virtual std::vector activeProblems() const override;
+ virtual QString shortDescription(unsigned int key) const override;
+ virtual QString fullDescription(unsigned int key) const override;
+ virtual bool hasGuidedFix(unsigned int key) const override;
+ virtual void startGuidedFix(unsigned int key) const override;
private:
+ MOBase::IOrganizer* m_MOInfo;
+ HMODULE m_RunnerLib;
+ std::unique_ptr m_Runner;
- MOBase::IOrganizer *m_MOInfo;
- HMODULE m_RunnerLib;
- std::unique_ptr m_Runner;
-
- enum class FailureType : unsigned int {
- NONE = 0,
- SEMICOLON = 1,
- DLL_NOT_FOUND = 2,
- INVALID_DLL = 3,
- INITIALIZATION = 4
- };
-
- FailureType m_LoadFailure;
+ enum class FailureType : unsigned int {
+ NONE = 0,
+ SEMICOLON = 1,
+ DLL_NOT_FOUND = 2,
+ INVALID_DLL = 3,
+ INITIALIZATION = 4
+ };
+ FailureType m_LoadFailure;
};
-#endif // PROXYPYTHON_H
+#endif // PROXYPYTHON_H
diff --git a/src/proxy/proxypython.json b/src/proxy/proxypython.json
deleted file mode 100644
index 69a88e3..0000000
--- a/src/proxy/proxypython.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/src/runner-pybind11/CMakeLists.txt b/src/runner-pybind11/CMakeLists.txt
index 4a01831..5468256 100644
--- a/src/runner-pybind11/CMakeLists.txt
+++ b/src/runner-pybind11/CMakeLists.txt
@@ -1,14 +1,11 @@
cmake_minimum_required(VERSION 3.16)
-# need to find Boost here with a dummy component to get Boost_LIBRARY_DIRS
-find_package(Boost COMPONENTS thread REQUIRED)
-
pybind11_add_module(pythonrunner SHARED)
mo2_configure_library(pythonrunner
WARNINGS OFF
AUTOMOC ON
TRANSLATIONS OFF
- PRIVATE_DEPENDS uibase boost Qt::Core
+ PRIVATE_DEPENDS uibase Qt::Core
)
set_target_properties(pythonrunner
PROPERTIES
@@ -19,11 +16,6 @@ target_link_libraries(pythonrunner PRIVATE pybind11::embed)
target_include_directories(pythonrunner PRIVATE ${PYTHON_ROOT}/Include)
# this is kind of broken but it only works with this...
-target_link_directories(pythonrunner
- PRIVATE
- ${Boost_LIBRARY_DIRS})
-target_compile_options(pythonrunner
- PRIVATE $<$:/MP>)
target_compile_definitions(pythonrunner
PRIVATE QT_NO_KEYWORDS PYTHONRUNNER_LIBRARY)
mo2_install_target(pythonrunner INSTALLDIR bin/plugins/data)
diff --git a/src/runner-pybind11/converters-old.h b/src/runner-pybind11/converters-old.h
deleted file mode 100644
index d941eaf..0000000
--- a/src/runner-pybind11/converters-old.h
+++ /dev/null
@@ -1,669 +0,0 @@
-#ifndef PYTHON_CONVERTERS_OLD_HPP
-#define PYTHON_CONVERTERS_OLD_HPP
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-// sip and qt slots seems to conflict
-#include
-
-// Include the container converters from utils:
-#include "pythonutils.h"
-
-namespace utils {
-
- namespace bpy = boost::python;
-
- namespace QString_converter {
-
- /**
- * We need this since sip does not expose QString but uses standard python str.
- */
- struct QString_to_python_str {
- static PyObject* convert(const QString& str)
- {
- // It's safer to explicitly convert to unicode as if we don't, this can
- // return either str or unicode without it being easy to know which to
- // expect
- bpy::object pyStr = bpy::object(qUtf8Printable(str));
- if (SIPBytes_Check(pyStr.ptr()))
- pyStr = pyStr.attr("decode")("utf-8");
- return bpy::incref(pyStr.ptr());
- }
- };
-
- struct QString_from_python_str {
-
- static void* convertible(PyObject* objPtr)
- {
- return SIPBytes_Check(objPtr) || PyUnicode_Check(objPtr) ? objPtr
- : nullptr;
- }
-
- static void construct(PyObject* objPtr,
- bpy::converter::rvalue_from_python_stage1_data* data)
- {
- // Ensure the string uses 8-bit characters
- PyObject* strPtr =
- PyUnicode_Check(objPtr) ? PyUnicode_AsUTF8String(objPtr) : objPtr;
-
- // Extract the character data from the python string
- const char* value = SIPBytes_AsString(strPtr);
- assert(value != nullptr);
-
- // allocate storage
- void* storage =
- ((bpy::converter::rvalue_from_python_storage*)data)
- ->storage.bytes;
-
- // construct QString in the allocated memory
- new (storage) QString(value);
-
- data->convertible = storage;
-
- // Deallocate local copy if one was made
- if (strPtr != objPtr)
- Py_DecRef(strPtr);
- }
- };
-
- } // namespace QString_converter
-
- namespace Enum_converter {
-
- /**
- *
- */
- template
- struct Enum_to_int {
- static PyObject* convert(const Enum& flags)
- {
- return bpy::incref(bpy::object(static_cast(flags)).ptr());
- }
- };
-
- template
- struct Enum_from_python_obj {
-
- static void* convertible(PyObject* objPtr)
- {
- return SIPLong_Check(objPtr) ? objPtr : nullptr;
- }
-
- static void construct(PyObject* objPtr,
- bpy::converter::rvalue_from_python_stage1_data* data)
- {
- int intVersion = (int)SIPLong_AsLong(objPtr);
- void* storage =
- ((bpy::converter::rvalue_from_python_storage*)data)
- ->storage.bytes;
- new (storage) Enum(static_cast(intVersion));
- data->convertible = storage;
- }
- };
-
- } // namespace Enum_converter
-
- namespace QFlags_converter {
-
- /**
- *
- */
- template
- struct QFlags_to_int {
- static PyObject* convert(const QFlags& flags)
- {
- return bpy::incref(bpy::object(static_cast(flags)).ptr());
- }
- };
-
- template
- struct QFlags_from_python_obj {
-
- static void* convertible(PyObject* objPtr)
- {
- return SIPLong_Check(objPtr) ? objPtr : nullptr;
- }
-
- static void construct(PyObject* objPtr,
- bpy::converter::rvalue_from_python_stage1_data* data)
- {
- int intVersion = (int)SIPLong_AsLong(objPtr);
- T tVersion = (T)intVersion;
- void* storage =
- ((bpy::converter::rvalue_from_python_storage>*)data)
- ->storage.bytes;
- new (storage) QFlags(tVersion);
-
- data->convertible = storage;
- }
- };
-
- } // namespace QFlags_converter
-
- namespace QVariant_converter {
-
- struct QVariant_to_python_obj {
- static PyObject* convert(const QVariant& var)
- {
- switch (var.type()) {
- case QVariant::Invalid:
- return bpy::incref(Py_None);
- case QVariant::Int:
- return SIPLong_FromLong(var.toInt());
- case QVariant::UInt:
- return PyLong_FromUnsignedLong(var.toUInt());
- case QVariant::Bool:
- return PyBool_FromLong(var.toBool());
- case QVariant::String:
- return bpy::incref(bpy::object(var.toString()).ptr());
- // We need to check for StringList here because these are not considered
- // List since List is QList will StringList is QList:
- case QVariant::StringList:
- return bpy::incref(bpy::object(var.toStringList()).ptr());
- case QVariant::List: {
- return bpy::incref(bpy::object(var.toList()).ptr());
- } break;
- case QVariant::Map: {
- return bpy::incref(bpy::object(var.toMap()).ptr());
- } break;
- default: {
- PyErr_Format(PyExc_TypeError, "type unsupported: %d", var.type());
- throw bpy::error_already_set();
- } break;
- }
- }
- };
-
- struct QVariant_from_python_obj {
-
- static void* convertible(PyObject* objPtr)
- {
- if (!SIPBytes_Check(objPtr) && !PyUnicode_Check(objPtr) &&
- !PyLong_Check(objPtr) && !PyBool_Check(objPtr) &&
- !PyList_Check(objPtr) && !PyDict_Check(objPtr) &&
- objPtr != Py_None) {
- return nullptr;
- }
- return objPtr;
- }
-
- template
- static void
- constructVariant(const T& value,
- bpy::converter::rvalue_from_python_stage1_data* data)
- {
- void* storage =
- ((bpy::converter::rvalue_from_python_storage*)data)
- ->storage.bytes;
-
- new (storage) QVariant(value);
-
- data->convertible = storage;
- }
-
- static void
- constructVariant(bpy::converter::rvalue_from_python_stage1_data* data)
- {
- void* storage =
- ((bpy::converter::rvalue_from_python_storage*)data)
- ->storage.bytes;
-
- new (storage) QVariant();
-
- data->convertible = storage;
- }
-
- static void construct(PyObject* objPtr,
- bpy::converter::rvalue_from_python_stage1_data* data)
- {
- if (PyList_Check(objPtr)) {
- // We could check if all the elements can be converted to QString
- // and store a QStringList in the QVariant but I am not sure that is
- // really useful.
- constructVariant(bpy::extract(objPtr)(), data);
- }
- else if (objPtr == Py_None) {
- constructVariant(data);
- }
- else if (PyDict_Check(objPtr)) {
- constructVariant(bpy::extract(objPtr)(), data);
- }
- else if (SIPBytes_Check(objPtr) || PyUnicode_Check(objPtr)) {
- constructVariant(bpy::extract(objPtr)(), data);
- }
- // PyBools will also return true for SIPLong_Check but not the other way
- // around, so the order here is relevant.
- else if (PyBool_Check(objPtr)) {
- constructVariant(bpy::extract(objPtr)(), data);
- }
- else if (SIPLong_Check(objPtr)) {
- // QVariant doesn't have long. It has int or long long. Given that
- // on m/s, long is 32 bits for 32- and 64- bit code...
- constructVariant(bpy::extract(objPtr)(), data);
- }
- else {
- PyErr_SetString(PyExc_TypeError, "type unsupported");
- throw bpy::error_already_set();
- }
- }
- };
-
- } // namespace QVariant_converter
-
- namespace QClass_converter {
-
- template
- struct MetaData;
-
- template <>
- struct MetaData {
- static const char* className() { return "QObject"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QWidget"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QMainWindow"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QDateTime"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QDir"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QFileInfo"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QIcon"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QSize"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QUrl"; }
- };
- template <>
- struct MetaData {
- static const char* className() { return "QVariant"; }
- };
-
- template
- struct QClass_converters {
- struct QClass_to_PyQt {
- template
- static typename std::enable_if_t, T*>
- getSafeCopy(T* qClass)
- {
- return new T(*qClass);
- }
-
- template
- static typename std::enable_if_t, T*>
- getSafeCopy(T* qClass)
- {
- return qClass;
- }
-
- static PyObject* convert(const T& object)
- {
- const sipTypeDef* type =
- sipAPIAccess::sipAPI()->api_find_type(MetaData::className());
- if (type == nullptr) {
- return bpy::incref(Py_None);
- }
-
- PyObject* sipObj = sipAPIAccess::sipAPI()->api_convert_from_type(
- (void*)getSafeCopy((T*)&object), type, 0);
- if (sipObj == nullptr) {
- return bpy::incref(Py_None);
- }
-
- if (std::is_copy_constructible_v)
- // Ensure Python deletes the C++ component
- sipAPIAccess::sipAPI()->api_transfer_back(sipObj);
-
- return bpy::incref(sipObj);
- }
-
- static PyObject* convert(T* object)
- {
- if (object == nullptr) {
- return bpy::incref(Py_None);
- }
-
- const sipTypeDef* type =
- sipAPIAccess::sipAPI()->api_find_type(MetaData::className());
- if (type == nullptr) {
- return bpy::incref(Py_None);
- }
-
- PyObject* sipObj = sipAPIAccess::sipAPI()->api_convert_from_type(
- getSafeCopy(object), type, 0);
- if (sipObj == nullptr) {
- return bpy::incref(Py_None);
- }
-
- if (std::is_copy_constructible_v)
- // Ensure Python deletes the C++ component
- sipAPIAccess::sipAPI()->api_transfer_back(sipObj);
-
- return bpy::incref(sipObj);
- }
-
- static PyObject* convert(const T* object)
- {
- return convert((T*)object);
- }
-
- static PyTypeObject const* get_pytype()
- {
- const sipTypeDef* type =
- sipAPIAccess::sipAPI()->api_find_type(MetaData::className());
- if (type == nullptr) {
- return bpy::incref(Py_None);
- }
- return bpy::incref(type->td_py_type);
- }
- };
-
- static void* QClass_from_PyQt(PyObject* objPtr)
- {
- // This would transfer responsibility for deconstructing the object to
- // C++, but Boost assumes l-value converters (such as this) don't do
- // that Instead, this should be called within the wrappers for functions
- // which return deletable pointers.
- // sipAPI()->api_transfer_to(objPtr, Py_None);
- if (PyObject_TypeCheck(
- objPtr, sipAPIAccess::sipAPI()->api_simplewrapper_type)) {
- sipSimpleWrapper* wrapper;
- wrapper = reinterpret_cast(objPtr);
- return wrapper->data;
- }
- else if (PyObject_TypeCheck(objPtr,
- sipAPIAccess::sipAPI()->api_wrapper_type)) {
- sipWrapper* wrapper;
- wrapper = reinterpret_cast(objPtr);
- return wrapper->super.data;
- }
- return nullptr;
- }
- };
-
- } // namespace QClass_converter
-
- namespace details {
-
- inline bool has_arity(PyObject* object, std::size_t arity)
- {
- // Mostly from https://stackoverflow.com/a/36143796/2666289
- bpy::object fn(bpy::handle<>(bpy::borrowed(object)));
-
- auto inspect = bpy::import("inspect");
- auto arg_spec = inspect.attr("getfullargspec")(fn);
- bpy::object args = arg_spec.attr("args"),
- varargs = arg_spec.attr("varargs"),
- defaults = arg_spec.attr("defaults");
-
- auto args_count = args ? bpy::len(args) : 0;
- auto defaults_count = defaults ? bpy::len(defaults) : 0;
-
- if (static_cast(inspect.attr("ismethod")(fn)) &&
- fn.attr("__self__")) {
- --args_count;
- }
-
- auto required_count = args_count - defaults_count;
-
- return required_count <=
- arity // Cannot require more parameters than given,
- &&
- (args_count >= arity || varargs); // Must accept enough parameters.
- }
-
- template
- struct wrap_impl;
-
- template <>
- struct wrap_impl<> {
- template
- static decltype(auto) apply(T&& t)
- {
- return std::forward(t);
- }
- };
-
- template
- struct wrap_impl, Ws...> : public wrap_impl<> {
- using wrap_impl<>::apply;
-
- static auto apply(T t) { return boost::ref(t); }
- };
-
- template
- struct wrap_impl, Ws...>
- : public wrap_impl<> {
- using wrap_impl<>::apply;
-
- static auto apply(T t) { return bpy::ptr(t); }
- };
-
- template
- struct wrap_impl {
- template
- static decltype(auto) apply(T&& t)
- {
- return wrap::apply(std::forward(t));
- }
- };
-
- } // namespace details
-
- /**
- * @brief Convert a python callable to a valid C++ Callable object. Also works
- * for None.
- */
- template
- struct Functor_converter;
-
- template
- struct Functor_converter {
-
- template
- static decltype(auto) wrap(T&& t)
- {
- return details::wrap_impl::apply(std::forward(t));
- }
-
- struct FunctorWrapper {
- FunctorWrapper(boost::python::object callable) : m_Callable(callable) {}
-
- ~FunctorWrapper()
- {
- GILock lock;
- m_Callable = bpy::object();
- }
-
- R operator()(Args... params)
- {
- GILock lock;
- try {
- if constexpr (std::is_same_v) {
- m_Callable(wrap(params)...);
- }
- else {
- return bpy::extract(m_Callable(wrap(params)...));
- }
- }
- catch (const boost::python::error_already_set&) {
- throw pyexcept::PythonError("");
- }
- catch (...) {
- throw pyexcept::UnknownException();
- }
- }
-
- boost::python::object m_Callable;
- };
-
- static void* convertible(PyObject* object)
- {
- // We allow None here, we will just default-construct a std::function:
- if (object == Py_None) {
- return object;
- }
-
- // Otherwize we check that we have a callable object:
- if (!PyCallable_Check(object) ||
- !details::has_arity(object, sizeof...(Args))) {
- return nullptr;
- }
- return object;
- }
-
- static void construct(PyObject* object,
- bpy::converter::rvalue_from_python_stage1_data* data)
- {
- bpy::object callable(bpy::handle<>(bpy::borrowed(object)));
- void* storage = ((bpy::converter::rvalue_from_python_storage<
- std::function>*)data)
- ->storage.bytes;
- if (callable.is_none()) {
- new (storage) std::function{};
- }
- else {
- new (storage) std::function(FunctorWrapper(callable));
- }
- data->convertible = storage;
- }
- };
-
- /**
- * @brief Call policy that automatically downcast shared pointer of type FromType
- * to shared pointer of type ToType.
- */
- template
- struct DowncastConverter {
-
- bool convertible() const { return true; }
-
- inline PyObject* operator()(std::shared_ptr p) const
- {
- if (p == nullptr) {
- return bpy::detail::none();
- }
- else {
- auto downcast_p = std::dynamic_pointer_cast(p);
- bpy::object p_value =
- downcast_p == nullptr ? bpy::object{p} : bpy::object{downcast_p};
- return bpy::incref(p_value.ptr());
- }
- }
-
- inline PyTypeObject const* get_pytype() const
- {
- return bpy::converter::registered_pytype::get_pytype();
- }
- };
-
- template
- struct downcast_return {
-
- template
- struct apply_;
-
- template
- struct apply_> {
- static_assert(
- std::is_convertible_v, std::shared_ptr>);
- using type = DowncastConverter;
- };
-
- template
- using apply = apply_>;
- };
-
- // Functions:
- inline void register_qstring_converter()
- {
- using namespace QString_converter;
- bpy::to_python_converter();
- bpy::converter::registry::push_back(&QString_from_python_str::convertible,
- &QString_from_python_str::construct,
- bpy::type_id());
- }
-
- inline void register_qvariant_converter()
- {
- using namespace QVariant_converter;
- bpy::to_python_converter();
- bpy::converter::registry::push_back(&QVariant_from_python_obj::convertible,
- &QVariant_from_python_obj::construct,
- bpy::type_id());
- }
-
- template
- inline void register_qflags_converter()
- {
- using T = typename Flags::enum_type;
- using namespace QFlags_converter;
- bpy::to_python_converter>();
- bpy::converter::registry::push_back(&QFlags_from_python_obj::convertible,
- &QFlags_from_python_obj::construct,
- bpy::type_id());
- }
-
- template
- inline void register_enum_converter()
- {
- using namespace Enum_converter;
- bpy::to_python_converter>();
- bpy::converter::registry::push_back(&Enum_from_python_obj::convertible,
- &Enum_from_python_obj::construct,
- bpy::type_id());
- }
-
- template
- inline void register_qclass_converter()
- {
- using Converter = QClass_converter::QClass_converters;
- bpy::converter::registry::insert(&Converter::QClass_from_PyQt,
- bpy::type_id());
- bpy::to_python_converter();
- bpy::to_python_converter();
- bpy::to_python_converter();
- }
-
- /**
- * @brief Register a functor converter.
- *
- * @tparam Fn The function type to register.
- * @tparam Wrappers... A list of wrapper (boost::python::pointer_wrapper or
- * boost::reference_wrapper) indicating if parameters of the given (wrapped) type
- * must be wrapped.
- */
- template
- inline void register_functor_converter()
- {
- using Converter = Functor_converter;
- bpy::converter::registry::push_back(&Converter::convertible,
- &Converter::construct,
- bpy::type_id>());
- }
-
-} // namespace utils
-
-#endif
diff --git a/src/runner-pybind11/gamefeatureswrappers.cpp b/src/runner-pybind11/gamefeatureswrappers.cpp
deleted file mode 100644
index 93e2b9e..0000000
--- a/src/runner-pybind11/gamefeatureswrappers.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-#include "gamefeatureswrappers.h"
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include "pythonwrapperutilities.h"
-#include "shared_ptr_converter.h"
-
-/////////////////////////////
-/// BSAInvalidation Wrapper
-
-bool BSAInvalidationWrapper::isInvalidationBSA(const QString& bsaName)
-{
- return basicWrapperFunctionImplementation(this, "isInvalidationBSA", bsaName);
-}
-
-void BSAInvalidationWrapper::deactivate(MOBase::IProfile* profile)
-{
- return basicWrapperFunctionImplementation(this, "deactivate",
- boost::python::ptr(profile));
-}
-
-void BSAInvalidationWrapper::activate(MOBase::IProfile* profile)
-{
- return basicWrapperFunctionImplementation(this, "activate",
- boost::python::ptr(profile));
-}
-
-bool BSAInvalidationWrapper::prepareProfile(MOBase::IProfile* profile)
-{
- return basicWrapperFunctionImplementation(this, "prepareProfile",
- boost::python::ptr(profile));
-}
-/// end BSAInvalidation Wrapper
-/////////////////////////////
-/// DataArchives Wrapper
-
-QStringList DataArchivesWrapper::vanillaArchives() const
-{
- return basicWrapperFunctionImplementation(this, "vanillaArchives");
-}
-
-QStringList DataArchivesWrapper::archives(const MOBase::IProfile* profile) const
-{
- return basicWrapperFunctionImplementation(this, "archives",
- boost::python::ptr(profile));
-}
-
-void DataArchivesWrapper::addArchive(MOBase::IProfile* profile, int index,
- const QString& archiveName)
-{
- return basicWrapperFunctionImplementation(
- this, "addArchive", boost::python::ptr(profile), index, archiveName);
-}
-
-void DataArchivesWrapper::removeArchive(MOBase::IProfile* profile,
- const QString& archiveName)
-{
- return basicWrapperFunctionImplementation(
- this, "removeArchive", boost::python::ptr(profile), archiveName);
-}
-/// end DataArchives Wrapper
-/////////////////////////////
-/// GamePlugins Wrapper
-
-void GamePluginsWrapper::writePluginLists(const MOBase::IPluginList* pluginList)
-{
- return basicWrapperFunctionImplementation(this, "writePluginLists",
- boost::python::ptr(pluginList));
-}
-
-void GamePluginsWrapper::readPluginLists(MOBase::IPluginList* pluginList)
-{
- return basicWrapperFunctionImplementation(this, "readPluginLists",
- boost::python::ptr(pluginList));
-}
-
-QStringList GamePluginsWrapper::getLoadOrder()
-{
- return basicWrapperFunctionImplementation(this, "getLoadOrder");
-}
-
-bool GamePluginsWrapper::lightPluginsAreSupported()
-{
- return basicWrapperFunctionImplementation(this, "lightPluginsAreSupported");
-}
-
-/// end GamePlugins Wrapper
-/////////////////////////////
-/// LocalSavegames Wrapper
-
-MappingType LocalSavegamesWrapper::mappings(const QDir& profileSaveDir) const
-{
- return basicWrapperFunctionImplementation(this, "mappings",
- profileSaveDir);
-}
-
-bool LocalSavegamesWrapper::prepareProfile(MOBase::IProfile* profile)
-{
- return basicWrapperFunctionImplementation(this, "prepareProfile",
- boost::python::ptr(profile));
-}
-
-/// end LocalSavegames Wrapper
-/////////////////////////////
-/// ModDataChecker Wrapper
-
-ModDataChecker::CheckReturn ModDataCheckerWrapper::dataLooksValid(
- std::shared_ptr fileTree) const
-{
- return basicWrapperFunctionImplementation(this, "dataLooksValid",
- fileTree);
-}
-
-std::shared_ptr
-ModDataCheckerWrapper::fix(std::shared_ptr fileTree) const
-{
- return utils::clean_shared_ptr(basicWrapperFunctionImplementationWithDefault<
- std::shared_ptr>(
- this,
- [](auto&&... args) {
- return nullptr;
- },
- "fix", fileTree));
-}
-
-/// end ModDataChecker Wrapper
-/////////////////////////////
-/// ModDataContent Wrapper
-
-std::vector ModDataContentWrapper::getAllContents() const
-{
- return basicWrapperFunctionImplementation>(this,
- "getAllContents");
-}
-std::vector ModDataContentWrapper::getContentsFor(
- std::shared_ptr fileTree) const
-{
- return basicWrapperFunctionImplementation>(this, "getContentsFor",
- fileTree);
-}
-
-/// end ModDataContent Wrapper
-/////////////////////////////
-/// SaveGameInfo Wrapper
-
-SaveGameInfoWrapper::MissingAssets
-SaveGameInfoWrapper::getMissingAssets(MOBase::ISaveGame const& save) const
-{
- return basicWrapperFunctionImplementation(
- this, "getMissingAssets", boost::ref(save));
-}
-
-MOBase::ISaveGameInfoWidget*
-SaveGameInfoWrapper::getSaveGameWidget(QWidget* parent) const
-{
- return basicWrapperFunctionImplementation(
- this, m_SaveGameWidget, "getSaveGameWidget", parent);
-}
-
-/// end SaveGameInfo Wrapper
-/////////////////////////////
-/// ScriptExtender Wrapper
-
-QString ScriptExtenderWrapper::BinaryName() const
-{
- return basicWrapperFunctionImplementation(this, "BinaryName");
-}
-
-QString ScriptExtenderWrapper::PluginPath() const
-{
- return basicWrapperFunctionImplementation(this, "PluginPath");
-}
-
-QString ScriptExtenderWrapper::loaderName() const
-{
- return basicWrapperFunctionImplementation(this, "loaderName");
-}
-
-QString ScriptExtenderWrapper::loaderPath() const
-{
- return basicWrapperFunctionImplementation(this, "loaderPath");
-}
-
-QString ScriptExtenderWrapper::savegameExtension() const
-{
- return basicWrapperFunctionImplementation(this, "savegameExtension");
-}
-
-bool ScriptExtenderWrapper::isInstalled() const
-{
- return basicWrapperFunctionImplementation(this, "isInstalled");
-}
-
-QString ScriptExtenderWrapper::getExtenderVersion() const
-{
- return basicWrapperFunctionImplementation(this, "getExtenderVersion");
-}
-
-WORD ScriptExtenderWrapper::getArch() const
-{
- return basicWrapperFunctionImplementation(this, "getArch");
-}
-
-/// end ScriptExtender Wrapper
-/////////////////////////////
-/// UnmanagedMods Wrapper
-
-QStringList UnmanagedModsWrapper::mods(bool onlyOfficial) const
-{
- return basicWrapperFunctionImplementation(this, "mods", onlyOfficial);
-}
-
-QString UnmanagedModsWrapper::displayName(const QString& modName) const
-{
- return basicWrapperFunctionImplementation(this, "displayName", modName);
-}
-
-QFileInfo UnmanagedModsWrapper::referenceFile(const QString& modName) const
-{
- return basicWrapperFunctionImplementation(this, "referenceFile",
- modName);
-}
-
-QStringList UnmanagedModsWrapper::secondaryFiles(const QString& modName) const
-{
- return basicWrapperFunctionImplementation(this, "secondaryFiles",
- modName);
-}
-/// end UnmanagedMods Wrapper
-/////////////////////////////
-
-game_features_map_from_python::game_features_map_from_python()
-{
- boost::python::converter::registry::push_back(
- &convertible, &construct,
- boost::python::type_id>());
-}
-
-void* game_features_map_from_python::convertible(PyObject* objPtr)
-{
- return PyDict_Check(objPtr) ? objPtr : nullptr;
-}
-
-template
-void insertGameFeature(std::map& map,
- const boost::python::object& pyObject)
-{
- map[std::type_index(typeid(T))] = boost::python::extract(pyObject)();
-}
-
-void game_features_map_from_python::construct(
- PyObject* objPtr, boost::python::converter::rvalue_from_python_stage1_data* data)
-{
- void* storage = ((boost::python::converter::rvalue_from_python_storage<
- std::map>*)data)
- ->storage.bytes;
- std::map* result =
- new (storage) std::map();
- boost::python::dict source(
- boost::python::handle<>(boost::python::borrowed(objPtr)));
- boost::python::list keys = source.keys();
- int len = boost::python::len(keys);
- for (int i = 0; i < len; ++i) {
- boost::python::object pyKey = keys[i];
- boost::python::object pyValue = source[pyKey];
-
- boost::mp11::mp_for_each<
- // Must user pointers because mp_for_each construct object:
- boost::mp11::mp_transform>(
- [&](auto* pt) {
- using T = std::remove_pointer_t;
- boost::python::extract extract(pyValue);
- if (extract.check()) {
- (*result)[std::type_index(typeid(T))] = extract();
- }
- });
- }
-
- data->convertible = storage;
-}
-
-void registerGameFeaturesPythonConverters()
-{
- namespace bpy = boost::python;
-
- game_features_map_from_python();
-
- // Features require defs for all methods as Python can access C++ features
- bpy::class_("BSAInvalidation")
- .def("isInvalidationBSA",
- bpy::pure_virtual(&BSAInvalidation::isInvalidationBSA), bpy::arg("name"))
- .def("deactivate", bpy::pure_virtual(&BSAInvalidation::deactivate),
- bpy::arg("profile"))
- .def("activate", bpy::pure_virtual(&BSAInvalidation::activate),
- bpy::arg("profile"));
-
- bpy::class_("DataArchives")
- .def("vanillaArchives", bpy::pure_virtual(&DataArchives::vanillaArchives))
- .def("archives", bpy::pure_virtual(&DataArchives::archives),
- bpy::arg("profile"))
- .def("addArchive", bpy::pure_virtual(&DataArchives::addArchive),
- (bpy::arg("profile"), "index", "name"))
- .def("removeArchive", bpy::pure_virtual(&DataArchives::removeArchive),
- (bpy::arg("profile"), "name"));
-
- bpy::class_("GamePlugins")
- .def("writePluginLists", bpy::pure_virtual(&GamePlugins::writePluginLists),
- bpy::arg("plugin_list"))
- .def("readPluginLists", bpy::pure_virtual(&GamePlugins::readPluginLists),
- bpy::arg("plugin_list"))
- .def("getLoadOrder", bpy::pure_virtual(&GamePlugins::getLoadOrder))
- .def("lightPluginsAreSupported",
- bpy::pure_virtual(&GamePlugins::lightPluginsAreSupported));
-
- bpy::class_("LocalSavegames")
- .def("mappings", bpy::pure_virtual(&LocalSavegames::mappings),
- bpy::arg("profile_save_dir"))
- .def("prepareProfile", bpy::pure_virtual(&LocalSavegames::prepareProfile),
- bpy::arg("profile"));
-
- auto modDataCheckerClass =
- bpy::class_("ModDataChecker");
- {
- bpy::scope scope = modDataCheckerClass;
-
- bpy::enum_("CheckReturn")
- .value("INVALID", ModDataChecker::CheckReturn::INVALID)
- .value("FIXABLE", ModDataChecker::CheckReturn::FIXABLE)
- .value("VALID", ModDataChecker::CheckReturn::VALID)
- .export_values();
-
- modDataCheckerClass
- .def("dataLooksValid", bpy::pure_virtual(&ModDataChecker::dataLooksValid),
- bpy::arg("filetree"))
- .def("fix", bpy::pure_virtual(&ModDataChecker::fix), bpy::arg("filetree"));
- }
-
- {
- bpy::scope scope =
- bpy::class_("ModDataContent")
- .def("getAllContents",
- bpy::pure_virtual(&ModDataContent::getAllContents))
- .def("getContentsFor",
- bpy::pure_virtual(&ModDataContent::getContentsFor),
- bpy::arg("filetree"));
-
- bpy::class_(
- "Content",
- bpy::init>(
- (bpy::arg("id"), "name", "icon", bpy::arg("filter_only") = false)))
- .add_property("id", &ModDataContent::Content::id)
- .add_property("name", &ModDataContent::Content::name)
- .add_property("icon", &ModDataContent::Content::icon)
- .def("isOnlyForFilter", &ModDataContent::Content::isOnlyForFilter);
- }
-
- bpy::class_("SaveGameInfo")
- .def("getMissingAssets", bpy::pure_virtual(&SaveGameInfo::getMissingAssets),
- bpy::arg("save"))
- .def("getSaveGameWidget", bpy::pure_virtual(&SaveGameInfo::getSaveGameWidget),
- bpy::return_value_policy(), bpy::arg("parent"),
- "[optional]");
-
- bpy::class_("ScriptExtender")
- .def("BinaryName", bpy::pure_virtual(&ScriptExtender::BinaryName))
- .def("PluginPath", bpy::pure_virtual(&ScriptExtender::PluginPath))
- .def("loaderName", bpy::pure_virtual(&ScriptExtender::loaderName))
- .def("loaderPath", bpy::pure_virtual(&ScriptExtender::loaderPath))
- .def("savegameExtension", bpy::pure_virtual(&ScriptExtender::savegameExtension))
- .def("isInstalled", bpy::pure_virtual(&ScriptExtender::isInstalled))
- .def("getExtenderVersion",
- bpy::pure_virtual(&ScriptExtender::getExtenderVersion))
- .def("getArch", bpy::pure_virtual(&ScriptExtender::getArch));
-
- bpy::class_("UnmanagedMods")
- .def("mods", bpy::pure_virtual(&UnmanagedMods::mods), bpy::arg("official_only"))
- .def("displayName", bpy::pure_virtual(&UnmanagedMods::displayName),
- bpy::arg("mod_name"))
- .def("referenceFile", bpy::pure_virtual(&UnmanagedMods::referenceFile),
- bpy::arg("mod_name"))
- .def("secondaryFiles", bpy::pure_virtual(&UnmanagedMods::secondaryFiles),
- bpy::arg("mod_name"));
-}
diff --git a/src/runner-pybind11/gamefeatureswrappers.h b/src/runner-pybind11/gamefeatureswrappers.h
deleted file mode 100644
index 3cd94e5..0000000
--- a/src/runner-pybind11/gamefeatureswrappers.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef GAMEFEATURESWRAPPERS_H
-#define GAMEFEATURESWRAPPERS_H
-
-#include