project-kyoku/include/core/spritecontainer.h

65 lines
1.6 KiB
C++

#pragma once
#include <map>
#include <memory>
#include <stack>
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->reset();
_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->createSprite(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;
};
} // namespace kku