Browse Source

Any{Scene,Image}Importer: propagate file callbacks as well.

pull/240/merge
Vladimír Vondruš 4 years ago
parent
commit
7a462590ab
  1. 3
      doc/changelog.dox
  2. 12
      src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp
  3. 14
      src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h
  4. 27
      src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp
  5. 7
      src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp
  6. 12
      src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h
  7. 29
      src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp

3
doc/changelog.dox

@ -491,6 +491,9 @@ See also:
plugin to apply the option to with `-I` / `-C`. For better usability, the plugin to apply the option to with `-I` / `-C`. For better usability, the
plugins also warn if the user specifies and option that is not present in plugins also warn if the user specifies and option that is not present in
the target implementation. the target implementation.
- @relativeref{Trade,AnyImageImporter} and
@relativeref{Trade,AnySceneImporter} now can propagate also file callbacks
to the concrete plugin.
- @relativeref{Trade,AnyImageConverter} now implements also conversion of 3D - @relativeref{Trade,AnyImageConverter} now implements also conversion of 3D
and multi-level 2D/3D images for formats that support it (such as Basis and multi-level 2D/3D images for formats that support it (such as Basis
Universal or OpenEXR) Universal or OpenEXR)

12
src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp

@ -48,7 +48,9 @@ AnyImageImporter::AnyImageImporter(AnyImageImporter&&) noexcept = default;
AnyImageImporter::~AnyImageImporter() = default; AnyImageImporter::~AnyImageImporter() = default;
ImporterFeatures AnyImageImporter::doFeatures() const { return ImporterFeature::OpenData; } ImporterFeatures AnyImageImporter::doFeatures() const {
return ImporterFeature::OpenData|ImporterFeature::FileCallback;
}
bool AnyImageImporter::doIsOpened() const { return !!_in; } bool AnyImageImporter::doIsOpened() const { return !!_in; }
@ -138,9 +140,10 @@ void AnyImageImporter::doOpenFile(const std::string& filename) {
d << "(provided by" << metadata->name() << Debug::nospace << ")"; d << "(provided by" << metadata->name() << Debug::nospace << ")";
} }
/* Instantiate the plugin, propagate flags */ /* Instantiate the plugin, propagate flags and the file callback, if set */
Containers::Pointer<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instantiate(plugin); Containers::Pointer<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instantiate(plugin);
importer->setFlags(flags()); importer->setFlags(flags());
if(fileCallback()) importer->setFileCallback(fileCallback(), fileCallbackUserData());
/* Propagate configuration */ /* Propagate configuration */
Magnum::Implementation::propagateConfiguration("Trade::AnyImageImporter::openFile():", {}, metadata->name(), configuration(), importer->configuration()); Magnum::Implementation::propagateConfiguration("Trade::AnyImageImporter::openFile():", {}, metadata->name(), configuration(), importer->configuration());
@ -244,7 +247,10 @@ void AnyImageImporter::doOpenData(Containers::Array<char>&& data, DataFlags) {
d << "(provided by" << metadata->name() << Debug::nospace << ")"; d << "(provided by" << metadata->name() << Debug::nospace << ")";
} }
/* Instantiate the plugin, propagate flags */ /* Instantiate the plugin, propagate flags. File callbacks not propagated
here as no image importers currently load any extra files. */
/** @todo revisit callbacks when that becomes true (such as loading XMP
files accompanying RAWs) */
Containers::Pointer<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instantiate(plugin); Containers::Pointer<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instantiate(plugin);
importer->setFlags(flags()); importer->setFlags(flags());

14
src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h

