Hot reloading: WIP Got something working

This commit is contained in:
Joseph Ferano 2024-01-09 22:46:30 +07:00
parent a5c6569162
commit 517df72ec3
5 changed files with 60 additions and 27 deletions

View File

@ -3,7 +3,7 @@ CC=gcc
.PHONY: build clean run all
all: main dod
all: main dod boids_main
main: main.c lib.h sprites.o sprites.h game_data.h ./lib/libraylib.a
$(CC) $(CFLAGS) -Iinclude/ -lm main.c -o main sprites.o ./lib/libraylib.a
@ -14,15 +14,15 @@ sprites.o: sprites.c sprites.h lib.h
dod: dod.c ./lib/libraylib.a
$(CC) $(CFLAGS) -Iinclude/ -lm dod.c -o dod ./lib/libraylib.a
boids_main: boids_main.c lib.h ./lib/libraylib.a
$(CC) $(CFLAGS) -Iinclude/ -lm $< -o $@ ./lib/libraylib.a
boids_main: boids_main.c lib.h ./lib/libraylib.a libboids.so
$(CC) $(CFLAGS) -Iinclude/ -fPIC -ldl -lm $< -o $@ ./lib/libraylib.a
libboids.so: boids_game.c boids_game.h lib.h
$(CC) $(CFLAGS) -Iinclude/ -lm -c $< -o $@
$(CC) $(CFLAGS) -shared -fPIC -Iinclude/ -lm -lOpenGL $< -o $@ ./lib/libraylib.a
run: all
./main
clean:
rm -vf main
rm -vf *.so *.o main boids_main dod

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <stdio.h>
#include "include/raylib.h"
#include "include/raymath.h"
#include "boids_game.h"
@ -6,7 +7,6 @@
#define SCREEN_WIDTH 1300
#define SCREEN_HEIGHT 1080
#define NUM_BOIDS 16
typedef struct Boid {
Point position;
@ -22,7 +22,11 @@ typedef struct GameState {
float max_force;
} GameState;
GameState *init() {
static GameState *init() {
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids");
SetTargetFPS(60);
GameState *state = malloc(sizeof(struct GameApi));
state->num_boids = 16;
state->max_speed = 5.0f;
@ -44,22 +48,23 @@ GameState *init() {
boid->acceleration = (Vector2){0};
}
printf("I loaded the contents\n");
return state;
}
void finalize(GameState *state) {
static void finalize(GameState *state) {
(void)state;
}
void reload(GameState *state) {
static void reload(GameState *state) {
(void)state;
}
void unload(GameState *state) {
static void unload(GameState *state) {
(void)state;
}
void step(GameState *state) {
static void step(GameState *state) {
// Process Input
if (IsMouseButtonPressed(0)) {
Vector2 mouse_pos = GetMousePosition();
@ -68,7 +73,7 @@ void step(GameState *state) {
// Update
for (int i = 0; i < NUM_BOIDS; i++) {
for (int i = 0; i < state->num_boids; i++) {
Boid *boid = &state->boids[i];
if (state->target_pos.tag == SOME) {
Vector2 desired = Vector2Subtract(state->target_pos.some.point, boid->position);
@ -92,11 +97,20 @@ void step(GameState *state) {
// want to get distracted with that
// DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, GREEN);
// DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, GREEN);
for (int i = 0; i < NUM_BOIDS; i++) {
for (int i = 0; i < state->num_boids; i++) {
Boid *boid = &state->boids[i];
DrawCircle(boid->position.x, boid->position.y, 27, BLACK);
DrawCircle(boid->position.x, boid->position.y, 20, GREEN);
}
}
EndDrawing();
}
const struct GameApi GAME_API = {
.init = init,
.reload = reload,
.step = step,
.unload = unload,
.finalize = finalize
};

View File

@ -3,11 +3,11 @@
struct GameState;
typedef struct GameApi {
struct GameApi *(*init)();
void (*finalize) (struct GameApi *state);
void (*reload) (struct GameApi *state);
void (*unload) (struct GameApi *state);
void (*step) (struct GameApi *state);
struct GameState *(*init)();
void (*finalize) (struct GameState *state);
void (*reload) (struct GameState *state);
void (*unload) (struct GameState *state);
void (*step) (struct GameState *state);
} GameApi;
extern const struct GameApi GAME_API;
extern const GameApi GAME_API;

View File

@ -24,6 +24,27 @@ struct Game {
};
#define MAX_EVENTS 1
void load_game(struct Game *game) {
void *handle = dlopen(GAME_LIB, RTLD_NOW);
if (handle) {
game->handle = handle;
const struct GameApi *api = dlsym(game->handle, "GAME_API");
if (api != NULL) {
printf("Loaded API, calling init()\n");
game->api = *api;
game->state = game->api.init();
} 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) {
int fd = inotify_init();
if (fd < 0) {
@ -42,17 +63,15 @@ int main(void) {
event.events = EPOLLIN;
event.data.fd = fd;
// register inotify fd with epoll
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event) == -1) {
fprintf(stderr, "Error adding inotify descriptor to epoll\n");
}
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids");
SetTargetFPS(TARGET_FPS);
struct epoll_event events[MAX_EVENTS];
struct Game game = {0};
load_game(&game);
while (!WindowShouldClose()) {
int nfds = epoll_wait(epollfd, events, MAX_EVENTS, 0);
if (nfds == -1) {
@ -63,13 +82,12 @@ int main(void) {
for (int n = 0; n < nfds; ++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));
}
}
BeginDrawing();
ClearBackground(BEIGE);
EndDrawing();
game.api.step(game.state);
}
inotify_rm_watch(fd, wd);

View File

@ -16,6 +16,7 @@ CLOCK: [2024-01-06 Sat 11:00]--[2024-01-06 Sat 13:10] => 2:10
:END:
** <2024-01-09 Tue>
:LOGBOOK:
CLOCK: [2024-01-09 Tue 21:28]
CLOCK: [2024-01-09 Tue 19:30]--[2024-01-09 Tue 20:31] => 1:01
CLOCK: [2024-01-09 Tue 10:45]--[2024-01-09 Tue 11:15] => 0:30
:END: