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"},