#define _DEFAULT_SOURCE // usleep() #include #include #include #include #include #include "include/raylib.h" #include "include/raymath.h" #include "boids_game.h" #define SCREEN_WIDTH 1300 #define SCREEN_HEIGHT 1080 #define TARGET_FPS 60 const char* GAME_LIB = "./libboids.so"; char inotify_buf[1024]; struct Game { void* handle; ino_t gamelib_id; struct GameApi api; struct GameState* state; }; #define MAX_EVENTS 1 void load_game(struct Game* game) { struct stat attr; if ((stat(GAME_LIB, &attr) == 0) && (game->gamelib_id != attr.st_ino)) { if (game->handle) { game->api.unload(game->state); dlclose(game->handle); } void* handle = dlopen(GAME_LIB, RTLD_NOW); if (handle) { game->handle = handle; game->gamelib_id = attr.st_ino; const struct GameApi* api = dlsym(game->handle, "GAME_API"); if (api != NULL) { printf("Loaded API, calling init()\n"); game->api = *api; if (game->state == NULL) { game->state = game->api.init(); } game->api.reload(game->state); } else { printf("Failed to load API\n"); dlclose(game->handle); } } else { fprintf(stderr, "Error loading %s\n", GAME_LIB); fprintf(stderr, "Error was: %s\n", dlerror()); exit(1); } } } int main(void) { struct Game game = {0}; int should_exit = 0; while (should_exit != 1) { load_game(&game); should_exit = game.api.step(game.state); } game.api.finalize(game.state); free(game.state); }