86 lines
2.1 KiB
C++
86 lines
2.1 KiB
C++
#include "scenes/timeline.hpp"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace scenes {
|
|
|
|
Timeline& Timeline::step(int duration_ms, StepFn fn) {
|
|
Step s;
|
|
s.duration_ms = duration_ms;
|
|
s.continuous = std::move(fn);
|
|
steps_.push_back(std::move(s));
|
|
return *this;
|
|
}
|
|
|
|
Timeline& Timeline::once(OnceFn fn) {
|
|
Step s;
|
|
s.duration_ms = 0;
|
|
s.oneshot = std::move(fn);
|
|
steps_.push_back(std::move(s));
|
|
return *this;
|
|
}
|
|
|
|
void Timeline::flushOneShots() {
|
|
while (current_ < steps_.size() && steps_[current_].duration_ms == 0) {
|
|
auto& s = steps_[current_];
|
|
if (!s.entered) {
|
|
s.entered = true;
|
|
if (s.oneshot) s.oneshot();
|
|
}
|
|
++current_;
|
|
elapsed_in_step_ = 0;
|
|
}
|
|
}
|
|
|
|
void Timeline::tick(int delta_ms) {
|
|
if (skipped_) return;
|
|
flushOneShots();
|
|
if (current_ >= steps_.size()) return;
|
|
|
|
auto& s = steps_[current_];
|
|
if (!s.entered) {
|
|
s.entered = true;
|
|
// Primer tick dins del pas: cridem amb progress=0 si hi ha callback.
|
|
if (s.continuous) s.continuous(0.0f);
|
|
}
|
|
|
|
elapsed_in_step_ += delta_ms;
|
|
if (elapsed_in_step_ >= s.duration_ms) {
|
|
// Tancament del pas: una crida final amb progress=1.
|
|
if (s.continuous) s.continuous(1.0f);
|
|
++current_;
|
|
elapsed_in_step_ = 0;
|
|
// Pot ser que el següent pas siga una cadena de one-shots.
|
|
flushOneShots();
|
|
} else if (s.continuous) {
|
|
const float p = static_cast<float>(elapsed_in_step_) /
|
|
static_cast<float>(std::max(1, s.duration_ms));
|
|
s.continuous(p);
|
|
}
|
|
}
|
|
|
|
void Timeline::skip() {
|
|
skipped_ = true;
|
|
current_ = steps_.size();
|
|
}
|
|
|
|
void Timeline::reset() {
|
|
for (auto& s : steps_) s.entered = false;
|
|
current_ = 0;
|
|
elapsed_in_step_ = 0;
|
|
skipped_ = false;
|
|
}
|
|
|
|
bool Timeline::done() const {
|
|
return skipped_ || current_ >= steps_.size();
|
|
}
|
|
|
|
float Timeline::currentProgress() const {
|
|
if (current_ >= steps_.size()) return 1.0f;
|
|
const auto& s = steps_[current_];
|
|
if (s.duration_ms <= 0) return 0.0f;
|
|
return static_cast<float>(elapsed_in_step_) / static_cast<float>(s.duration_ms);
|
|
}
|
|
|
|
} // namespace scenes
|