#include "state_machine.h" #include "state.h" void StateMachine::_bind_methods() {} void StateMachine::switch_to_state(State *state) { if (this->current_state != nullptr) { this->current_state_is_active = false; this->current_state->exit_state(); } this->current_state = state; if (this->current_state != nullptr) { this->current_state_is_active = true; this->current_state->enter_state(); } else { print_error("StateMachine::switch_to_state: New state is nullptr, StateMachine will now stop working"); } } void StateMachine::process(double delta) { if (this->current_state) { this->current_state->process(delta); String new_state{ this->current_state->get_next_state() }; if (new_state != this->current_state->get_class()) { this->switch_to_state(this->states.has(new_state) ? this->states[new_state] : nullptr); } } } void StateMachine::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { default: return; case NOTIFICATION_READY: set_process(true); return; case NOTIFICATION_PROCESS: process(get_process_delta_time()); return; case NOTIFICATION_DISABLED: case NOTIFICATION_EXIT_TREE: if (this->current_state_is_active && this->current_state != nullptr) { this->current_state_is_active = false; this->current_state->exit_state(); } return; case NOTIFICATION_ENABLED: case NOTIFICATION_ENTER_TREE: if (!this->current_state_is_active && this->current_state != nullptr) { this->current_state_is_active = true; this->current_state->enter_state(); } return; } } StateMachine::~StateMachine() { for (KeyValue kvp : this->states) { if (kvp.value != nullptr) { memdelete(kvp.value); } } } void StateMachine::add_state(State *state) { state->set_state_machine(this); state->set_target(this->get_parent()); this->states.insert(state->get_class(), state); if (this->current_state == nullptr) { this->switch_to_state(state); } }