From c04b375bfc81141fda19cd22187f606c09880d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 5 Apr 2023 16:25:20 +0200 Subject: [PATCH] Trade: add isAnimationTrackTargetCustom() etc. helpers. For consistency with what's already done for MeshAttribute and SceneField. The ::Custom enum value is deprecated in favor of these, the only actually breaking change is that the debug printer now subtracts 32768 for custom values (consistently with custom mesh attributes and scene fields), while it printed the absolute enum value before. --- src/Magnum/Trade/AnimationData.cpp | 8 ++- src/Magnum/Trade/AnimationData.h | 71 ++++++++++++++++++-- src/Magnum/Trade/Test/AnimationDataTest.cpp | 72 +++++++++++++++++---- 3 files changed, 131 insertions(+), 20 deletions(-) diff --git a/src/Magnum/Trade/AnimationData.cpp b/src/Magnum/Trade/AnimationData.cpp index b965d8258..f8fa56134 100644 --- a/src/Magnum/Trade/AnimationData.cpp +++ b/src/Magnum/Trade/AnimationData.cpp @@ -198,8 +198,8 @@ Debug& operator<<(Debug& debug, const AnimationTrackTarget value) { if(!packed) debug << "Trade::AnimationTrackTarget" << Debug::nospace; - if(UnsignedShort(value) >= UnsignedShort(AnimationTrackTarget::Custom)) - return debug << (packed ? "Custom(" : "::Custom(") << Debug::nospace << UnsignedShort(value) << Debug::nospace << ")"; + if(isAnimationTrackTargetCustom(value)) + return debug << (packed ? "Custom(" : "::Custom(") << Debug::nospace << animationTrackTargetCustom(value) << Debug::nospace << ")"; switch(value) { /* LCOV_EXCL_START */ @@ -213,8 +213,12 @@ Debug& operator<<(Debug& debug, const AnimationTrackTarget value) { #undef _c /* LCOV_EXCL_STOP */ + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH /* To silence compiler warnings about unhandled values */ case AnimationTrackTarget::Custom: CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ + CORRADE_IGNORE_DEPRECATED_POP + #endif } return debug << (packed ? "" : "(") << Debug::nospace << reinterpret_cast(UnsignedShort(value)) << Debug::nospace << (packed ? "" : ")"); diff --git a/src/Magnum/Trade/AnimationData.h b/src/Magnum/Trade/AnimationData.h index b3f72c8f9..c286bce85 100644 --- a/src/Magnum/Trade/AnimationData.h +++ b/src/Magnum/Trade/AnimationData.h @@ -165,10 +165,23 @@ enum class AnimationTrackType: UnsignedByte { /** @debugoperatorenum{AnimationTrackType} */ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, AnimationTrackType value); +namespace Implementation { + enum: UnsignedShort { AnimationTrackTargetCustom = 32768 }; +} + /** @brief Target of an animation track -@see @ref AnimationData +See @ref AnimationData for more information. + +Apart from builtin target types it's possible to have custom ones, which use +the upper half of the enum range. Those are detected via +@ref isAnimationTrackTargetCustom() and can be converted to and from a +numeric identifier using @ref animationTrackTargetCustom(AnimationTrackTarget) +and @ref animationTrackTargetCustom(UnsignedShort). Unlike the builtin ones, +these can be of any type and @ref AnimationData::trackTarget() might or might +not point to an existing object. +@see @ref AnimationTrackData @experimental */ enum class AnimationTrackTarget: UnsignedShort { @@ -246,13 +259,15 @@ enum class AnimationTrackTarget: UnsignedShort { */ Scaling3D, + #ifdef MAGNUM_BUILD_DEPRECATED /** - * This and all higher values are for importer-specific targets. Can be of - * any type, @ref AnimationData::trackTarget() might or might not point to - * an existing object. See documentation of a particular importer for - * details. + * This and all higher values are for importer-specific targets. + * + * @m_deprecated_since_latest Use @ref animationTrackTargetCustom() and + * @ref isAnimationTrackTargetCustom() instead. */ - Custom = 32768 + Custom CORRADE_DEPRECATED_ENUM("use animationTrackTargetCustom() instead") = Implementation::AnimationTrackTargetCustom + #endif }; #ifdef MAGNUM_BUILD_DEPRECATED @@ -266,6 +281,50 @@ typedef CORRADE_DEPRECATED("use AnimationTrackTarget instead") AnimationTrackTar /** @debugoperatorenum{AnimationTrackTarget} */ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, AnimationTrackTarget value); +/** +@brief Whether a target for an animation track is custom +@m_since_latest + +Returns @cpp true @ce if @p name has a value in the upper 15 bits of the enum +range, @cpp false @ce otherwise. +@see @ref animationTrackTargetCustom(UnsignedShort), + @ref animationTrackTargetCustom(AnimationTrackTarget) +*/ +constexpr bool isAnimationTrackTargetCustom(AnimationTrackTarget name) { + return UnsignedShort(name) >= Implementation::AnimationTrackTargetCustom; +} + +/** +@brief Create a custom target for an animation track +@m_since_latest + +Returns a custom animation track target with index @p id. The index is expected +to fit into 15 bits. Use +@ref animationTrackTargetCustom(AnimationTrackTarget) to get the index +back. +*/ +/* Constexpr so it's usable for creating compile-time AnimationData + instances */ +constexpr AnimationTrackTarget animationTrackTargetCustom(UnsignedShort id) { + return CORRADE_CONSTEXPR_ASSERT(id < Implementation::AnimationTrackTargetCustom, + "Trade::animationTrackTargetCustom(): index" << id << "too large"), + AnimationTrackTarget(Implementation::AnimationTrackTargetCustom + id); +} + +/** +@brief Get index of a custom target for an animation track +@m_since_latest + +Inverse to @ref animationTrackTargetCustom(UnsignedShort). Expects that the +type is custom. +@see @ref isAnimationTrackTargetCustom() +*/ +constexpr UnsignedShort animationTrackTargetCustom(AnimationTrackTarget name) { + return CORRADE_CONSTEXPR_ASSERT(isAnimationTrackTargetCustom(name), + "Trade::animationTrackTargetCustom():" << name << "is not custom"), + UnsignedShort(name) - Implementation::AnimationTrackTargetCustom; +} + /** @brief Animation track data diff --git a/src/Magnum/Trade/Test/AnimationDataTest.cpp b/src/Magnum/Trade/Test/AnimationDataTest.cpp index 7298e760d..3234603a2 100644 --- a/src/Magnum/Trade/Test/AnimationDataTest.cpp +++ b/src/Magnum/Trade/Test/AnimationDataTest.cpp @@ -38,6 +38,10 @@ struct AnimationDataTest: TestSuite::Tester { void debugTrackType(); void debugTrackTypePacked(); + + void customTrackTarget(); + void customTrackTargetTooLarge(); + void customTrackTargetNotCustom(); void debugTrackTarget(); void debugTrackTargetPacked(); @@ -78,6 +82,10 @@ struct { AnimationDataTest::AnimationDataTest() { addTests({&AnimationDataTest::debugTrackType, &AnimationDataTest::debugTrackTypePacked, + + &AnimationDataTest::customTrackTarget, + &AnimationDataTest::customTrackTargetTooLarge, + &AnimationDataTest::customTrackTargetNotCustom, &AnimationDataTest::debugTrackTarget, &AnimationDataTest::debugTrackTargetPacked, @@ -126,18 +134,58 @@ void AnimationDataTest::debugTrackTypePacked() { CORRADE_COMPARE(out.str(), "DualQuaternion 0xde Trade::AnimationTrackType::Float\n"); } +void AnimationDataTest::customTrackTarget() { + CORRADE_VERIFY(!isAnimationTrackTargetCustom(AnimationTrackTarget::Rotation3D)); + CORRADE_VERIFY(!isAnimationTrackTargetCustom(AnimationTrackTarget(32767))); + CORRADE_VERIFY(isAnimationTrackTargetCustom(AnimationTrackTarget(Implementation::AnimationTrackTargetCustom))); + CORRADE_VERIFY(isAnimationTrackTargetCustom(AnimationTrackTarget(65535))); + + CORRADE_COMPARE(UnsignedShort(animationTrackTargetCustom(0)), 32768); + CORRADE_COMPARE(UnsignedShort(animationTrackTargetCustom(8290)), 41058); + CORRADE_COMPARE(UnsignedShort(animationTrackTargetCustom(32767)), 65535); + + CORRADE_COMPARE(animationTrackTargetCustom(AnimationTrackTarget(Implementation::AnimationTrackTargetCustom)), 0); + CORRADE_COMPARE(animationTrackTargetCustom(AnimationTrackTarget(41058)), 8290); + CORRADE_COMPARE(animationTrackTargetCustom(AnimationTrackTarget(65535)), 32767); + + constexpr bool is = isAnimationTrackTargetCustom(AnimationTrackTarget(41058)); + CORRADE_VERIFY(is); + constexpr AnimationTrackTarget a = animationTrackTargetCustom(8290); + CORRADE_COMPARE(UnsignedShort(a), 41058); + constexpr UnsignedShort b = animationTrackTargetCustom(a); + CORRADE_COMPARE(b, 8290); +} + +void AnimationDataTest::customTrackTargetTooLarge() { + CORRADE_SKIP_IF_NO_ASSERT(); + + std::ostringstream out; + Error redirectError{&out}; + animationTrackTargetCustom(32768); + CORRADE_COMPARE(out.str(), "Trade::animationTrackTargetCustom(): index 32768 too large\n"); +} + +void AnimationDataTest::customTrackTargetNotCustom() { + CORRADE_SKIP_IF_NO_ASSERT(); + + std::ostringstream out; + Error redirectError{&out}; + animationTrackTargetCustom(AnimationTrackTarget::Translation2D); + CORRADE_COMPARE(out.str(), "Trade::animationTrackTargetCustom(): Trade::AnimationTrackTarget::Translation2D is not custom\n"); +} + void AnimationDataTest::debugTrackTarget() { std::ostringstream out; - Debug{&out} << AnimationTrackTarget::Rotation3D << AnimationTrackTarget(32777) << AnimationTrackTarget(0x4242); - CORRADE_COMPARE(out.str(), "Trade::AnimationTrackTarget::Rotation3D Trade::AnimationTrackTarget::Custom(32777) Trade::AnimationTrackTarget(0x4242)\n"); + Debug{&out} << AnimationTrackTarget::Rotation3D << animationTrackTargetCustom(9) << AnimationTrackTarget(0x4242); + CORRADE_COMPARE(out.str(), "Trade::AnimationTrackTarget::Rotation3D Trade::AnimationTrackTarget::Custom(9) Trade::AnimationTrackTarget(0x4242)\n"); } void AnimationDataTest::debugTrackTargetPacked() { std::ostringstream out; /* Last is not packed, ones before should not make any flags persistent */ - Debug{&out} << Debug::packed << AnimationTrackTarget::Rotation3D << Debug::packed << AnimationTrackTarget(32888) << Debug::packed << AnimationTrackTarget(0x4242) << AnimationTrackType::Float; - CORRADE_COMPARE(out.str(), "Rotation3D Custom(32888) 0x4242 Trade::AnimationTrackType::Float\n"); + Debug{&out} << Debug::packed << AnimationTrackTarget::Rotation3D << Debug::packed << animationTrackTargetCustom(120) << Debug::packed << AnimationTrackTarget(0x4242) << AnimationTrackType::Float; + CORRADE_COMPARE(out.str(), "Rotation3D Custom(120) 0x4242 Trade::AnimationTrackType::Float\n"); } void AnimationDataTest::constructTrack() { @@ -277,12 +325,12 @@ void AnimationDataTest::constructImplicitDuration() { const int state = 5; AnimationData data{std::move(buffer), { - AnimationTrackData{AnimationTrackTarget(32769), 0, + AnimationTrackData{animationTrackTargetCustom(1), 0, Animation::TrackView{ {view, &view[0].time, 2, sizeof(Data)}, {view, &view[0].value, 2, sizeof(Data)}, Animation::Interpolation::Constant}}, - AnimationTrackData{AnimationTrackTarget(32770), 1, + AnimationTrackData{animationTrackTargetCustom(2), 1, Animation::TrackView{ {view, &view[2].time, 2, sizeof(Data)}, {view, &view[2].value, 2, sizeof(Data)}, @@ -296,7 +344,7 @@ void AnimationDataTest::constructImplicitDuration() { { CORRADE_COMPARE(data.trackType(0), AnimationTrackType::Bool); CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Bool); - CORRADE_COMPARE(data.trackTargetName(0), AnimationTrackTarget(32769)); + CORRADE_COMPARE(data.trackTargetName(0), animationTrackTargetCustom(1)); CORRADE_COMPARE(data.trackTarget(0), 0); Animation::TrackView track = data.track(0); @@ -315,7 +363,7 @@ void AnimationDataTest::constructImplicitDuration() { } { CORRADE_COMPARE(data.trackType(1), AnimationTrackType::Bool); CORRADE_COMPARE(data.trackResultType(1), AnimationTrackType::Bool); - CORRADE_COMPARE(data.trackTargetName(1), AnimationTrackTarget(32770)); + CORRADE_COMPARE(data.trackTargetName(1), animationTrackTargetCustom(2)); CORRADE_COMPARE(data.trackTarget(1), 1); Animation::TrackView track = data.track(1); @@ -393,7 +441,7 @@ void AnimationDataTest::constructImplicitDurationNotOwned() { const int state = 5; AnimationData data{instanceData.dataFlags, keyframes, { - AnimationTrackData{AnimationTrackTarget(32769), 0, + AnimationTrackData{animationTrackTargetCustom(1), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, }, &state}; @@ -408,7 +456,7 @@ void AnimationDataTest::constructImplicitDurationNotOwned() { { CORRADE_COMPARE(data.trackType(0), AnimationTrackType::Bool); CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Bool); - CORRADE_COMPARE(data.trackTargetName(0), AnimationTrackTarget(32769)); + CORRADE_COMPARE(data.trackTargetName(0), animationTrackTargetCustom(1)); CORRADE_COMPARE(data.trackTarget(0), 0); Animation::TrackView track = data.track(0); @@ -560,7 +608,7 @@ void AnimationDataTest::mutableAccessNotAllowed() { }; AnimationData data{{}, keyframes, { - AnimationTrackData{AnimationTrackTarget(32769), 0, + AnimationTrackData{animationTrackTargetCustom(1), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, }}; CORRADE_COMPARE(data.dataFlags(), DataFlags{}); @@ -668,7 +716,7 @@ void AnimationDataTest::release() { }; AnimationData data{{}, keyframes, { - AnimationTrackData{AnimationTrackTarget(32769), 0, + AnimationTrackData{animationTrackTargetCustom(1), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, }}; CORRADE_COMPARE(data.trackCount(), 1);