91 lines
2.0 KiB
C
91 lines
2.0 KiB
C
#include "twn_game_object_c.h"
|
|
#include "twn_engine_context_c.h"
|
|
#include "twn_util_c.h"
|
|
#include "twn_util.h"
|
|
|
|
#include <errhandlingapi.h>
|
|
#include <libloaderapi.h>
|
|
|
|
|
|
#define GAME_OBJECT_PATH "libgame.dll"
|
|
|
|
|
|
static void (*game_tick_callback)(void);
|
|
static void (*game_end_callback)(void);
|
|
|
|
static void *handle = NULL;
|
|
|
|
|
|
static void load_game_object(void) {
|
|
/* needs to be closed otherwise symbols aren't resolved again */
|
|
if (handle) {
|
|
FreeLibrary(handle);
|
|
handle = NULL;
|
|
game_tick_callback = NULL;
|
|
game_end_callback = NULL;
|
|
}
|
|
|
|
void *new_handle = LoadLibraryA(GAME_OBJECT_PATH);
|
|
if (!new_handle) {
|
|
log_critical("Hot Reload Error: Cannot open game code shared object (%s)", GetLastError());
|
|
goto ERR_OPENING_SO;
|
|
}
|
|
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
|
|
game_tick_callback = (void (*)(void))GetProcAddress(new_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))GetProcAddress(new_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
|
|
|
|
handle = new_handle;
|
|
|
|
if (ctx.game.frame_number != 0)
|
|
log_info("Game object was reloaded\n");
|
|
|
|
return;
|
|
|
|
ERR_GETTING_PROC:
|
|
FreeLibrary(new_handle);
|
|
game_tick_callback = NULL;
|
|
game_end_callback = NULL;
|
|
|
|
ERR_OPENING_SO:
|
|
die_abruptly();
|
|
}
|
|
|
|
|
|
void game_object_load(void) {
|
|
load_game_object();
|
|
}
|
|
|
|
|
|
void game_object_unload(void) {
|
|
game_end_callback();
|
|
FreeLibrary(handle);
|
|
handle = NULL;
|
|
game_tick_callback = NULL;
|
|
game_end_callback = NULL;
|
|
}
|
|
|
|
|
|
/* doesn't support reloading because of problems with file watching */
|
|
bool game_object_try_reloading(void) {
|
|
return false;
|
|
}
|
|
|
|
|
|
void game_object_tick(void) {
|
|
game_tick_callback();
|
|
}
|