#include "twn_game_object_c.h" #include "twn_engine_context_c.h" #include "twn_util_c.h" #include "twn_util.h" #include #include #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(); }