From 85b7140f119f081ae2ab2747d6b8e85f1fe2a253 Mon Sep 17 00:00:00 2001 From: Kasper Date: Tue, 6 May 2025 21:27:16 +0300 Subject: [PATCH] turn HiisiEngine into a regular solib instead of built module --- CMakeLists.txt | 4 +- hiisi/CMakeLists.txt | 2 + hiisi/hiisi.cpp | 74 +++++++++++++++++--------------- hiisi/hiisi.h | 30 +++++-------- hiisi/main.cpp | 100 +++---------------------------------------- 5 files changed, 60 insertions(+), 150 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d21f6a2..a5da1da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.21) project(Hiisi) -# I just like to have this with my tooling set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_STANDARD 17) @@ -13,4 +12,5 @@ add_subdirectory(hiisi) add_executable(hiisi-run hiisi/main.cpp) -target_link_libraries(hiisi-run hiload) +target_link_libraries(hiisi-run hiisi-engine) +# target_link_libraries(hiisi-run hiload) diff --git a/hiisi/CMakeLists.txt b/hiisi/CMakeLists.txt index e52fb74..46507ec 100644 --- a/hiisi/CMakeLists.txt +++ b/hiisi/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(hiisi-engine SHARED hiisi.h hiisi.cpp) +target_compile_options(hiisi-engine PRIVATE "-Wall" "-Wextra" "-Wpedantic") + set_property(TARGET hiisi-engine PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET hiisi-engine PROPERTY LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) diff --git a/hiisi/hiisi.cpp b/hiisi/hiisi.cpp index ddc819d..698adc8 100644 --- a/hiisi/hiisi.cpp +++ b/hiisi/hiisi.cpp @@ -1,14 +1,16 @@ #include "hiisi.h" -#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ #include #define WINDOW_WIDTH 1280 #define WINDOW_HEIGHT 720 /* This function runs once at startup. */ -int init(EngineData *state, int argc, char *argv[]) -{ +int HiisiEngine::init(int argc, char *argv[]) { + (void)argc; + (void)argv; + SDL_SetAppMetadata("Hiisi Engine", "0.0.1", "me.kitemoonsche.hiisi-engine"); SDL_Window *window = 0; @@ -19,44 +21,46 @@ int init(EngineData *state, int argc, char *argv[]) return SDL_APP_FAILURE; } - if (!SDL_CreateWindowAndRenderer("Hiisi Engine", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + if (!SDL_CreateWindowAndRenderer("Hiisi Engine", WINDOW_WIDTH, + WINDOW_HEIGHT, 0, &window, &renderer)) { SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); return SDL_APP_FAILURE; } - state->window = window; - state->renderer = renderer; + _window = window; + _renderer = renderer; - return SDL_APP_CONTINUE; /* carry on with the program! */ + return SDL_APP_CONTINUE; /* carry on with the program! */ } /* This function runs when a new event (mouse input, keypresses, etc) occurs. */ -int event(EngineData* state) -{ +int HiisiEngine::event() { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_EVENT_QUIT) { - return 0; /* end the program, reporting success to the OS. */ + return 0; /* end the program, reporting success to the OS. */ } } - return 1; /* carry on with the program! */ + return 1; /* carry on with the program! */ } /* This function runs once per frame, and is the heart of the program. */ -int iterate(EngineData *state) -{ - SDL_Renderer *renderer = (SDL_Renderer*)state->renderer; +int HiisiEngine::iterate() { + SDL_Renderer *renderer = (SDL_Renderer *)_renderer; SDL_FRect rects[16]; const Uint64 now = SDL_GetTicks(); - int i; + size_t i; /* we'll have the rectangles grow and shrink over a few seconds. */ const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; - const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; + 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_RenderClear(renderer); /* start with a blank canvas. */ + /* 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_RenderClear(renderer); /* start with a blank canvas. */ /* Rectangles are comprised of set of X and Y coordinates, plus width and height. (0, 0) is the top left of the window, and larger numbers go @@ -66,47 +70,49 @@ int iterate(EngineData *state) /* 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, 250, 0, 255, SDL_ALPHA_OPAQUE); /* red, full alpha */ + SDL_SetRenderDrawColor(renderer, 250, 0, 255, + SDL_ALPHA_OPAQUE); /* red, full alpha */ SDL_RenderRect(renderer, &rects[0]); /* Now let's draw several rectangles with one function call. */ for (i = 0; i < 3; i++) { - const float size = (i+1) * 500.0f; + const float size = (i + 1) * 500.0f; rects[i].w = rects[i].h = size + (size * scale); rects[i].x = (WINDOW_WIDTH - rects[i].w) / 2; /* center it. */ - rects[i].y = (WINDOW_HEIGHT - rects[i].h) / 2; /* center it. */ + rects[i].y = (WINDOW_HEIGHT - rects[i].h) / 2; /* center it. */ } - SDL_SetRenderDrawColor(renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */ - SDL_RenderRects(renderer, rects, 3); /* draw three rectangles at once */ + SDL_SetRenderDrawColor(renderer, 255, 255, 0, + SDL_ALPHA_OPAQUE); /* green, full alpha */ + SDL_RenderRects(renderer, rects, 3); /* draw three rectangles at once */ - /* those were rectangle _outlines_, really. You can also draw _filled_ rectangles! */ + /* those were rectangle _outlines_, really. You can also draw _filled_ + * rectangles! */ rects[0].x = 400; rects[0].y = 50; rects[0].w = 100 + (100 * scale); rects[0].h = 50 + (50 * scale); - SDL_SetRenderDrawColor(renderer, 50, 25, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */ + SDL_SetRenderDrawColor(renderer, 50, 25, 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)); + const float w = (float)(WINDOW_WIDTH / SDL_arraysize(rects)); const float h = i * 8.0f; rects[i].x = i * w; rects[i].y = WINDOW_HEIGHT - h; rects[i].w = w; rects[i].h = h; } - SDL_SetRenderDrawColor(renderer, 25, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */ + SDL_SetRenderDrawColor(renderer, 25, 255, 255, + SDL_ALPHA_OPAQUE); /* white, full alpha */ SDL_RenderFillRects(renderer, rects, SDL_arraysize(rects)); - SDL_RenderPresent(renderer); /* put it all on the screen! */ + SDL_RenderPresent(renderer); /* put it all on the screen! */ - return SDL_APP_CONTINUE; /* carry on with the program! */ + return SDL_APP_CONTINUE; /* carry on with the program! */ } /* This function runs once at shutdown. */ -void quit(EngineData *state) -{ - /* SDL will clean up the window/renderer for us. */ +void HiisiEngine::quit() { /* SDL will clean up the window/renderer for us. */ } diff --git a/hiisi/hiisi.h b/hiisi/hiisi.h index 3d5510a..3bf1dba 100644 --- a/hiisi/hiisi.h +++ b/hiisi/hiisi.h @@ -1,25 +1,17 @@ #ifndef HIISI_H_ #define HIISI_H_ -extern "C" { +class HiisiEngine { + public: + int init(int argc, char *argv[]); + int event(); + int iterate(); + void quit(); - struct EngineData { - void *window = 0; - void *renderer = 0; - }; + private: + void *_window = 0; + void *_renderer = 0; + void *_module = 0; +}; - 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 dc6dcc3..7ab2e2b 100644 --- a/hiisi/main.cpp +++ b/hiisi/main.cpp @@ -8,105 +8,15 @@ #include #include -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; - dlinfo(mod, RTLD_DI_LMID, &list); - printf("link-map list id: %ld\n", list); - - link_map *lmap = 0; - dlinfo(mod, RTLD_DI_LINKMAP, &lmap); - - printf("Link map:\n"); - printf("addr: %lu\n", lmap->l_addr); - printf("name: %s\n", lmap->l_name); - printf("dynamic section: %p\n", lmap->l_ld); - - char pathname[256]; - dlinfo(mod, RTLD_DI_ORIGIN, pathname); - printf("path: %s\n", pathname); - - /* Discover the size of the buffer that we must pass to - RTLD_DI_SERINFO. */ - Dl_serinfo serinfo; - Dl_serinfo *sip; - - if (dlinfo(mod, RTLD_DI_SERINFOSIZE, &serinfo) == -1) { - fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); - exit(EXIT_FAILURE); - } - - /* Allocate the buffer for use with RTLD_DI_SERINFO. */ - - sip = (Dl_serinfo *)malloc(serinfo.dls_size); - if (sip == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } - - /* Initialize the 'dls_size' and 'dls_cnt' fields in the newly - allocated buffer. */ - - if (dlinfo(mod, RTLD_DI_SERINFOSIZE, sip) == -1) { - fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); - exit(EXIT_FAILURE); - } - - /* Fetch and print library search list. */ - - if (dlinfo(mod, RTLD_DI_SERINFO, sip) == -1) { - fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror()); - exit(EXIT_FAILURE); - } - - for (size_t j = 0; j < serinfo.dls_cnt; j++) - printf("dls_serpath[%zu].dls_name = %s\n", j, - sip->dls_serpath[j].dls_name); - - Engine engine; - engine.module = mod; - *(void **)&engine.init = dlsym(mod, "init"); - *(void **)&engine.event = dlsym(mod, "event"); - *(void **)&engine.iterate = dlsym(mod, "iterate"); - *(void **)&engine.quit = dlsym(mod, "quit"); - - assert(engine.init); - assert(engine.event); - assert(engine.iterate); - assert(engine.quit); - - return engine; -} - int main(int argc, char **argv) { - signal(SIGUSR1, reload_signal_handler); + HiisiEngine hiisi; - EngineData state; - - Engine hiisi = load_hiisi(); - if (!hiisi.module) { - printf("%s\n", dlerror()); - return 1; + hiisi.init(argc, argv); + while (hiisi.event()) { + hiisi.iterate(); } - 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); - + hiisi.quit(); return 0; }