@ -53,8 +53,9 @@ namespace Magnum { namespace Trade {
/** /**
@brief Any image importer plugin @brief Any image importer plugin
Detects file type based on file extension, loads corresponding plugin and then Detects file type based on file extension or a signature at the start of the
tries to open the file with it. Supported formats: file, loads corresponding plugin and then tries to open the file with it.
Supported formats:
- Basis Universal (`*.basis` or data with corresponding signature), loaded - Basis Universal (`*.basis` or data with corresponding signature), loaded
with @ref BasisImporter or any other plugin that provides it with @ref BasisImporter or any other plugin that provides it
@ -99,6 +100,7 @@ tries to open the file with it. Supported formats:
Detecting file type through @ref openData() is supported only for a subset of Detecting file type through @ref openData() is supported only for a subset of
formats that are marked as such in the list above. formats that are marked as such in the list above.
@ref ImporterFeature::FileCallback is supported as well.
@section Trade-AnyImageImporter-usage Usage @section Trade-AnyImageImporter-usage Usage
@ -135,10 +137,10 @@ information.
On a call to @ref openFile() / @ref openData(), a file format is detected from On a call to @ref openFile() / @ref openData(), a file format is detected from
the extension / file signature and a corresponding plugin is loaded. After the extension / file signature and a corresponding plugin is loaded. After
that, flags set via @ref setFlags() and options set through that, flags set via @ref setFlags(), file callbacks set via
@ref configuration() are propagated to the concrete implementation, with a @ref setFileCallback() and options set through @ref configuration() are
warning emitted in case given option is not present in the default propagated to the concrete implementation. A warning is emitted in case an
configuration of the target plugin. option set is not present in the default configuration of the target plugin.
Calls to the @ref image1DCount() / @ref image2DCount() / @ref image3DCount(), Calls to the @ref image1DCount() / @ref image2DCount() / @ref image3DCount(),
@ref image1DLevelCount() / @ref image2DLevelCount() / @ref image3DLevelCount() @ref image1DLevelCount() / @ref image2DLevelCount() / @ref image3DLevelCount()

27
src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp

@ -60,6 +60,7 @@ struct AnyImageImporterTest: TestSuite::Tester {
void propagateConfigurationUnknown(); void propagateConfigurationUnknown();
/* configuration propagation fully tested in AnySceneImporter, as there the /* configuration propagation fully tested in AnySceneImporter, as there the
plugins have configuration subgroups as well */ plugins have configuration subgroups as well */
void propagateFileCallback();
/* Explicitly forbid system-wide plugin dependencies */ /* Explicitly forbid system-wide plugin dependencies */
PluginManager::Manager<AbstractImporter> _manager{"nonexistent"}; PluginManager::Manager<AbstractImporter> _manager{"nonexistent"};
@ -182,6 +183,8 @@ AnyImageImporterTest::AnyImageImporterTest() {
addInstancedTests({&AnyImageImporterTest::propagateConfigurationUnknown}, addInstancedTests({&AnyImageImporterTest::propagateConfigurationUnknown},
Containers::arraySize(Load2DData)); Containers::arraySize(Load2DData));
addTests({&AnyImageImporterTest::propagateFileCallback});
/* Load the plugin directly from the build tree. Otherwise it's static and /* Load the plugin directly from the build tree. Otherwise it's static and
already loaded. */ already loaded. */
#ifdef ANYIMAGEIMPORTER_PLUGIN_FILENAME #ifdef ANYIMAGEIMPORTER_PLUGIN_FILENAME
@ -405,6 +408,30 @@ void AnyImageImporterTest::propagateConfigurationUnknown() {
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::AnyImageImporter::{}(): option noSuchOption not recognized by TgaImporter\n", data.messageFunctionName)); CORRADE_COMPARE(out.str(), Utility::formatString("Trade::AnyImageImporter::{}(): option noSuchOption not recognized by TgaImporter\n", data.messageFunctionName));
} }
void AnyImageImporterTest::propagateFileCallback() {
if(!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("TgaImporter plugin not enabled, cannot test");
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("AnyImageImporter");
Containers::Array<char> storage;
importer->setFileCallback([](const std::string&, InputFileCallbackPolicy, Containers::Array<char>& storage) -> Containers::Optional<Containers::ArrayView<const char>> {
storage = Utility::Directory::read(TGA_FILE);
return Containers::ArrayView<const char>{storage};
}, storage);
CORRADE_VERIFY(importer->openFile("you-know-where-the-file-is.tga"));
CORRADE_COMPARE(importer->image2DCount(), 1);
/* Check only size, as it is good enough proof that it is working */
Containers::Optional<ImageData2D> image = importer->image2D(0);
CORRADE_VERIFY(image);
CORRADE_COMPARE(image->size(), Vector2i(3, 2));
importer->close();
CORRADE_VERIFY(!importer->isOpened());
}
}}}} }}}}
CORRADE_TEST_MAIN(Magnum::Trade::Test::AnyImageImporterTest) CORRADE_TEST_MAIN(Magnum::Trade::Test::AnyImageImporterTest)

7
src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp

@ -61,7 +61,9 @@ AnySceneImporter::AnySceneImporter(PluginManager::AbstractManager& manager, cons
AnySceneImporter::~AnySceneImporter() = default; AnySceneImporter::~AnySceneImporter() = default;
ImporterFeatures AnySceneImporter::doFeatures() const { return {}; } ImporterFeatures AnySceneImporter::doFeatures() const {
return ImporterFeature::FileCallback;
}
bool AnySceneImporter::doIsOpened() const { return !!_in; } bool AnySceneImporter::doIsOpened() const { return !!_in; }
@ -152,9 +154,10 @@ void AnySceneImporter::doOpenFile(const std::string& filename) {
d << "(provided by" << metadata->name() << Debug::nospace << ")"; d << "(provided by" << metadata->name() << Debug::nospace << ")";
} }
/* Instantiate the plugin, propagate flags */ /* Instantiate the plugin, propagate flags and the file callback, if set */
Containers::Pointer<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instantiate(plugin); Containers::Pointer<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instantiate(plugin);
importer->setFlags(flags()); importer->setFlags(flags());
if(fileCallback()) importer->setFileCallback(fileCallback(), fileCallbackUserData());
/* Propagate configuration */ /* Propagate configuration */
Magnum::Implementation::propagateConfiguration("Trade::AnySceneImporter::openFile():", {}, metadata->name(), configuration(), importer->configuration()); Magnum::Implementation::propagateConfiguration("Trade::AnySceneImporter::openFile():", {}, metadata->name(), configuration(), importer->configuration());

