Browse Source

Animation: added Player::elapsed().

It's not working exactly as it should yet, but the proper update
wouldn't apply so cleanly, so doing that in the next commit.
pull/255/merge
Vladimír Vondruš 8 years ago
parent
commit
8a71cb6415
  1. 22
      src/Magnum/Animation/Player.h
  2. 72
      src/Magnum/Animation/Player.hpp
  3. 101
      src/Magnum/Animation/Test/PlayerTest.cpp

22
src/Magnum/Animation/Player.h

@ -287,6 +287,7 @@ template<class T, class K
* If the duration was not set explicitly using @ref setDuration(), * If the duration was not set explicitly using @ref setDuration(),
* returns value calculated implicitly from all added tracks. If no * returns value calculated implicitly from all added tracks. If no
* tracks are added, returns default-constructed value. * tracks are added, returns default-constructed value.
* @see @ref elapsed()
*/ */
Math::Range1D<K> duration() const { return _duration; } Math::Range1D<K> duration() const { return _duration; }
@ -593,6 +594,24 @@ template<class T, class K
*/ */
State state() const { return _state; } State state() const { return _state; }
/**
* @brief Elapsed animation iteration and keyframe
*
* Returns repeat iteration index and elapsed animation keyframe in
* given iteration corresponding to @p time. If @ref state() is
* @ref State::Stopped and the player was stopped explicitly, the
* function returns a default-constructed value (usually
* @cpp {0, 0.0f} @ce). If @ref state() is @ref State::Stopped due to
* the animation running out, the function returns the iteration count
* and duration end keyframe. If @ref state() is @ref State::Paused,
* the function returns a time at which the animation was paused.
*
* Unlike @ref advance(), this function doesn't modify the animation
* state in any way, it's merely a query.
* @see @ref duration()
*/
std::pair<UnsignedInt, K> elapsed(T time) const;
/** /**
* @brief Play * @brief Play
* *
@ -677,6 +696,7 @@ template<class T, class K
* to the begin time of @ref duration() to correctly "park" the * to the begin time of @ref duration() to correctly "park" the
* animation back to its initial state. After that, no more updates are * animation back to its initial state. After that, no more updates are
* done until the animation is started again. * done until the animation is started again.
* @see @ref elapsed()
*/ */
Player<T, K>& advance(T time); Player<T, K>& advance(T time);
@ -685,6 +705,8 @@ template<class T, class K
Player<T, K>& addInternal(const TrackViewStorage<K>& track, void (*advancer)(const TrackViewStorage<K>&, K, std::size_t&, void*, void(*)(), void*), void* destination, void(*userCallback)(), void* userCallbackData); Player<T, K>& addInternal(const TrackViewStorage<K>& track, void (*advancer)(const TrackViewStorage<K>&, K, std::size_t&, void*, void(*)(), void*), void* destination, void(*userCallback)(), void* userCallbackData);
Containers::Optional<std::pair<UnsignedInt, K>> elapsedInternal(T time, T& updatedStartTime, T& updatedPauseTime, State& updatedState) const;
std::vector<Track> _tracks; std::vector<Track> _tracks;
Math::Range1D<K> _duration; Math::Range1D<K> _duration;
UnsignedInt _playCount{1}; UnsignedInt _playCount{1};

72
src/Magnum/Animation/Player.hpp

