Merge branch 'test' into master

This commit is contained in:
Jeremy Rimpo
2020-09-21 13:26:04 -05:00
5 changed files with 53 additions and 5 deletions
+1
View File
@@ -7,5 +7,6 @@ GILock::GILock()
GILock::~GILock()
{
PyErr_Clear();
PyGILState_Release(m_State);
}
+13 -1
View File
@@ -38,6 +38,16 @@ QString class_name::name() const \
return basicWrapperFunctionImplementation<QString>(this, "name"); \
} \
\
QString class_name::localizedName() const \
{ \
return basicWrapperFunctionImplementationWithDefault<QString>(this, &class_name::localizedName_Default, "localizedName"); \
} \
\
IPlugin* class_name::master() const \
{ \
return basicWrapperFunctionImplementationWithDefault<IPlugin*>(this, &class_name::master_Default, "master"); \
} \
\
QString class_name::author() const \
{ \
return basicWrapperFunctionImplementation<QString>(this, "author"); \
@@ -61,7 +71,9 @@ bool class_name::isActive() const \
QList<MOBase::PluginSetting> class_name::settings() const \
{ \
return basicWrapperFunctionImplementation<QList<MOBase::PluginSetting>>(this, "settings"); \
}
} \
QString class_name::localizedName_Default() const { return IPlugin::localizedName(); } \
IPlugin* class_name::master_Default() const { return IPlugin::master(); }
/// end COMMON_I_PLUGIN_WRAPPER_DEFINITIONS
/////////////////////////////
+5 -2
View File
@@ -19,12 +19,15 @@
#define COMMON_I_PLUGIN_WRAPPER_DECLARATIONS public: \
virtual bool init(MOBase::IOrganizer *moInfo) override; \
virtual QString name() const override; \
virtual QString localizedName() const override; \
virtual IPlugin* master() const override; \
virtual QString author() const override; \
virtual QString description() const override; \
virtual MOBase::VersionInfo version() const override; \
virtual bool isActive() const override; \
virtual QList<MOBase::PluginSetting> settings() const override;
virtual QList<MOBase::PluginSetting> settings() const override; \
QString localizedName_Default() const; \
IPlugin* master_Default() const;
// Even though the base interface is not a 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
+28
View File
@@ -677,9 +677,14 @@ BOOST_PYTHON_MODULE(mobase)
.def("onModMoved", &MOBase::IModList::onModMoved, bpy::arg("callback"))
;
// Note: localizedName() and master() have to go in all the plugin wrappers declaration,
// since the default functions are specific to each wrapper, otherwise in turns into an
// infinite recursion mess.
bpy::class_<IPluginWrapper, boost::noncopyable>("IPlugin")
.def("init", bpy::pure_virtual(&MOBase::IPlugin::init), bpy::arg("organizer"))
.def("name", bpy::pure_virtual(&MOBase::IPlugin::name))
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("author", bpy::pure_virtual(&MOBase::IPlugin::author))
.def("description", bpy::pure_virtual(&MOBase::IPlugin::description))
.def("version", bpy::pure_virtual(&MOBase::IPlugin::version))
@@ -688,6 +693,9 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginDiagnoseWrapper, bpy::bases<IPlugin>, boost::noncopyable>("IPluginDiagnose")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginDiagnoseWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginDiagnoseWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("activeProblems", bpy::pure_virtual(&MOBase::IPluginDiagnose::activeProblems))
.def("shortDescription", bpy::pure_virtual(&MOBase::IPluginDiagnose::shortDescription), bpy::arg("key"))
.def("fullDescription", bpy::pure_virtual(&MOBase::IPluginDiagnose::fullDescription), bpy::arg("key"))
@@ -704,6 +712,8 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginFileMapperWrapper, bpy::bases<IPlugin>, boost::noncopyable>("IPluginFileMapper")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginFileMapperWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginFileMapperWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("mappings", bpy::pure_virtual(&MOBase::IPluginFileMapper::mappings))
;
@@ -736,6 +746,9 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginGameWrapper, bpy::bases<IPlugin>, boost::noncopyable>("IPluginGame")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginGameWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginGameWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("gameName", bpy::pure_virtual(&MOBase::IPluginGame::gameName))
.def("initializeProfile", bpy::pure_virtual(&MOBase::IPluginGame::initializeProfile), (bpy::arg("directory"), "settings"))
.def("savegameExtension", bpy::pure_virtual(&MOBase::IPluginGame::savegameExtension))
@@ -826,6 +839,9 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginInstallerSimpleWrapper, bpy::bases<IPluginInstaller>, boost::noncopyable>("IPluginInstallerSimple")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginInstallerSimpleWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginInstallerSimpleWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
// Note: Keeping the variant here even if we always return a tuple to be consistent with the wrapper and
// have proper stubs generation.
.def("install", +[](IPluginInstallerSimple* p, GuessedValue<QString>& modName, std::shared_ptr<IFileTree>& tree, QString& version, int& nexusID)
@@ -838,6 +854,9 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginInstallerCustomWrapper, bpy::bases<IPluginInstaller>, boost::noncopyable>("IPluginInstallerCustom")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginInstallerCustomWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginInstallerCustomWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
// Needs to add both otherwize boost does not understand:
.def("isArchiveSupported", &IPluginInstaller::isArchiveSupported, bpy::arg("tree"))
.def("isArchiveSupported", &IPluginInstallerCustom::isArchiveSupported, bpy::arg("archive_name"))
@@ -848,6 +867,9 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginModPageWrapper, bpy::bases<IPlugin>, boost::noncopyable>("IPluginModPage")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginModPageWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginModPageWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("displayName", bpy::pure_virtual(&IPluginModPage::displayName))
.def("icon", bpy::pure_virtual(&IPluginModPage::icon))
.def("pageURL", bpy::pure_virtual(&IPluginModPage::pageURL))
@@ -858,12 +880,18 @@ BOOST_PYTHON_MODULE(mobase)
;
bpy::class_<IPluginPreviewWrapper, bpy::bases<IPlugin>, boost::noncopyable>("IPluginPreview")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginPreviewWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginPreviewWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("supportedExtensions", bpy::pure_virtual(&IPluginPreview::supportedExtensions))
.def("genFilePreview", bpy::pure_virtual(&IPluginPreview::genFilePreview), bpy::return_value_policy<bpy::return_by_value>(),
(bpy::arg("filename"), "max_size"))
;
bpy::class_<IPluginToolWrapper, bpy::bases<IPlugin>, boost::noncopyable>("IPluginTool")
.def("localizedName", &MOBase::IPlugin::localizedName, &IPluginToolWrapper::localizedName_Default)
.def("master", &MOBase::IPlugin::master, &IPluginToolWrapper::master_Default, bpy::return_value_policy<bpy::reference_existing_object>())
.def("displayName", bpy::pure_virtual(&IPluginTool::displayName))
.def("tooltip", bpy::pure_virtual(&IPluginTool::tooltip))
.def("icon", bpy::pure_virtual(&IPluginTool::icon))
+6 -2
View File
@@ -19,8 +19,10 @@ namespace details {
*/
template <class ReturnType, class WrapperTypePtr, class Fn, class... Args>
ReturnType wrapperFunctionImplementation(WrapperTypePtr wrapper, bool apiTransfer, Fn fn, boost::python::object* objPtr, const char *methodName, Args... args) {
GILock lock;
boost::python::override implementation = wrapper->get_override(methodName);
boost::python::override implementation = [&]() {
GILock lock;
return wrapper->get_override(methodName);
}();
if (!implementation) {
if constexpr (std::is_same_v<Fn, std::nullptr_t>) {
throw pyexcept::MissingImplementation(wrapper->className, methodName);
@@ -29,6 +31,8 @@ namespace details {
return std::invoke(fn, wrapper, args...);
}
}
GILock lock;
try {
boost::python::object result = implementation(args...);
if (objPtr) {