Browse Source

doc: freshen up plugin-related documentation.

pull/529/head
Vladimír Vondruš 5 years ago
parent
commit
a2b8fb73c2
  1. 16
      doc/file-formats.dox
  2. 104
      doc/plugins.dox
  3. 6
      doc/snippets/plugins.cpp

16
doc/file-formats.dox

@ -33,12 +33,16 @@ namespace Magnum {
The @ref Audio::AnyImporter "AnyAudioImporter", The @ref Audio::AnyImporter "AnyAudioImporter",
@relativeref{Trade,AnyImageImporter}, @relativeref{Trade,AnySceneImporter}, @relativeref{Trade,AnyImageImporter}, @relativeref{Trade,AnySceneImporter},
@relativeref{Trade,AnyImageConverter}, @relativeref{Trade,AnySceneConverter} @relativeref{Trade,AnyImageConverter}, @relativeref{Trade,AnySceneConverter}
and @ref ShaderTools::AnyConverter "AnyShaderConverter" plugins can be used for and @ref ShaderTools::AnyConverter "AnyShaderConverter" plugins
generic handling of any of the recognized formats, they'll proxy the operation @ref plugins-aliases "described on the previous page" can be used for generic
to a concrete plugin implementation. The following tables list the most widely handling of any of the formats they recognize and they'll proxy the operation
used formats with alternative plugin implementations and known caveats for to a concrete plugin implementation.
each. When one format is supported by more than one plugin, you can use
@ref Corrade::PluginManager::AbstractManager::setPreferredPlugins() to To support diverse use cases, there's commonly more than one alternative
implementation for given format. The following tables list the most widely used
formats with corresponding plugin implementations and known caveats for each.
When one format is supported by more than one plugin, you can use
@relativeref{Corrade,PluginManager::AbstractManager::setPreferredPlugins()} to
prioritize a particular plugin implementation. prioritize a particular plugin implementation.
See the @ref file-formats-legend section at the bottom of the page for a See the @ref file-formats-legend section at the bottom of the page for a

104
doc/plugins.dox

@ -59,8 +59,8 @@ Plugin functionality is exposed via an interface that's common for all plugins
of given type. Magnum provides these plugin interfaces: of given type. Magnum provides these plugin interfaces:
- @ref Trade::AbstractImporter --- importers for general 2D and 3D scene, - @ref Trade::AbstractImporter --- importers for general 2D and 3D scene,
mesh, material, texture and image data. See `*Importer` classes in the mesh, material, texture, image and animation data. See `*Importer` classes
@ref Trade namespace for available importer plugins. in the @ref Trade namespace for available importer plugins.
- @ref Trade::AbstractImageConverter --- conversion among various image - @ref Trade::AbstractImageConverter --- conversion among various image
formats. See `*ImageConverter` classes in the @ref Trade namespace for formats. See `*ImageConverter` classes in the @ref Trade namespace for
available image converter plugins. available image converter plugins.
@ -97,13 +97,14 @@ whole lifetime of all plugin instances created using it.
@section plugins-dependencies Plugin dependencies @section plugins-dependencies Plugin dependencies
Some plugins have dependencies, for example the @ref Trade::TinyGltfImporter "TinyGltfImporter" Some plugins have dependencies, for example the @relativeref{Trade,TinyGltfImporter}
plugin uses @ref Trade::AnyImageImporter "AnyImageImporter" to load texture plugin uses @relativeref{Trade,AnyImageImporter} to load texture data. The
data. The dependency loading is done automatically, but in some cases it's dependency loading is done automatically, but in some cases it's across
across plugin types (for example the @ref Text::MagnumFont "MagnumFont" plugin different plugin interfaces (for example the @relativeref{Text,MagnumFont}
depends on the @ref Trade::TgaImporter "TgaImporter" plugin, which is of a *font* plugin depends on the @relativeref{Trade,TgaImporter} *importer* plugin)
different type) --- there you need to create manager instances for all required --- there you need to create manager instances for all required plugin
plugin interfaces: interfaces and connect them together using
@relativeref{Corrade::PluginManager::Manager,registerExternalManager()}:
@snippet plugins.cpp dependencies @snippet plugins.cpp dependencies
@ -134,21 +135,28 @@ target_link_libraries(my-app PRIVATE
@endcode @endcode
The only user-visible behavioral change in the code will be that The only user-visible behavioral change in the code will be that
@ref Corrade::PluginManager::AbstractManager::load() "PluginManager::Manager::load()" @relativeref{Corrade,PluginManager::AbstractManager::load()} will return
will return @ref Corrade::PluginManager::LoadState::Static "PluginManager::LoadState::Static" @relativeref{Corrade,PluginManager::LoadState::Static} instead of
instead of @ref Corrade::PluginManager::LoadState::Loaded "PluginManager::LoadState::Loaded", @relativeref{Corrade::PluginManager,LoadState::Loaded}, but there is no need to
but there is no need to change the above code, as it will work for both dynamic change anything in the C++ code --- it will work for both dynamic and static
and static case. case.
The static plugin needs to be explicitly registered so the plugin manager is @m_class{m-block m-warning}
aware it's there. If you use CMake, it's done automatically. Otherwise, you can
achieve the same if you explicitly @cpp #include @ce the static plugin import @par Using static plugins with custom buildsystems
file (named `importStaticPlugin.cpp`, residing in plugin's include directory) The static plugin needs to be explicitly registered so the plugin manager
in a source file that gets compiled into your main application. The static is aware it's there. If you use CMake, it's done automatically through the
import file contains just a simple call to @ref CORRADE_PLUGIN_IMPORT(), see @cmake target_link_libraries() @ce call. Otherwise, besides linking the
its documentation for further information. plugin library itself, you have to explicitly @cpp #include @ce the static
plugin import file (named `importStaticPlugin.cpp`, residing in plugin's
@snippet plugins.cpp static-import include directory) in a source file that gets compiled into your main
executable:
@par
@snippet plugins.cpp static-import
@par
The static import file contains a call to @ref CORRADE_PLUGIN_IMPORT(),
executed in a global constructor, which will do the required registration
automatically during application startup.
@section plugins-aliases Plugin aliases and "any" plugins @section plugins-aliases Plugin aliases and "any" plugins
@ -180,15 +188,14 @@ plugin).
@snippet plugins.cpp aliases @snippet plugins.cpp aliases
To make your life even simpler, there are various "any format" plugins --- To make your life even simpler, there are various "any format" plugins ---
these detect format based on file extension, map it to a plugin alias and then these detect format based on file extension or its contents and then proxy the
proxy the rest of the work to a corresponding plugin: rest of the work to a concrete plugin suited for given format:
@snippet plugins.cpp anyimporter @snippet plugins.cpp anyimporter
Besides convenience for the end user, this allows for example the scene Besides convenience for the end user, this allows the scene importer plugins to
importer plugins to load any image formats without needing to have a knowledge load arbitrary image formats without having to explicitly deal with and depend
about them or having an explicit dependency on multitude of image importer on multitude of image importer plugins.
plugins.
So far, the following plugins have the "any format" ability: So far, the following plugins have the "any format" ability:
@ -204,27 +211,46 @@ So far, the following plugins have the "any format" ability:
any formats any formats
- @ref Audio::AnyImporter "AnyImporter" --- imports any audio format - @ref Audio::AnyImporter "AnyImporter" --- imports any audio format
@section plugins-configuration Plugin-specific configuration @section plugins-configuration Editing plugin-specific configuration
Because it's not possible for a general statically typed plugin API to expose Because it's not possible for a general statically typed plugin API to expose
all possible knobs and switches that a file format could support, the plugins all possible knobs and switches that a file format could support, the plugins
have a possibility to supply additional configuration via the have a possibility to supply additional configuration via the
@ref Corrade::PluginManager::AbstractPlugin::configuration() "configuration()" @ref Corrade::PluginManager::AbstractPlugin::configuration() "configuration()"
function. For example, in the @ref Trade-AssimpImporter-configuration "AssimpImporter" function. Plugins that offer such possibility then show how the default
plugin you can toggle various postprocessing steps that are applied to loaded configuration looks like and document the purpose of each option. For example,
scene files: in case of the @relativeref{Trade,AssimpImporter} plugin you can toggle various
import options and postprocessing steps --- this is how a subset of its
@ref Trade-AssimpImporter-configuration "default configuration file" looks
like:
@code{.ini}
[configuration]
mergeAnimationClips=false
[configuration/postprocess]
PreTransformVertices=false
@endcode
@m_class{m-noindent}
and this is how you can edit it using @relativeref{Corrade,Utility::Configuration}:
@snippet plugins.cpp configuration @snippet plugins.cpp configuration
Besides affecting a single plugin instance, you can also change the Besides affecting a single plugin instance, you can also change the
configuration globally via @ref Corrade::PluginManager::PluginMetadata::configuration() "PluginManager::PluginMetadata::configuration()". configuration globally via @relativeref{Corrade,PluginManager::PluginMetadata::configuration()}.
That will affect all plugin instances created after. Resetting the global That will affect all subsequently created plugin instances. Resetting the global
configuration back to the initial state can be done by recreating the plugin configuration back to the initial state can be done by recreating the plugin
manager. manager.
@section plugins-direct Direct usage of plugins A special case is the "Any" plugins @ref plugins-aliases "described above" ---
these don't contain any implicit configuration on their own, but will propagate
@todoc and also check that this is not already mentioned above anything you set to the concrete plugin implementation. So you could do the
above with @cpp "AnySceneImporter" @ce as well, and if @relativeref{Trade,AssimpImporter} would end up being used, it correctly
receives the options you have set.
@section plugins-develop Developing your own plugins @section plugins-develop Developing your own plugins

6
doc/snippets/plugins.cpp

@ -39,6 +39,7 @@ int main() {
/* [dependencies] */ /* [dependencies] */
PluginManager::Manager<Trade::AbstractImporter> importerManager; PluginManager::Manager<Trade::AbstractImporter> importerManager;
PluginManager::Manager<Text::AbstractFont> fontManager; PluginManager::Manager<Text::AbstractFont> fontManager;
fontManager.registerExternalManager(importerManager);
// As a side effect TgaImporter is loaded by importerManager // As a side effect TgaImporter is loaded by importerManager
fontManager.load("MagnumFont"); fontManager.load("MagnumFont");
@ -57,7 +58,9 @@ PluginManager::Manager<Trade::AbstractImporter> manager;
/* [anyimporter] */ /* [anyimporter] */
Containers::Pointer<Trade::AbstractImporter> importer = Containers::Pointer<Trade::AbstractImporter> importer =
manager.instantiate("AnyImageImporter"); manager.instantiate("AnyImageImporter");
importer->openFile("texture.dds"); /* Delegates to the DdsImporter plugin */
/* Delegates to the DdsImporter plugin, if it's available */
importer->openFile("texture.dds");
/* [anyimporter] */ /* [anyimporter] */
} }
@ -66,6 +69,7 @@ PluginManager::Manager<Trade::AbstractImporter> manager;
/* [configuration] */ /* [configuration] */
Containers::Pointer<Trade::AbstractImporter> importer = Containers::Pointer<Trade::AbstractImporter> importer =
manager.instantiate("AssimpImporter"); manager.instantiate("AssimpImporter");
importer->configuration().setValue("mergeAnimationClips", true);
importer->configuration().group("postprocess")->setValue("PreTransformVertices", true); importer->configuration().group("postprocess")->setValue("PreTransformVertices", true);
/* [configuration] */ /* [configuration] */
} }

Loading…
Cancel
Save