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')
|
meson_version: '1.5.0')
|
||||||
|
|
||||||
add_global_arguments(
|
add_global_arguments(
|
||||||
['-fobjc-arc', '-fobjc-arc-exceptions'],
|
[
|
||||||
|
'-fobjc-arc',
|
||||||
|
'-fobjc-arc-exceptions'
|
||||||
|
],
|
||||||
language: 'objcpp')
|
language: 'objcpp')
|
||||||
|
|
||||||
objfw_dep = dependency('objfw')
|
objfw_dep = dependency('objfw')
|
||||||
|
@ -39,6 +42,7 @@ executable('client',
|
||||||
'src/console.mm',
|
'src/console.mm',
|
||||||
'src/editing.mm',
|
'src/editing.mm',
|
||||||
'src/entities.mm',
|
'src/entities.mm',
|
||||||
|
'src/init.mm',
|
||||||
'src/main.mm',
|
'src/main.mm',
|
||||||
'src/menus.mm',
|
'src/menus.mm',
|
||||||
'src/monster.mm',
|
'src/monster.mm',
|
||||||
|
|
43
src/cube.h
43
src/cube.h
|
@ -1,5 +1,7 @@
|
||||||
// one big bad include file for the whole engine... nasty!
|
// one big bad include file for the whole engine... nasty!
|
||||||
|
|
||||||
|
#import <ObjFW/ObjFW.h>
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
enum // block types, order matters!
|
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
|
// nasty macros for registering script functions, abuses globals to avoid
|
||||||
// excessive infrastructure
|
// excessive infrastructure
|
||||||
#define COMMANDN(name, fun, nargs) \
|
#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 COMMAND(name, nargs) COMMANDN(name, name, nargs)
|
||||||
#define VARP(name, min, cur, max) \
|
#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) \
|
#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) \
|
#define VARF(name, min, cur, max, body) \
|
||||||
void var_##name(); \
|
void var_##name(); \
|
||||||
static int name = \
|
static int name; \
|
||||||
variable(#name, min, cur, max, &name, var_##name, false); \
|
OF_CONSTRUCTOR() \
|
||||||
|
{ \
|
||||||
|
enqueueInit(#name, ^{ \
|
||||||
|
name = variable( \
|
||||||
|
#name, min, cur, max, &name, var_##name, false); \
|
||||||
|
}); \
|
||||||
|
} \
|
||||||
void var_##name() { body; }
|
void var_##name() { body; }
|
||||||
#define VARFP(name, min, cur, max, body) \
|
#define VARFP(name, min, cur, max, body) \
|
||||||
void var_##name(); \
|
void var_##name(); \
|
||||||
static int name = \
|
static int name; \
|
||||||
|
OF_CONSTRUCTOR() \
|
||||||
|
{ \
|
||||||
|
enqueueInit(#name, ^{ \
|
||||||
|
name = \
|
||||||
variable(#name, min, cur, max, &name, var_##name, true); \
|
variable(#name, min, cur, max, &name, var_##name, true); \
|
||||||
|
}); \
|
||||||
|
} \
|
||||||
void var_##name() { body; }
|
void var_##name() { body; }
|
||||||
|
|
||||||
#define ATOI(s) strtol(s, NULL, 0) // supports hexadecimal numbers
|
#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 = "";
|
char *sdesc = "", *ip = "", *master = NULL, *passwd = "";
|
||||||
islittleendian = *((char *)&islittleendian);
|
islittleendian = *((char *)&islittleendian);
|
||||||
|
|
||||||
|
processInitQueue();
|
||||||
|
|
||||||
#define log(s) conoutf("init: %s", s)
|
#define log(s) conoutf("init: %s", s)
|
||||||
log("sdl");
|
log("sdl");
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ extern void conoutf(const char *s, ...);
|
||||||
extern char *getcurcommand();
|
extern char *getcurcommand();
|
||||||
extern void writebinds(FILE *f);
|
extern void writebinds(FILE *f);
|
||||||
|
|
||||||
|
// init
|
||||||
|
extern void enqueueInit(const char *name, void (^init)(void));
|
||||||
|
extern void processInitQueue(void);
|
||||||
|
|
||||||
// menus
|
// menus
|
||||||
extern bool rendermenu();
|
extern bool rendermenu();
|
||||||
extern void menuset(int menu);
|
extern void menuset(int menu);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue