#include <chrono>
#include <functional>
class Project {
public:
using seconds = std::chrono::duration<float>;
};
class Timer {
public:
Timer(float seconds) : _remaining{ seconds } {}
virtual bool operator()(Project::seconds, Project::seconds);
float remaining() const { return _remaining; }
protected:
virtual void operator()(Project::seconds time) = 0;
private:
float _remaining;
};
bool Timer::operator()(Project::seconds frame, Project::seconds total)
{
_remaining -= frame.count();
if (_remaining <= 0) {
(*this)(total);
return false;
}
return true;
}
class Easing : public Timer {
public:
Easing(float seconds) : Timer{ seconds }, _duration{ seconds } {}
bool operator()(Project::seconds, Project::seconds) override;
protected:
void operator()(Project::seconds) override {}
virtual void operator()(float progress, float fraction) = 0;
private:
float _duration;
};
bool Easing::operator()(Project::seconds frame, Project::seconds total)
{
float elapsed = _duration - remaining();
operator()(frame.count() / _duration, elapsed / _duration);
return Timer::operator()(frame, total);
}
class Slide : public Easing {
public:
Slide(float duration, long& target, float destination)
: Easing{duration}, _target { target }, _destination{ destination }, _start{ target / 0.5 }
{}
// using Easing::operator(); // required fix
protected:
void operator()(float progress, float fraction) override;
private:
long& _target;
double _destination, _start;
};
void Slide::operator()(float progress, float fraction)
{
_target += (_destination - _start) * progress);
}
long x = 16;
std::function<bool(Project::seconds, Project::seconds)> motion { Slide { 4.0f, x, 12.15f } }; // fails without using declaration
Comments