diff --git a/doc/changelog.dox b/doc/changelog.dox index 811235ec5..00e714173 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -48,6 +48,9 @@ See also: @ref Animation::unpack(), @ref Animation::unpackEase() and @ref Animation::unpackEaseClamped() utilities for combining interpolators with easing functions and/or unpackers +- @ref Animation::Player::resume() that acts the same as + @ref Animation::Player::play() "play()" except it doesn't restart the + animation from the start if it is already playing @subsubsection changelog-latest-new-math Math library diff --git a/src/Magnum/Animation/Player.h b/src/Magnum/Animation/Player.h index 9e35022e6..471f1afce 100644 --- a/src/Magnum/Animation/Player.h +++ b/src/Magnum/Animation/Player.h @@ -637,6 +637,14 @@ template& play(T startTime); + /** + * @brief Resume + * + * Behaves similarly to @ref play(), but doesn't restart the animation + * from the beginning when @ref state() is already @ref State::Playing. + */ + Player& resume(T startTime); + /** * @brief Pause * diff --git a/src/Magnum/Animation/Player.hpp b/src/Magnum/Animation/Player.hpp index 1f933bb6e..7930c9828 100644 --- a/src/Magnum/Animation/Player.hpp +++ b/src/Magnum/Animation/Player.hpp @@ -118,6 +118,11 @@ template Player& Player::play(T startTime) { return *this; } +template Player& Player::resume(T startTime) { + if(_state == State::Playing) return *this; + return play(startTime); +} + template Player& Player::pause(T pauseTime) { /* Avoid breaking the pause state when not playing */ if(_state != State::Playing) return *this; diff --git a/src/Magnum/Animation/Test/PlayerTest.cpp b/src/Magnum/Animation/Test/PlayerTest.cpp index a4a066479..887bef9e1 100644 --- a/src/Magnum/Animation/Test/PlayerTest.cpp +++ b/src/Magnum/Animation/Test/PlayerTest.cpp @@ -48,6 +48,7 @@ struct PlayerTest: TestSuite::Tester { void advanceNotRunning(); void advancePlaying(); void advanceRestart(); + void advanceResume(); void advanceStop(); void advancePauseResume(); void advancePauseStop(); @@ -129,6 +130,7 @@ PlayerTest::PlayerTest() { &PlayerTest::advanceNotRunning, &PlayerTest::advancePlaying, &PlayerTest::advanceRestart, + &PlayerTest::advanceResume, &PlayerTest::advanceStop, &PlayerTest::advancePauseResume, &PlayerTest::advancePauseStop, @@ -430,6 +432,43 @@ void PlayerTest::advanceRestart() { CORRADE_COMPARE(value, 2.5f); } +void PlayerTest::advanceResume() { + /* A variant of advanceRestart() that doesn't restart */ + + Float value = -1.0f; + Player player; + player.add(Track, value) + .resume(2.0f); + + CORRADE_COMPARE(player.state(), State::Playing); + CORRADE_COMPARE(player.elapsed(0.0f), std::make_pair(0, 0.0f)); + CORRADE_COMPARE(value, -1.0f); + + /* Still before starting time, nothing is done */ + player.advance(1.75f); + CORRADE_COMPARE(player.state(), State::Playing); + CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f)); + CORRADE_COMPARE(value, -1.0f); + + /* 1.75 secs in */ + player.advance(3.75f); + CORRADE_COMPARE(player.state(), State::Playing); + CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f)); + CORRADE_COMPARE(value, 4.0f); + + /* Calling resume() will not restart from the beginning */ + value = -1.0f; + player.resume(4.0f); + CORRADE_COMPARE(player.state(), State::Playing); + CORRADE_COMPARE(player.elapsed(4.0f), std::make_pair(0, 2.0f)); + CORRADE_COMPARE(value, -1.0f); + + player.advance(4.5f); + CORRADE_COMPARE(player.state(), State::Playing); + CORRADE_COMPARE(player.elapsed(4.5f), std::make_pair(0, 2.5f)); + CORRADE_COMPARE(value, 3.5f); +} + void PlayerTest::advanceStop() { Float value = -1.0f; Player player;