ohsp

Prototype for a game with dual thruster controls.
git clone git://git.amin.space/ohsp.git
Log | Files | Refs | LICENSE

util_linux.h (2269B)


      1 #ifndef UTIL_LINUX_H
      2 #define UTIL_LINUX_H
      3 
      4 #include <dlfcn.h>
      5 #include <sys/stat.h>
      6 
      7 
      8 time_t file_get_modified_time(char *file_path)
      9 {
     10     time_t mtime = 0;
     11     struct stat file_status = {0};
     12     if (stat(file_path, &file_status) == 0)
     13     {
     14         //printf("File: %s last modified: %s\n", file_path, ctime(&file_status.st_mtime));
     15         mtime = file_status.st_mtime;
     16     }
     17     else
     18     {
     19         fprintf(stderr, "ERROR: Failed to stat file: %s\n", file_path);
     20     }
     21     return mtime;
     22 }
     23 
     24 
     25 void unload_game_code(struct SDLGameCode *game_code)
     26 {
     27     if (!game_code)
     28     {
     29         printf("Invalid pointer *game_code\n");
     30         return;
     31     }
     32 
     33     if (game_code->game_code_library)
     34     {
     35         dlclose(game_code->game_code_library);
     36         game_code->game_code_library = 0;
     37     }
     38     game_code->is_valid = false;
     39     game_code->game_update = 0;
     40     game_code->game_render = 0;
     41 }
     42 
     43 
     44 // TODO: Add backup dll in case loading fails
     45 struct SDLGameCode load_game_code(char *source_lib_path)
     46 {
     47     struct SDLGameCode game_code = {0};
     48 
     49     game_code.last_write_time = file_get_modified_time(source_lib_path);
     50     if (game_code.last_write_time)
     51     {
     52         game_code.game_code_library = dlopen(source_lib_path, RTLD_LAZY);
     53         if (game_code.game_code_library)
     54         {
     55             // NOTE: The C standard (as of C99) distinguishes function pointers
     56             // from object pointers (`void *` is an object pointer). Technically it
     57             // is undefined behavior to cast between these two pointer types. In
     58             // practice, it works on most modern platforms.
     59             //
     60             // In this case, we are protected by POSIX, which specifies that
     61             // function and data pointers must be the same size. We will only ever
     62             // be using dlsym on POSIX-compliant platforms.
     63             game_code.game_update = (game_update_t *) dlsym(game_code.game_code_library, "game_update");
     64             game_code.game_render = (game_render_t *) dlsym(game_code.game_code_library, "game_render");
     65             game_code.is_valid = (game_code.game_update && game_code.game_render);
     66         }
     67     }
     68 
     69     if (!game_code.is_valid)
     70     {
     71         fprintf(stderr, "ERROR: Game code is not valid: %s\n", dlerror());
     72     }
     73 
     74     return game_code;
     75 }
     76 
     77 
     78 #endif