From ab18ed1d4a055c3f53f2543b70d146c536a6c05e Mon Sep 17 00:00:00 2001 From: Kasper Date: Thu, 13 Mar 2025 00:52:35 +0200 Subject: [PATCH] not quite yet working live reload --- hiisi/hiisi.cpp | 24 ++++++++++++++---------- hiisi/hiisi.h | 25 +++++++++++++++---------- hiisi/main.cpp | 24 +++++++++++++++++++----- live-reloader.sh | 10 ++++++++++ 4 files changed, 58 insertions(+), 25 deletions(-) create mode 100755 live-reloader.sh diff --git a/hiisi/hiisi.cpp b/hiisi/hiisi.cpp index b408320..3755bbc 100644 --- a/hiisi/hiisi.cpp +++ b/hiisi/hiisi.cpp @@ -3,18 +3,17 @@ #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ #include -/* We will use this renderer to draw into this window every frame. */ -static SDL_Window *window = NULL; -static SDL_Renderer *renderer = NULL; - #define WINDOW_WIDTH 1280 #define WINDOW_HEIGHT 720 /* This function runs once at startup. */ -int init(void *appstate, int argc, char *argv[]) +int init(EngineData *state, int argc, char *argv[]) { SDL_SetAppMetadata("Hiisi Engine", "0.0.1", "me.kitemoonsche.hiisi-engine"); + SDL_Window *window = 0; + SDL_Renderer *renderer = 0; + if (!SDL_Init(SDL_INIT_VIDEO)) { SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); return SDL_APP_FAILURE; @@ -25,11 +24,14 @@ int init(void *appstate, int argc, char *argv[]) return SDL_APP_FAILURE; } + state->window = window; + state->renderer = renderer; + return SDL_APP_CONTINUE; /* carry on with the program! */ } /* This function runs when a new event (mouse input, keypresses, etc) occurs. */ -int event(void *appstate) +int event(EngineData* state) { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -41,8 +43,9 @@ int event(void *appstate) } /* This function runs once per frame, and is the heart of the program. */ -int iterate(void *appstate) +int iterate(EngineData *state) { + SDL_Renderer *renderer = (SDL_Renderer*)state->renderer; SDL_FRect rects[16]; const Uint64 now = SDL_GetTicks(); int i; @@ -52,7 +55,7 @@ int iterate(void *appstate) const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; /* as you can see from this, rendering draws over whatever was drawn before it. */ - SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_SetRenderDrawColor(renderer, 0, 50, 50, SDL_ALPHA_OPAQUE); /* black, full alpha */ SDL_RenderClear(renderer); /* start with a blank canvas. */ /* Rectangles are comprised of set of X and Y coordinates, plus width and @@ -63,7 +66,7 @@ int iterate(void *appstate) /* Let's draw a single rectangle (square, really). */ rects[0].x = rects[0].y = 100; rects[0].w = rects[0].h = 100 + (100 * scale); - SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */ + SDL_SetRenderDrawColor(renderer, 250, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */ SDL_RenderRect(renderer, &rects[0]); /* Now let's draw several rectangles with one function call. */ @@ -84,6 +87,7 @@ int iterate(void *appstate) SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */ SDL_RenderFillRect(renderer, &rects[0]); + /* ...and also fill a bunch of rectangles at once... */ for (i = 0; i < SDL_arraysize(rects); i++) { const float w = (float) (WINDOW_WIDTH / SDL_arraysize(rects)); @@ -102,7 +106,7 @@ int iterate(void *appstate) } /* This function runs once at shutdown. */ -void quit(void *appstate) +void quit(EngineData *state) { /* SDL will clean up the window/renderer for us. */ } diff --git a/hiisi/hiisi.h b/hiisi/hiisi.h index 40b4aed..3d5510a 100644 --- a/hiisi/hiisi.h +++ b/hiisi/hiisi.h @@ -3,18 +3,23 @@ extern "C" { - struct Engine { - void *module = 0; - int (*init)(void *, int, char**); - int (*event)(void *); - int (*iterate)(void *); - void (*quit)(void *); + struct EngineData { + void *window = 0; + void *renderer = 0; }; - int init(void *appstate, int argc, char *argv[]); - int event(void *appstate); - int iterate(void *appstate); - void quit(void *appstate); + struct Engine { + void *module = 0; + int (*init)(EngineData *, int, char**); + int (*event)(EngineData *); + int (*iterate)(EngineData *); + void (*quit)(EngineData *); + }; + + int init(EngineData *state, int argc, char *argv[]); + int event(EngineData *state); + int iterate(EngineData *state); + void quit(EngineData *state); } #endif // HIISI_H_ diff --git a/hiisi/main.cpp b/hiisi/main.cpp index 8969bbe..0f842dc 100644 --- a/hiisi/main.cpp +++ b/hiisi/main.cpp @@ -1,15 +1,23 @@ #include "hiisi.h" #include -#include #include #include #include #include +#include +#include struct app_state {}; -Engine load_hiisi(const char *name) { +std::atomic reload_requested(false); + +void reload_signal_handler(int) { + reload_requested = true; +} + +Engine load_hiisi() { + const char *name = "build/hiisi/libhiisi-engine.so"; void *mod = dlopen(name, RTLD_NOW); Lmid_t list; @@ -82,10 +90,11 @@ Engine load_hiisi(const char *name) { int main(int argc, char **argv) { - app_state state; - void *state_ptr = &state; + signal(SIGUSR1, reload_signal_handler); - Engine hiisi = load_hiisi("build/hiisi/libhiisi-engine.so"); + EngineData state; + + Engine hiisi = load_hiisi(); if (!hiisi.module) { printf("%s\n", dlerror()); return 1; @@ -94,6 +103,11 @@ int main(int argc, char **argv) { hiisi.init(&state, argc, argv); while (hiisi.event(&state)) { hiisi.iterate(&state); + if (reload_requested) { + dlclose(hiisi.module); + hiisi = load_hiisi(); + reload_requested = false; + } } dlclose(hiisi.module); diff --git a/live-reloader.sh b/live-reloader.sh new file mode 100755 index 0000000..a8f33a0 --- /dev/null +++ b/live-reloader.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +echo "Watching changes in hiisi..." +while true; do + inotifywait -e modify build/hiisi/libhiisi-engine.so + echo "$(date \"%H:%M:%S\") - Hiisi changed!" + + HIISI_PID=$(pgrep -x hiisi-run) + kill -USR1 "${HIISI_PID}" && echo "Signal sent!" || echo "Signal send failed!" +done