Hot reloading: Finally got it working with the stat
syscall
This commit is contained in:
parent
93972ba1d4
commit
4b63f91494
16
boids_game.c
16
boids_game.c
@ -5,8 +5,10 @@
|
|||||||
#include "boids_game.h"
|
#include "boids_game.h"
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
#define SCREEN_WIDTH 1300
|
// #define SCREEN_WIDTH 1300
|
||||||
#define SCREEN_HEIGHT 1080
|
// #define SCREEN_HEIGHT 1080
|
||||||
|
#define SCREEN_WIDTH 800
|
||||||
|
#define SCREEN_HEIGHT 600
|
||||||
|
|
||||||
typedef struct Boid {
|
typedef struct Boid {
|
||||||
Point position;
|
Point position;
|
||||||
@ -25,6 +27,13 @@ typedef struct GameState {
|
|||||||
static GameState *init() {
|
static GameState *init() {
|
||||||
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids");
|
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids");
|
||||||
|
|
||||||
|
int monitor = GetCurrentMonitor();
|
||||||
|
int monitor_width = GetMonitorWidth(monitor);
|
||||||
|
// int monitor_height = GetMonitorHeight(monitor);
|
||||||
|
int win_pos_x = monitor_width - SCREEN_WIDTH - 7;
|
||||||
|
int win_pos_y = 30;
|
||||||
|
SetWindowPosition(win_pos_x, win_pos_y);
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
|
|
||||||
GameState *state = malloc(sizeof(struct GameApi));
|
GameState *state = malloc(sizeof(struct GameApi));
|
||||||
@ -99,7 +108,6 @@ static int step(GameState *state) {
|
|||||||
boid->position = Vector2Add(boid->position, boid->velocity);
|
boid->position = Vector2Add(boid->position, boid->velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
{
|
{
|
||||||
@ -113,7 +121,7 @@ static int step(GameState *state) {
|
|||||||
DrawCircle(boid->position.x, boid->position.y, 27, BLACK);
|
DrawCircle(boid->position.x, boid->position.y, 27, BLACK);
|
||||||
DrawCircle(boid->position.x, boid->position.y, 20, GREEN);
|
DrawCircle(boid->position.x, boid->position.y, 20, GREEN);
|
||||||
}
|
}
|
||||||
|
DrawFPS(SCREEN_WIDTH - 80, 10);
|
||||||
}
|
}
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
return return_int;
|
return return_int;
|
||||||
|
67
boids_main.c
67
boids_main.c
@ -2,10 +2,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/inotify.h>
|
|
||||||
// #include "inotify-syscalls.h"
|
|
||||||
#include "include/raylib.h"
|
#include "include/raylib.h"
|
||||||
#include "include/raymath.h"
|
#include "include/raymath.h"
|
||||||
#include "boids_game.h"
|
#include "boids_game.h"
|
||||||
@ -15,11 +13,11 @@
|
|||||||
#define TARGET_FPS 60
|
#define TARGET_FPS 60
|
||||||
|
|
||||||
const char* GAME_LIB = "./libboids.so";
|
const char* GAME_LIB = "./libboids.so";
|
||||||
char epoll_buf[1024];
|
char inotify_buf[1024];
|
||||||
|
|
||||||
struct Game
|
struct Game {
|
||||||
{
|
|
||||||
void* handle;
|
void* handle;
|
||||||
|
ino_t gamelib_id;
|
||||||
struct GameApi api;
|
struct GameApi api;
|
||||||
struct GameState* state;
|
struct GameState* state;
|
||||||
};
|
};
|
||||||
@ -27,14 +25,16 @@ struct Game
|
|||||||
#define MAX_EVENTS 1
|
#define MAX_EVENTS 1
|
||||||
|
|
||||||
void load_game(struct Game* game) {
|
void load_game(struct Game* game) {
|
||||||
|
struct stat attr;
|
||||||
|
if ((stat(GAME_LIB, &attr) == 0) && (game->gamelib_id != attr.st_ino)) {
|
||||||
if (game->handle) {
|
if (game->handle) {
|
||||||
game->api.unload(game->state);
|
game->api.unload(game->state);
|
||||||
dlclose(game->handle);
|
dlclose(game->handle);
|
||||||
}
|
}
|
||||||
void* handle = dlopen(GAME_LIB, RTLD_NOW);
|
void* handle = dlopen(GAME_LIB, RTLD_NOW);
|
||||||
|
|
||||||
if (handle) {
|
if (handle) {
|
||||||
game->handle = handle;
|
game->handle = handle;
|
||||||
|
game->gamelib_id = attr.st_ino;
|
||||||
const struct GameApi* api = dlsym(game->handle, "GAME_API");
|
const struct GameApi* api = dlsym(game->handle, "GAME_API");
|
||||||
if (api != NULL) {
|
if (api != NULL) {
|
||||||
printf("Loaded API, calling init()\n");
|
printf("Loaded API, calling init()\n");
|
||||||
@ -52,67 +52,16 @@ void load_game(struct Game* game) {
|
|||||||
fprintf(stderr, "Error was: %s\n", dlerror());
|
fprintf(stderr, "Error was: %s\n", dlerror());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
int fd = inotify_init();
|
|
||||||
if (fd < 0) {
|
|
||||||
fprintf(stderr, "Error initializing inotify\n");
|
|
||||||
}
|
|
||||||
int wd;
|
|
||||||
wd = inotify_add_watch(fd, GAME_LIB, IN_MODIFY);
|
|
||||||
|
|
||||||
// create epoll instance
|
|
||||||
int epollfd = epoll_create1(0);
|
|
||||||
if (epollfd == -1) {
|
|
||||||
fprintf(stderr, "Error creating epoll instance\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct epoll_event event;
|
|
||||||
event.events = EPOLLIN;
|
|
||||||
event.data.fd = fd;
|
|
||||||
|
|
||||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event) == -1) {
|
|
||||||
fprintf(stderr, "Error adding inotify descriptor to epoll\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct epoll_event events[MAX_EVENTS];
|
|
||||||
|
|
||||||
struct Game game = {0};
|
struct Game game = {0};
|
||||||
load_game(&game);
|
|
||||||
int should_exit = 0;
|
int should_exit = 0;
|
||||||
while (should_exit != 1) {
|
while (should_exit != 1) {
|
||||||
int nfds = epoll_wait(epollfd, events, MAX_EVENTS, 0);
|
|
||||||
if (nfds == -1) {
|
|
||||||
fprintf(stderr, "epoll_wait failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("%d %d\n", nfds, fd);
|
|
||||||
for (int n = 0; n < nfds; ++n) {
|
|
||||||
// printf("DO I EVER GET CALLED\n", events[n].data.fd, fd);
|
|
||||||
printf("DO I EVER GET CALLED\n");
|
|
||||||
if (events[n].data.fd == fd) {
|
|
||||||
printf("SO has been updated!\n");
|
|
||||||
// This clears the inotify queue so we don't get any more events
|
|
||||||
read(fd, epoll_buf, sizeof(epoll_buf));
|
|
||||||
load_game(&game);
|
load_game(&game);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
should_exit = game.api.step(game.state);
|
should_exit = game.api.step(game.state);
|
||||||
if (should_exit == 2) {
|
|
||||||
printf("I should exit?\n");
|
|
||||||
load_game(&game);
|
|
||||||
should_exit = 0;
|
|
||||||
usleep(1000);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
game.api.finalize(game.state);
|
game.api.finalize(game.state);
|
||||||
free(game.state);
|
free(game.state);
|
||||||
inotify_rm_watch(fd, wd);
|
|
||||||
close(fd);
|
|
||||||
close(epollfd);
|
|
||||||
// CloseWindow();
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user