Transitions being a way to allow for automatic state change and allow for a way to allow or forbbid a transition between two states
93 lines
2.2 KiB
C++
93 lines
2.2 KiB
C++
#ifndef STATE_MACHINE_HPP
|
|
#define STATE_MACHINE_HPP
|
|
|
|
#include <string>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include "state.hpp"
|
|
#include "state_factory.hpp"
|
|
|
|
using json = nlohmann::json;
|
|
|
|
template<typename T>
|
|
class StateMachine {
|
|
public:
|
|
StateMachine(T &owner, const StateFactory<T> &factory) : owner(owner), factory(factory) {};
|
|
|
|
void ChangeState(const std::string &id) {
|
|
auto new_state = factory.Get(id);
|
|
if (!new_state)
|
|
return;
|
|
|
|
if (current_state) {
|
|
current_state->OnExit(owner);
|
|
history.push_back(current_state->Id());
|
|
}
|
|
|
|
current_state = std::move(new_state);
|
|
current_state->OnEnter(owner);
|
|
};
|
|
|
|
void SetState(const std::string &id) {
|
|
auto new_state = factory.Get(id);
|
|
if (!new_state)
|
|
return;
|
|
|
|
if (current_state)
|
|
current_state->OnExit(owner);
|
|
|
|
current_state = std::move(new_state);
|
|
current_state->OnEnter(owner);
|
|
}
|
|
|
|
void RevertState() {
|
|
if (history.empty())
|
|
return;
|
|
|
|
std::string last = history.back();
|
|
history.pop_back();
|
|
ChangeState(last);
|
|
}
|
|
|
|
void Update() {
|
|
if (!current_state)
|
|
return;
|
|
|
|
current_state->OnUpdate(owner);
|
|
}
|
|
|
|
const std::vector<std::string> &GetHistory() const {
|
|
return history;
|
|
}
|
|
|
|
void SetHistory(const std::vector<std::string> history) {
|
|
this->history = history;
|
|
}
|
|
|
|
void ReplayHistory() {
|
|
for (const std::string &stateId : history)
|
|
ChangeState(stateId);
|
|
}
|
|
|
|
const std::string GetCurrentStateId() const {
|
|
static const std::string nullState = "nullstate";
|
|
return current_state ? current_state->Id() : nullState;
|
|
}
|
|
|
|
T &GetOwner() {
|
|
return owner;
|
|
}
|
|
|
|
private:
|
|
T &owner;
|
|
const StateFactory<T> &factory;
|
|
std::shared_ptr<State<T>> current_state;
|
|
std::vector<std::string> history;
|
|
};
|
|
|
|
#endif // STATE_MACHINE_HPP
|