diff --git a/doc/python/pages/changelog.rst b/doc/python/pages/changelog.rst index 13f4e78..3f44441 100644 --- a/doc/python/pages/changelog.rst +++ b/doc/python/pages/changelog.rst @@ -125,7 +125,8 @@ Changelog - Exposed the :ref:`text` library - Exposed the minimal interface of :ref:`utility.ConfigurationGroup` and :ref:`utility.Configuration` -- Exposed :ref:`pluginmanager.AbstractManager.set_preferred_plugins()` +- Exposed :ref:`pluginmanager.AbstractManager.set_preferred_plugins()` and + the base :ref:`pluginmanager.AbstractPlugin` class - Fixed issues with an in-source build (see :gh:`mosra/magnum-bindings#13`) - All CMake build options are now prefixed with ``MAGNUM_``. For backwards compatibility, unless ``MAGNUM_BUILD_DEPRECATED`` is disabled and unless a diff --git a/src/python/corrade/pluginmanager.cpp b/src/python/corrade/pluginmanager.cpp index bbf310e..4f9094b 100644 --- a/src/python/corrade/pluginmanager.cpp +++ b/src/python/corrade/pluginmanager.cpp @@ -23,12 +23,15 @@ DEALINGS IN THE SOFTWARE. */ +#include "pluginmanager.h" + #include #include /* for pluginList() and aliasList() */ #include #include /** @todo drop once we have our string casters */ #include #include +#include #include "Corrade/PythonBindings.h" @@ -124,6 +127,14 @@ void pluginmanager(py::module_& m) { return state; }, "Unload a plugin", py::arg("plugin")); + + py::class_>{m, "AbstractPlugin", "Base class for plugin interfaces"} + /* Plugin interface string, search paths, suffix, metadata file suffix + are meant to be overriden in subclasses */ + .def_property_readonly("plugin", [](PluginManager::AbstractPlugin& self) { + /** @todo drop std::string in favor of our own string caster */ + return std::string{self.plugin()}; + }, "Plugin identifier string"); } } diff --git a/src/python/corrade/pluginmanager.h b/src/python/corrade/pluginmanager.h index 22bf224..9694b29 100644 --- a/src/python/corrade/pluginmanager.h +++ b/src/python/corrade/pluginmanager.h @@ -68,7 +68,7 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, Corrade::PluginManager::PyPluginHolder) namespace corrade { -template void plugin(py::class_>& c) { +template void plugin(py::class_, PluginManager::AbstractPlugin>& c) { c .def_property_readonly("manager", [](const T& self) { return pyObjectHolderFor(self).manager; diff --git a/src/python/magnum/test/test_trade.py b/src/python/magnum/test/test_trade.py index da7a7e4..e03802d 100644 --- a/src/python/magnum/test/test_trade.py +++ b/src/python/magnum/test/test_trade.py @@ -988,7 +988,7 @@ class SceneData(unittest.TestCase): scene.mutable_field(string_field) class Importer(unittest.TestCase): - def test(self): + def test_manager(self): manager = trade.ImporterManager() self.assertIn('StbImageImporter', manager.alias_list) self.assertEqual(manager.load_state('StbImageImporter'), pluginmanager.LoadState.NOT_LOADED) @@ -1001,6 +1001,10 @@ class Importer(unittest.TestCase): with self.assertRaisesRegex(RuntimeError, "can't unload plugin"): manager.unload('NonexistentImporter') + def test(self): + importer = trade.ImporterManager().load_and_instantiate('StbImageImporter') + self.assertEqual(importer.plugin, 'StbImageImporter') + def test_set_preferred_plugins(self): manager = trade.ImporterManager() # TODO test this better once we can verify it gets actually loaded diff --git a/src/python/magnum/text.cpp b/src/python/magnum/text.cpp index 21ccebd..ecfc226 100644 --- a/src/python/magnum/text.cpp +++ b/src/python/magnum/text.cpp @@ -101,7 +101,7 @@ void text(py::module_& m) { ; /* Font */ - py::class_> abstractFont{m, "AbstractFont", "Interface for font plugins"}; + py::class_, PluginManager::AbstractPlugin> abstractFont{m, "AbstractFont", "Interface for font plugins"}; abstractFont /** @todo features */ .def_property_readonly("is_opened", &Text::AbstractFont::isOpened, "Whether any file is opened") diff --git a/src/python/magnum/trade.cpp b/src/python/magnum/trade.cpp index 0e18480..b1e883f 100644 --- a/src/python/magnum/trade.cpp +++ b/src/python/magnum/trade.cpp @@ -1445,7 +1445,7 @@ void trade(py::module_& m) { void*. Leaving the name as AbstractImporter (instead of Importer) to avoid needless name differences and because in the future there *might* be pure Python importers (not now tho). */ - py::class_> abstractImporter{m, "AbstractImporter", "Interface for importer plugins"}; + py::class_, PluginManager::AbstractPlugin> abstractImporter{m, "AbstractImporter", "Interface for importer plugins"}; corrade::plugin(abstractImporter); abstractImporter /** @todo features */ @@ -1545,7 +1545,7 @@ void trade(py::module_& m) { corrade::manager(importerManager); /* Image converter */ - py::class_> abstractImageConverter{m, "AbstractImageConverter", "Interface for image converter plugins"}; + py::class_, PluginManager::AbstractPlugin> abstractImageConverter{m, "AbstractImageConverter", "Interface for image converter plugins"}; abstractImageConverter /** @todo features */ .def("convert_to_file", checkImageConverterResult, "Convert a 1D image to a file", py::arg("image"), py::arg("filename")) @@ -1557,7 +1557,7 @@ void trade(py::module_& m) { corrade::manager(imageConverterManager); /* Scene converter */ - py::class_> abstractSceneConverter{m, "AbstractSceneConverter", "Interface for scene converter plugins"}; + py::class_, PluginManager::AbstractPlugin> abstractSceneConverter{m, "AbstractSceneConverter", "Interface for scene converter plugins"}; abstractSceneConverter /** @todo features */ .def("convert_to_file", checkSceneConverterResult, "Convert a mesh to a file", py::arg("mesh"), py::arg("filename"));