feat(state machine): state machine now no longer has a separate next function
instead update is expected to return the next state
This commit is contained in:
parent
fd0183d34a
commit
7a0a60846a
|
@ -8,23 +8,20 @@ typedef struct State State;
|
||||||
struct State {
|
struct State {
|
||||||
void (*const enter)(void* data);
|
void (*const enter)(void* data);
|
||||||
void (*const exit)(void* data);
|
void (*const exit)(void* data);
|
||||||
void (*const update)(void* data, float dt);
|
const State* (*const update)(void* data, float dt);
|
||||||
const State* (*const next)(void* data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DefineState(_StateName, enter_fn, exit_fn, update_fn, next_fn)\
|
#define DefineState(_StateName, enter_fn, exit_fn, update_fn)\
|
||||||
static inline const State* _StateName() {\
|
static inline const State* _StateName() {\
|
||||||
TC_FN_TYPECHECK(void, enter_fn, void*);\
|
TC_FN_TYPECHECK(void, enter_fn, void*);\
|
||||||
TC_FN_TYPECHECK(void, exit_fn, void*);\
|
TC_FN_TYPECHECK(void, exit_fn, void*);\
|
||||||
TC_FN_TYPECHECK(void, update_fn, void*, float);\
|
TC_FN_TYPECHECK(const State*, update_fn, void*, float);\
|
||||||
TC_FN_TYPECHECK(const State*, next_fn, void*);\
|
|
||||||
static const State instance = {\
|
static const State instance = {\
|
||||||
.enter = (void(*const)(void*)) enter_fn,\
|
.enter = (void(*const)(void*)) enter_fn,\
|
||||||
.exit = (void(*const)(void*)) exit_fn,\
|
.exit = (void(*const)(void*)) exit_fn,\
|
||||||
.update = (void(*const)(void*, float)) update_fn,\
|
.update = (const State*(*const)(void*, float)) update_fn,\
|
||||||
.next = (const State*(*const)(void*)) next_fn\
|
|
||||||
};\
|
};\
|
||||||
return instance;\
|
return &instance;\
|
||||||
}\
|
}\
|
||||||
|
|
||||||
#endif // !_fencer_state_h
|
#endif // !_fencer_state_h
|
||||||
|
|
|
@ -1,20 +1,29 @@
|
||||||
#include "state_machine.h"
|
#include "state_machine.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
struct StateMachine {
|
struct StateMachine {
|
||||||
const State* current_state;
|
const State* current_state;
|
||||||
void* data;
|
void* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void internal_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);
|
||||||
|
}
|
||||||
|
|
||||||
StateMachine* state_machine_init(void* data, const State* start_state) {
|
StateMachine* state_machine_init(void* data, const State* start_state) {
|
||||||
StateMachine* self = malloc(sizeof(StateMachine));
|
StateMachine* self = malloc(sizeof(StateMachine));
|
||||||
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for StateMachine instance");
|
||||||
|
|
||||||
*self = (StateMachine){
|
*self = (StateMachine){
|
||||||
.current_state = start_state,
|
.current_state = start_state,
|
||||||
.data = data
|
.data = data
|
||||||
};
|
};
|
||||||
|
|
||||||
self->current_state->enter(self->data);
|
self->current_state->enter(self->data);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,20 +32,12 @@ void state_machine_destroy(StateMachine* self) {
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void state_machine_set_state(StateMachine* self, const State* state) {
|
void state_machine_update(StateMachine* self, float dt) {
|
||||||
self->current_state->exit(self->data);
|
const State* next = self->current_state->update(self->data, dt);
|
||||||
self->current_state = state;
|
if(next != self->current_state)
|
||||||
self->current_state->enter(self->data);
|
internal_state_machine_set_state(self, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
const State* state_machine_get_state(StateMachine* self) {
|
const State* state_machine_get_current_state(StateMachine* self) {
|
||||||
return self->current_state;
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ typedef struct StateMachine StateMachine;
|
||||||
extern StateMachine* state_machine_init(void* data, const State* start_state);
|
extern StateMachine* state_machine_init(void* data, const State* start_state);
|
||||||
extern void state_machine_destroy(StateMachine* self);
|
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);
|
extern void state_machine_update(StateMachine* self, float dt);
|
||||||
|
|
||||||
|
extern const State* state_machine_get_current_state(StateMachine* self);
|
||||||
|
|
||||||
#endif // !_fencer_state_machine_h
|
#endif // !_fencer_state_machine_h
|
||||||
|
|
Loading…
Reference in a new issue