I'm trying to create a flexible multi-track animation system using only C++11.
So far I have this code:
#include <vector>
#include <array>
#include <unordered_map>
#include <map>
template<typename T>
struct AnimationTrack
{
using map_type = std::map<float, T>;
map_type keyframes;
AnimationTrack(std::initializer_list<typename map_type::value_type>&& keyframes) :
keyframes(std::move(keyframes)) {}
};
template<typename T>
struct AnimationTrackView
{
AnimationTrack<T>* track;
AnimationTrackView() :
track(nullptr) {}
AnimationTrackView(AnimationTrack<T>* track) :
track(track) {}
};
template<typename... TrackTs>
class Animation
{
public:
Animation(AnimationTrack<TrackTs>&... tracks)
{
StoreViews(tracks...);
}
template<std::size_t Index>
auto& GetTrack()
{
return GetStorage<std::tuple_element<Index, std::tuple<TrackTs...>>::type>()[this].track;
}
private:
template<typename T>
static auto& GetStorage()
{
static std::unordered_map<Animation*, AnimationTrackView<T>> storage;
return storage;
}
template<typename T, typename... Ts>
void StoreViews(AnimationTrack<T>& current, AnimationTrack<Ts>&... rest)
{
auto& storage = GetStorage<T>();
storage.emplace(this, std::addressof(current));
using expander = int[];
(void)expander {
0, (void(GetStorage<Ts>().emplace(this, std::addressof(rest))), 0)...
};
}
};
int main()
{
AnimationTrack<float> test1(
{
{ 0.2f, 1.0f },
{ 0.5f, 2.0f },
{ 0.9f, 3.0f }
});
AnimationTrack<int> test2(
{
{ 0.2f, 1 },
{ 0.5f, 2 },
{ 0.9f, 3 }
});
Animation<float, int> anim(test1, test2);
auto track0 = anim.GetTrack<0>();
auto track1 = anim.GetTrack<1>();
}
This example works fine in this use case, but what if I wanted to keep two tracks of the same type? With my current code both tracks would grab from the same static storage when calling GetTrack
, but the problem is I can't figure out a way to make it work with repeats of the same type. Any suggestions?
Aucun commentaire:
Enregistrer un commentaire