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:
Jonathan Schleifer 2024-08-03 14:50:31 +00:00
parent 2fc4599331
commit 0bbe1c8bee
5 changed files with 73 additions and 8 deletions

View file

@ -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