#ifndef STATES_H #define STATES_H #include #include #include "states/ids.h" #include "resourceManager.h" #include "resourceIds.h" class StateStack; class State { public: using Ptr = std::unique_ptr; struct Context{ sf::RenderWindow *window; TextureManager *textures; TextureFontManager *textureFonts; // add IO controller }; State(StateStack &stack, State::Context context); virtual void update(sf::Time dt) =0; virtual void render() =0; virtual void handleEvent(const sf::Event &event) =0; protected: void requestPush(States::Id state_id); void requestPop(); void requestClear(); Context context_; StateStack *stack_; }; class StateStack{ public: enum class OpId{ Push, Pop, Clear }; struct Op{ Op(OpId op_id, States::Id state_id = States::None) : id(op_id) , state(state_id){} OpId id; States::Id state; }; private: std::vector pendingOps_; std::vector states_; std::map> stateFactory_; State::Context context_; public: StateStack(State::Context context); void update(sf::Time dt); void render(); void handleEvent(const sf::Event &event); void requestOp(Op op); void push(States::Id state_id); void pop(); void clear(); void applyPending(); bool isEmpty() const; template void registerState(States::Id id); State::Ptr createState(States::Id id); }; template void StateStack::registerState(States::Id id){ static_assert(std::is_base_of::value, "StateStack: attempting to registerState something that is not a State"); stateFactory_[id] = [this] () { return State::Ptr(new T(*this, context_)); }; } #endif // STATES_H