Browse Source

Animation: pausing animation should never result in a stopped state.

inverted-ranges
Vladimír Vondruš 8 years ago
parent
commit
65b870dfc8
  1. 5
      src/Magnum/Animation/Player.h
  2. 16
      src/Magnum/Animation/Player.hpp
  3. 64
      src/Magnum/Animation/Test/PlayerTest.cpp

5
src/Magnum/Animation/Player.h

@ -635,8 +635,9 @@ template<class T, class K
*
* Pauses the currently playing animation at given @p pauseTime. If
* @ref state() is not @ref State::Playing, the function does nothing.
* See @ref advance() for a detailed description of behavior when the
* animation gets paused.
* If @p pauseTime is too far in the future, the animation will get
* paused at the end (i.e., not stopped). See @ref advance() for a
* detailed description of behavior when the animation gets paused.
* @see @ref setState()
*/
Player<T, K>& pause(T pauseTime);

16
src/Magnum/Animation/Player.hpp

@ -183,7 +183,7 @@ template<class T, class K> Containers::Optional<std::pair<UnsignedInt, K>> playe
key = K{};
playIteration = 0;
if(playCount != 0) {
state = State::Stopped;
if(state != State::Paused) state = State::Stopped;
startTime = {};
}
@ -193,7 +193,7 @@ template<class T, class K> Containers::Optional<std::pair<UnsignedInt, K>> playe
} else {
std::tie(playIteration, key) = scaler(timeToUse, duration);
if(playCount && playIteration >= playCount) {
state = State::Stopped;
if(state != State::Paused) state = State::Stopped;
/* Don't reset the startTime to disambiguate between explicitly
stopped and "time run out" animation */
playIteration = playCount - 1;
@ -217,9 +217,15 @@ template<class T, class K> std::pair<UnsignedInt, K> Player<T, K>::elapsed(const
if(elapsed) return *elapsed;
/* If not advancing, the animation can be paused -- calculate the iteration
index and keyframe at which it was paused if the duration is nonzero. */
if(_state == State::Paused && duration)
return _scaler(_startTime, duration);
index and keyframe at which it was paused if the duration is nonzero. If
the paused animation ran out, return the last iteration index and the
duration, otherwise just the calculated value. */
if(_state == State::Paused && duration) {
const std::pair<UnsignedInt, K> elapsed = _scaler(_startTime, duration);
if(_playCount && elapsed.first >= _playCount)
return {_playCount - 1, duration};
return elapsed;
}
/* It can be also stopped by running out, in that case return the last
iteration index and the duration. Again have to use comparison to

64
src/Magnum/Animation/Test/PlayerTest.cpp

@ -56,8 +56,10 @@ struct PlayerTest: TestSuite::Tester {
void advancePlayCount();
void advancePlayCountInfinite();
void advanceChrono();
void advanceZeroDuration();
void advanceZeroDurationChrono();
void advanceZeroDurationStop();
void advanceZeroDurationPause();
void advanceZeroDurationInfinitePlayCount();
void advanceZeroDurationInfinitePlayCountChrono();
void setState();
@ -125,8 +127,10 @@ PlayerTest::PlayerTest() {
&PlayerTest::advancePlayCount,
&PlayerTest::advancePlayCountInfinite,
&PlayerTest::advanceChrono,
&PlayerTest::advanceZeroDuration,
&PlayerTest::advanceZeroDurationChrono,
&PlayerTest::advanceZeroDurationStop,
&PlayerTest::advanceZeroDurationPause,
&PlayerTest::advanceZeroDurationInfinitePlayCount,
&PlayerTest::advanceZeroDurationInfinitePlayCountChrono,
&PlayerTest::setState,
@ -573,14 +577,14 @@ void PlayerTest::advancePauseTooLate() {
CORRADE_COMPARE(player.elapsed(23.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f);
/* Pausing too late will set the state to paused at first */
/* Pausing too late will set the state to paused */
player.pause(50.0f);
CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(50.0f), std::make_pair(0, 3.0f));
/* But advancing will make it stopped since it's too late */
/* And advancing will keep it paused, not transforming to stopped */
player.advance(50.5f);
CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(50.5f), std::make_pair(0, 3.0f));
}
@ -696,7 +700,49 @@ void PlayerTest::advanceChrono() {
CORRADE_COMPARE(value, 4.0f);
}
void PlayerTest::advanceZeroDuration() {
void PlayerTest::advanceZeroDurationStop() {
Float value = -1.0f;
Player<Float> player;
player.add(Track, value)
/* 1.75 secs since the start of the original duration */
.setDuration(Range1D::fromSize(1.0f + 1.75f, 0.0f))
.play(2.0f);
CORRADE_COMPARE(player.duration().size(), 0.0f);
CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f);
/* The value at 1.75 secs is returned independent of time, state is stopped */
player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, 4.0f);
}
void PlayerTest::advanceZeroDurationPause() {
Float value = -1.0f;
Player<Float> player;
player.add(Track, value)
/* 1.75 secs since the start of the original duration */
.setDuration(Range1D::fromSize(1.0f + 1.75f, 0.0f))
.play(2.0f);
CORRADE_COMPARE(player.duration().size(), 0.0f);
CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f);
/* The value at 1.75 secs is returned independent of time, state is paused
(explicitly not stopped) */
player.pause(100.0f);
player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, 4.0f);
}
void PlayerTest::advanceZeroDurationInfinitePlayCount() {
Float value = -1.0f;
Player<Float> player;
player.add(Track, value)
@ -723,7 +769,7 @@ void PlayerTest::advanceZeroDuration() {
CORRADE_COMPARE(value, 4.0f);
}
void PlayerTest::advanceZeroDurationChrono() {
void PlayerTest::advanceZeroDurationInfinitePlayCountChrono() {
Float value = -1.0f;
Player<std::chrono::nanoseconds, Float> player;
player.add(Track, value)

Loading…
Cancel
Save