psemek/libs/util/include/psemek/util/animation_manager.hpp

83 lines
1.5 KiB
C++

#pragma once
#include <vector>
#include <algorithm>
#include <cmath>
namespace psemek::util
{
template <typename Time, typename Data>
struct animation_manager
{
struct animation
{
Time time;
Time duration;
Data data;
Time position() const
{
return std::max(Time{0}, std::min(Time{1}, time / duration));
}
Time remaining() const
{
return duration - time;
}
bool finished() const
{
return remaining() <= Time{0};
}
};
void add(Time duration, Data data)
{
animations_.push_back(animation{Time{0}, duration, data});
std::push_heap(animations_.begin(), animations_.end(), compare{});
}
std::vector<Data> update(Time dt)
{
for (auto & animation : animations_)
animation.time += dt;
std::vector<Data> finished;
while (!animations_.empty() && animations_.front().finished())
{
std::pop_heap(animations_.begin(), animations_.end(), compare{});
finished.push_back(std::move(animations_.back().data));
animations_.pop_back();
}
return finished;
}
animation const * begin() const
{
return animations_.data();
}
animation const * end() const
{
return animations_.data() + animations_.size();
}
std::size_t size() const
{
return animations_.size();
}
private:
std::vector<animation> animations_;
struct compare
{
bool operator() (animation const & a1, animation const & a2)
{
return a1.remaining() > a2.remaining();
}
};
};
}