Files

102 lines
2.6 KiB
C++

#include "game/scenes/timeline.hpp"
#include <algorithm>
namespace Scenes {
auto Timeline::step(int duration_ms, StepFn fn) -> Timeline& {
Step s;
s.duration_ms = duration_ms;
s.continuous = std::move(fn);
steps_.push_back(std::move(s));
return *this;
}
auto Timeline::once(OnceFn fn) -> Timeline& {
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;
}
auto Timeline::done() const -> bool {
return skipped_ || current_ >= steps_.size();
}
auto Timeline::currentProgress() const -> float {
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