Don't depend on global constructors for commands
This breaks when using ObjC, as these can run before the ObjC module is initialized, resulting in non-working message sends as the selectors are not registered yet. FossilOrigin-Name: 1ee33c99835abc029ac202afad1f9b3bf26028e55ea1c53c53416c7566ef749d
This commit is contained in:
parent
2fc4599331
commit
0bbe1c8bee
5 changed files with 73 additions and 8 deletions
|
@ -2,7 +2,10 @@ 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')
|
||||
|
@ -39,6 +42,7 @@ executable('client',
|
|||
'src/console.mm',
|
||||
'src/editing.mm',
|
||||
'src/entities.mm',
|
||||
'src/init.mm',
|
||||
'src/main.mm',
|
||||
'src/menus.mm',
|
||||
'src/monster.mm',
|
||||
|
|
45
src/cube.h
45
src/cube.h
|
@ -1,5 +1,7 @@
|
|||
// one big bad include file for the whole engine... nasty!
|
||||
|
||||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
enum // block types, order matters!
|
||||
|
@ -390,21 +392,50 @@ enum // function signatures for script functions, see command.cpp
|
|||
// 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
|
||||
|
|
24
src/init.mm
Normal file
24
src/init.mm
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <vector>
|
||||
|
||||
#import "cube.h"
|
||||
#import "protos.h"
|
||||
|
||||
static std::vector<void (^)(void)> *queue;
|
||||
|
||||
void
|
||||
enqueueInit(const char *name, void (^init)(void))
|
||||
{
|
||||
if (queue == NULL)
|
||||
queue = new std::vector<void (^)(void)>();
|
||||
|
||||
queue->push_back(init);
|
||||
}
|
||||
|
||||
void
|
||||
processInitQueue(void)
|
||||
{
|
||||
for (auto &init : *queue)
|
||||
init();
|
||||
|
||||
queue->clear();
|
||||
}
|
|
@ -104,6 +104,8 @@ main(int argc, char **argv)
|
|||
char *sdesc = "", *ip = "", *master = NULL, *passwd = "";
|
||||
islittleendian = *((char *)&islittleendian);
|
||||
|
||||
processInitQueue();
|
||||
|
||||
#define log(s) conoutf("init: %s", s)
|
||||
log("sdl");
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ 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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue