diff --git a/doc/changelog.dox b/doc/changelog.dox index ff5043bc1..b6fca800d 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -283,6 +283,8 @@ See also: - New convenience @ref Trade::AnimationTrackData constructor taking a templated @ref Animation::TrackView type, autodetecting value and result @ref Trade::AnimationTrackType out of it +- New convenience @ref Trade::AnimationData constructors taking an + @ref std::initializer_list of @ref Trade::AnimationTrackData @subsection changelog-latest-buildsystem Build system diff --git a/src/Magnum/Trade/AnimationData.cpp b/src/Magnum/Trade/AnimationData.cpp index dca88ba8d..d315a0bef 100644 --- a/src/Magnum/Trade/AnimationData.cpp +++ b/src/Magnum/Trade/AnimationData.cpp @@ -29,17 +29,22 @@ #include "Magnum/Math/Vector4.h" #include "Magnum/Math/Quaternion.h" +#include "Magnum/Trade/Implementation/arrayUtilities.h" namespace Magnum { namespace Trade { AnimationData::AnimationData(Containers::Array&& data, Containers::Array&& tracks, const Range1D& duration, const void* importerState) noexcept: _dataFlags{DataFlag::Owned|DataFlag::Mutable}, _duration{duration}, _data{std::move(data)}, _tracks{std::move(tracks)}, _importerState{importerState} {} +AnimationData::AnimationData(Containers::Array&& data, std::initializer_list tracks, const Range1D& duration, const void* importerState): AnimationData{std::move(data), Implementation::initializerListToArrayWithDefaultDeleter(tracks), duration, importerState} {} + AnimationData::AnimationData(const DataFlags dataFlags, const Containers::ArrayView data, Containers::Array&& tracks, const Range1D& duration, const void* importerState) noexcept: AnimationData{Containers::Array{const_cast(static_cast(data.data())), data.size(), Implementation::nonOwnedArrayDeleter}, std::move(tracks), duration, importerState} { CORRADE_ASSERT(!(dataFlags & DataFlag::Owned), "Trade::AnimationData: can't construct a non-owned instance with" << dataFlags, ); _dataFlags = dataFlags; } +AnimationData::AnimationData(const DataFlags dataFlags, const Containers::ArrayView data, std::initializer_list tracks, const Range1D& duration, const void* importerState): AnimationData{dataFlags, data, Implementation::initializerListToArrayWithDefaultDeleter(tracks), duration, importerState} {} + AnimationData::AnimationData(Containers::Array&& data, Containers::Array&& tracks, const void* importerState) noexcept: _dataFlags{DataFlag::Owned|DataFlag::Mutable}, _data{std::move(data)}, _tracks{std::move(tracks)}, _importerState{importerState} { if(!_tracks.empty()) { /* Reset duration to duration of the first track so it properly support @@ -50,12 +55,16 @@ AnimationData::AnimationData(Containers::Array&& data, Containers::Array&& data, std::initializer_list tracks, const void* importerState): AnimationData{std::move(data), Implementation::initializerListToArrayWithDefaultDeleter(tracks), importerState} {} + AnimationData::AnimationData(const DataFlags dataFlags, const Containers::ArrayView data, Containers::Array&& tracks, const void* importerState) noexcept: AnimationData{Containers::Array{const_cast(static_cast(data.data())), data.size(), Implementation::nonOwnedArrayDeleter}, std::move(tracks), importerState} { CORRADE_ASSERT(!(dataFlags & DataFlag::Owned), "Trade::AnimationData: can't construct a non-owned instance with" << dataFlags, ); _dataFlags = dataFlags; } +AnimationData::AnimationData(const DataFlags dataFlags, const Containers::ArrayView data, std::initializer_list tracks, const void* importerState): AnimationData{dataFlags, data, Implementation::initializerListToArrayWithDefaultDeleter(tracks), importerState} {} + AnimationData::~AnimationData() = default; AnimationData::AnimationData(AnimationData&&) noexcept = default; diff --git a/src/Magnum/Trade/AnimationData.h b/src/Magnum/Trade/AnimationData.h index 02f13ebf3..d8bfd5688 100644 --- a/src/Magnum/Trade/AnimationData.h +++ b/src/Magnum/Trade/AnimationData.h @@ -327,6 +327,13 @@ class MAGNUM_TRADE_EXPORT AnimationData { */ explicit AnimationData(Containers::Array&& data, Containers::Array&& tracks, const void* importerState = nullptr) noexcept; + /** + * @overload + * @m_since_latest + */ + /* Not noexcept because allocation happens inside */ + explicit AnimationData(Containers::Array&& data, std::initializer_list tracks, const void* importerState = nullptr); + /** * @brief Construct a non-owned animation data * @param dataFlags Data flags @@ -344,6 +351,13 @@ class MAGNUM_TRADE_EXPORT AnimationData { */ explicit AnimationData(DataFlags dataFlags, Containers::ArrayView data, Containers::Array&& tracks, const void* importerState = nullptr) noexcept; + /** + * @overload + * @m_since_latest + */ + /* Not noexcept because allocation happens inside */ + explicit AnimationData(DataFlags dataFlags, Containers::ArrayView data, std::initializer_list tracks, const void* importerState = nullptr); + /** * @brief Construct an animation data with explicit duration * @param data Buffer containing all keyframe data for this @@ -362,6 +376,13 @@ class MAGNUM_TRADE_EXPORT AnimationData { */ explicit AnimationData(Containers::Array&& data, Containers::Array&& tracks, const Range1D& duration, const void* importerState = nullptr) noexcept; + /** + * @overload + * @m_since_latest + */ + /* Not noexcept because allocation happens inside */ + explicit AnimationData(Containers::Array&& data, std::initializer_list tracks, const Range1D& duration, const void* importerState = nullptr); + /** * @brief Construct a non-owned animation data with explicit duration * @param dataFlags Data flags @@ -380,6 +401,13 @@ class MAGNUM_TRADE_EXPORT AnimationData { */ explicit AnimationData(DataFlags dataFlags, Containers::ArrayView data, Containers::Array&& tracks, const Range1D& duration, const void* importerState = nullptr) noexcept; + /** + * @overload + * @m_since_latest + */ + /* Not noexcept because allocation happens inside */ + explicit AnimationData(DataFlags dataFlags, Containers::ArrayView data, std::initializer_list tracks, const Range1D& duration, const void* importerState = nullptr); + ~AnimationData(); /** @brief Copying is not allowed */ diff --git a/src/Magnum/Trade/Test/AbstractImporterTest.cpp b/src/Magnum/Trade/Test/AbstractImporterTest.cpp index 0e5c7ebc8..f714854ce 100644 --- a/src/Magnum/Trade/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImporterTest.cpp @@ -1228,7 +1228,12 @@ void AbstractImporterTest::animation() { else return {}; } Containers::Optional doAnimation(UnsignedInt id) override { - if(id == 7) return AnimationData{{}, {}, &state}; + /* Verify that initializer list is converted to an array with + the default deleter and not something disallowed */ + if(id == 7) return AnimationData{nullptr, { + {AnimationTrackType::Vector3, + AnimationTrackTargetType::Scaling3D, 0, {}} + }, &state}; else return AnimationData{{}, {}}; } } importer; diff --git a/src/Magnum/Trade/Test/AnimationDataTest.cpp b/src/Magnum/Trade/Test/AnimationDataTest.cpp index f5072512b..96ae3c3e5 100644 --- a/src/Magnum/Trade/Test/AnimationDataTest.cpp +++ b/src/Magnum/Trade/Test/AnimationDataTest.cpp @@ -164,8 +164,6 @@ void AnimationDataTest::constructTrackDataDefault() { } void AnimationDataTest::construct() { - /* Ain't the prettiest, but trust me: you won't do it like this in the - plugins anyway */ struct Data { Float time; Vector3 position; @@ -178,7 +176,7 @@ void AnimationDataTest::construct() { view[2] = {7.5f, {1.0f, 0.3f, 2.1f}, Quaternion{}}; const int state = 5; - AnimationData data{std::move(buffer), Containers::Array{Containers::InPlaceInit, { + AnimationData data{std::move(buffer), { {AnimationTrackTargetType::Translation3D, 42, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, @@ -191,7 +189,7 @@ void AnimationDataTest::construct() { {view, &view[0].rotation, view.size(), sizeof(Data)}, Animation::Interpolation::Linear, animationInterpolatorFor(Animation::Interpolation::Linear)}} - }}, {-1.0f, 7.0f}, &state}; + }, {-1.0f, 7.0f}, &state}; CORRADE_COMPARE(data.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(data.duration(), (Range1D{-1.0f, 7.0f})); @@ -234,8 +232,6 @@ void AnimationDataTest::construct() { } void AnimationDataTest::constructImplicitDuration() { - /* Ain't the prettiest, but trust me: you won't do it like this in the - plugins anyway */ struct Data { Float time; bool value; @@ -248,7 +244,7 @@ void AnimationDataTest::constructImplicitDuration() { view[3] = {7.0f, false}; const int state = 5; - AnimationData data{std::move(buffer), Containers::Array{Containers::InPlaceInit, { + AnimationData data{std::move(buffer), { {AnimationTrackTargetType(129), 0, Animation::TrackView{ {view, &view[0].time, 2, sizeof(Data)}, @@ -259,7 +255,7 @@ void AnimationDataTest::constructImplicitDuration() { {view, &view[2].time, 2, sizeof(Data)}, {view, &view[2].value, 2, sizeof(Data)}, Animation::Interpolation::Linear}} - }}, &state}; + }, &state}; CORRADE_COMPARE(data.dataFlags(), DataFlag::Owned|DataFlag::Mutable); CORRADE_COMPARE(data.duration(), (Range1D{1.0f, 7.0f})); @@ -316,13 +312,13 @@ void AnimationDataTest::constructNotOwned() { }; const int state = 5; - AnimationData data{instanceData.dataFlags, keyframes, Containers::Array{Containers::InPlaceInit, { + AnimationData data{instanceData.dataFlags, keyframes, { {AnimationTrackTargetType::Translation3D, 42, Animation::TrackView{ keyframes, Animation::Interpolation::Constant, animationInterpolatorFor(Animation::Interpolation::Constant)}} - }}, {-1.0f, 7.0f}, &state}; + }, {-1.0f, 7.0f}, &state}; CORRADE_COMPARE(data.dataFlags(), instanceData.dataFlags); CORRADE_COMPARE(data.duration(), (Range1D{-1.0f, 7.0f})); @@ -364,10 +360,10 @@ void AnimationDataTest::constructImplicitDurationNotOwned() { }; const int state = 5; - AnimationData data{instanceData.dataFlags, keyframes, Containers::Array{Containers::InPlaceInit, { + AnimationData data{instanceData.dataFlags, keyframes, { {AnimationTrackTargetType(129), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, - }}, &state}; + }, &state}; CORRADE_COMPARE(data.dataFlags(), instanceData.dataFlags); CORRADE_COMPARE(data.duration(), (Range1D{1.0f, 5.0f})); @@ -436,7 +432,7 @@ void AnimationDataTest::constructMove() { view[2] = {7.5f, {1.0f, 0.3f, 2.1f}, Quaternion{}}; const int state = 5; - AnimationData a{std::move(buffer), Containers::Array{Containers::InPlaceInit, { + AnimationData a{std::move(buffer), { {AnimationTrackTargetType::Translation3D, 42, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, @@ -449,7 +445,7 @@ void AnimationDataTest::constructMove() { {view, &view[0].rotation, view.size(), sizeof(Data)}, Animation::Interpolation::Linear, animationInterpolatorFor(Animation::Interpolation::Linear)}} - }}, {-1.0f, 7.0f}, &state}; + }, {-1.0f, 7.0f}, &state}; AnimationData b{std::move(a)}; @@ -525,10 +521,10 @@ void AnimationDataTest::mutableAccessNotAllowed() { {5.0f, false} }; - AnimationData data{{}, keyframes, Containers::Array{Containers::InPlaceInit, { + AnimationData data{{}, keyframes, { {AnimationTrackTargetType(129), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, - }}}; + }}; CORRADE_COMPARE(data.dataFlags(), DataFlags{}); std::ostringstream out; @@ -554,15 +550,15 @@ void AnimationDataTest::trackCustomResultType() { view[0] = {0.0f, {300, 100, 10}}; view[1] = {5.0f, {30, 60, 100}}; - AnimationData data{std::move(buffer), Containers::Array{Containers::InPlaceInit, { + AnimationData data{std::move(buffer), { {AnimationTrackTargetType::Scaling3D, 0, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, {view, &view[0].position, view.size(), sizeof(Data)}, [](const Vector3i& a, const Vector3i& b, Float t) -> Vector3 { return Math::lerp(Vector3{a}*0.01f, Vector3{b}*0.01f, t); - }}}} - }}; + }}} + }}; CORRADE_COMPARE((data.track(0).at(2.5f)), (Vector3{1.65f, 0.8f, 0.55f})); } @@ -590,11 +586,11 @@ void AnimationDataTest::trackWrongType() { std::ostringstream out; Error redirectError{&out}; - AnimationData data{nullptr, Containers::Array{Containers::InPlaceInit, { + AnimationData data{nullptr, { {AnimationTrackType::Vector3i, AnimationTrackType::Vector3, AnimationTrackTargetType::Scaling3D, 0, {}} - }}}; + }}; data.track(0); @@ -605,11 +601,11 @@ void AnimationDataTest::trackWrongResultType() { std::ostringstream out; Error redirectError{&out}; - AnimationData data{nullptr, Containers::Array{Containers::InPlaceInit, { + AnimationData data{nullptr, { {AnimationTrackType::Vector3i, AnimationTrackType::Vector3, AnimationTrackTargetType::Scaling3D, 0, {}} - }}}; + }}; data.track(0); @@ -622,10 +618,10 @@ void AnimationDataTest::release() { {5.0f, false} }; - AnimationData data{{}, keyframes, Containers::Array{Containers::InPlaceInit, { + AnimationData data{{}, keyframes, { {AnimationTrackTargetType(129), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, - }}}; + }}; CORRADE_COMPARE(data.trackCount(), 1); Containers::Array released = data.release();