99 lines
2.4 KiB
C
99 lines
2.4 KiB
C
#include "twn_game_object_c.h"
|
|
#include "twn_engine_context_c.h"
|
|
#include "twn_filewatch_c.h"
|
|
#include "twn_util_c.h"
|
|
#include "twn_util.h"
|
|
#include "twn_loop_c.h"
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
#ifdef _WIN32
|
|
#define GAME_OBJECT_NAME "libgame.dll"
|
|
#else
|
|
#define GAME_OBJECT_NAME "libgame.so"
|
|
#endif
|
|
|
|
static void (*game_tick_callback)(void);
|
|
static void (*game_end_callback)(void);
|
|
|
|
static void *handle = NULL;
|
|
|
|
|
|
static void game_object_file_action(char const *path, enum FilewatchAction action) {
|
|
(void)action;
|
|
|
|
if (action != FILEWATCH_ACTION_FILE_CREATED)
|
|
return;
|
|
|
|
if (handle) {
|
|
SDL_UnloadObject(handle);
|
|
game_tick_callback = NULL;
|
|
game_end_callback = NULL;
|
|
handle = NULL;
|
|
}
|
|
|
|
handle = SDL_LoadObject(path);
|
|
if (!handle) {
|
|
CRY_SDL("Hot Reload Error: Cannot open game code shared object");
|
|
return;
|
|
}
|
|
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
|
|
game_tick_callback = (void (*)(void))SDL_LoadFunction(handle, "game_tick");
|
|
if (!game_tick_callback) {
|
|
CRY("Hot Reload Error", "game_tick_callback() symbol wasn't found");
|
|
goto ERR_GETTING_PROC;
|
|
}
|
|
|
|
game_end_callback = (void (*)(void))SDL_LoadFunction(handle, "game_end");
|
|
if (!game_end_callback) {
|
|
CRY("Hot Reload Error", "game_end_callback() symbol wasn't found");
|
|
goto ERR_GETTING_PROC;
|
|
}
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
if (fabsf(0.0f - ctx.game.frame_number) > 0.00001f) {
|
|
log_info("Game object was reloaded\n");
|
|
reset_state();
|
|
}
|
|
|
|
return;
|
|
|
|
ERR_GETTING_PROC:
|
|
SDL_UnloadObject(handle);
|
|
handle = NULL;
|
|
game_tick_callback = NULL;
|
|
game_end_callback = NULL;
|
|
}
|
|
|
|
|
|
void game_object_load(void) {
|
|
static bool filewatch_attached;
|
|
if (!filewatch_attached) {
|
|
char *game_object_path;
|
|
SDL_asprintf(&game_object_path, "%s%s", ctx.base_dir, GAME_OBJECT_NAME);
|
|
filewatch_add_file(game_object_path, game_object_file_action);
|
|
game_object_file_action(game_object_path, FILEWATCH_ACTION_FILE_CREATED);
|
|
SDL_free(game_object_path);
|
|
filewatch_attached = true;
|
|
}
|
|
}
|
|
|
|
|
|
void game_object_unload(void) {
|
|
game_end_callback();
|
|
/* needs to be closed otherwise symbols aren't resolved again */
|
|
SDL_UnloadObject(handle);
|
|
game_tick_callback = NULL;
|
|
game_end_callback = NULL;
|
|
handle = NULL;
|
|
}
|
|
|
|
|
|
void game_object_tick(void) {
|
|
game_tick_callback();
|
|
}
|