83 lines
1.5 KiB
C++
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();
|
|
}
|
|
};
|
|
};
|
|
|
|
}
|