Browse Source

[wip] Trade: add a protected openData() overload taking a rvalue Array.

Meant to be used from within plugin implementations to avoid copies in
the delegated importers.

TODO: the heck, why can't I call a protected function from a subclass
   but another instance?
TODO: figure out a way to test this
TODO: update docs and behavior for the ZeroCopy flag
TODO: adapt AnySceneImporter also
pull/240/head
Vladimír Vondruš 5 years ago
parent
commit
4446300d18
  1. 8
      src/Magnum/Trade/AbstractImporter.cpp
  2. 28
      src/Magnum/Trade/AbstractImporter.h
  3. 4
      src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp

8
src/Magnum/Trade/AbstractImporter.cpp

@ -147,7 +147,7 @@ void AbstractImporter::setFileCallback(Containers::Optional<Containers::ArrayVie
void AbstractImporter::doSetFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) {} void AbstractImporter::doSetFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) {}
bool AbstractImporter::openData(Containers::ArrayView<const void> data) { bool AbstractImporter::openData(Containers::Array<char>&& data, const DataFlags dataFlags) {
CORRADE_ASSERT(features() & ImporterFeature::OpenData, CORRADE_ASSERT(features() & ImporterFeature::OpenData,
"Trade::AbstractImporter::openData(): feature not supported", {}); "Trade::AbstractImporter::openData(): feature not supported", {});
@ -155,10 +155,14 @@ bool AbstractImporter::openData(Containers::ArrayView<const void> data) {
the check doesn't be done on the plugin side) because for some file the check doesn't be done on the plugin side) because for some file
formats it could be valid (e.g. OBJ or JSON-based formats). */ formats it could be valid (e.g. OBJ or JSON-based formats). */
close(); close();
doOpenData(Containers::Array<char>{const_cast<char*>(static_cast<const char*>(data.data())), data.size(), Implementation::nonOwnedArrayDeleter}, {}); doOpenData(std::move(data), dataFlags);
return isOpened(); return isOpened();
} }
bool AbstractImporter::openData(Containers::ArrayView<const void> data) {
return openData(Containers::Array<char>{const_cast<char*>(static_cast<const char*>(data.data())), data.size(), Implementation::nonOwnedArrayDeleter}, {});
}
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
void AbstractImporter::doOpenData(Containers::ArrayView<const char>) { void AbstractImporter::doOpenData(Containers::ArrayView<const char>) {
CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImporter::openData(): feature advertised but not implemented", ); CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImporter::openData(): feature advertised but not implemented", );

28
src/Magnum/Trade/AbstractImporter.h

@ -1900,6 +1900,34 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
const void* importerState() const; const void* importerState() const;
protected: protected:
/**
* @brief Open data that originated elsewhere
* @m_since_latest
*
* Closes previous file, if it was opened, and tries to open given raw
* data. Available only if @ref ImporterFeature::OpenData is supported.
* Returns @cpp true @ce on success, @cpp false @ce otherwise.
*
* Designed to be called instead of the public
* @ref openData(Containers::ArrayView<const void>) by importers that
* proxy loading to other plugins, with the intent of enabling
* zero-copy import in the proxied-to implementations as well. Possible
* scenarios:
*
* - Called from inside a @ref doOpenData() implementation that
* proxies loading to other plugins (for example based on file
* type). In this case it's meant to pass through the @p data and
* @p dataFlags unchanged.
* - Called from inside (for example) a @ref doImage2D() in a scene
* importer that delegates image loading to specialized plugins.
* Assuming the delegated-to importer receives a subrange of the
* data held by the originating importer and its lifetime doesn't
* exceed the originating importer lifetime, the @p data should
* have a no-op deleter and @p dataFlags should be
* @ref DataFlag::Owned.
*/
bool openData(Containers::Array<char>&& data, DataFlags dataFlags);
/** /**
* @brief Implementation for @ref openFile() * @brief Implementation for @ref openFile()
* *

4
src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp

@ -153,7 +153,7 @@ void AnyImageImporter::doOpenFile(const std::string& filename) {
_in = std::move(importer); _in = std::move(importer);
} }
void AnyImageImporter::doOpenData(Containers::Array<char>&& data, DataFlags) { void AnyImageImporter::doOpenData(Containers::Array<char>&& data, const DataFlags dataFlags) {
using namespace Containers::Literals; using namespace Containers::Literals;
CORRADE_INTERNAL_ASSERT(manager()); CORRADE_INTERNAL_ASSERT(manager());
@ -253,7 +253,7 @@ void AnyImageImporter::doOpenData(Containers::Array<char>&& data, DataFlags) {
/* Try to open the file (error output should be printed by the plugin /* Try to open the file (error output should be printed by the plugin
itself) */ itself) */
if(!importer->openData(data)) return; if(!importer->openData(std::move(data), dataFlags)) return;
/* Success, save the instance */ /* Success, save the instance */
_in = std::move(importer); _in = std::move(importer);

Loading…
Cancel
Save