Browse Source

Trade: AbstractSceneConverter::begin*() should have a way to fail.

Initially I thought there was no reason for this to fail, but then
realized AnySceneConverter would need it. And also any other plugin
relying on something external that might fail during initialization --
there's no other moment after plugin instantiation where it could
signalize a failure, and deferring that to the first add() call,
whichever would it be, is really not a sane idea.
pull/592/head
Vladimír Vondruš 4 years ago
parent
commit
cc8440184a
  1. 50
      src/Magnum/Trade/AbstractSceneConverter.cpp
  2. 23
      src/Magnum/Trade/AbstractSceneConverter.h
  3. 572
      src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp

50
src/Magnum/Trade/AbstractSceneConverter.cpp

@ -301,22 +301,28 @@ void AbstractSceneConverter::abort() {
void AbstractSceneConverter::doAbort() {} void AbstractSceneConverter::doAbort() {}
void AbstractSceneConverter::begin() { bool AbstractSceneConverter::begin() {
if(_state) abort(); if(_state) abort();
_state.emplace(State::Type::Convert); _state.emplace(State::Type::Convert);
if(features() >= SceneConverterFeature::ConvertMultiple) { if(features() >= SceneConverterFeature::ConvertMultiple) {
doBegin(); if(!doBegin()) {
_state = {};
return false;
}
return true;
} else if(features() & SceneConverterFeature::ConvertMesh) { } else if(features() & SceneConverterFeature::ConvertMesh) {
/* Actual operation performed in doAdd(const MeshData&) */ /* Actual operation performed in doAdd(const MeshData&) */
return true;
} else CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::begin(): feature not supported", ); } else CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::begin(): feature not supported", {});
} }
void AbstractSceneConverter::doBegin() { bool AbstractSceneConverter::doBegin() {
CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::begin(): feature advertised but not implemented", ); CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::begin(): feature advertised but not implemented", {});
} }
Containers::Pointer<AbstractImporter> AbstractSceneConverter::end() { Containers::Pointer<AbstractImporter> AbstractSceneConverter::end() {
@ -378,22 +384,28 @@ Containers::Pointer<AbstractImporter> AbstractSceneConverter::doEnd() {
CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::end(): feature advertised but not implemented", {}); CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::end(): feature advertised but not implemented", {});
} }
void AbstractSceneConverter::beginData() { bool AbstractSceneConverter::beginData() {
if(_state) abort(); if(_state) abort();
_state.emplace(State::Type::ConvertToData); _state.emplace(State::Type::ConvertToData);
if(features() >= SceneConverterFeature::ConvertMultipleToData) { if(features() >= SceneConverterFeature::ConvertMultipleToData) {
doBeginData(); if(!doBeginData()) {
_state = {};
return false;
}
return true;
} else if(features() >= SceneConverterFeature::ConvertMeshToData) { } else if(features() >= SceneConverterFeature::ConvertMeshToData) {
/* Actual operation performed in doAdd(const MeshData&) */ /* Actual operation performed in doAdd(const MeshData&) */
return true;
} else CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::beginData(): feature not supported", ); } else CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::beginData(): feature not supported", {});
} }
void AbstractSceneConverter::doBeginData() { bool AbstractSceneConverter::doBeginData() {
CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::beginData(): feature advertised but not implemented", ); CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::beginData(): feature advertised but not implemented", {});
} }
Containers::Optional<Containers::Array<char>> AbstractSceneConverter::endData() { Containers::Optional<Containers::Array<char>> AbstractSceneConverter::endData() {
@ -429,26 +441,32 @@ Containers::Optional<Containers::Array<char>> AbstractSceneConverter::doEndData(
CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::endData(): feature advertised but not implemented", {}); CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::endData(): feature advertised but not implemented", {});
} }
void AbstractSceneConverter::beginFile(const Containers::StringView filename) { bool AbstractSceneConverter::beginFile(const Containers::StringView filename) {
if(_state) abort(); if(_state) abort();
_state.emplace(State::Type::ConvertToFile); _state.emplace(State::Type::ConvertToFile);
_state->filename = Containers::String::nullTerminatedGlobalView(filename); _state->filename = Containers::String::nullTerminatedGlobalView(filename);
if(features() >= SceneConverterFeature::ConvertMultipleToFile) { if(features() >= SceneConverterFeature::ConvertMultipleToFile) {
doBeginFile(_state->filename); if(!doBeginFile(_state->filename)) {
_state = {};
return false;
}
return true;
} else if(features() >= SceneConverterFeature::ConvertMeshToFile) { } else if(features() >= SceneConverterFeature::ConvertMeshToFile) {
/* Actual operation performed in doAdd(const MeshData&) */ /* Actual operation performed in doAdd(const MeshData&) */
return true;
} else CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::beginFile(): feature not supported", ); } else CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::beginFile(): feature not supported", {});
} }
void AbstractSceneConverter::doBeginFile(Containers::StringView) { bool AbstractSceneConverter::doBeginFile(Containers::StringView) {
CORRADE_ASSERT(features() >= SceneConverterFeature::ConvertMultipleToData, CORRADE_ASSERT(features() >= SceneConverterFeature::ConvertMultipleToData,
"Trade::AbstractSceneConverter::beginFile(): feature advertised but not implemented", ); "Trade::AbstractSceneConverter::beginFile(): feature advertised but not implemented", {});
doBeginData(); return doBeginData();
} }
bool AbstractSceneConverter::endFile() { bool AbstractSceneConverter::endFile() {

23
src/Magnum/Trade/AbstractSceneConverter.h

@ -753,7 +753,8 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* If a conversion is currently in progress, calls @ref abort() first. * If a conversion is currently in progress, calls @ref abort() first.
* The converted output of data supplied via various @ref add() and * The converted output of data supplied via various @ref add() and
* `set*()` APIs is returned via an importer instance upon calling * `set*()` APIs is returned via an importer instance upon calling
* @ref end(). * @ref end(). On failure prints a message to @relativeref{Magnum,Error}
* and returns @cpp false @ce.
* *
* Expects that @ref SceneConverterFeature::ConvertMultiple is * Expects that @ref SceneConverterFeature::ConvertMultiple is
* supported. If not and @ref SceneConverterFeature::ConvertMesh is * supported. If not and @ref SceneConverterFeature::ConvertMesh is
@ -763,7 +764,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* @ref end(). * @ref end().
* @see @ref features(), @ref beginData(), @ref beginFile() * @see @ref features(), @ref beginData(), @ref beginFile()
*/ */
void begin(); bool begin();
/** /**
* @brief End converting a scene * @brief End converting a scene
@ -806,7 +807,9 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* *
* If a conversion is currently in progress, calls @ref abort() first. * If a conversion is currently in progress, calls @ref abort() first.
* The converted output of data supplied via various @ref add() and * The converted output of data supplied via various @ref add() and
* `set*()` APIs is returned upon calling @ref endData(). * `set*()` APIs is returned upon calling @ref endData(). On failure
* prints a message to @relativeref{Magnum,Error} and returns
* @cpp false @ce.
* *
* Expects that @ref SceneConverterFeature::ConvertMultipleToData is * Expects that @ref SceneConverterFeature::ConvertMultipleToData is
* supported. If not and @ref SceneConverterFeature::ConvertMeshToData * supported. If not and @ref SceneConverterFeature::ConvertMeshToData
@ -816,7 +819,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* @ref endData(). * @ref endData().
* @see @ref features(), @ref begin(), @ref beginFile() * @see @ref features(), @ref begin(), @ref beginFile()
*/ */
void beginData(); bool beginData();
/** /**
* @brief End converting a scene to raw data * @brief End converting a scene to raw data
@ -842,7 +845,9 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* *
* If a conversion is currently in progress, calls @ref abort() first. * If a conversion is currently in progress, calls @ref abort() first.
* The converted output of data supplied via various @ref add() and * The converted output of data supplied via various @ref add() and
* `set*()` APIs is returned upon calling @ref endFile(). * `set*()` APIs is returned upon calling @ref endFile(). On failure
* prints a message to @relativeref{Magnum,Error} and returns
* @cpp false @ce.
* *
* Expects that @ref SceneConverterFeature::ConvertMultipleToFile is * Expects that @ref SceneConverterFeature::ConvertMultipleToFile is
* supported. If not and @ref SceneConverterFeature::ConvertMeshToFile * supported. If not and @ref SceneConverterFeature::ConvertMeshToFile
@ -852,7 +857,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* return the result from @ref endFile(). * return the result from @ref endFile().
* @see @ref features(), @ref begin(), @ref beginData() * @see @ref features(), @ref begin(), @ref beginData()
*/ */
void beginFile(Containers::StringView filename); bool beginFile(Containers::StringView filename);
/** /**
* @brief End converting a scene to raw data * @brief End converting a scene to raw data
@ -1757,7 +1762,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* @relativeref{Corrade,Containers::StringViewFlag::NullTerminated}, * @relativeref{Corrade,Containers::StringViewFlag::NullTerminated},
* however. * however.
*/ */
virtual void doBeginFile(Containers::StringView filename); virtual bool doBeginFile(Containers::StringView filename);
/** /**
* @brief Implementation for @ref endFile() * @brief Implementation for @ref endFile()
@ -1832,7 +1837,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* @brief Implementation for @ref begin() * @brief Implementation for @ref begin()
* @m_since_latest * @m_since_latest
*/ */
virtual void doBegin(); virtual bool doBegin();
/** /**
* @brief Implementation for @ref end() * @brief Implementation for @ref end()
@ -1847,7 +1852,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract
* @brief Implementation for @ref beginData() * @brief Implementation for @ref beginData()
* @m_since_latest * @m_since_latest
*/ */
virtual void doBeginData(); virtual bool doBeginData();
/** /**
* @brief Implementation for @ref endData() * @brief Implementation for @ref endData()

572
src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save