From 3ebc370ca45f34705d1e6f028180306e6a7a15e0 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 22 Nov 2023 11:46:46 +0100 Subject: [PATCH] added state machine --- core/src/state.h | 30 ++++++++++++++++++++++++++++ core/src/state_machine.c | 42 ++++++++++++++++++++++++++++++++++++++++ core/src/state_machine.h | 15 ++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 core/src/state.h create mode 100644 core/src/state_machine.c create mode 100644 core/src/state_machine.h diff --git a/core/src/state.h b/core/src/state.h new file mode 100644 index 0000000..5e281fa --- /dev/null +++ b/core/src/state.h @@ -0,0 +1,30 @@ +#ifndef _fencer_state_h +#define _fencer_state_h + +#include "typeclass_helpers.h" + +typedef struct State State; + +struct State { + void (*const enter)(void* data); + void (*const exit)(void* data); + void (*const update)(void* data, float dt); + const State* (*const next)(void* data); +}; + +#define DefineState(_StateName, enter_fn, exit_fn, update_fn, next_fn)\ +static inline const State* _StateName() {\ + TC_FN_TYPECHECK(void, enter_fn, void*);\ + TC_FN_TYPECHECK(void, exit_fn, void*);\ + TC_FN_TYPECHECK(void, update_fn, void*, float);\ + TC_FN_TYPECHECK(const State*, next_fn, void*);\ + static const State instance = {\ + .enter = (void(*const)(void*)) enter_fn,\ + .exit = (void(*const)(void*)) exit_fn,\ + .update = (void(*const)(void*, float)) update_fn,\ + .next = (const State*(*const)(void*)) next_fn\ + };\ + return instance;\ +}\ + +#endif // !_fencer_state_h diff --git a/core/src/state_machine.c b/core/src/state_machine.c new file mode 100644 index 0000000..23d6ace --- /dev/null +++ b/core/src/state_machine.c @@ -0,0 +1,42 @@ +#include "state_machine.h" +#include "stdlib.h" + +struct StateMachine { + const State* current_state; + void* data; +}; + +StateMachine* state_machine_init(void* data, const State* start_state) { + StateMachine* self = malloc(sizeof(StateMachine)); + *self = (StateMachine){ + .current_state = start_state, + .data = data + }; + + self->current_state->enter(self->data); + + return self; +} + +void state_machine_destroy(StateMachine* self) { + self->current_state->exit(self->data); + free(self); +} + +void state_machine_set_state(StateMachine* self, const State* state) { + self->current_state->exit(self->data); + self->current_state = state; + self->current_state->enter(self->data); +} + +const State* state_machine_get_state(StateMachine* self) { + return self->current_state; +} + +void state_machine_update(StateMachine* self, float dt) { + self->current_state->update(self->data, dt); + const State* next = self->current_state->next(self->data); + + if(next != self->current_state) + state_machine_set_state(self, next); +} diff --git a/core/src/state_machine.h b/core/src/state_machine.h new file mode 100644 index 0000000..6e5a414 --- /dev/null +++ b/core/src/state_machine.h @@ -0,0 +1,15 @@ +#ifndef _fencer_state_machine_h +#define _fencer_state_machine_h + +#include "state.h" + +typedef struct StateMachine StateMachine; + +extern StateMachine* state_machine_init(void* data, const State* start_state); +extern void state_machine_destroy(StateMachine* self); + +extern void state_machine_set_state(StateMachine* self, const State* state); +extern const State* state_machine_get_current_state(StateMachine* self); +extern void state_machine_update(StateMachine* self, float dt); + +#endif // !_fencer_state_machine_h