Overview
Comment: | Make execute() take an OFString |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
acc50da079501c3c301f3a742f14cdfe |
User & Date: | js on 2025-03-07 22:44:37 |
Other Links: | manifest | tags |
Context
2025-03-07
| ||
23:29 | Clean up argument passing of commands check-in: 22520cd0d9 user: js tags: trunk | |
22:44 | Make execute() take an OFString check-in: acc50da079 user: js tags: trunk | |
22:30 | Migrate strings for all commands check-in: 11889bf242 user: js tags: trunk | |
Changes
Modified src/Command.mm from [91c3da5caf] to [b83be0b4d8].
︙ | ︙ | |||
74 75 76 77 78 79 80 | case ARG_DWN1: ((void(__cdecl *)(bool, OFString *))_function)( isDown, @(arguments[1])); break; case ARG_1EXP: if (isDown) return ((int(__cdecl *)(int))_function)( | | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | case ARG_DWN1: ((void(__cdecl *)(bool, OFString *))_function)( isDown, @(arguments[1])); break; case ARG_1EXP: if (isDown) return ((int(__cdecl *)(int))_function)( execute(@(arguments[1]))); break; case ARG_2EXP: if (isDown) return ((int(__cdecl *)(int, int))_function)( execute(@(arguments[1])), execute(@(arguments[2]))); break; case ARG_1EST: if (isDown) return ((int(__cdecl *)(OFString *))_function)( @(arguments[1])); break; case ARG_2EST: |
︙ | ︙ |
Modified src/clientgame.mm from [33b9c3010f] to [e005695b56].
1 2 3 4 | // clientgame.cpp: core game related stuff #include "cube.h" | < < | 1 2 3 4 5 6 7 8 9 10 11 | // clientgame.cpp: core game related stuff #include "cube.h" int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); void mode(int n) { addmsg(1, 2, SV_GAMEMODE, nextmode = n); |
︙ | ︙ | |||
243 244 245 246 247 248 249 | void updateworld(int millis) // main game update loop { if (lastmillis) { curtime = millis - lastmillis; if (sleepwait && lastmillis > sleepwait) { sleepwait = 0; | < < < | < < > < < > > < > | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | void updateworld(int millis) // main game update loop { if (lastmillis) { curtime = millis - lastmillis; if (sleepwait && lastmillis > sleepwait) { sleepwait = 0; execute(sleepcmd); } physicsframe(); checkquad(curtime); if (m_arena) arenarespawn(); moveprojectiles((float)curtime); demoplaybackstep(); if (!demoplayback) { if (getclientnum() >= 0) shoot(player1, worldpos); // only shoot when // connected to server gets2c(); // do this first, so we have most accurate // information when our player moves } otherplayers(); if (!demoplayback) { monsterthink(); if (player1->state == CS_DEAD) { if (lastmillis - player1->lastaction < 2000) { player1->move = player1->strafe = 0; moveplayer(player1, 10, false); } else if (!m_arena && !m_sp && lastmillis - player1->lastaction > 10000) respawn(); } else if (!intermission) { moveplayer(player1, 20, true); checkitems(); }; c2sinfo(player1); // do this last, to reduce the // effective frame lag } } lastmillis = millis; } void entinmap(dynent * d) // brute force but effective way to find a free spawn spot in the map { loopi(100) // try max 100 times { |
︙ | ︙ |
Modified src/commands.mm from [f53c401a17] to [f1b5888486].
︙ | ︙ | |||
131 132 133 134 135 136 137 | conoutf(@"missing \"%c\"", right); return NULL; } } char *s = newstring(word, p - word - 1); if (left == '(') { string t; | < < | > > > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | conoutf(@"missing \"%c\"", right); return NULL; } } char *s = newstring(word, p - word - 1); if (left == '(') { string t; // evaluate () exps directly, and substitute result @autoreleasepool { itoa(t, execute(@(s))); } s = exchangestr(s, t); } return s; } char * parseword(char *&p) // parse single argument, including expressions |
︙ | ︙ | |||
184 185 186 187 188 189 190 | } conoutf(@"unknown alias lookup: %s", n + 1); return n; } int | > | > > > | | | | < > | | | > | | | > | | | | | | | | | | < | > | > | | > | | < < | | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | } conoutf(@"unknown alias lookup: %s", n + 1); return n; } int execute( OFString *string, bool isdown) // all evaluation happens here, recursively { @autoreleasepool { std::unique_ptr<char> copy(strdup(string.UTF8String)); char *p = copy.get(); const int MAXWORDS = 25; // limit, remove char *w[MAXWORDS]; int val = 0; for (bool cont = true; cont;) { // for each ; seperated statement int numargs = MAXWORDS; loopi(MAXWORDS) { // collect all argument values w[i] = ""; if (i > numargs) continue; // parse and evaluate exps char *s = parseword(p); if (!s) { numargs = i; s = ""; } if (*s == '$') s = lookup(s); // substitute variables w[i] = s; } p += strcspn(p, ";\n\0"); // more statements if this isn't the end of the string cont = *p++ != 0; char *c = w[0]; // strip irc-style command prefix if (*c == '/') c++; // empty statement if (!*c) continue; __kindof Identifier *identifier = identifiers[@(c)]; if (identifier == nil) { val = ATOI(c); if (!val && *c != '0') conoutf(@"unknown command: %s", c); } else { if ([identifier isKindOfClass:[Command class]]) { // game defined commands use very // ad-hoc function signature, and just // call it val = [identifier callWithArguments:w numArguments:numargs isDown:isdown]; } else if ([identifier isKindOfClass:[Variable class]]) { |
︙ | ︙ | |||
263 264 265 266 267 268 269 | stringWithFormat: @"arg%d", i]; alias(t, @(w[i])); } } // create new string here because alias // could rebind itself | < < | | < | | | > | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | stringWithFormat: @"arg%d", i]; alias(t, @(w[i])); } } // create new string here because alias // could rebind itself val = execute( [[identifier action] copy], isdown); break; } } loopj(numargs) gp()->deallocstr(w[j]); } return val; } } // tab-completion of all identifiers int completesize = 0, completeidx = 0; void |
︙ | ︙ | |||
341 342 343 344 345 346 347 | } @catch (id e) { return false; } // Ensure \0 termination. [data addItem:""]; | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | } @catch (id e) { return false; } // Ensure \0 termination. [data addItem:""]; execute(@((char *)data.mutableItems)); return true; } } void exec(OFString *cfgfile) { |
︙ | ︙ | |||
423 424 425 426 427 428 429 | alias(name, [OFString stringWithFormat:@"%d", v]); } } void ifthen(OFString *cond, OFString *thenp, OFString *elsep) { | < < < | < | | < | < | | < < < < | | < | < | | | < < | < | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | alias(name, [OFString stringWithFormat:@"%d", v]); } } void ifthen(OFString *cond, OFString *thenp, OFString *elsep) { execute((![cond hasPrefix:@"0"] ? thenp : elsep)); } void loopa(OFString *times, OFString *body) { @autoreleasepool { int t = (int)times.longLongValue; loopi(t) { intset(@"i", i); execute(body); } } } void whilea(OFString *cond, OFString *body) { while (execute(cond)) execute(body); } void onrelease(bool on, OFString *body) { if (!on) execute(body); } void concat(OFString *s) { alias(@"s", s); } void concatword(OFString *s) { // The original used this code which does nothing: // for (char *a = s, *b = s; *a = *b; b++) |
︙ | ︙ |
Modified src/console.mm from [86266db4fd] to [2969d1193c].
1 2 3 4 5 | // console.cpp: the console buffer, its display, and command line control #include "cube.h" #include <ctype.h> | < | 1 2 3 4 5 6 7 8 9 10 11 12 | // console.cpp: the console buffer, its display, and command line control #include "cube.h" #include <ctype.h> #import "KeyMapping.h" struct cline { char *cref; int outtime; }; |
︙ | ︙ | |||
169 170 171 172 173 174 175 | void history(int n) { static bool rec = false; if (!rec && n >= 0 && n < vhistory.count) { rec = true; | | < < | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | void history(int n) { static bool rec = false; if (!rec && n >= 0 && n < vhistory.count) { rec = true; execute(vhistory[vhistory.count - n - 1]); rec = false; } } COMMAND(history, ARG_1INT) void keypress(int code, bool isdown, int cooked) |
︙ | ︙ | |||
245 246 247 248 249 250 251 | [vhistory addObject: [commandbuf copy]]; } } histpos = vhistory.count; | | < < | < | < | < | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | [vhistory addObject: [commandbuf copy]]; } } histpos = vhistory.count; if ([commandbuf hasPrefix:@"/"]) execute(commandbuf, true); else toserver(commandbuf); } saycommand(NULL); } else if (code == SDLK_ESCAPE) { saycommand(NULL); } } } else if (!menukey(code, isdown)) { // keystrokes go to menu for (KeyMapping *mapping in keyMappings) { if (mapping.code == code) { // keystrokes go to game, lookup in keymap and // execute execute(mapping.action, isdown); return; } } } } OFString * |
︙ | ︙ |
Modified src/menus.mm from [1d03f1ff21] to [27b088d99d].
1 2 3 4 | // menus.cpp: ingame menu system (also used for scores and serverlist) #include "cube.h" | < < | 1 2 3 4 5 6 7 8 9 10 11 | // menus.cpp: ingame menu system (also used for scores and serverlist) #include "cube.h" #import "Menu.h" #import "MenuItem.h" static OFMutableArray<OFNumber *> *menuStack; static OFMutableArray<Menu *> *menus; static int vmenu = -1; |
︙ | ︙ | |||
164 165 166 167 168 169 170 | if (menuStack == nil) menuStack = [[OFMutableArray alloc] init]; [menuStack addObject:@(vmenu)]; menuset(-1); | < | | 162 163 164 165 166 167 168 169 170 171 172 173 174 | if (menuStack == nil) menuStack = [[OFMutableArray alloc] init]; [menuStack addObject:@(vmenu)]; menuset(-1); execute(action, true); } } return true; } |
Modified src/protos.h from [0b98b4aee6] to [cecc5f4a0e].
1 2 3 4 5 6 7 8 9 | // protos for ALL external functions in cube... // command extern int variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist); extern void setvar(OFString *name, int i); extern int getvar(OFString *name); extern bool identexists(OFString *name); extern bool addcommand(OFString *name, void (*fun)(), int narg); | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // protos for ALL external functions in cube... // command extern int variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist); extern void setvar(OFString *name, int i); extern int getvar(OFString *name); extern bool identexists(OFString *name); extern bool addcommand(OFString *name, void (*fun)(), int narg); extern int execute(OFString *p, bool down = true); extern void exec(OFString *cfgfile); extern bool execfile(OFString *cfgfile); extern void resetcomplete(); extern void complete(OFString *s); extern void alias(OFString *name, OFString *action); extern OFString *getalias(OFString *name); extern void writecfg(); |
︙ | ︙ |
Modified src/serverbrowser.mm from [a2f42f1499] to [23e77d6100].
︙ | ︙ | |||
313 314 315 316 317 318 319 | uchar buf[MAXUPD]; uchar *reply = retrieveservers(buf, MAXUPD); if (!*reply || strstr((char *)reply, "<html>") || strstr((char *)reply, "<HTML>")) conoutf(@"master server not replying"); else { servers.setsize(0); | > | < > > | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | uchar buf[MAXUPD]; uchar *reply = retrieveservers(buf, MAXUPD); if (!*reply || strstr((char *)reply, "<html>") || strstr((char *)reply, "<HTML>")) conoutf(@"master server not replying"); else { servers.setsize(0); @autoreleasepool { execute(@((char *)reply)); } } servermenu(); } COMMAND(addserver, ARG_1STR) COMMAND(servermenu, ARG_NONE) COMMAND(updatefrommaster, ARG_NONE) |
︙ | ︙ |
Modified src/world.mm from [67fd387b5f] to [cee211ba17].
1 2 3 4 | // world.cpp: core map management stuff #include "cube.h" | < < | 1 2 3 4 5 6 7 8 9 10 11 | // world.cpp: core map management stuff #include "cube.h" extern OFString *entnames[]; // lookup from map entities above to strings sqr *world = NULL; int sfactor, ssize, cubicsize, mipsize; header hdr; |
︙ | ︙ | |||
66 67 68 69 70 71 72 | if (!savegame && type != 3) playsound(S_RUMBLE); @autoreleasepool { OFString *aliasname = [OFString stringWithFormat:@"level_trigger_%d", tag]; | | < | < | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | if (!savegame && type != 3) playsound(S_RUMBLE); @autoreleasepool { OFString *aliasname = [OFString stringWithFormat:@"level_trigger_%d", tag]; if (identexists(aliasname)) execute(aliasname); } if (type == 2) endsp(false); } COMMAND(trigger, ARG_2INT) |
︙ | ︙ | |||
498 499 500 501 502 503 504 | } calclight(); startmap(@"base/unnamed"); if (oldworld) { free(oldworld); toggleedit(); | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 | } calclight(); startmap(@"base/unnamed"); if (oldworld) { free(oldworld); toggleedit(); execute(@"fullbright 1"); } } void mapenlarge() { empty_world(-1, false); |
︙ | ︙ |