1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 19:32:49 +01:00
openrw/rwgame/StateManager.hpp
Daniel Evans 887e0333c8 Improve state access to always get the current scene
Prevents events being recieved by states that are no-longer in effect

Fixes #292
2017-09-17 00:45:58 +01:00

78 lines
1.6 KiB
C++

#ifndef RWGAME_STATEMANAGER_HPP
#define RWGAME_STATEMANAGER_HPP
#include "State.hpp"
#include <memory>
#include <queue>
/**
* @brief Handles current state focus and transitions
*
* Possible states:
* Foreground (topmost state)
* Background (any other position)
*
* Transitions:
* New State (at the top)
* Suspended (a state was created above us)
* Resumed (blocking state was removed)
*/
class StateManager {
public:
static StateManager& get() {
static StateManager m;
return m;
}
std::deque<std::unique_ptr<State>> states;
void clear() {
cleared = true;
}
template <class T, class... Targs>
void enter(Targs&&... args) {
// Notify the previous state it has been suspended
if (!states.empty()) {
states.back()->exit();
}
states.emplace_back(std::move(std::make_unique<T>(args...)));
states.back()->enter();
}
void updateStack() {
if (cleared) {
states.clear();
cleared = false;
}
while (!states.empty() && states.back()->hasExited()) {
states.back()->exit();
states.pop_back();
if (!states.empty()) {
states.back()->enter();
}
}
}
void tick(float dt) {
states.back()->tick(dt);
}
void draw(GameRenderer* r) {
states.back()->draw(r);
}
static State* currentState() {
if (StateManager::get().states.empty()) {
return nullptr;
}
return StateManager::get().states.back().get();
}
private:
bool cleared = false;
};
#endif