+// Like tweened_transform but for framerates
+class speed_tweener
+{
+ boost::rational<int64_t> source_ = 1LL;
+ boost::rational<int64_t> dest_ = 1LL;
+ int duration_ = 0;
+ int time_ = 0;
+ tweener tweener_;
+public:
+ speed_tweener() = default;
+ speed_tweener(
+ const boost::rational<int64_t>& source,
+ const boost::rational<int64_t>& dest,
+ int duration,
+ const tweener& tween)
+ : source_(source)
+ , dest_(dest)
+ , duration_(duration)
+ , time_(0)
+ , tweener_(tween)
+ {
+ }
+
+ const boost::rational<int64_t>& dest() const
+ {
+ return dest_;
+ }
+
+ boost::rational<int64_t> fetch() const
+ {
+ if (time_ == duration_)
+ return dest_;
+
+ double source = boost::rational_cast<double>(source_);
+ double delta = boost::rational_cast<double>(dest_) - source;
+ double result = tweener_(time_, source, delta, duration_);
+
+ return boost::rational<int64_t>(static_cast<int64_t>(result * 1000000.0), 1000000);
+ }
+
+ boost::rational<int64_t> fetch_and_tick()
+ {
+ time_ = std::min(time_ + 1, duration_);
+ return fetch();
+ }
+};
+