Line data Source code
1 : /**
2 : * @file command.h
3 : * @brief Script binding functionality.
4 : *
5 : * This file describes the CubeScript API for binding and executing code from within
6 : * the engine's CubeScript context.
7 : */
8 :
9 : #ifndef COMMAND_H_
10 : #define COMMAND_H_
11 :
12 : enum
13 : {
14 : Value_Null = 0,
15 : Value_Integer,
16 : Value_Float,
17 : Value_String,
18 : Value_Any,
19 : Value_Code,
20 : Value_Macro,
21 : Value_Ident,
22 : Value_CString,
23 : Value_CAny,
24 : Value_Word,
25 : Value_Pop,
26 : Value_Cond,
27 : };
28 :
29 : enum
30 : {
31 : Id_Var, //0
32 : Id_FloatVar,
33 : Id_StringVar,
34 : Id_Command,
35 : Id_Alias,
36 : Id_Local, //5
37 : Id_Do,
38 : Id_DoArgs,
39 : Id_If,
40 : Id_Result,
41 : Id_Not, //10
42 : Id_And,
43 : Id_Or, //12
44 : };
45 :
46 : enum
47 : {
48 : Idf_Persist = 1<<0,
49 : Idf_Override = 1<<1,
50 : Idf_Hex = 1<<2,
51 : Idf_ReadOnly = 1<<3,
52 : Idf_Overridden = 1<<4,
53 : Idf_Unknown = 1<<5,
54 : Idf_Arg = 1<<6,
55 : };
56 :
57 : struct ident;
58 :
59 : struct identval
60 : {
61 : union
62 : {
63 : int i; // Id_Var, ValueInteger
64 : float f; // Id_FloatVar, ValueFloat
65 : char *s; // Id_StringVar, ValueString
66 : const uint *code; // ValueCode
67 : ident *id; // ValueIdent
68 : const char *cstr; // ValueCString
69 : };
70 : };
71 :
72 : struct tagval : identval
73 : {
74 : int type;
75 :
76 : void setint(int val);
77 : void setfloat(float val);
78 : void setnumber(double val);
79 : void setstr(char *val);
80 : void setnull();
81 : void setcode(const uint *val);
82 : void setmacro(const uint *val);
83 : void setcstr(const char *val);
84 : void setident(ident *val);
85 :
86 : const char *getstr() const;
87 : int getint() const;
88 : float getfloat() const;
89 : double getnumber() const;
90 : bool getbool() const;
91 : void getval(tagval &r) const;
92 :
93 : void cleanup();
94 : };
95 :
96 : struct identstack
97 : {
98 : identval val;
99 : int valtype;
100 : identstack *next;
101 : };
102 :
103 : typedef void (__cdecl *identfun)(ident *id);
104 :
105 : /**
106 : * @brief An object representing all Cubescript objects.
107 : *
108 : * This object defines all possible state for any object in Cubescript. Different
109 : * types will have different members due to the union types, but the ident object
110 : * is common to them regardless. This allows storage of CS objects in a uniform
111 : * map consisting of one type.
112 : */
113 : struct ident
114 : {
115 : //this pointer will point to different types depending upon the type of variable
116 : union identvalptr /**< points to an ident's value */
117 : {
118 : void *p; /**< can point to any Id_*Var */
119 : int *i; /**< points to an Id_Var (int) */
120 : float *f; /**< points to an Id_FloatVar */
121 : char **s; /**< points to a pointer to a Id_StringVar (C string) */
122 : };
123 :
124 : uchar type; /**< one of Id_* in Id_ enum */
125 : union
126 : {
127 : uchar valtype; /**< if alias, points to Id_Alias's type */
128 : uchar numargs; /**< if command, number of commands the Id_Command has */
129 : };
130 : ushort flags;
131 : int index;
132 : const char *name;
133 : union
134 : {
135 : struct // Id_Var, Id_FloatVar, Id_StringVar
136 : {
137 : union //number var range union type
138 : {
139 : struct
140 : {
141 : int minval, /**< if an int variable, its min allowed value*/
142 : maxval; /**< if an int variable, its max allowed value*/
143 : }; // Id_Var
144 : struct
145 : {
146 : float minvalf, /**< if a float variable, its min allowed value*/
147 : maxvalf; /**< if a float variable, its max allowed value*/
148 : }; // Id_FloatVar
149 : };
150 : identvalptr storage;
151 : identval overrideval;
152 : };
153 : struct // Id_Alias
154 : {
155 : uint *code;
156 : identval val;
157 : identstack *stack;
158 : };
159 : struct // Id_Command
160 : {
161 : const char *args;
162 : uint argmask;
163 : };
164 : };
165 : identfun fun; /**< the pointer a command or variable points to (the on-change command for a var)*/
166 :
167 1114 : ident() {}
168 : /**
169 : * @brief Constructor for an ident for an int variable.
170 : */
171 387 : ident(int t, const char *n, int m, int x, int *s, void *f = nullptr, int flags = 0)
172 387 : : type(t), flags(flags | (m > x ? Idf_ReadOnly : 0)), name(n), minval(m), maxval(x), fun((identfun)f)
173 387 : { storage.i = s; }
174 :
175 : /**
176 : * @brief Constructor for an ident for a float variable.
177 : */
178 112 : ident(int t, const char *n, float m, float x, float *s, void *f = nullptr, int flags = 0)
179 112 : : type(t), flags(flags | (m > x ? Idf_ReadOnly : 0)), name(n), minvalf(m), maxvalf(x), fun((identfun)f)
180 112 : { storage.f = s; }
181 :
182 : /**
183 : * @brief Constructor for an ident for a string variable.
184 : */
185 5 : ident(int t, const char *n, char **s, void *f = nullptr, int flags = 0)
186 5 : : type(t), flags(flags), name(n), fun((identfun)f)
187 5 : { storage.s = s; }
188 :
189 : // Id_Alias
190 : ident(int t, const char *n, char *a, int flags)
191 : : type(t), valtype(Value_String), flags(flags), name(n), code(nullptr), stack(nullptr)
192 : { val.s = a; }
193 :
194 : ident(int t, const char *n, int a, int flags)
195 : : type(t), valtype(Value_Integer), flags(flags), name(n), code(nullptr), stack(nullptr)
196 : { val.i = a; }
197 :
198 : ident(int t, const char *n, float a, int flags)
199 : : type(t), valtype(Value_Float), flags(flags), name(n), code(nullptr), stack(nullptr)
200 : { val.f = a; }
201 :
202 32 : ident(int t, const char *n, int flags)
203 32 : : type(t), valtype(Value_Null), flags(flags), name(n), code(nullptr), stack(nullptr)
204 32 : {}
205 2 : ident(int t, const char *n, const tagval &v, int flags)
206 2 : : type(t), valtype(v.type), flags(flags), name(n), code(nullptr), stack(nullptr)
207 2 : { val = v; }
208 :
209 : /**
210 : * @brief Constructor for an ident for a C++ bound command.
211 : */
212 596 : ident(int t, const char *n, const char *args, uint argmask, int numargs, void *f = nullptr, int flags = 0)
213 596 : : type(t), numargs(numargs), flags(flags), name(n), args(args), argmask(argmask), fun((identfun)f)
214 596 : {}
215 :
216 : /**
217 : * @brief Calls a change effect for this ident, if one exists.
218 : *
219 : * If there is no function pointed to by `fun` (it is null), then nothing
220 : * will occur.
221 : */
222 1 : void changed()
223 : {
224 1 : if(fun)
225 : {
226 0 : fun(this);
227 : }
228 1 : }
229 :
230 : /**
231 : * @brief Sets the value and type of value of this ident given a tagval
232 : *
233 : * Sets this ident's value type and value to the corresponding values from
234 : * the passed tagval object.
235 : *
236 : * @param v the tagval to set values from
237 : */
238 285 : void setval(const tagval &v)
239 : {
240 285 : valtype = v.type;
241 285 : val = v;
242 285 : }
243 :
244 : /**
245 : * @brief Sets the value and type of value of this ident given an identstack
246 : *
247 : * Sets this ident's value type and value to the corresponding values from
248 : * the passed identstack object.
249 : *
250 : * @param v the identstack to set values from
251 : */
252 95 : void setval(const identstack &v)
253 : {
254 95 : valtype = v.valtype;
255 95 : val = v.val;
256 95 : }
257 :
258 : /**
259 : * @brief Sets the value type of this ident to null.
260 : *
261 : * If a string is being stored inside this ident, it is freed.
262 : */
263 28 : void forcenull()
264 : {
265 28 : if(valtype==Value_String)
266 : {
267 2 : delete[] val.s;
268 : }
269 28 : valtype = Value_Null;
270 28 : }
271 :
272 : /**
273 : * @brief Returns the saved value of the ident as a float.
274 : *
275 : * Returns a float even if the ident is of another type, e.g. integer
276 : *
277 : * @return the float value of the ident
278 : */
279 : float getfloat() const;
280 :
281 : /**
282 : * @brief Returns the saved value of the ident as an integer.
283 : *
284 : * Returns an int even if the ident is of another type, e.g. float
285 : */
286 : int getint() const;
287 :
288 : /**
289 : * @brief Returns the saved value of the ident as a double.
290 : *
291 : * Returns a double even if the ident is of another type, e.g. integer
292 : *
293 : * @return the double value of the ident
294 : */
295 : double getnumber() const;
296 : const char *getstr() const;
297 : void getval(tagval &r) const;
298 : void getcstr(tagval &v) const;
299 : void getcval(tagval &v) const;
300 : };
301 :
302 : /**
303 : * @brief Returns an integer value from a Cubescript command.
304 : *
305 : * When writing a CS command, this function returns an integer value to the inheriting
306 : * CS environment.
307 : *
308 : * @param v the value to return
309 : */
310 : extern void intret(int v);
311 :
312 : extern const char *floatstr(float v);
313 :
314 : /**
315 : * @brief Returns a float value from a Cubescript command.
316 : *
317 : * When writing a CS command, this function returns a float value to the inheriting
318 : * CS environment.
319 : *
320 : * @param v the value to return
321 : */
322 : extern void floatret(float v);
323 :
324 : /**
325 : * @brief Returns a string value from a Cubescript command.
326 : *
327 : * When writing a CS command, this function returns a string value to the inheriting
328 : * CS environment.
329 : *
330 : * @param v the value to return
331 : */
332 : extern void stringret(char *s);
333 :
334 : /**
335 : * @brief Returns an alias' name from a Cubescript command.
336 : *
337 : * When writing a CS command, this functions a string value representing the name
338 : * of a Cubescript object to the inheriting CS environment.
339 : *
340 : * @param s the name of the ident to return
341 : */
342 : extern void result(const char *s);
343 :
344 : /**
345 : * @brief Returns the string passed as an integer.
346 : *
347 : * Parses the entire string, returning the value of the passed value as an integer.
348 : * The value of this value will always be greater than zero unless there is an
349 : * overflow beyond the size of `int`. The output may be converted by a trailing
350 : * radix digit as described in `strtoul`.
351 : *
352 : * @param s the string to turn into an integer
353 : */
354 596 : inline int parseint(const char *s)
355 : {
356 596 : return static_cast<int>(std::strtoul(s, nullptr, 0));
357 : }
358 :
359 : /**
360 : * @brief Registers an int variable in the Cubescript ident table.
361 : *
362 : * @param name the name of the aliased variable in Cubescript
363 : * @param min the minimum value the variable can be set at
364 : * @param cur the starting value of the variable
365 : * @param max the maximum value the variable can be set at
366 : * @param storage the pointer to the variable to be aliased to Cubescript
367 : * @param fun a function pointer to be called upon modification of the variable
368 : * @param flags the handling flags for the variable
369 : *
370 : * @return the value cur passed
371 : */
372 : extern int variable(const char *name, int min, int cur, int max, int *storage, identfun fun, int flags);
373 :
374 : /**
375 : * @brief Registers a float variable in the Cubescript ident table.
376 : *
377 : * Adds a float variable to the Cubescript ident table. The name of the Cubescript
378 : * variable does not necessarily need to correspond to the C++ variable's name.
379 : *
380 : * @param name the name of the aliased variable in Cubescript
381 : * @param min the minimum value the variable can be set at
382 : * @param cur the starting value of the variable
383 : * @param max the maximum value the variable can be set at
384 : * @param storage the pointer to the variable to be aliased to Cubescript
385 : * @param fun a function pointer to be called upon modification of the variable
386 : * @param flags the handling flags for the variable
387 : *
388 : * @return the value cur passed
389 : */
390 : extern float fvariable(const char *name, float min, float cur, float max, float *storage, identfun fun, int flags);
391 :
392 : /**
393 : * @brief Registers a C string variable in the Cubescript ident table.
394 : *
395 : * @param name the name of the aliased variable in Cubescript
396 : * @param cur the starting value of the variable
397 : * @param storage the pointer to the pointer to the variable to be aliased to Cubescript
398 : * @param fun a function pointer to be called upon modification of the variable
399 : * @param flags the handling flags for the variable
400 : *
401 : * @return the value cur passed
402 : */
403 : extern char *svariable(const char *name, const char *cur, char **storage, identfun fun, int flags);
404 :
405 : /**
406 : * @brief Sets a Cubescript integer value to the given value.
407 : *
408 : * @param name the name of the cubescript alias to change
409 : * @param i the value to set
410 : * @param dofunc whether to run the onchange function
411 : * @param doclamp whether to clamp the value to the specified limits
412 : */
413 : extern void setvar(const char *name, int i, bool dofunc = true, bool doclamp = true);
414 :
415 : /**
416 : * @brief Sets a Cubescript float value to the given value.
417 : *
418 : * @param name the name of the cubescript alias to change
419 : * @param i the value to set
420 : * @param dofunc whether to run the onchange function
421 : * @param doclamp whether to clamp the value to the specified limits
422 : */
423 : extern void setfvar(const char *name, float f, bool dofunc = true, bool doclamp = true);
424 :
425 : /**
426 : * @brief Sets a Cubescript string value to the given value.
427 : *
428 : * @param name the name of the cubescript alias to change
429 : * @param i the value to set
430 : * @param dofunc whether to run the onchange function
431 : */
432 : extern void setsvar(const char *name, const char *str, bool dofunc = true);
433 :
434 : /**
435 : * @brief Registers a command in the Cubescript ident table.
436 : *
437 : * The arguments of the function passed are cast away, so they are reconstructed using
438 : * the char * string passed to `narg`.
439 : *
440 : * @param name of the command in Cubescript
441 : * @param fun a function pointer to be called when the command is executed
442 : * @param narg string containing the arguments of the function
443 : * @param type the type of the command to create
444 : */
445 : extern bool addcommand(const char *name, identfun fun, const char *narg = "", int type = Id_Command);
446 :
447 : extern std::queue<ident *> triggerqueue; /**< A queue of game events for the engine to process */
448 :
449 : /**
450 : * @brief Returns the pointer to the ident object with the given CS alias.
451 : *
452 : * @param the name of the cubescript object to get
453 : *
454 : * @return The address of the ident object.
455 : */
456 : extern ident *getident(const char *name);
457 : extern int execute(const uint *code);
458 :
459 : /**
460 : * @brief Executes the contents of the string passed.
461 : *
462 : * Parses and executes the line of Cubescript given.
463 : *
464 : * @param p the C string containing the code to execute
465 : *
466 : * @return an int from the results of the execution
467 : */
468 : extern int execute(const char *p);
469 :
470 : /**
471 : * @brief Executes the contents of an ident, searched by name.
472 : *
473 : * Attempts to find in the ident table an ident with the given name, and
474 : * if found executes it.
475 : *
476 : * @param name the name of the ident to look for
477 : * @param noid the value to return if no ident is found
478 : * @param lookup if a command, and parameters are of format 'N', sets to -1
479 : */
480 : extern int execident(const char *name, int noid = 0, bool lookup = false);
481 : extern bool executebool(const uint *code);
482 :
483 : /**
484 : * @brief Executes the contents of the referenced file.
485 : *
486 : * @param cfgfile the relative director of the file to execute
487 : * @param msg whether to print to console a failure message
488 : *
489 : * @return true if the file was successfully loaded
490 : * @return false if the file was not found
491 : */
492 : extern bool execfile(const char *cfgfile, bool msg = true);
493 :
494 : /**
495 : * @brief Replaces C style excape characters with Cubescript ones
496 : *
497 : * The resulting string is also wrapped in quotes ("").
498 : *
499 : * @param s the string to convert
500 : *
501 : * @return a string containing the escaped changes
502 : */
503 : extern const char *escapestring(const char *s);
504 :
505 : /**
506 : * @brief Prints out the formatted variable
507 : *
508 : * The param is intended to represent the value the ident object represents.
509 : *
510 : * @param id the ident object to print out
511 : * @param i the value to print out the variable equalling.
512 : */
513 : extern void printvar(const ident *id, int i);
514 :
515 : /**
516 : * @brief Modifies the value passed to fall within the boundaries passed.
517 : *
518 : * Clamps the value i to within minval and maxval. If hex is passed, warns in hex
519 : * mode, otherwise decimal. If the values are not within bounds, issued aformentioned
520 : * warning, refering to the passed name in the console message.
521 : *
522 : * @param hex toggles whether to display hex warning instead of decimal
523 : * @param name the name
524 : * @param i the value to clamp
525 : * @param minval the lowest value to clamp to
526 : * @param maxval the largest value to clamp to
527 : *
528 : * @return the clamped value
529 : */
530 : extern int clampvar(bool hex, std::string name, int i, int minval, int maxval);
531 : extern void loopiter(ident *id, identstack &stack, int i);
532 : extern void loopend(ident *id, identstack &stack);
533 :
534 : /**
535 : * @brief Escapes a string unless it is null.
536 : *
537 : * If an empty string is passed, escapestring() is not called. Otherwise, the same
538 : * behavior as in escapestring() is executed.
539 : *
540 : * @param s the string to convert
541 : *
542 : * @return a string containing the potentially applied escape changes
543 : */
544 : const char *escapeid(const char *s);
545 :
546 : /**
547 : * @brief Writes out the state of the CubeScript idents to a file.
548 : *
549 : * @param savedconfig the path to write to if name is nullptr
550 : * @param autoexec the path for the autoexec file for user modification, for display in top of file comment
551 : * @param defaultconfig the path for the master copy of the configuration file, for display in top of file comment
552 : * @param name the path to write to, if nullptr savedconfig is used instead
553 : */
554 : extern void writecfg(const char *savedconfig, const char *autoexec = nullptr, const char *defaultconfig = nullptr, const char *name = nullptr);
555 :
556 : /**
557 : * @brief Processes the cubescript sleep queue.
558 : *
559 : * At most, one sleep command is removed from the queue per cycle. Removes
560 : * queued sleep commands as they expire, which stops CS commands from executing
561 : * for a certain period of time.
562 : *
563 : * @param millis the current timestamp
564 : */
565 : extern void checksleep(int millis);
566 :
567 : /**
568 : * @brief Initializes the CubeScript preset argument idents.
569 : *
570 : * Intitializes the argument parameters (arg1, arg2, ..., arg<Max_Args>) as CS
571 : * ident objects. Required to use of $argN variables.
572 : * Also initializes the dummy ident, `//dummy`.
573 : *
574 : * @return always returns true
575 : */
576 : extern bool initidents();
577 :
578 : extern int identflags; /**< The flags to automatically set on ident objects */
579 :
580 : /**
581 : * @brief Clears all aliases from the ident map.
582 : *
583 : * All aliases, aka objects created from within CubeScript, have their contents
584 : * (the names and code values associated with them) freed. Does not remove the
585 : * ident object itself from the global ident map.
586 : */
587 : extern void clear_command();
588 :
589 : // nasty macros for registering script functions, abuses globals to avoid excessive infrastructure
590 :
591 : //* note: many of the VARF comments are very repetitive, because the code itself is nearly duplicated too *//
592 :
593 : /* how command registration works:
594 : * In C++, all global variables must be initiated before main() is called
595 : * Each of these macro kludges (which are placed at the global scope level) initializes some kind of global variable
596 : * Because the macro kludges are the definition of global variables, at program initializiation, they must be run first
597 : * The values of the variables themselves don't matter because they only exist to cheat and run before main()
598 : * The macro kludges themselves register commands or values within some vector<>-s which keeps track of all cmds/vars
599 : */
600 :
601 : /*
602 : * Parameter Flags (exhaustive list, not exhaustive descriptions)
603 : * i an integer parameter
604 : * b a boolean parameter
605 : * f a float parameter (sets to 0 if over parameter limit)
606 : * F a float parameter (sets to value of previous parameter if over parameter limit)
607 : * s a string parameter (sets to new allocated string "" if over parameter limit)
608 : * S a string paremter (sets current string to "" if over parameter limit)
609 : * t sets to null if over parameter limit
610 : * T same as "t"
611 : * e a code block parameter
612 : * E a code block paremter (null)
613 : * r an ident parameter
614 : * $ an ident parameter
615 : * N a number parameter
616 : * D a bind parameter (e.g. player movement), adds a release action for the command
617 : * C an ident parameter, ComC
618 : * V a series of variadic parameter(s) (open ended series of values)
619 : * 1 repeat one arg
620 : * 2 repeat two args
621 : * 3 repeat three args
622 : * 4 repeat four args
623 : */
624 :
625 : //integer var macros
626 : //VAR_, _VARF, VARM_ are templates for "normal" macros that do not execute an inline function
627 : #define VAR_(name, global, min, cur, max, persist) int global = variable(#name, min, cur, max, &global, nullptr, persist)
628 : #define VARN(name, global, min, cur, max) VAR_(name, global, min, cur, max, 0)
629 : #define VARNP(name, global, min, cur, max) VAR_(name, global, min, cur, max, Idf_Persist)
630 : #define VARNR(name, global, min, cur, max) VAR_(name, global, min, cur, max, Idf_Override)
631 : #define VAR(name, min, cur, max) VAR_(name, name, min, cur, max, 0)
632 : #define VARP(name, min, cur, max) VAR_(name, name, min, cur, max, Idf_Persist)
633 : #define VARR(name, min, cur, max) VAR_(name, name, min, cur, max, Idf_Override)
634 :
635 : //variable with inline function to be executed on change (VARiable with Function = VARF)
636 : #define VARF_(name, global, min, cur, max, body, persist) \
637 : int global = variable(#name, min, cur, max, &global, [] (ident *) { body; }, persist); /* assign variable, needs fxn prototype declared above */
638 :
639 : #define VARFN(name, global, min, cur, max, body) VARF_(name, global, min, cur, max, body, 0)
640 : #define VARF(name, min, cur, max, body) VARF_(name, name, min, cur, max, body, 0)
641 : #define VARFP(name, min, cur, max, body) VARF_(name, name, min, cur, max, body, Idf_Persist)
642 : #define VARFR(name, min, cur, max, body) VARF_(name, name, min, cur, max, body, Idf_Override)
643 : #define VARFNP(name, global, min, cur, max, body) VARF_(name, global, min, cur, max, body, Idf_Persist)
644 :
645 : //hexadecimal var macros
646 : #define HVAR_(name, global, min, cur, max, persist) int global = variable(#name, min, cur, max, &global, nullptr, persist | Idf_Hex)
647 : #define HVARP(name, min, cur, max) HVAR_(name, name, min, cur, max, Idf_Persist)
648 :
649 : //hex variable with function to be executed on change (Hexadecimal VARiable with Function = HVARF)
650 : //the CVAR series of macros borrows the HVARF macro as it deals with hex colors
651 : #define HVARF_(name, global, min, cur, max, body, persist) \
652 : int global = variable(#name, min, cur, max, &global, [] (ident *) { body; }, persist | Idf_Hex); /* assign variable, needs fxn prototype declared above */
653 :
654 : //color var macros
655 : #define CVAR_(name, cur, init, body, persist) bvec name = bvec::hexcolor(cur); HVARF_(name, _##name, 0, cur, 0xFFFFFF, { init; name = bvec::hexcolor(_##name); body; }, persist)
656 : #define CVARP(name, cur) CVAR_(name, cur, , , Idf_Persist)
657 : #define CVARR(name, cur) CVAR_(name, cur, , , Idf_Override)
658 : #define CVARFP(name, cur, body) CVAR_(name, cur, , body, Idf_Persist)
659 : #define CVAR0_(name, cur, body, persist) CVAR_(name, cur, { if(!_##name) _##name = cur; }, body, persist)
660 : #define CVAR0R(name, cur) CVAR0_(name, cur, , Idf_Override)
661 : #define CVAR1_(name, cur, body, persist) CVAR_(name, cur, { if(_##name <= 255) _##name |= (_##name<<8) | (_##name<<16); }, body, persist)
662 : #define CVAR1R(name, cur) CVAR1_(name, cur, , Idf_Override)
663 : #define CVAR1FR(name, cur, body) CVAR1_(name, cur, body, Idf_Override)
664 :
665 : //float var macros
666 : #define FVAR_(name, global, min, cur, max, persist) float global = fvariable(#name, min, cur, max, &global, nullptr, persist)
667 : #define FVARNP(name, global, min, cur, max) FVAR_(name, global, min, cur, max, Idf_Persist)
668 : #define FVAR(name, min, cur, max) FVAR_(name, name, min, cur, max, 0)
669 : #define FVARP(name, min, cur, max) FVAR_(name, name, min, cur, max, Idf_Persist)
670 : #define FVARR(name, min, cur, max) FVAR_(name, name, min, cur, max, Idf_Override)
671 :
672 : //float variable with function to be executed on change (Float VARiable with Function = FVARF)
673 : #define FVARF_(name, global, min, cur, max, body, persist) \
674 : float global = fvariable(#name, min, cur, max, &global, [] (ident *) { body; }, persist); /* assign variable, needs fxn prototype declared above */ \
675 :
676 : #define FVARF(name, min, cur, max, body) FVARF_(name, name, min, cur, max, body, 0)
677 : #define FVARFP(name, min, cur, max, body) FVARF_(name, name, min, cur, max, body, Idf_Persist)
678 : #define FVARFR(name, min, cur, max, body) FVARF_(name, name, min, cur, max, body, Idf_Override)
679 :
680 : //string var macros
681 : #define SVAR_(name, global, cur, persist) char *global = svariable(#name, cur, &global, nullptr, persist)
682 : #define SVAR(name, cur) SVAR_(name, name, cur, 0)
683 : #define SVARP(name, cur) SVAR_(name, name, cur, Idf_Persist)
684 : #define SVARR(name, cur) SVAR_(name, name, cur, Idf_Override)
685 :
686 : //string variable with function to be executed on change (Float VARiable with Function = FVARF)
687 : #define SVARF_(name, global, cur, body, persist) \
688 : char *global = svariable(#name, cur, &global, [] (ident *) { body; }, persist); /* assign variable, needs fxn prototype declared above */
689 :
690 : #define SVARF(name, cur, body) SVARF_(name, name, cur, body, 0)
691 : #define SVARFR(name, cur, body) SVARF_(name, name, cur, body, Idf_Override)
692 :
693 : #endif /* COMMAND_H_ */
|