@ -31,6 +31,8 @@
#include "Player.h" #include "Player.h"
#include <Corrade/Containers/Optional.h>
namespace Magnum { namespace Animation { namespace Magnum { namespace Animation {
namespace Implementation { namespace Implementation {
@ -140,7 +142,9 @@ template<class T, class K> Player<T, K>& Player<T, K>::setState(State state, T t
CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
template<class T, class K> Player<T, K>& Player<T, K>::advance(T time) { namespace Implementation {
template<class T, class K> Containers::Optional<std::pair<UnsignedInt, K>> playerElapsed(const K duration, const UnsignedInt playCount, const typename Player<T, K>::Scaler scaler, const T time, T& startTime, T& pauseTime, State& state) {
/* Time to use for advancing the animation */ /* Time to use for advancing the animation */
T timeToUse = time; T timeToUse = time;
@ -150,49 +154,81 @@ template<class T, class K> Player<T, K>& Player<T, K>::advance(T time) {
std::chrono::duration doesn't have operator bool, so I need to compare std::chrono::duration doesn't have operator bool, so I need to compare
to default-constructed value. Ugh. */ to default-constructed value. Ugh. */
if(_state == State::Paused && (_pauseTime != T{})) { if(state == State::Paused && (pauseTime != T{})) {
timeToUse = _pauseTime; timeToUse = pauseTime;
_startTime = _pauseTime - _startTime; startTime = pauseTime - startTime;
_pauseTime = {}; pauseTime = {};
/* The animation was stopped by the user right before this iteration, /* The animation was stopped by the user right before this iteration,
"park" the animation to the initial time */ "park" the animation to the initial time */
} else if(_state == State::Stopped && (_startTime != T{})) { } else if(state == State::Stopped && (startTime != T{})) {
_startTime = {}; startTime = {};
timeToUse = {}; timeToUse = {};
/* Otherwise, if the player is not playing or scheduled to start playing in /* Otherwise, if the player is not playing or scheduled to start playing in
the future, do nothing */ the future, do nothing */
} else if(_state != State::Playing || time < _startTime) return *this; } else if(state != State::Playing || time < startTime)
return Containers::NullOpt;
/* If the player duration is empty, we can't call the scaler. If play count /* If the player duration is empty, we can't call the scaler. If play count
is infinite, infinitely advance to a key at duration start. If not, stop is infinite, infinitely advance to a key at duration start. If not, stop
the animation. */ the animation. */
UnsignedInt playIteration;
K key; K key;
const K duration = _duration.size()[0];
if(duration == K{}) { if(duration == K{}) {
key = K{}; key = K{};
if(_playCount != 0) { playIteration = 0;
_state = State::Stopped; if(playCount != 0) {
_startTime = {}; state = State::Stopped;
startTime = {};
} }
/* Otherwise calculate current play iteration and key value in that /* Otherwise calculate current play iteration and key value in that
iteration. If we exceeded play count, stop the animation and give out iteration. If we exceeded play count, stop the animation and give out
value at duration end. */ value at duration end. */
} else { } else {
UnsignedInt playCount; std::tie(playIteration, key) = scaler(timeToUse - startTime, duration);
std::tie(playCount, key) = _scaler(timeToUse - _startTime, duration); if(playCount && playIteration >= playCount) {
if(_playCount && playCount >= _playCount) { state = State::Stopped;
_state = State::Stopped; startTime = {}; /** @todo no? so we can distinguish between stopped by itself and not */
_startTime = {}; playIteration = playCount - 1;
key = duration; key = duration;
} }
} }
return {Containers::InPlaceInit, playIteration, key};
}
}
template<class T, class K> std::pair<UnsignedInt, K> Player<T, K>::elapsed(const T time) const {
/* Get the elapsed time. This is an immutable query, so make copies of the
(otherwise to be modified) internal state. */
T startTime = _startTime;
T pauseTime = _pauseTime;
State state = _state;
const Containers::Optional<std::pair<UnsignedInt, K>> elapsed = Implementation::playerElapsed(_duration.size()[0], _playCount, _scaler, time, startTime, pauseTime, state);
if(elapsed) return *elapsed;
/* If not advancing, the animation can be paused: calculate the keyframe at
which it was paused */
if(state == State::Paused) return _scaler(_startTime, _duration.size()[0]);
/** @todo stopped by itself vs. explicitly */
/* Otherwise the animation is just stopped: return a zero value */
return {0, K{}};
}
template<class T, class K> Player<T, K>& Player<T, K>::advance(const T time) {
/* Get the elapsed time. If we shouldn't advance anything (player already
stopped / not yet playing, quit */
Containers::Optional<std::pair<UnsignedInt, K>> elapsed = Implementation::playerElapsed(_duration.size()[0], _playCount, _scaler, time, _startTime, _pauseTime, _state);
if(!elapsed) return *this;
/* Advance all tracks. Properly handle durations that don't start at 0. */ /* Advance all tracks. Properly handle durations that don't start at 0. */
for(Track& t: _tracks) for(Track& t: _tracks)
t.advancer(t.track, _duration.min()[0] + key, t.hint, t.destination, t.userCallback, t.userCallbackData); t.advancer(t.track, _duration.min()[0] + elapsed->second, t.hint, t.destination, t.userCallback, t.userCallbackData);
return *this; return *this;
} }

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

@ -295,11 +295,17 @@ void PlayerTest::advanceNotRunning() {
player.add(Track, value); player.add(Track, value);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(0.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f);
/* Asking for elapsed doesn't change anything */
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
player.advance(1.75f); player.advance(1.75f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
} }
@ -311,32 +317,58 @@ void PlayerTest::advancePlaying() {
CORRADE_COMPARE(player.duration().size(), 3.0f); CORRADE_COMPARE(player.duration().size(), 3.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(0.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(1.75f); player.advance(1.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f);
/* Asking for elapsed will say it's playing already, but doesn't change
anything */
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* 1.75 secs in */ /* 1.75 secs in */
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* 2.67 secs in */ /* 2.67 secs in */
player.advance(4.6666667f); player.advance(4.666666667f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
/** @todo make std::pair/std::tuple comparisons respect fuzzyness inside */
CORRADE_COMPARE(player.elapsed(4.666666667f).first, 0);
CORRADE_COMPARE(player.elapsed(4.666666667f).second, 2.666666667f);
CORRADE_COMPARE(value, 3.0f); CORRADE_COMPARE(value, 3.0f);
/* When the player gets stopped, the value at the stop time is written */ /* Asking for elapsed will say the stop time, but again doesn't change the
state */
CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(5.5f), std::make_pair(0, 3.0f));
CORRADE_COMPARE(value, 3.0f);
/* When the player gets stopped, the value at the stop time is written.
Elapsed time still shows that it stopped by itself. */
player.advance(5.5f); player.advance(5.5f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
{
CORRADE_EXPECT_FAIL("Not yet implemented.");
CORRADE_COMPARE(player.elapsed(5.5f), std::make_pair(0, 3.0f));
}
CORRADE_COMPARE(value, 2.0f); CORRADE_COMPARE(value, 2.0f);
/* But further advancing will not write anything */ /* But further advancing will not write anything */
value = -1.0f; value = -1.0f;
player.advance(100.0f); player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
{
CORRADE_EXPECT_FAIL("Not yet implemented.");
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 3.0f));
}
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
} }
@ -347,27 +379,32 @@ void PlayerTest::advanceRestart() {
.play(2.0f); .play(2.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(0.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(1.75f); player.advance(1.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* 1.75 secs in */ /* 1.75 secs in */
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* Call play again, will restart from the beginning... */ /* Call play again, will restart from the beginning... */
value = -1.0f; value = -1.0f;
player.play(4.0f); player.play(4.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(4.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* ... but only after calling advance() again. Now at 1 sec in. */ /* ... but only after calling advance() again. Now at 1 sec in. */
player.advance(5.0f); player.advance(5.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(5.0f), std::make_pair(0, 1.0f));
CORRADE_COMPARE(value, 2.5f); CORRADE_COMPARE(value, 2.5f);
} }
@ -379,23 +416,29 @@ void PlayerTest::advanceStop() {
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* Stop, should not update anything */ /* Stop, should not update anything. Elapsed will report a time from the
beginning again. */
value = -1.0; value = -1.0;
player.stop(); player.stop();
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(5.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Advancing will update with a value from beginning of the duration */ /* Advancing will update with a value from beginning of the duration.
Elapsed shows the same. */
player.advance(5.0f); player.advance(5.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(5.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, 1.5f); CORRADE_COMPARE(value, 1.5f);
/* But further advancing will not write anything */ /* But further advancing will not write anything */
value = -1.0f; value = -1.0f;
player.advance(100.0f); player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
} }
@ -406,43 +449,52 @@ void PlayerTest::advancePauseResume() {
.play(2.0f); .play(2.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* Pausing should not update anything */ /* Pausing should not update anything */
value = -1.0f; value = -1.0f;
player.pause(4.0f); player.pause(4.0f);
CORRADE_COMPARE(player.state(), State::Paused); CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(4.0f), std::make_pair(0, 2.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Pausing again should be a no-op */ /* Pausing again should be a no-op */
player.pause(4.1f); player.pause(4.1f);
CORRADE_COMPARE(player.state(), State::Paused); CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(4.1f), std::make_pair(0, 2.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* But advance() after should. No matter what time is passed to it, it /* But advance() after should. No matter what time is passed to it, it
should update with time of pause. */ should update with time of pause. */
player.advance(4.5f); player.advance(4.5f);
CORRADE_COMPARE(player.state(), State::Paused); CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(4.5f), std::make_pair(0, 2.0f));
CORRADE_COMPARE(value, 5.0f); /* value at 2.0f, not 2.5f */ CORRADE_COMPARE(value, 5.0f); /* value at 2.0f, not 2.5f */
/* Advancing further should do nothing */ /* Advancing further should do nothing */
value = -1.0f; value = -1.0f;
player.advance(50.0f); player.advance(50.0f);
CORRADE_COMPARE(player.state(), State::Paused); CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(50.0f), std::make_pair(0, 2.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Resuming the animation, again should not update anything */ /* Resuming the animation, again should not update anything */
player.play(100.0f); player.play(100.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 2.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Advancing the animation should update again. It was paused after two /* Advancing the animation should update again. It was paused after two
seconds, so continuing at 2.5 seconds now. */ seconds, so continuing at 2.5 seconds now. */
player.advance(100.5f); player.advance(100.5f);
CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(100.5f), std::make_pair(0, 2.5f));
CORRADE_COMPARE(value, 3.5f); CORRADE_COMPARE(value, 3.5f);
} }
@ -454,35 +506,41 @@ void PlayerTest::advancePauseStop() {
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* Pause, get value from the pause time */ /* Pause, get value from the pause time */
player.pause(4.0f); player.pause(4.0f);
player.advance(4.5f); player.advance(4.5f);
CORRADE_COMPARE(player.state(), State::Paused); CORRADE_COMPARE(player.state(), State::Paused);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 2.0f));
CORRADE_COMPARE(value, 5.0f); CORRADE_COMPARE(value, 5.0f);
/* Stop, should not update anything */ /* Stop, should not update anything */
value = -1.0; value = -1.0;
player.stop(); player.stop();
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(5.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Advancing will update with a value from beginning of the duration */ /* Advancing will update with a value from beginning of the duration */
player.advance(5.0f); player.advance(5.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(5.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, 1.5f); CORRADE_COMPARE(value, 1.5f);
/* But further advancing will not write anything */ /* But further advancing will not write anything */
value = -1.0f; value = -1.0f;
player.advance(100.0f); player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Pause while stopped is a no-op */ /* Pause while stopped is a no-op */
player.pause(101.0f); player.pause(101.0f);
player.advance(101.0f); player.advance(101.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
CORRADE_COMPARE(player.elapsed(101.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
} }
@ -494,37 +552,50 @@ void PlayerTest::advancePlayCount() {
.play(2.0f); .play(2.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(1.75f); player.advance(1.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* 1.75 secs in */ /* 1.75 secs in */
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* 2 secs in, second round */ /* 2 secs in, second round */
player.advance(7.0f); player.advance(7.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(7.0f), std::make_pair(1, 2.0f));
CORRADE_COMPARE(value, 5.0f); CORRADE_COMPARE(value, 5.0f);
/* 1.75 secs in, third round */ /* 1.75 secs in, third round */
player.advance(9.75f); player.advance(9.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(9.75f), std::make_pair(2, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* When the player gets stopped, the value at the stop time is written */ /* When the player gets stopped, the value at the stop time is written */
player.advance(11.5f); player.advance(11.5f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
{
CORRADE_EXPECT_FAIL("Not yet implemented.");
CORRADE_COMPARE(player.elapsed(11.5f), std::make_pair(2, 3.0f));
}
CORRADE_COMPARE(value, 2.0f); CORRADE_COMPARE(value, 2.0f);
/* But further advancing will not write anything */ /* But further advancing will not write anything */
value = -1.0f; value = -1.0f;
player.advance(100.0f); player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Stopped); CORRADE_COMPARE(player.state(), State::Stopped);
{
CORRADE_EXPECT_FAIL("Not yet implemented.");
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(2, 3.0f));
}
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
} }
@ -536,26 +607,31 @@ void PlayerTest::advancePlayCountInfinite() {
.play(2.0f); .play(2.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(1.75f); player.advance(1.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* 1.75 secs in */ /* 1.75 secs in */
player.advance(3.75f); player.advance(3.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(3.75f), std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
/* 2 secs in, second round */ /* 2 secs in, second round */
player.advance(7.0f); player.advance(7.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(7.0f), std::make_pair(1, 2.0f));
CORRADE_COMPARE(value, 5.0f); CORRADE_COMPARE(value, 5.0f);
/* 1.75 secs in, 10th round */ /* 1.75 secs in, 11th round */
player.advance(33.75f); player.advance(33.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(33.75f), std::make_pair(10, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
} }
@ -567,16 +643,22 @@ void PlayerTest::advanceChrono() {
CORRADE_COMPARE(player.duration().size(), 3.0f); CORRADE_COMPARE(player.duration().size(), 3.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(std::chrono::milliseconds{1750}),
std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(std::chrono::milliseconds{1750}); player.advance(std::chrono::milliseconds{1750});
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(std::chrono::milliseconds{1750}),
std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* 1.75 secs in */ /* 1.75 secs in */
player.advance(std::chrono::milliseconds{3750}); player.advance(std::chrono::milliseconds{3750});
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(std::chrono::milliseconds{3750}),
std::make_pair(0, 1.75f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
} }
@ -591,16 +673,19 @@ void PlayerTest::advanceZeroDuration() {
CORRADE_COMPARE(player.duration().size(), 0.0f); CORRADE_COMPARE(player.duration().size(), 0.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(1.75f); player.advance(1.75f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(1.75f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* After that, the value at 1.75 secs is returned independent of time */ /* After that, the value at 1.75 secs is returned independent of time */
player.advance(100.0f); player.advance(100.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(100.0f), std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
} }
@ -615,17 +700,23 @@ void PlayerTest::advanceZeroDurationChrono() {
CORRADE_COMPARE(player.duration().size(), 0.0f); CORRADE_COMPARE(player.duration().size(), 0.0f);
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(std::chrono::milliseconds{1750}),
std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* Still before starting time, nothing is done */ /* Still before starting time, nothing is done */
player.advance(std::chrono::milliseconds{1750}); player.advance(std::chrono::milliseconds{1750});
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(std::chrono::milliseconds{1750}),
std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, -1.0f); CORRADE_COMPARE(value, -1.0f);
/* After that, the value at 1.75 seconds is returned independent of the /* After that, the value at 1.75 seconds is returned independent of the
time */ time */
player.advance(std::chrono::seconds{100}); player.advance(std::chrono::seconds{100});
CORRADE_COMPARE(player.state(), State::Playing); CORRADE_COMPARE(player.state(), State::Playing);
CORRADE_COMPARE(player.elapsed(std::chrono::seconds{100}),
std::make_pair(0, 0.0f));
CORRADE_COMPARE(value, 4.0f); CORRADE_COMPARE(value, 4.0f);
} }

Loading…
Cancel
Save