Index: meson.build ================================================================== --- meson.build +++ meson.build @@ -1,10 +1,13 @@ project('Cube', ['c', 'objcpp'], meson_version: '1.5.0') add_global_arguments( - ['-fobjc-arc', '-fobjc-arc-exceptions'], + [ + '-fobjc-arc', + '-fobjc-arc-exceptions' + ], language: 'objcpp') objfw_dep = dependency('objfw') sdl12_dep = dependency('sdl12_compat') sdlimage_dep = dependency('SDL_image') @@ -37,10 +40,11 @@ 'src/clients2c.mm', 'src/command.mm', 'src/console.mm', 'src/editing.mm', 'src/entities.mm', + 'src/init.mm', 'src/main.mm', 'src/menus.mm', 'src/monster.mm', 'src/physics.mm', 'src/rendercubes.mm', Index: src/cube.h ================================================================== --- src/cube.h +++ src/cube.h @@ -1,7 +1,9 @@ // one big bad include file for the whole engine... nasty! +#import + #include "tools.h" enum // block types, order matters! { SOLID = 0, // entirely solid cube [only specifies wtex] @@ -388,25 +390,54 @@ }; // nasty macros for registering script functions, abuses globals to avoid // excessive infrastructure #define COMMANDN(name, fun, nargs) \ - static bool __dummy_##fun = addcommand(#name, (void (*)())fun, nargs) + OF_CONSTRUCTOR() \ + { \ + enqueueInit(#name, ^{ \ + addcommand(#name, (void (*)())fun, nargs); \ + }); \ + } #define COMMAND(name, nargs) COMMANDN(name, name, nargs) #define VARP(name, min, cur, max) \ - int name = variable(#name, min, cur, max, &name, NULL, true) + int name; \ + OF_CONSTRUCTOR() \ + { \ + enqueueInit(#name, ^{ \ + name = variable(#name, min, cur, max, &name, NULL, true); \ + }); \ + } #define VAR(name, min, cur, max) \ - int name = variable(#name, min, cur, max, &name, NULL, false) + int name; \ + OF_CONSTRUCTOR() \ + { \ + enqueueInit(#name, ^{ \ + name = variable(#name, min, cur, max, &name, NULL, false); \ + }); \ + } #define VARF(name, min, cur, max, body) \ void var_##name(); \ - static int name = \ - variable(#name, min, cur, max, &name, var_##name, false); \ + static int name; \ + OF_CONSTRUCTOR() \ + { \ + enqueueInit(#name, ^{ \ + name = variable( \ + #name, min, cur, max, &name, var_##name, false); \ + }); \ + } \ void var_##name() { body; } #define VARFP(name, min, cur, max, body) \ void var_##name(); \ - static int name = \ - variable(#name, min, cur, max, &name, var_##name, true); \ + static int name; \ + OF_CONSTRUCTOR() \ + { \ + enqueueInit(#name, ^{ \ + name = \ + variable(#name, min, cur, max, &name, var_##name, true); \ + }); \ + } \ void var_##name() { body; } #define ATOI(s) strtol(s, NULL, 0) // supports hexadecimal numbers #ifdef WIN32 ADDED src/init.mm Index: src/init.mm ================================================================== --- /dev/null +++ src/init.mm @@ -0,0 +1,24 @@ +#include + +#import "cube.h" +#import "protos.h" + +static std::vector *queue; + +void +enqueueInit(const char *name, void (^init)(void)) +{ + if (queue == NULL) + queue = new std::vector(); + + queue->push_back(init); +} + +void +processInitQueue(void) +{ + for (auto &init : *queue) + init(); + + queue->clear(); +} Index: src/main.mm ================================================================== --- src/main.mm +++ src/main.mm @@ -101,10 +101,12 @@ { bool dedicated = false; int fs = SDL_FULLSCREEN, par = 0, uprate = 0, maxcl = 4; char *sdesc = "", *ip = "", *master = NULL, *passwd = ""; islittleendian = *((char *)&islittleendian); + + processInitQueue(); #define log(s) conoutf("init: %s", s) log("sdl"); for (int i = 1; i < argc; i++) { Index: src/protos.h ================================================================== --- src/protos.h +++ src/protos.h @@ -21,10 +21,14 @@ extern void renderconsole(); extern void conoutf(const char *s, ...); extern char *getcurcommand(); extern void writebinds(FILE *f); +// init +extern void enqueueInit(const char *name, void (^init)(void)); +extern void processInitQueue(void); + // menus extern bool rendermenu(); extern void menuset(int menu); extern void menumanual(int m, int n, char *text); extern void sortmenu(int start, int num);