Test hot reloading
This commit is contained in:
parent
8ad090b582
commit
b4f41103f2
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
.cache
|
||||
compile_commands.json
|
||||
main
|
||||
*.so
|
||||
*.o
|
||||
|
49
compile
49
compile
@ -1,9 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
CC=clang
|
||||
CFLAGS="-g -Wall $(pkg-config --cflags sdl2)"
|
||||
LIBS="$(pkg-config --libs sdl2)"
|
||||
SRC=src/*.c
|
||||
OUT=main
|
||||
BUILD_TYPE="debug"
|
||||
|
||||
(set -x ; $CC $CFLAGS $LIBS $SRC -o $OUT)
|
||||
while [[ $# > 0 ]];do
|
||||
case $1 in
|
||||
--release)
|
||||
BUILD_TYPE="release"
|
||||
shift
|
||||
;;
|
||||
*|-*|--*)
|
||||
echo "Unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
CC=clang
|
||||
CFLAGS="-Wall $(pkg-config --cflags sdl2)"
|
||||
LIBS="$(pkg-config --libs sdl2)"
|
||||
MAIN=src/main.c
|
||||
MAIN_FLAGS=""
|
||||
GAME=src/game.c
|
||||
GAME_FLAGS="-DNDEBUG"
|
||||
OUT=main
|
||||
GAME_OUT=""
|
||||
|
||||
if [[ $BUILD_TYPE == "debug" ]]; then
|
||||
CFLAGS+=" -g"
|
||||
MAIN_FLAGS="-ldl -Wl,-rpath,\$ORIGIN"
|
||||
GAME_FLAGS+=" -fPIC -shared"
|
||||
GAME_OUT="-o game.so"
|
||||
MAIN+=" src/game.c"
|
||||
else
|
||||
CFLAGS+=" -O3"
|
||||
MAIN_FLAGS="-DNDEBUG"
|
||||
GAME_FLAGS+=" -c"
|
||||
MAIN+=" game.o"
|
||||
fi
|
||||
|
||||
LOCKFILE="game.so.lock"
|
||||
touch $LOCKFILE && (set -x ; $CC $CFLAGS $GAME_FLAGS $LIBS $GAME $GAME_OUT)
|
||||
if [[ -f $LOCKFILE ]];then
|
||||
rm $LOCKFILE
|
||||
fi
|
||||
(set -x ; $CC $CFLAGS $MAIN_FLAGS $LIBS $MAIN -o $OUT)
|
||||
|
102
src/game.c
Normal file
102
src/game.c
Normal file
@ -0,0 +1,102 @@
|
||||
#include "game.h"
|
||||
|
||||
#if DEBUG
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#define LIB "game.so"
|
||||
#define LOCKFILE "game.so.lock"
|
||||
|
||||
static void *handle = NULL;
|
||||
static long int last_mtime;
|
||||
void (*update_character)(int window_height) = NULL;
|
||||
void (*render_character)(SDL_Renderer *renderer) = NULL;
|
||||
|
||||
bool load_symbols(void) {
|
||||
struct stat st;
|
||||
if (stat(LOCKFILE, &st) == 0) {
|
||||
// If lock file exists, don't reload the library
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stat(LIB, &st) != 0) {
|
||||
perror("Error checking library stat: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
long int mtime = st.st_mtim.tv_sec * 1000000000 + st.st_mtim.tv_nsec;
|
||||
if (mtime == last_mtime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
last_mtime = mtime;
|
||||
|
||||
if (handle) {
|
||||
close_library();
|
||||
}
|
||||
|
||||
handle = dlopen(LIB, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "Failed to load library: %s\n", dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
dlerror(); // Clear errors
|
||||
|
||||
*(void **)(&update_character) = dlsym(handle, "update_character");
|
||||
*(void **)(&render_character) = dlsym(handle, "render_character");
|
||||
|
||||
char *error = dlerror();
|
||||
if (error != NULL) {
|
||||
fprintf(stderr, "Failed to load function symbol: %s", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void close_library(void) {
|
||||
if (handle) {
|
||||
dlclose(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#include "SDL_rect.h"
|
||||
#include "SDL_render.h"
|
||||
|
||||
typedef struct state State;
|
||||
struct state {
|
||||
float delta;
|
||||
float speed;
|
||||
SDL_Rect character;
|
||||
};
|
||||
|
||||
static State game = {
|
||||
.delta = 1.f / 60.f,
|
||||
.speed = 1600.f,
|
||||
.character = {.x = 375, .y = 0, .w = 50, .h = 50},
|
||||
};
|
||||
|
||||
void update_character(int window_height) {
|
||||
game.character.y += game.speed * game.delta;
|
||||
if (game.character.y < 0 ||
|
||||
game.character.y + game.character.h > window_height) {
|
||||
game.speed *= -1.f;
|
||||
|
||||
if (game.character.y < 0) {
|
||||
game.character.y = 0;
|
||||
} else {
|
||||
game.character.y = window_height - game.character.h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render_character(SDL_Renderer *renderer) {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(renderer, &game.character);
|
||||
}
|
||||
#endif
|
22
src/game.h
Normal file
22
src/game.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "SDL_render.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DEBUG 0
|
||||
#else
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#include <stdbool.h>
|
||||
|
||||
bool load_symbols(void);
|
||||
void close_library(void);
|
||||
|
||||
extern void (*update_character)(int window_height);
|
||||
extern void (*render_character)(SDL_Renderer *renderer);
|
||||
#else
|
||||
void update_character(int window_height);
|
||||
void render_character(SDL_Renderer *renderer);
|
||||
#endif
|
29
src/main.c
29
src/main.c
@ -1,9 +1,16 @@
|
||||
#include "game.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_events.h>
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <SDL2/SDL_video.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DEBUG 0
|
||||
#else
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
||||
@ -21,6 +28,13 @@ int main(void) {
|
||||
|
||||
SDL_Event event = {0};
|
||||
|
||||
#if DEBUG
|
||||
if (!load_symbols()) {
|
||||
fprintf(stderr, "Failed to load game library\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (running) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
@ -30,13 +44,28 @@ int main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (!load_symbols()) {
|
||||
fprintf(stderr, "Failed to load game library\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
update_character(WINDOW_HEIGHT);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
render_character(renderer);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
close_library();
|
||||
#endif
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
|
||||
SDL_DestroyWindow(window);
|
||||
|
Loading…
Reference in New Issue
Block a user