From 51fa67412ab3d90a22c57a2a9e5e6244dd08c921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 27 Jul 2018 10:28:18 +0200 Subject: [PATCH] Animation: TrackViewStorage doesn't need to be *that* type-erased. Moreover, this will prevent from passing e.g. integer-based keys to Trade::AnimationData. And this also now allows me to add duration() to Trade::AnimationData. I also moved all accessors that don't need a concrete value type to this base class. --- src/Magnum/Animation/Animation.h | 2 +- src/Magnum/Animation/Test/TrackViewTest.cpp | 2 +- src/Magnum/Animation/Track.h | 131 ++++++++++---------- src/Magnum/Trade/AnimationData.h | 6 +- 4 files changed, 73 insertions(+), 68 deletions(-) diff --git a/src/Magnum/Animation/Animation.h b/src/Magnum/Animation/Animation.h index 4852f55ca..d2792b545 100644 --- a/src/Magnum/Animation/Animation.h +++ b/src/Magnum/Animation/Animation.h @@ -44,7 +44,7 @@ enum class Interpolation: UnsignedByte; enum class Extrapolation: UnsignedByte; template> class Track; -class TrackViewStorage; +template class TrackViewStorage; template> class TrackView; }} diff --git a/src/Magnum/Animation/Test/TrackViewTest.cpp b/src/Magnum/Animation/Test/TrackViewTest.cpp index 3e69bc95d..199f537b9 100644 --- a/src/Magnum/Animation/Test/TrackViewTest.cpp +++ b/src/Magnum/Animation/Test/TrackViewTest.cpp @@ -366,7 +366,7 @@ void TrackViewTest::constructCopyStorage() { const TrackView a{data, Interpolation::Constant, customLerp, Extrapolation::Extrapolated, Extrapolation::DefaultConstructed}; - const TrackViewStorage b = a; + const TrackViewStorage b = a; auto& bv = *static_cast*>(&b); diff --git a/src/Magnum/Animation/Track.h b/src/Magnum/Animation/Track.h index f0c0026fb..a2f6f7d4c 100644 --- a/src/Magnum/Animation/Track.h +++ b/src/Magnum/Animation/Track.h @@ -418,19 +418,73 @@ template class TrackViewStorage { public: + /** @brief Key type */ + typedef K KeyType; + constexpr /*implicit*/ TrackViewStorage() noexcept: _keys{}, _values{}, _interpolator{}, _interpolation{}, _before{}, _after{} {} + /** + * @brief Interpolation behavior + * + * Acts as a behavior hint to users that might want to supply their own + * interpolator function to @ref TrackView::at() or + * @ref TrackView::atStrict(). + * @see @ref TrackView::interpolator() + */ + Interpolation interpolation() const { return _interpolation; } + + /** + * @brief Extrapolation behavior before first keyframe + * + * @see @ref TrackView::after(), @ref TrackView::at(), + * @ref TrackView::atStrict() + */ + Extrapolation before() const { return _before; } + + /** + * @brief Extrapolation behavior after last keyframe + * + * @see @ref TrackView::before(), @ref TrackView::at(), + * @ref TrackView::atStrict() + */ + Extrapolation after() const { return _after; } + + /** + * @brief Duration of the track + * + * Calculated from first and last keyframe. If there are no keyframes, + * a default-constructed value is returned. Use @ref Math::join() to + * calculate combined duration for a set of tracks. + */ + Math::Range1D duration() const { + return _keys.empty() ? Math::Range1D{} : Math::Range1D{_keys.front(), _keys.back()}; + } + + /** @brief Keyframe count */ + std::size_t size() const { + return _keys.size(); + } + + /** + * @brief Key data + * + * @see @ref TrackView::values(), @ref TrackView::operator[]() + */ + Containers::StridedArrayView keys() const { + return _keys; + } + private: template friend class TrackView; - template explicit TrackViewStorage(const Containers::StridedArrayView& keys, const Containers::StridedArrayView& values, Interpolation interpolation, R(*interpolator)(const V&, const V&, Float), Extrapolation before, Extrapolation after) noexcept: _keys{reinterpret_cast&>(keys)}, _values{reinterpret_cast&>(values)}, _interpolator{reinterpret_cast(interpolator)}, _interpolation{interpolation}, _before{before}, _after{after} {} + template explicit TrackViewStorage(const Containers::StridedArrayView& keys, const Containers::StridedArrayView& values, Interpolation interpolation, R(*interpolator)(const V&, const V&, Float), Extrapolation before, Extrapolation after) noexcept: _keys{keys}, _values{reinterpret_cast&>(values)}, _interpolator{reinterpret_cast(interpolator)}, _interpolation{interpolation}, _before{before}, _after{after} {} - Containers::StridedArrayView _keys; + Containers::StridedArrayView _keys; Containers::StridedArrayView _values; void(*_interpolator)(void); Interpolation _interpolation; @@ -451,11 +505,8 @@ template #endif -> class TrackView: public TrackViewStorage { +> class TrackView: public TrackViewStorage { public: - /** @brief Key type */ - typedef K KeyType; - /** @brief Value type */ typedef V ValueType; @@ -489,7 +540,7 @@ template&, const Containers::StridedArrayView&, Interpolation, Extrapolation, Extrapolation) * for an alternative. */ - explicit TrackView(const Containers::StridedArrayView& keys, const Containers::StridedArrayView& values, Interpolator interpolator, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{keys, values, Interpolation::Custom, interpolator, before, after} {} + explicit TrackView(const Containers::StridedArrayView& keys, const Containers::StridedArrayView& values, Interpolator interpolator, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{keys, values, Interpolation::Custom, interpolator, before, after} {} /** @overload * Equivalent to calling @ref TrackView(const Containers::StridedArrayView&, const Containers::StridedArrayView&, Interpolator, Extrapolation, Extrapolation) @@ -530,7 +581,7 @@ template& keys, const Containers::StridedArrayView& values, Interpolation interpolation, Interpolator interpolator, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{keys, values, interpolation, interpolator, before, after} {} + explicit TrackView(const Containers::StridedArrayView& keys, const Containers::StridedArrayView& values, Interpolation interpolation, Interpolator interpolator, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{keys, values, interpolation, interpolator, before, after} {} /** @overload * Equivalent to calling @ref TrackView(const Containers::StridedArrayView&, const Containers::StridedArrayView&, Interpolation, Interpolator, Extrapolation, Extrapolation) @@ -549,7 +600,7 @@ template&, const Containers::StridedArrayView&, Interpolator, Extrapolation, Extrapolation). */ - explicit TrackView(Containers::ArrayView> data, Interpolation interpolation, Interpolator interpolator, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{Containers::StridedArrayView{data ? &data[0].first : nullptr, data.size(), sizeof(std::pair)}, Containers::StridedArrayView{data ? &data[0].second : nullptr, data.size(), sizeof(std::pair)}, interpolation, interpolator, before, after} {} + explicit TrackView(Containers::ArrayView> data, Interpolation interpolation, Interpolator interpolator, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{Containers::StridedArrayView{data ? &data[0].first : nullptr, data.size(), sizeof(std::pair)}, Containers::StridedArrayView{data ? &data[0].second : nullptr, data.size(), sizeof(std::pair)}, interpolation, interpolator, before, after} {} /** @overload * Equivalent to calling @ref TrackView(Containers::ArrayView>, Interpolation, Interpolator, Extrapolation, Extrapolation) @@ -571,7 +622,7 @@ template& keys, const Containers::StridedArrayView& values, Interpolation interpolation, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{keys, values, interpolation, interpolatorFor(interpolation), before, after} {} + explicit TrackView(const Containers::StridedArrayView& keys, const Containers::StridedArrayView& values, Interpolation interpolation, Extrapolation before, Extrapolation after) noexcept: TrackViewStorage{keys, values, interpolation, interpolatorFor(interpolation), before, after} {} /** @overload * Equivalent to calling @ref TrackView(const Containers::StridedArrayView&, const Containers::StridedArrayView&, Interpolation, Extrapolation, Extrapolation) @@ -597,59 +648,13 @@ template> data, Interpolation interpolation, Extrapolation extrapolation = Extrapolation::Extrapolated) noexcept: TrackView{data, interpolation, extrapolation, extrapolation} {} - /** - * @brief Interpolation behavior - * - * Acts as a behavior hint to users that might want to supply their own - * interpolator function to @ref at() or @ref atStrict(). - * @see @ref interpolator() - */ - Interpolation interpolation() const { return _interpolation; } - /** * @brief Interpolation function * * @see @ref interpolation() */ Interpolator interpolator() const { - return reinterpret_cast(_interpolator); - } - - /** - * @brief Extrapolation behavior before first keyframe - * - * @see @ref after(), @ref at(), @ref atStrict() - */ - Extrapolation before() const { return _before; } - - /** - * @brief Extrapolation behavior after last keyframe - * - * @see @ref before(), @ref at(), @ref atStrict() - */ - Extrapolation after() const { return _after; } - - /** - * @brief Duration of the track - * - * Calculated from first and last keyframe. If there are no keyframes, - * a default-constructed value is returned. Use @ref Math::join() to - * calculate combined duration for a set of tracks. - */ - Math::Range1D duration() const { - return _keys.empty() ? Math::Range1D{} : Math::Range1D{keys().front(), keys().back()}; - } - - /** @brief Keyframe count */ - std::size_t size() const { return _keys.size(); } - - /** - * @brief Key data - * - * @see @ref values(), @ref operator[]() - */ - Containers::StridedArrayView keys() const { - return reinterpret_cast&>(_keys); + return reinterpret_cast(TrackViewStorage::_interpolator); } /** @@ -658,7 +663,7 @@ template values() const { - return reinterpret_cast&>(_values); + return reinterpret_cast&>(TrackViewStorage::_values); } /** @@ -667,7 +672,7 @@ template operator[](std::size_t i) const { - return {keys()[i], values()[i]}; + return {TrackViewStorage::_keys[i], values()[i]}; } /** @@ -719,7 +724,7 @@ template::_keys, values(), TrackViewStorage::_before, TrackViewStorage::_after, interpolator, frame, hint); } /** @@ -743,7 +748,7 @@ template::_keys, values(), interpolator, frame, hint); } }; diff --git a/src/Magnum/Trade/AnimationData.h b/src/Magnum/Trade/AnimationData.h index 259b46a6e..13ba5cf22 100644 --- a/src/Magnum/Trade/AnimationData.h +++ b/src/Magnum/Trade/AnimationData.h @@ -180,14 +180,14 @@ class AnimationTrackData { * @param targetId Track target ID * @param view Type-erased @ref Animation::TrackView instance */ - /*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackType resultType, AnimationTrackTarget target, UnsignedInt targetId, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{resultType}, _target{target}, _targetId{targetId}, _view{view} {} + /*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackType resultType, AnimationTrackTarget target, UnsignedInt targetId, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{resultType}, _target{target}, _targetId{targetId}, _view{view} {} /** @overload * * Equivalent to the above with @p type used as both value type and * result type. */ - /*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackTarget target, UnsignedInt targetId, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{type}, _target{target}, _targetId{targetId}, _view{view} {} + /*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackTarget target, UnsignedInt targetId, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{type}, _target{target}, _targetId{targetId}, _view{view} {} private: friend AnimationData; @@ -195,7 +195,7 @@ class AnimationTrackData { AnimationTrackType _type, _resultType; AnimationTrackTarget _target; UnsignedInt _targetId; - Animation::TrackViewStorage _view; + Animation::TrackViewStorage _view; }; /**