Capture the Flag, 2008 Jun 17
[SauerbratenRemote.git] / src / shared / command.h
blob6baeacdb7edad071c45978f7cad4135f8e57c99a
1 // script binding functionality
4 enum { ID_VAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_CCOMMAND, ID_ALIAS };
6 enum { NO_OVERRIDE = INT_MAX, OVERRIDDEN = 0 };
8 enum { IDF_PERSIST = 1<<0, IDF_OVERRIDE = 1<<1 };
10 struct identstack
12 char *action;
13 identstack *next;
16 union identval
18 int i; // ID_VAR
19 float f; // ID_FVAR
20 char *s; // ID_SVAR
23 union identvalptr
25 int *i; // ID_VAR
26 float *f; // ID_FVAR
27 char **s; // ID_SVAR
30 struct ident
32 int type; // one of ID_* above
33 const char *name;
34 int minval, maxval; // ID_VAR
35 int override; // either NO_OVERRIDE, OVERRIDDEN, or value
36 union
38 void (__cdecl *fun)(); // ID_VAR, ID_COMMAND, ID_CCOMMAND
39 identstack *stack; // ID_ALIAS
41 union
43 const char *narg; // ID_COMMAND, ID_CCOMMAND
44 char *action; // ID_ALIAS
45 identval val; // ID_VAR, ID_FVAR, ID_SVAR
47 union
49 void *self; // ID_COMMAND, ID_CCOMMAND
50 char *isexecuting; // ID_ALIAS
51 identval overrideval; // ID_VAR, ID_FVAR, ID_SVAR
53 identvalptr storage; // ID_VAR, ID_FVAR, ID_SVAR
54 int flags;
56 ident() {}
57 // ID_VAR
58 ident(int t, const char *n, int m, int c, int x, int *s, void *f = NULL, int flags = 0)
59 : type(t), name(n), minval(m), maxval(x), override(NO_OVERRIDE), fun((void (__cdecl *)())f), flags(flags)
60 { val.i = c; storage.i = s; }
61 // ID_FVAR
62 ident(int t, const char *n, float c, float *s, void *f = NULL, int flags = 0)
63 : type(t), name(n), override(NO_OVERRIDE), fun((void (__cdecl *)())f), flags(flags)
64 { val.f = c; storage.f = s; }
65 // ID_SVAR
66 ident(int t, const char *n, char *c, char **s, void *f = NULL, int flags = 0)
67 : type(t), name(n), override(NO_OVERRIDE), fun((void (__cdecl *)())f), flags(flags)
68 { val.s = c; storage.s = s; }
69 // ID_ALIAS
70 ident(int t, const char *n, char *a, int flags)
71 : type(t), name(n), override(NO_OVERRIDE), stack(NULL), action(a), flags(flags) {}
72 // ID_COMMAND, ID_CCOMMAND
73 ident(int t, const char *n, const char *narg, void *f = NULL, void *s = NULL, int flags = 0)
74 : type(t), name(n), fun((void (__cdecl *)(void))f), narg(narg), self(s), flags(flags) {}
76 virtual ~ident() {}
78 ident &operator=(const ident &o) { memcpy(this, &o, sizeof(ident)); return *this; } // force vtable copy, ugh
80 virtual void changed() { if(fun) fun(); }
83 extern void addident(const char *name, ident *id);
84 extern void intret(int v);
85 extern void result(const char *s);
87 // nasty macros for registering script functions, abuses globals to avoid excessive infrastructure
88 #define COMMANDN(name, fun, nargs) static bool __dummy_##fun = addcommand(#name, (void (*)())fun, nargs)
89 #define COMMAND(name, nargs) COMMANDN(name, name, nargs)
91 #define _VAR(name, global, min, cur, max, persist) int global = variable(#name, min, cur, max, &global, NULL, persist)
92 #define VARN(name, global, min, cur, max) _VAR(name, global, min, cur, max, 0)
93 #define VARNP(name, global, min, cur, max) _VAR(name, global, min, cur, max, IDF_PERSIST)
94 #define VARNR(name, global, min, cur, max) _VAR(name, global, min, cur, max, IDF_OVERRIDE)
95 #define VAR(name, min, cur, max) _VAR(name, name, min, cur, max, 0)
96 #define VARP(name, min, cur, max) _VAR(name, name, min, cur, max, IDF_PERSIST)
97 #define VARR(name, min, cur, max) _VAR(name, name, min, cur, max, IDF_OVERRIDE)
98 #define _VARF(name, global, min, cur, max, body, persist) void var_##name(); int global = variable(#name, min, cur, max, &global, var_##name, persist); void var_##name() { body; }
99 #define VARFN(name, global, min, cur, max, body) _VARF(name, global, min, cur, max, body, 0)
100 #define VARF(name, min, cur, max, body) _VARF(name, name, min, cur, max, body, 0)
101 #define VARFP(name, min, cur, max, body) _VARF(name, name, min, cur, max, body, IDF_PERSIST)
102 #define VARFR(name, min, cur, max, body) _VARF(name, name, min, cur, max, body, IDF_OVERRIDE)
104 #define _FVAR(name, global, cur, persist) float global = fvariable(#name, cur, &global, NULL, persist)
105 #define FVARN(name, global, cur) _FVAR(name, global, cur, 0)
106 #define FVARNP(name, global, cur) _FVAR(name, global, cur, IDF_PERSIST)
107 #define FVARNR(name, global, cur) _FVAR(name, global, cur, IDF_OVERRIDE)
108 #define FVAR(name, cur) _FVAR(name, name, cur, 0)
109 #define FVARP(name, cur) _FVAR(name, name, cur, IDF_PERSIST)
110 #define FVARR(name, cur) _FVAR(name, name, cur, IDF_OVERRIDE)
111 #define _FVARF(name, global, cur, body, persist) void var_##name(); float global = fvariable(#name, cur, &global, var_##name, persist); void var_##name() { body; }
112 #define FVARFN(name, global, cur, body) _FVARF(name, global, cur, body, 0)
113 #define FVARF(name, cur, body) _FVARF(name, name, cur, body, 0)
114 #define FVARFP(name, cur, body) _FVARF(name, name, cur, body, IDF_PERSIST)
115 #define FVARFR(name, cur, body) _FVARF(name, name, cur, body, IDF_OVERRIDE)
117 #define _SVAR(name, global, cur, persist) char *global = svariable(#name, cur, &global, NULL, persist)
118 #define SVARN(name, global, cur) _SVAR(name, global, cur, 0)
119 #define SVARNP(name, global, cur) _SVAR(name, global, cur, IDF_PERSIST)
120 #define SVARNR(name, global, cur) _SVAR(name, global, cur, IDF_OVERRIDE)
121 #define SVAR(name, cur) _SVAR(name, name, cur, 0)
122 #define SVARP(name, cur) _SVAR(name, name, cur, IDF_PERSIST)
123 #define SVARR(name, cur) _SVAR(name, name, cur, IDF_OVERRIDE)
124 #define _SVARF(name, global, cur, body, persist) void var_##name(); char *global = svariable(#name, cur, &global, var_##name, persist); void var_##name() { body; }
125 #define SVARFN(name, global, cur, body) _SVARF(name, global, cur, body, 0)
126 #define SVARF(name, cur, body) _SVARF(name, name, cur, body, 0)
127 #define SVARFP(name, cur, body) _SVARF(name, name, cur, body, IDF_PERSIST)
128 #define SVARFR(name, cur, body) _SVARF(name, name, cur, body, IDF_OVERRIDE)
130 // new style macros, have the body inline, and allow binds to happen anywhere, even inside class constructors, and access the surrounding class
131 #define _COMMAND(idtype, tv, n, g, proto, b) \
132 struct cmd_##n : ident \
134 cmd_##n(void *self = NULL) : ident(idtype, #n, g, (void *)run, self) \
136 addident(name, this); \
138 static void run proto { b; } \
139 } icom_##n tv
140 #define ICOMMAND(n, g, proto, b) _COMMAND(ID_COMMAND, , n, g, proto, b)
141 #define CCOMMAND(n, g, proto, b) _COMMAND(ID_CCOMMAND, (this), n, g, proto, b)
143 #define _IVAR(n, m, c, x, b, p) \
144 struct var_##n : ident \
146 var_##n() : ident(ID_VAR, #n, m, c, x, &val.i, NULL, p) \
148 addident(name, this); \
150 int operator()() { return val.i; } \
153 #define IVAR(n, m, c, x) _IVAR(n, m, c, x, , 0)
154 #define IVARF(n, m, c, x, b) _IVAR(n, m, c, x, void changed() { b; }, 0)
155 #define IVARP(n, m, c, x) _IVAR(n, m, c, x, , IDF_PERSIST)
156 #define IVARR(n, m, c, x) _IVAR(n, m, c, x, , IDF_OVERRIDE)
157 #define IVARFP(n, m, c, x, b) _IVAR(n, m, c, x, void changed() { b; }, IDF_PERSIST)
158 #define IVARFR(n, m, c, x, b) _IVAR(n, m, c, x, void changed() { b; }, IDF_OVERRIDE)
159 //#define ICALL(n, a) { char *args[] = a; icom_##n.run(args); }