12
src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h

@ -95,7 +95,8 @@ tries to open the file with it. Supported formats:
`ValveImporter` `ValveImporter`
- XGL (`*.xgl`, `*.zgl`), loaded with any plugin that provides `XglImporter` - XGL (`*.xgl`, `*.zgl`), loaded with any plugin that provides `XglImporter`
Only loading from files is supported. Only loading from files is supported as the filename is used to detect the
format, however @ref ImporterFeature::FileCallback is supported as well.
@section Trade-AnySceneImporter-usage Usage @section Trade-AnySceneImporter-usage Usage
@ -131,10 +132,11 @@ information.
@section Trade-AnySceneImporter-proxy Interface proxying and option propagation @section Trade-AnySceneImporter-proxy Interface proxying and option propagation
On a call to @ref openFile(), a file format is detected from the extension and On a call to @ref openFile(), a file format is detected from the extension and
a corresponding plugin is loaded. After that, flags set via @ref setFlags() and a corresponding plugin is loaded. After that, flags set via @ref setFlags(),
options set through @ref configuration() are propagated to the concrete file callbacks set via @ref setFileCallback() and options set through
implementation, with a warning emitted in case given option is not present in @ref configuration() are propagated to the concrete implementation. A warning
the default configuration of the target plugin. is emitted in case an option set is not present in the default configuration of
the target plugin.
Calls to the @ref animation(), @ref scene(), @ref light(), @ref camera(), Calls to the @ref animation(), @ref scene(), @ref light(), @ref camera(),
@ref object2D(), @ref object3D(), @ref skin2D(), @ref skin3D(), @ref mesh(), @ref object2D(), @ref object3D(), @ref skin2D(), @ref skin3D(), @ref mesh(),

29
src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp

@ -30,6 +30,7 @@
#include <Corrade/TestSuite/Tester.h> #include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/ConfigurationGroup.h> #include <Corrade/Utility/ConfigurationGroup.h>
#include <Corrade/Utility/DebugStl.h> #include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Directory.h>
#include <Corrade/Utility/FormatStl.h> #include <Corrade/Utility/FormatStl.h>
#include "Magnum/Math/Vector3.h" #include "Magnum/Math/Vector3.h"
@ -60,6 +61,7 @@ struct AnySceneImporterTest: TestSuite::Tester {
void propagateFlags(); void propagateFlags();
void propagateConfiguration(); void propagateConfiguration();
void propagateConfigurationUnknown(); void propagateConfigurationUnknown();
void propagateFileCallback();
/* Explicitly forbid system-wide plugin dependencies */ /* Explicitly forbid system-wide plugin dependencies */
PluginManager::Manager<AbstractImporter> _manager{"nonexistent"}; PluginManager::Manager<AbstractImporter> _manager{"nonexistent"};
@ -103,7 +105,8 @@ AnySceneImporterTest::AnySceneImporterTest() {
&AnySceneImporterTest::propagateFlags, &AnySceneImporterTest::propagateFlags,
&AnySceneImporterTest::propagateConfiguration, &AnySceneImporterTest::propagateConfiguration,
&AnySceneImporterTest::propagateConfigurationUnknown}); &AnySceneImporterTest::propagateConfigurationUnknown,
&AnySceneImporterTest::propagateFileCallback});
/* Load the plugin directly from the build tree. Otherwise it's static and /* Load the plugin directly from the build tree. Otherwise it's static and
already loaded. */ already loaded. */
@ -271,6 +274,30 @@ void AnySceneImporterTest::propagateConfigurationUnknown() {
"Trade::AnySceneImporter::openFile(): option postprocess/feh/noHereNotEither not recognized by AssimpImporter\n"); "Trade::AnySceneImporter::openFile(): option postprocess/feh/noHereNotEither not recognized by AssimpImporter\n");
} }
void AnySceneImporterTest::propagateFileCallback() {
if(!(_manager.loadState("ObjImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("ObjImporter plugin not enabled, cannot test");
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("AnySceneImporter");
Containers::Array<char> storage;
importer->setFileCallback([](const std::string&, InputFileCallbackPolicy, Containers::Array<char>& storage) -> Containers::Optional<Containers::ArrayView<const char>> {
storage = Utility::Directory::read(OBJ_FILE);
return Containers::ArrayView<const char>{storage};
}, storage);
CORRADE_VERIFY(importer->openFile("you-know-where-the-file-is.obj"));
CORRADE_COMPARE(importer->meshCount(), 1);
/* Check only size, as it is good enough proof that it is working */
Containers::Optional<MeshData> mesh = importer->mesh(0);
CORRADE_VERIFY(mesh);
CORRADE_COMPARE(mesh->vertexCount(), 3);
importer->close();
CORRADE_VERIFY(!importer->isOpened());
}
}}}} }}}}
CORRADE_TEST_MAIN(Magnum::Trade::Test::AnySceneImporterTest) CORRADE_TEST_MAIN(Magnum::Trade::Test::AnySceneImporterTest)

Loading…
Cancel
Save