diff options
Diffstat (limited to 'src/states.h')
-rw-r--r-- | src/states.h | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/states.h b/src/states.h new file mode 100644 index 0000000..57898a6 --- /dev/null +++ b/src/states.h @@ -0,0 +1,93 @@ +#ifndef STATES_H +#define STATES_H + +#include <SFML/Graphics.hpp> +#include <functional> +#include "states/ids.h" +#include "resourceManager.h" +#include "resourceIds.h" + +class StateStack; + +class State { + public: + using Ptr = std::unique_ptr<State>; + + struct Context{ + sf::RenderWindow *window; + TextureManager *textures; + // 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<Op> pendingOps_; + std::vector<State::Ptr> states_; + std::map<States::Id, std::function<State::Ptr()>> 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<typename T> + void registerState(States::Id id); + + + State::Ptr createState(States::Id id); +}; + + +template<typename T> +void StateStack::registerState(States::Id id){ + static_assert(std::is_base_of<State, T>::value, + "StateStack: attempting to registerState something that is not a State"); + stateFactory_[id] = [this] () + { + return State::Ptr(new T(*this, context_)); + }; +} + +#endif // STATES_H |