From e3fc0d037cd4c550f8e57a0a7cbaa327d3919acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 8 Mar 2019 10:40:27 +0100 Subject: [PATCH] Move Trade::ImporterFileCallbackPolicy to InputFileCallbackPolicy. It'll get used outside of the root namespace and since the callbacks tend to be quite complex, it would be silly to require users to implement one callback for Trade, one for Text and one for Audio, for example. --- doc/changelog.dox | 3 + doc/snippets/MagnumTrade.cpp | 9 +- src/Magnum/CMakeLists.txt | 2 + src/Magnum/FileCallback.cpp | 46 ++++++++++ src/Magnum/FileCallback.h | 92 +++++++++++++++++++ src/Magnum/Magnum.h | 2 + src/Magnum/Test/CMakeLists.txt | 1 + src/Magnum/Test/FileCallbackTest.cpp | 52 +++++++++++ src/Magnum/Trade/AbstractImporter.cpp | 27 ++---- src/Magnum/Trade/AbstractImporter.h | 91 +++++------------- .../Trade/Test/AbstractImporterTest.cpp | 50 +++++----- src/Magnum/Trade/Trade.h | 10 +- .../Test/AnyImageImporterTest.cpp | 6 +- 13 files changed, 265 insertions(+), 126 deletions(-) create mode 100644 src/Magnum/FileCallback.cpp create mode 100644 src/Magnum/FileCallback.h create mode 100644 src/Magnum/Test/FileCallbackTest.cpp diff --git a/doc/changelog.dox b/doc/changelog.dox index 0e4191d7b..571a57247 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -198,6 +198,9 @@ See also: @subsection changelog-latest-deprecated Deprecated APIs +- @cpp Trade::ImporterFileCallbackPolicy @ce is deprecated as it was moved + to @ref InputFileCallbackPolicy in the root namespace to be shared with + APIs outside of the @ref Trade namespace - @cpp DebugTools::ForceRendererOptions::scale() @ce is deprecated in favor of @ref DebugTools::ForceRendererOptions::size(), as that's more consistent with the documentation and the corresponding setter. diff --git a/doc/snippets/MagnumTrade.cpp b/doc/snippets/MagnumTrade.cpp index 9246f0ba5..8f3eb69c4 100644 --- a/doc/snippets/MagnumTrade.cpp +++ b/doc/snippets/MagnumTrade.cpp @@ -27,6 +27,7 @@ #include #include +#include "Magnum/FileCallback.h" #include "Magnum/PixelFormat.h" #include "Magnum/Animation/Player.h" #include "Magnum/MeshTools/Transform.h" @@ -72,13 +73,13 @@ struct Data { } data; importer->setFileCallback([](const std::string& filename, - Trade::ImporterFileCallbackPolicy policy, Data& data) + InputFileCallbackPolicy policy, Data& data) -> Containers::Optional> { auto found = data.files.find(filename); /* Discard the memory mapping, if not needed anymore */ - if(policy == Trade::ImporterFileCallbackPolicy::Close) { + if(policy == InputFileCallbackPolicy::Close) { if(found != data.files.end()) data.files.erase(found); return {}; } @@ -114,7 +115,7 @@ static_cast(shininess); Containers::Pointer importer; /* [AbstractImporter-setFileCallback] */ importer->setFileCallback([](const std::string& filename, - Trade::ImporterFileCallbackPolicy, void*) { + InputFileCallbackPolicy, void*) { Utility::Resource rs("data"); return Containers::optional(rs.getRaw(filename)); }); @@ -129,7 +130,7 @@ struct Data { } data; importer->setFileCallback([](const std::string& filename, - Trade::ImporterFileCallbackPolicy, Data& data) + InputFileCallbackPolicy, Data& data) -> Containers::Optional> { auto found = data.files.find(filename); diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index 25ce0f693..a31a84f36 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -28,6 +28,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake # Files shared between main library and unit test library set(Magnum_SRCS + FileCallback.cpp Mesh.cpp PixelStorage.cpp Resource.cpp @@ -46,6 +47,7 @@ set(Magnum_HEADERS AbstractResourceLoader.h Array.h DimensionTraits.h + FileCallback.h Image.h ImageView.h Magnum.h diff --git a/src/Magnum/FileCallback.cpp b/src/Magnum/FileCallback.cpp new file mode 100644 index 000000000..6c0fd6c5f --- /dev/null +++ b/src/Magnum/FileCallback.cpp @@ -0,0 +1,46 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "FileCallback.h" + +#include + +namespace Magnum { + +Debug& operator<<(Debug& debug, const InputFileCallbackPolicy value) { + switch(value) { + /* LCOV_EXCL_START */ + #define _c(v) case InputFileCallbackPolicy::v: return debug << "InputFileCallbackPolicy::" #v; + _c(LoadTemporary) + _c(LoadPernament) + _c(Close) + #undef _c + /* LCOV_EXCL_STOP */ + } + + return debug << "InputFileCallbackPolicy(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; +} + +} diff --git a/src/Magnum/FileCallback.h b/src/Magnum/FileCallback.h new file mode 100644 index 000000000..6dcf3869d --- /dev/null +++ b/src/Magnum/FileCallback.h @@ -0,0 +1,92 @@ +#ifndef Magnum_FileCallback_h +#define Magnum_FileCallback_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Enum @ref Magnum::InputFileCallbackPolicy + */ + +#include "Magnum/Magnum.h" +#include "Magnum/visibility.h" + +namespace Magnum { + +/** +@brief Input file callback policy + +@see @ref Trade::AbstractImporter::setFileCallback(), + @ref Trade-AbstractImporter-usage-callbacks +*/ +enum class InputFileCallbackPolicy: UnsignedByte { + /** + * The requested file is used only during a call of given function and the + * memory view is not referenced anymore once the function exits. + * + * This can be the case for example when importing image data using + * @ref Trade::AbstractImporter::image2D() --- imported data are copied + * into the returned @ref Trade::ImageData2D object and the original file + * is not needed anymore. Note, however, that this might not be the case + * for all importers --- see documentation of a particular plugin for + * concrete info. + */ + LoadTemporary, + + /** + * The requested file may be used for loading most or all data in the next + * steps, so the importer expects the memory view to be valid for as long + * as data import functions are called on it, but at most until the + * data importer is destroyed, its @ref Trade::AbstractImporter::close() "close()" + * function is called or another file is opened. + * + * This can be the case for example when importing mesh data using + * @ref Trade::AbstractImporter::mesh3D() --- all vertex data might be + * combined in a single binary file and each mesh occupies only a portion + * of it. Note, however, that this might not be the case for all importers + * --- see documentation of a particular plugin for concrete info. + */ + LoadPernament, + + /** + * A file that has been previously loaded by this callback can be closed + * now (and its memory freed). This is just a hint, it's not *required* for + * the callback to close it. This policy is also only ever called with a + * file that was previously opened with the same callback, so it's possible + * to completely ignore it and just return the cached value. + * + * This can be the case for example when an importer is done parsing a text + * file into an internal representation and the original data are no longer + * needed (and, for example, other files need to be loaded and they could + * repurpose the unused memory). + */ + Close +}; + +/** @debugoperatorenum{InputFileCallbackPolicy} */ +MAGNUM_EXPORT Debug& operator<<(Debug& debug, InputFileCallbackPolicy value); + +} + +#endif diff --git a/src/Magnum/Magnum.h b/src/Magnum/Magnum.h index f9c659670..dd888f873 100644 --- a/src/Magnum/Magnum.h +++ b/src/Magnum/Magnum.h @@ -697,6 +697,8 @@ template class Array1D; template class Array2D; template class Array3D; +enum class InputFileCallbackPolicy: UnsignedByte; + template class Image; typedef Image<1> Image1D; typedef Image<2> Image2D; diff --git a/src/Magnum/Test/CMakeLists.txt b/src/Magnum/Test/CMakeLists.txt index be8369d8c..2e94fa982 100644 --- a/src/Magnum/Test/CMakeLists.txt +++ b/src/Magnum/Test/CMakeLists.txt @@ -24,6 +24,7 @@ # corrade_add_test(ArrayTest ArrayTest.cpp LIBRARIES Magnum) +corrade_add_test(FileCallbackTest FileCallbackTest.cpp LIBRARIES Magnum) corrade_add_test(ImageTest ImageTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(ImageViewTest ImageViewTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(MeshTest MeshTest.cpp LIBRARIES Magnum) diff --git a/src/Magnum/Test/FileCallbackTest.cpp b/src/Magnum/Test/FileCallbackTest.cpp new file mode 100644 index 000000000..22817a600 --- /dev/null +++ b/src/Magnum/Test/FileCallbackTest.cpp @@ -0,0 +1,52 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + +#include "Magnum/FileCallback.h" + +namespace Magnum { namespace Test { namespace { + +struct FileCallbackTest: TestSuite::Tester { + explicit FileCallbackTest(); + + void debugInputFileCallbackPolicy(); +}; + +FileCallbackTest::FileCallbackTest() { + addTests({&FileCallbackTest::debugInputFileCallbackPolicy}); +} + +void FileCallbackTest::debugInputFileCallbackPolicy() { + std::ostringstream out; + + Debug{&out} << InputFileCallbackPolicy::Close << InputFileCallbackPolicy(0xf0); + CORRADE_COMPARE(out.str(), "InputFileCallbackPolicy::Close InputFileCallbackPolicy(0xf0)\n"); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Test::FileCallbackTest) diff --git a/src/Magnum/Trade/AbstractImporter.cpp b/src/Magnum/Trade/AbstractImporter.cpp index 72b73e726..8871dbc2b 100644 --- a/src/Magnum/Trade/AbstractImporter.cpp +++ b/src/Magnum/Trade/AbstractImporter.cpp @@ -31,6 +31,7 @@ #include #include +#include "Magnum/FileCallback.h" #include "Magnum/Trade/AbstractMaterialData.h" #include "Magnum/Trade/AnimationData.h" #include "Magnum/Trade/CameraData.h" @@ -73,7 +74,7 @@ AbstractImporter::AbstractImporter(PluginManager::Manager& man AbstractImporter::AbstractImporter(PluginManager::AbstractManager& manager, const std::string& plugin): PluginManager::AbstractManagingPlugin{manager, plugin} {} -void AbstractImporter::setFileCallback(Containers::Optional>(*callback)(const std::string&, ImporterFileCallbackPolicy, void*), void* const userData) { +void AbstractImporter::setFileCallback(Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* const userData) { CORRADE_ASSERT(!isOpened(), "Trade::AbstractImporter::setFileCallback(): can't be set while a file is opened", ); CORRADE_ASSERT(features() & (Feature::FileCallback|Feature::OpenData), "Trade::AbstractImporter::setFileCallback(): importer supports neither loading from data nor via callbacks, callbacks can't be used", ); @@ -82,7 +83,7 @@ void AbstractImporter::setFileCallback(Containers::Optional>(*)(const std::string&, ImporterFileCallbackPolicy, void*), void*) {} +void AbstractImporter::doSetFileCallback(Containers::Optional>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) {} bool AbstractImporter::openData(Containers::ArrayView data) { CORRADE_ASSERT(features() & Feature::OpenData, @@ -135,13 +136,13 @@ bool AbstractImporter::openFile(const std::string& filename) { file loading to the default implementation (callback used in the base doOpenFile() implementation, because this branch is never taken in that case) */ - const Containers::Optional> data = _fileCallback(filename, ImporterFileCallbackPolicy::LoadTemporary, _fileCallbackUserData); + const Containers::Optional> data = _fileCallback(filename, InputFileCallbackPolicy::LoadTemporary, _fileCallbackUserData); if(!data) { Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename; return isOpened(); } doOpenData(*data); - _fileCallback(filename, ImporterFileCallbackPolicy::Close, _fileCallbackUserData); + _fileCallback(filename, InputFileCallbackPolicy::Close, _fileCallbackUserData); /* Shouldn't get here, the assert is fired already in setFileCallback() */ } else CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ @@ -155,13 +156,13 @@ void AbstractImporter::doOpenFile(const std::string& filename) { /* If callbacks are set, use them. This is the same implementation as in openFile(), see the comment there for details. */ if(_fileCallback) { - const Containers::Optional> data = _fileCallback(filename, ImporterFileCallbackPolicy::LoadTemporary, _fileCallbackUserData); + const Containers::Optional> data = _fileCallback(filename, InputFileCallbackPolicy::LoadTemporary, _fileCallbackUserData); if(!data) { Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename; return; } doOpenData(*data); - _fileCallback(filename, ImporterFileCallbackPolicy::Close, _fileCallbackUserData); + _fileCallback(filename, InputFileCallbackPolicy::Close, _fileCallbackUserData); /* Otherwise open the file directly */ } else { @@ -632,18 +633,4 @@ Debug& operator<<(Debug& debug, const AbstractImporter::Features value) { AbstractImporter::Feature::FileCallback}); } -Debug& operator<<(Debug& debug, const ImporterFileCallbackPolicy value) { - switch(value) { - /* LCOV_EXCL_START */ - #define _c(v) case ImporterFileCallbackPolicy::v: return debug << "Trade::ImporterFileCallbackPolicy::" #v; - _c(LoadTemporary) - _c(LoadPernament) - _c(Close) - #undef _c - /* LCOV_EXCL_STOP */ - } - - return debug << "Trade::ImporterFileCallbackPolicy(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; -} - }} diff --git a/src/Magnum/Trade/AbstractImporter.h b/src/Magnum/Trade/AbstractImporter.h index 813bae8a5..5e353e452 100644 --- a/src/Magnum/Trade/AbstractImporter.h +++ b/src/Magnum/Trade/AbstractImporter.h @@ -38,59 +38,18 @@ #ifdef MAGNUM_BUILD_DEPRECATED #include + +#include "Magnum/FileCallback.h" #endif namespace Magnum { namespace Trade { -/** -@brief Importer file loading callback policy - -@see @ref AbstractImporter::setFileCallback(), - @ref Trade-AbstractImporter-usage-callbacks -*/ -enum class ImporterFileCallbackPolicy: UnsignedByte { - /** - * The requested file is used only during a call of given function and the - * memory view is not referenced anymore once the function exits. - * - * This can be the case for example when importing image data using - * @ref AbstractImporter::image2D() --- imported data are copied into the - * returned @ref ImageData2D object and the original file is not needed - * anymore. Note, however, that this might not be the case for all - * importers --- see documentation of a particular plugin for concrete - * info. - */ - LoadTemporary, - - /** - * The requested file may be used for loading most or all data in the next - * steps, so the importer expects the memory view to be valid for as long - * as data import functions are called on it, but at most until the - * importer is destroyed, @ref AbstractImporter::close() is called or - * another file is opened. - * - * This can be the case for example when importing mesh data using - * @ref AbstractImporter::mesh3D() --- all vertex data might be combined in - * a single binary file and each mesh occupies only a portion of it. Note, - * however, that this might not be the case for all importers --- see - * documentation of a particular plugin for concrete info. - */ - LoadPernament, - - /** - * A file that has been previously loaded by this callback can be closed - * now (and its memory freed). This is just a hint, it's not *required* for - * the callback to close it. This policy is also only ever called with a - * file that was previously opened with the same callback, so it's possible - * to completely ignore it and just return the cached value. - * - * This can be the case for example when an importer is done parsing a text - * file into an internal representation and the original data are no longer - * needed (and, for example, other files need to be loaded and they could - * repurpose the unused memory). - */ - Close -}; +#ifdef MAGNUM_BUILD_DEPRECATED +/** @brief @copybrief InputFileCallbackPolicy + * @deprecated Use @ref InputFileCallbackPolicy instead. + */ +typedef CORRADE_DEPRECATED("use InputFileCallbackPolicy instead") InputFileCallbackPolicy ImporterFileCallbackPolicy; +#endif /** @brief Base for importer plugins @@ -109,7 +68,7 @@ like this, completely with all error handling: See @ref plugins for more information about general plugin usage and `*Importer` classes in the @ref Trade namespace for available importer plugins. -@subsection Trade-AbstractImporter-usage-callbacks Loading data from memory +@subsection Trade-AbstractImporter-usage-callbacks Loading data from memory, using file callbacks Besides loading data directly from the filesystem using @ref openFile() like shown above, it's possible to use @ref openData() to import data from memory. @@ -120,7 +79,7 @@ Complex scene files often reference other files such as images and in that case you may want to intercept those references and load them in a custom way as well. For importers that advertise support for this with @ref Feature::FileCallback this is done by specifying a file loading callback using @ref setFileCallback(). -The callback gets a filename, @ref ImporterFileCallbackPolicy and an user +The callback gets a filename, @ref InputFileCallbackPolicy and an user pointer as parameters; returns a non-owning view on the loaded data or a @ref Corrade::Containers::NullOpt "Containers::NullOpt" to indicate the file loading failed. For example, loading a scene from memory-mapped files could @@ -311,7 +270,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * * @see @ref Trade-AbstractImporter-usage-callbacks */ - auto fileCallback() const -> Containers::Optional>(*)(const std::string&, ImporterFileCallbackPolicy, void*) { return _fileCallback; } + auto fileCallback() const -> Containers::Optional>(*)(const std::string&, InputFileCallbackPolicy, void*) { return _fileCallback; } /** * @brief File opening callback user data @@ -328,7 +287,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * callback. Besides that, all external files referenced by the * top-level file will be loaded through the callback function as well, * usually on demand. The callback function gets a filename, - * @ref ImporterFileCallbackPolicy and the @p userData pointer as input + * @ref InputFileCallbackPolicy and the @p userData pointer as input * and returns a non-owning view on the loaded data as output or a * @ref Corrade::Containers::NullOpt if loading failed --- because * empty files might also be valid in some circumstances, @cpp nullptr @ce @@ -338,11 +297,11 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * supports at least @ref Feature::OpenData, a file opened through * @ref openFile() will be internally loaded through the provided * callback and then passed to @ref openData(). First the file is - * loaded with @ref ImporterFileCallbackPolicy::LoadTemporary passed to + * loaded with @ref InputFileCallbackPolicy::LoadTemporary passed to * the callback, then the returned memory view is passed to * @ref openData() (sidestepping the potential @ref openFile() * implementation of that particular importer) and after that the - * callback is called again with @ref ImporterFileCallbackPolicy::Close + * callback is called again with @ref InputFileCallbackPolicy::Close * because the semantics of @ref openData() don't require the data to * be alive after. In case you need a different behavior, use * @ref openData() directly. @@ -355,9 +314,8 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * It's expected that this function is called *before* a file is * opened. It's also expected that the loaded data are kept in scope * for as long as the importer needs them, based on the value of - * @ref ImporterFileCallbackPolicy. Documentation of particular - * importers provides more information about the expected callback - * behavior. + * @ref InputFileCallbackPolicy. Documentation of particular importers + * provides more information about the expected callback behavior. * * Following is an example of setting up a file loading callback for * fetching compiled-in resources from @ref Corrade::Utility::Resource. @@ -368,7 +326,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * * @see @ref Trade-AbstractImporter-usage-callbacks */ - void setFileCallback(Containers::Optional>(*callback)(const std::string&, ImporterFileCallbackPolicy, void*), void* userData = nullptr); + void setFileCallback(Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* userData = nullptr); /** * @brief Set file opening callback @@ -382,7 +340,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * @see @ref Trade-AbstractImporter-usage-callbacks */ #ifdef DOXYGEN_GENERATING_OUTPUT - template void setFileCallback(Containers::Optional>(*callback)(const std::string&, ImporterFileCallbackPolicy, T&), T& userData); + template void setFileCallback(Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, T&), T& userData); #else /* Otherwise the user would be forced to use the + operator to convert a lambda to a function pointer and (besides being weird and @@ -852,7 +810,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * and user data pointer are available through @ref fileCallback() and * @ref fileCallbackUserData(). */ - virtual void doSetFileCallback(Containers::Optional>(*callback)(const std::string&, ImporterFileCallbackPolicy, void*), void* userData); + virtual void doSetFileCallback(Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* userData); /** @brief Implementation for @ref isOpened() */ virtual bool doIsOpened() const = 0; @@ -1189,7 +1147,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi virtual const void* doImporterState() const; private: - Containers::Optional>(*_fileCallback)(const std::string&, ImporterFileCallbackPolicy, void*){}; + Containers::Optional>(*_fileCallback)(const std::string&, InputFileCallbackPolicy, void*){}; void* _fileCallbackUserData{}; /* Used by the templated version only */ @@ -1203,13 +1161,13 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi template void AbstractImporter::setFileCallback(Callback callback, T& userData) { /* Don't try to wrap a null function pointer. Need to cast first because MSVC (even 2017) can't apply ! to a lambda. Ugh. */ - const auto callbackPtr = static_cast>(*)(const std::string&, ImporterFileCallbackPolicy, T&)>(callback); + const auto callbackPtr = static_cast>(*)(const std::string&, InputFileCallbackPolicy, T&)>(callback); if(!callbackPtr) return setFileCallback(nullptr); _fileCallbackTemplate = { reinterpret_cast(callbackPtr), &userData }; - setFileCallback([](const std::string& filename, const ImporterFileCallbackPolicy flags, void* const userData) { + setFileCallback([](const std::string& filename, const InputFileCallbackPolicy flags, void* const userData) { auto& s = *reinterpret_cast(userData); - return reinterpret_cast>(*)(const std::string&, ImporterFileCallbackPolicy, T&)>(s.callback)(filename, flags, *static_cast(s.userData)); + return reinterpret_cast>(*)(const std::string&, InputFileCallbackPolicy, T&)>(s.callback)(filename, flags, *static_cast(s.userData)); }, &_fileCallbackTemplate); } #endif @@ -1222,9 +1180,6 @@ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, AbstractImporter::Feature va /** @debugoperatorclassenum{AbstractImporter,AbstractImporter::Features} */ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, AbstractImporter::Features value); -/** @debugoperatorenum{ImporterFileCallbackPolicy} */ -MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImporterFileCallbackPolicy value); - }} #endif diff --git a/src/Magnum/Trade/Test/AbstractImporterTest.cpp b/src/Magnum/Trade/Test/AbstractImporterTest.cpp index be77b7fc8..7fef9a2e0 100644 --- a/src/Magnum/Trade/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImporterTest.cpp @@ -29,6 +29,7 @@ #include #include +#include "Magnum/FileCallback.h" #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/AnimationData.h" #include "Magnum/Trade/CameraData.h" @@ -240,7 +241,6 @@ class AbstractImporterTest: public TestSuite::Tester { void debugFeature(); void debugFeatures(); - void debugFileCallbackPolicy(); }; AbstractImporterTest::AbstractImporterTest() { @@ -433,8 +433,7 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::importerStateNoFile, &AbstractImporterTest::debugFeature, - &AbstractImporterTest::debugFeatures, - &AbstractImporterTest::debugFileCallbackPolicy}); + &AbstractImporterTest::debugFeatures}); } void AbstractImporterTest::construct() { @@ -593,14 +592,14 @@ void AbstractImporterTest::setFileCallback() { Features doFeatures() const override { return Feature::OpenData|Feature::FileCallback; } bool doIsOpened() const override { return false; } void doClose() override {} - void doSetFileCallback(Containers::Optional>(*)(const std::string&, ImporterFileCallbackPolicy, void*), void* userData) override { + void doSetFileCallback(Containers::Optional>(*)(const std::string&, InputFileCallbackPolicy, void*), void* userData) override { *static_cast(userData) = 1337; } }; int a = 0; Importer importer; - auto lambda = [](const std::string&, ImporterFileCallbackPolicy, void*) { + auto lambda = [](const std::string&, InputFileCallbackPolicy, void*) { return Containers::Optional>{}; }; importer.setFileCallback(lambda, &a); @@ -614,7 +613,7 @@ void AbstractImporterTest::setFileCallbackTemplate() { Features doFeatures() const override { return Feature::OpenData|Feature::FileCallback; } bool doIsOpened() const override { return false; } void doClose() override {} - void doSetFileCallback(Containers::Optional>(*)(const std::string&, ImporterFileCallbackPolicy, void*), void*) override { + void doSetFileCallback(Containers::Optional>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) override { called = true; } @@ -622,7 +621,7 @@ void AbstractImporterTest::setFileCallbackTemplate() { }; int a = 0; - auto lambda = [](const std::string&, ImporterFileCallbackPolicy, int&) { + auto lambda = [](const std::string&, InputFileCallbackPolicy, int&) { return Containers::Optional>{}; }; Importer importer; @@ -632,7 +631,7 @@ void AbstractImporterTest::setFileCallbackTemplate() { CORRADE_VERIFY(importer.called); /* The data pointers should be wrapped, thus not the same */ - CORRADE_VERIFY(reinterpret_cast(importer.fileCallback()) != reinterpret_cast(static_cast>(*)(const std::string&, ImporterFileCallbackPolicy, int&)>(lambda))); + CORRADE_VERIFY(reinterpret_cast(importer.fileCallback()) != reinterpret_cast(static_cast>(*)(const std::string&, InputFileCallbackPolicy, int&)>(lambda))); CORRADE_VERIFY(importer.fileCallbackUserData() != &a); } @@ -641,7 +640,7 @@ void AbstractImporterTest::setFileCallbackTemplateNull() { Features doFeatures() const override { return Feature::OpenData|Feature::FileCallback; } bool doIsOpened() const override { return false; } void doClose() override {} - void doSetFileCallback(Containers::Optional>(*callback)(const std::string&, ImporterFileCallbackPolicy, void*), void* userData) override { + void doSetFileCallback(Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* userData) override { called = !callback && !userData; } @@ -650,7 +649,7 @@ void AbstractImporterTest::setFileCallbackTemplateNull() { int a = 0; Importer importer; - importer.setFileCallback(static_cast>(*)(const std::string&, ImporterFileCallbackPolicy, int&)>(nullptr), a); + importer.setFileCallback(static_cast>(*)(const std::string&, InputFileCallbackPolicy, int&)>(nullptr), a); CORRADE_VERIFY(!importer.fileCallback()); CORRADE_VERIFY(!importer.fileCallbackUserData()); CORRADE_VERIFY(importer.called); @@ -667,7 +666,7 @@ void AbstractImporterTest::setFileCallbackFileOpened() { Error redirectError{&out}; Importer importer; - importer.setFileCallback([](const std::string&, ImporterFileCallbackPolicy, void*) { + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) { return Containers::Optional>{}; }); CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::setFileCallback(): can't be set while a file is opened\n"); @@ -681,7 +680,7 @@ void AbstractImporterTest::setFileCallbackNotImplemented() { }; int a; - auto lambda = [](const std::string&, ImporterFileCallbackPolicy, void*) { + auto lambda = [](const std::string&, InputFileCallbackPolicy, void*) { return Containers::Optional>{}; }; Importer importer; @@ -703,7 +702,7 @@ void AbstractImporterTest::setFileCallbackNotSupported() { int a; Importer importer; - importer.setFileCallback([](const std::string&, ImporterFileCallbackPolicy, void*) { + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) { return Containers::Optional>{}; }, &a); CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::setFileCallback(): importer supports neither loading from data nor via callbacks, callbacks can't be used\n"); @@ -731,7 +730,7 @@ void AbstractImporterTest::setFileCallbackOpenFileDirectly() { bool calledNotSureWhy = false; Importer importer; - importer.setFileCallback([](const std::string&, ImporterFileCallbackPolicy, bool& calledNotSureWhy) -> Containers::Optional> { + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, bool& calledNotSureWhy) -> Containers::Optional> { calledNotSureWhy = true; return {}; }, calledNotSureWhy); @@ -767,13 +766,13 @@ void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementation() { bool calledNotSureWhy = false; } state; Importer importer; - importer.setFileCallback([](const std::string& filename, ImporterFileCallbackPolicy policy, State& state) -> Containers::Optional> { - if(filename == "file.dat" && policy == ImporterFileCallbackPolicy::LoadTemporary) { + importer.setFileCallback([](const std::string& filename, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { + if(filename == "file.dat" && policy == InputFileCallbackPolicy::LoadTemporary) { state.loaded = true; return Containers::arrayView(&state.data, 1); } - if(filename == "file.dat" && policy == ImporterFileCallbackPolicy::Close) { + if(filename == "file.dat" && policy == InputFileCallbackPolicy::Close) { state.closed = true; return {}; } @@ -804,7 +803,7 @@ void AbstractImporterTest::setFileCallbackOpenFileThroughBaseImplementationFaile }; Importer importer; - importer.setFileCallback([](const std::string&, ImporterFileCallbackPolicy, void*) -> Containers::Optional> { + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) -> Containers::Optional> { return {}; }); @@ -841,13 +840,13 @@ void AbstractImporterTest::setFileCallbackOpenFileAsData() { bool calledNotSureWhy = false; } state; Importer importer; - importer.setFileCallback([](const std::string& filename, ImporterFileCallbackPolicy policy, State& state) -> Containers::Optional> { - if(filename == "file.dat" && policy == ImporterFileCallbackPolicy::LoadTemporary) { + importer.setFileCallback([](const std::string& filename, InputFileCallbackPolicy policy, State& state) -> Containers::Optional> { + if(filename == "file.dat" && policy == InputFileCallbackPolicy::LoadTemporary) { state.loaded = true; return Containers::arrayView(&state.data, 1); } - if(filename == "file.dat" && policy == ImporterFileCallbackPolicy::Close) { + if(filename == "file.dat" && policy == InputFileCallbackPolicy::Close) { state.closed = true; return {}; } @@ -877,7 +876,7 @@ void AbstractImporterTest::setFileCallbackOpenFileAsDataFailed() { }; Importer importer; - importer.setFileCallback([](const std::string&, ImporterFileCallbackPolicy, void*) { + importer.setFileCallback([](const std::string&, InputFileCallbackPolicy, void*) { return Containers::Optional>{}; }); @@ -3271,13 +3270,6 @@ void AbstractImporterTest::debugFeatures() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::Feature::OpenData|Trade::AbstractImporter::Feature::OpenState Trade::AbstractImporter::Features{}\n"); } -void AbstractImporterTest::debugFileCallbackPolicy() { - std::ostringstream out; - - Debug{&out} << ImporterFileCallbackPolicy::Close << ImporterFileCallbackPolicy(0xf0); - CORRADE_COMPARE(out.str(), "Trade::ImporterFileCallbackPolicy::Close Trade::ImporterFileCallbackPolicy(0xf0)\n"); -} - }}}} CORRADE_TEST_MAIN(Magnum::Trade::Test::AbstractImporterTest) diff --git a/src/Magnum/Trade/Trade.h b/src/Magnum/Trade/Trade.h index 9b983bd2c..3b9b8c469 100644 --- a/src/Magnum/Trade/Trade.h +++ b/src/Magnum/Trade/Trade.h @@ -31,14 +31,20 @@ #include "Magnum/Types.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include "Magnum/Magnum.h" +#endif + namespace Magnum { namespace Trade { #ifndef DOXYGEN_GENERATING_OUTPUT class AbstractImageConverter; - -enum class ImporterFileCallbackPolicy: UnsignedByte; class AbstractImporter; +#ifdef MAGNUM_BUILD_DEPRECATED +typedef CORRADE_DEPRECATED("use InputFileCallbackPolicy instead") InputFileCallbackPolicy ImporterFileCallbackPolicy; +#endif + enum class MaterialType: UnsignedByte; enum class MaterialAlphaMode: UnsignedByte; class AbstractMaterialData; diff --git a/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp b/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp index 8a3fa9424..b3244f5c2 100644 --- a/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp +++ b/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp @@ -51,7 +51,7 @@ struct AnyImageImporterTest: TestSuite::Tester { PluginManager::Manager _manager{"nonexistent"}; }; -Containers::Optional> fileCallback(const std::string& filename, Trade::ImporterFileCallbackPolicy, Containers::Array& storage) { +Containers::Optional> fileCallback(const std::string& filename, InputFileCallbackPolicy, Containers::Array& storage) { storage = Utility::Directory::read(filename); return Containers::ArrayView{storage}; } @@ -59,7 +59,7 @@ Containers::Optional> fileCallback(const std:: constexpr struct { const char* name; const char* filename; - Containers::Optional>(*callback)(const std::string&, Trade::ImporterFileCallbackPolicy, Containers::Array&); + Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, Containers::Array&); } LoadData[]{ {"TGA", TGA_FILE, nullptr}, {"TGA data", TGA_FILE, fileCallback} @@ -68,7 +68,7 @@ constexpr struct { constexpr struct { const char* name; const char* filename; - Containers::Optional>(*callback)(const std::string&, Trade::ImporterFileCallbackPolicy, Containers::Array&); + Containers::Optional>(*callback)(const std::string&, InputFileCallbackPolicy, Containers::Array&); const char* plugin; } DetectData[]{ {"PNG", "rgb.png", nullptr, "PngImporter"},