project-kyoku/include/core/spritecontainer.h

63 lines
1.5 KiB
C++

#pragma once
#include <memory>
#include <stack>
#include <map>
namespace kku
{
template<typename Type, class SpriteFactory, class Sprite,
typename = std::enable_if_t<std::is_enum<Type>::value>>
class SpriteContainer
{
public:
explicit SpriteContainer(std::initializer_list<Type>&& types,
const std::shared_ptr<SpriteFactory>& factory,
std::size_t reserve_size = 20) :
_sprite_factory(factory),
_poll_reserve_size(reserve_size)
{
for (const Type& type : types)
reallocatePoll(type);
}
inline std::shared_ptr<Sprite> getSprite(Type type)
{
SpritePoll& poll = _sprite_dispatcher.at(type);
if (poll.empty())
reallocatePoll(type);
std::shared_ptr<Sprite> sprite = poll.top();
poll.pop();
return sprite;
}
inline void resetSprite(const std::shared_ptr<Sprite> &sprite, Type action) noexcept
{
_sprite_dispatcher[action].push(sprite);
}
~SpriteContainer() = default;
private:
inline void reallocatePoll(Type sprite_type)
{
SpritePoll &poll = _sprite_dispatcher[sprite_type];
for (std::size_t i = 0; i < _poll_reserve_size; ++i)
{
poll.push(_sprite_factory->create(sprite_type));
}
}
using SpritePoll = std::stack<std::shared_ptr<Sprite>>;
std::map<Type, SpritePoll> _sprite_dispatcher;
const std::shared_ptr<SpriteFactory> _sprite_factory;
std::size_t _poll_reserve_size;
};
}