diff options
| author | 0scar <qgt268@alumni.ku.dk> | 2024-02-05 16:36:47 +0000 |
|---|---|---|
| committer | 0scar <qgt268@alumni.ku.dk> | 2024-02-05 16:48:20 +0000 |
| commit | e85f81ec109782a01f1f741d4c2ed5f21af0c124 (patch) | |
| tree | 8708c742b296de20e2d54ef9fa8ea7c2036d3d82 /src/core/state.c | |
| parent | 457a4a3b1f00bf4d6c31b693085aa7150d2dcded (diff) | |
Organize the sourcefiles
Diffstat (limited to 'src/core/state.c')
| -rw-r--r-- | src/core/state.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/core/state.c b/src/core/state.c new file mode 100644 index 0000000..55f2a12 --- /dev/null +++ b/src/core/state.c @@ -0,0 +1,178 @@ +#include <string.h> + +#include <engine/dltools.h> +#include <engine/input.h> +#include <engine/logging.h> +#include <engine/state.h> + +typedef StateType state_update_t(void*); + +const char* StateTypeStr[] = { + "null", +#define State(name) #name, +#include <states/list_of_states.h> +#undef State + "quit", +}; + +// Setup API for states +#define State(name) \ + typedef struct name##_state name##_state; \ + typedef void(state_##name##_init_t)(name##_state*); \ + typedef void(state_##name##_free_t)(name##_state*); \ + typedef StateType(state_##name##_update_t)(name##_state*); +#include <states/list_of_states.h> +#undef State + +#ifdef DAW_BUILD_HOTRELOAD + +// When hotreloading is enabled, we want to assign state function pointers +// dynamically. +#define State(name) \ + state_##name##_init_t* name##_init = NULL; \ + state_##name##_free_t* name##_free = NULL; \ + state_##name##_update_t* name##_update = NULL; \ + \ + void* libstate_##name = NULL; \ + const char* libstate_##name##_str = "lib" #name ".so"; +#else + +// Otherwise we just declare them. +#define State(name) \ + extern state_##name##_init_t name##_init; \ + extern state_##name##_free_t name##_free; \ + extern state_##name##_update_t name##_update; +#endif + +#include <states/list_of_states.h> +#undef State + +#include <states/all_states.h> + +void binding_t_free(binding_t* b); + +void State_init(StateType type, memory* mem) { + switch (type) { +#define State(name) \ + case (STATE_##name): { \ + name##_init(memory_allocate(mem, sizeof(name##_state))); \ + break; \ + } +#include <states/list_of_states.h> +#undef State + case STATE_null: + case STATE_quit: + DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); + } +} + +void State_free(StateType type, memory* mem) { + switch (type) { +#define State(name) \ + case (STATE_##name): { \ + name##_free(mem->data); \ + break; \ + } +#include <states/list_of_states.h> +#undef State + case STATE_null: + case STATE_quit: + DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); + } + memory_clear(mem); +} + +StateType (*State_updateFunc(StateType type))(void*) { + switch (type) { +#ifdef DAW_BUILD_HOTRELOAD +#define State(name) \ + case (STATE_##name): { \ + return (state_update_t*)name##_update; \ + break; \ + } +#else +#define State(name) \ + case (STATE_##name): { \ + return (state_update_t*)&name##_update; \ + break; \ + } +#endif +#include <states/list_of_states.h> +#undef State + case STATE_null: + case STATE_quit: + return NULL; // DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); + } + return NULL; +} + +StateType State_update(StateType type, memory* mem) { + StateType next_state = STATE_null; + switch (type) { +#define State(name) \ + case (STATE_##name): { \ + next_state = name##_update(mem->data); \ + break; \ + } +#include <states/list_of_states.h> +#undef State + case STATE_null: + case STATE_quit: + DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); + } + return next_state; +} + +#ifdef DAW_BUILD_HOTRELOAD +bool State_reload(StateType type, i_ctx** ctx, usize ctx_len) { + void* libptr = NULL; + + switch (type) { +#define State(name) \ + case (STATE_##name): { \ + if (libstate_##name == NULL) { \ + libstate_##name = dynamic_library_open(libstate_##name##_str); \ + } else { \ + libstate_##name = \ + dynamic_library_reload(libstate_##name, libstate_##name##_str); \ + } \ + if (libstate_##name == NULL) { \ + ERROR("Failed loading shared object: %s (%s)", libstate_##name##_str, \ + dynamic_library_get_error()); \ + return false; \ + } \ + \ + name##_init = (state_##name##_init_t*)dynamic_library_get_symbol( \ + libstate_##name, STR(name##_init)); \ + name##_free = (state_##name##_free_t*)dynamic_library_get_symbol( \ + libstate_##name, STR(name##_free)); \ + name##_update = (state_##name##_update_t*)dynamic_library_get_symbol( \ + libstate_##name, STR(name##_update)); \ + libptr = libstate_##name; \ + break; \ + } +#include <states/list_of_states.h> +#undef State + case STATE_null: + case STATE_quit: + ERROR("Invalid state"); + DEBUG("Got %s state.\n", StateTypeStr[type]); + return false; + default: + exit(EXIT_FAILURE); + } + return state_refresh_input_ctx(libptr, ctx, ctx_len); +} +#endif |
