Implement wrapper and bindings for IPluginDiagnose

This commit is contained in:
AnyOldName3
2018-04-20 16:40:38 +01:00
parent c70f78adfe
commit 5a730941db
3 changed files with 115 additions and 1 deletions
+50
View File
@@ -83,6 +83,56 @@ QList<MOBase::PluginSetting> class_name::settings() const \
COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginWrapper)
/// end IPlugin Wrapper
/////////////////////////////////////
/// IPluginDiagnose Wrapper
COMMON_I_PLUGIN_WRAPPER_DEFINITIONS(IPluginDiagnoseWrapper)
std::vector<unsigned int> IPluginDiagnoseWrapper::activeProblems() const
{
try {
GILock lock;
return this->get_override("activeProblems")();
} PYCATCH;
}
QString IPluginDiagnoseWrapper::shortDescription(unsigned int key) const
{
try {
return this->get_override("shortDescription")(key);
} PYCATCH;
}
QString IPluginDiagnoseWrapper::fullDescription(unsigned int key) const
{
try {
return this->get_override("fullDescription")(key);
} PYCATCH;
}
bool IPluginDiagnoseWrapper::hasGuidedFix(unsigned int key) const
{
try {
return this->get_override("hasGuidedFix")(key);
} PYCATCH;
}
void IPluginDiagnoseWrapper::startGuidedFix(unsigned int key) const
{
try {
GILock lock;
this->get_override("startGuidedFix")(key);
} PYCATCH;
}
void IPluginDiagnoseWrapper::invalidate()
{
IPluginDiagnose::invalidate();
}
/// end IPluginDiagnose Wrapper
/////////////////////////////////////
/// IPluginGame Wrapper
+23 -1
View File
@@ -2,10 +2,11 @@
#define PROXYPLUGINWRAPPERS_H
#include <iplugintool.h>
#include <iplugindiagnose.h>
#include <iplugingame.h>
#include <iplugininstallersimple.h>
#include <iplugininstallercustom.h>
#include <iplugintool.h>
#ifndef Q_MOC_RUN
#include <boost/python.hpp>
@@ -30,6 +31,27 @@ class IPluginWrapper : public MOBase::IPlugin, public boost::python::wrapper<MOB
};
// Even though the base interface is not an IPlugin or QObject, this has to be because we have no way to pass Mod Organizer a plugin that implements multiple interfaces.
// QObject must be the first base class because moc assumes the first base class is a QObject
class IPluginDiagnoseWrapper : public QObject, public MOBase::IPluginDiagnose, public MOBase::IPlugin, public boost::python::wrapper<MOBase::IPluginDiagnose>
{
Q_OBJECT
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginDiagnose)
public:
virtual std::vector<unsigned int> 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;
// Other functions exist, but shouldn't need wrapping as a default implementation exists
// This was protected, but Python doesn't have that, so it needs making public
virtual void invalidate();
COMMON_I_PLUGIN_WRAPPER_DECLARATIONS
};
class IPluginGameWrapper : public MOBase::IPluginGame, public boost::python::wrapper<MOBase::IPluginGame> {
Q_OBJECT
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginGame)
+42
View File
@@ -339,6 +339,35 @@ struct QList_from_python_obj
};
template <typename T>
struct std_vector_from_python_obj
{
std_vector_from_python_obj() {
bpy::converter::registry::push_back(
&convertible,
&construct,
bpy::type_id<std::vector<T> >());
}
static void* convertible(PyObject *objPtr) {
if (PyList_Check(objPtr)) return objPtr;
return nullptr;
}
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
void *storage = ((bpy::converter::rvalue_from_python_storage<std::vector<T> >*)data)->storage.bytes;
std::vector<T> *result = new (storage) std::vector<T>();
bpy::list source(bpy::handle<>(bpy::borrowed(objPtr)));
int length = bpy::len(source);
for (int i = 0; i < length; ++i) {
result->push_back(bpy::extract<T>(source[i]));
}
data->convertible = storage;
}
};
template <typename T>
struct QFlags_from_python_obj
{
@@ -898,6 +927,15 @@ BOOST_PYTHON_MODULE(mobase)
bpy::class_<IPluginWrapper, boost::noncopyable>("IPlugin");
bpy::class_<IPluginDiagnoseWrapper, boost::noncopyable>("IPluginDiagnose")
.def("activeProblems", bpy::pure_virtual(&MOBase::IPluginDiagnose::activeProblems))
.def("shortDescription", bpy::pure_virtual(&MOBase::IPluginDiagnose::shortDescription))
.def("fullDescription", bpy::pure_virtual(&MOBase::IPluginDiagnose::fullDescription))
.def("hasGuidedFix", bpy::pure_virtual(&MOBase::IPluginDiagnose::hasGuidedFix))
.def("startGuidedFix", bpy::pure_virtual(&MOBase::IPluginDiagnose::startGuidedFix))
.def("_invalidate", &IPluginDiagnoseWrapper::invalidate)
;
bpy::enum_<MOBase::IPluginGame::LoadOrderMechanism>("LoadOrderMechanism")
.value("FileTime", MOBase::IPluginGame::LoadOrderMechanism::FileTime)
.value("PluginsTxt", MOBase::IPluginGame::LoadOrderMechanism::PluginsTxt)
@@ -992,6 +1030,8 @@ BOOST_PYTHON_MODULE(mobase)
bpy::to_python_converter<QList<QFileInfo>,
QList_to_python_list<QFileInfo>>();
std_vector_from_python_obj<unsigned int>();
stdset_from_python_list<QString>();
}
@@ -1107,6 +1147,8 @@ QObject *PythonRunner::instantiate(const QString &pluginName)
bpy::object pluginObj = m_PythonObjects[pluginName];
TRY_PLUGIN_TYPE(IPluginGame, pluginObj);
// Must try the wrapper because it's only a plugin extension interface in C++, so doesn't extend QObject
TRY_PLUGIN_TYPE(IPluginDiagnoseWrapper, pluginObj);
TRY_PLUGIN_TYPE(IPluginInstallerCustom, pluginObj);
TRY_PLUGIN_TYPE(IPluginTool, pluginObj);
} catch (const bpy::error_already_set&) {