From 06e2e30b6b02992a12643d1e60d9f7427162926c Mon Sep 17 00:00:00 2001 From: TimePath Date: Tue, 29 Dec 2015 21:08:22 +1100 Subject: [PATCH] Iter: prevent invalidation --- qcsrc/lib/iter.qh | 57 ++++++++++++++++++++++------------ qcsrc/server/_all.qh | 5 +-- qcsrc/server/command/sv_cmd.qc | 24 +++++++------- qcsrc/server/mapvoting.qc | 22 ++++++------- 4 files changed, 61 insertions(+), 47 deletions(-) diff --git a/qcsrc/lib/iter.qh b/qcsrc/lib/iter.qh index d86d77c46..0eebddd40 100644 --- a/qcsrc/lib/iter.qh +++ b/qcsrc/lib/iter.qh @@ -4,8 +4,9 @@ #define FOREACH_ARRAY(arr, start, end, cond, body) \ MACRO_BEGIN \ { \ - for (int i = start; i < end; ++i) \ + for (int _i = start; _i < end; ++_i) \ { \ + const noref int i = _i; \ const noref entity it = arr[i]; \ if (cond) { LAMBDA(body) } \ } \ @@ -14,9 +15,11 @@ #define FOREACH_LIST(list, next, cond, body) \ MACRO_BEGIN \ { \ - int i = 0; \ - for (entity it = list##_first; it; (it = it.next, ++i)) \ + int _i = 0; \ + for (entity _it = list##_first; _it; (_it = _it.next, ++_i)) \ { \ + const noref int i = _i; \ + const noref entity it = _it; \ if (cond) { LAMBDA(body) } \ } \ } MACRO_END @@ -25,9 +28,10 @@ MACRO_BEGIN \ { \ string _words = words; \ - int i = 0; \ - for (string _it; (_it = car(_words)); (_words = cdr(_words), ++i)) \ + int _i = 0; \ + for (string _it; (_it = car(_words)); (_words = cdr(_words), ++_i)) \ { \ + const noref int i = _i; \ const noref string it = _it; \ if (cond) { LAMBDA(body) } \ } \ @@ -49,9 +53,10 @@ MACRO_BEGIN \ { \ STRING_ITERATOR(iter, s, 0); \ - int it; \ - while ((it = STRING_ITERATOR_GET(iter)) > 0) \ + int _it; \ + while ((_it = STRING_ITERATOR_GET(iter)) > 0) \ { \ + const noref int it = _it; \ if (cond) { LAMBDA(body) } \ } \ } MACRO_END @@ -78,55 +83,67 @@ #define FOREACH_ENTITY_UNORDERED(cond, body) \ MACRO_BEGIN { \ - int i = 0; \ - for (entity it = findchainentity_tofield(_FOREACH_ENTITY_fld, NULL, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \ + int _i = 0; \ + for (entity _it = findchainentity_tofield(_FOREACH_ENTITY_fld, NULL, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \ { \ + const noref int i = _i; \ + const noref entity it = _it; \ if (cond) { LAMBDA(body) } \ } \ } MACRO_END #define FOREACH_ENTITY_ORDERED(cond, body) \ MACRO_BEGIN { \ - int i = 0; \ - for (entity it = NULL; (it = nextent(it)); ++i) \ + int _i = 0; \ + for (entity _it = NULL; (_it = nextent(_it)); ++_i) \ { \ + const noref int i = _i; \ + const noref entity it = _it; \ if (cond) { LAMBDA(body) } \ } \ } MACRO_END #define FOREACH_ENTITY_FLOAT(fld, match, body) \ MACRO_BEGIN { \ - int i = 0; \ - for (entity it = _findchainfloat_tofield(fld, match, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \ + int _i = 0; \ + for (entity _it = _findchainfloat_tofield(fld, match, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \ { \ + const noref int i = _i; \ + const noref entity it = _it; \ LAMBDA(body) \ } \ } MACRO_END #define FOREACH_ENTITY_FLAGS(fld, match, body) \ MACRO_BEGIN { \ - int i = 0; \ - for (entity it = _findchainflags_tofield(fld, match, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \ + int _i = 0; \ + for (entity _it = _findchainflags_tofield(fld, match, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \ { \ + const noref int i = _i; \ + const noref entity it = _it; \ LAMBDA(body) \ } \ } MACRO_END #define FOREACH_ENTITY_CLASS(class, cond, body) \ MACRO_BEGIN { \ - int i = 0; \ - for (entity it = _findchainstring_tofield(classname, class, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \ + int _i = 0; \ + for (entity _it = _findchainstring_tofield(classname, class, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \ { \ + const noref int i = _i; \ + const noref entity it = _it; \ if (cond) { LAMBDA(body) } \ } \ } MACRO_END #define FOREACH_ENTITY_ENT(fld, match, body) \ do { \ - int i = 0; \ - for (entity it = findchainentity_tofield(fld, match, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \ + int _i = 0; \ + for (entity _it = findchainentity_tofield(fld, match, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \ { \ - body \ + const noref int i = _i; \ + const noref entity it = _it; \ + LAMBDA(body) \ } \ } \ while (0) diff --git a/qcsrc/server/_all.qh b/qcsrc/server/_all.qh index c1ee6c828..3636f8984 100644 --- a/qcsrc/server/_all.qh +++ b/qcsrc/server/_all.qh @@ -31,9 +31,10 @@ const string STR_OBSERVER = "observer"; #define FOREACH_CLIENT(cond, body) \ MACRO_BEGIN { \ - for(int i = 1; i <= maxclients; ++i) \ + for(int _i = 1; _i <= maxclients; ++_i) \ { \ - entity it = ftoe(i); \ + const noref int i = _i; \ + const noref entity it = ftoe(i); \ if(it == NULL || !IS_CLIENT(it)) continue; \ if(cond) { LAMBDA(body) } \ } \ diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index b75eb5514..13829504a 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -195,14 +195,13 @@ void GameCommand_allspec(float request, float argc) case CMD_REQUEST_COMMAND: { string reason = argv(1); - float i = 0; - + int n = 0; FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA( if (it.caplayer) it.caplayer = 0; WITH(entity, self, it, PutObserverInServer()); - ++i; + ++n; )); - if (i) bprint(strcat("Successfully forced all (", ftos(i), ") players to spectate", (reason ? strcat(" for reason: '", reason, "'") : ""), ".\n")); + if (n) bprint(strcat("Successfully forced all (", ftos(n), ") players to spectate", (reason ? strcat(" for reason: '", reason, "'") : ""), ".\n")); else LOG_INFO("No players found to spectate.\n"); return; } @@ -551,15 +550,15 @@ void GameCommand_defer_clear_all(float request) { case CMD_REQUEST_COMMAND: { - float i = 0; + int n = 0; float argc; FOREACH_CLIENT(true, LAMBDA( argc = tokenize_console(strcat("defer_clear ", ftos(etof(it)))); GameCommand_defer_clear(CMD_REQUEST_COMMAND, argc); - ++i; + ++n; )); - if (i) LOG_INFO(strcat("Successfully stuffed defer clear to all clients (", ftos(i), ")\n")); // should a message be added if no players were found? + if (n) LOG_INFO(strcat("Successfully stuffed defer clear to all clients (", ftos(n), ")\n")); // should a message be added if no players were found? return; } @@ -1360,7 +1359,6 @@ void GameCommand_shuffleteams(float request) { if (teamplay) { - int i; float x, t_teams, t_players, team_color; // count the total amount of players and total amount of teams @@ -1381,15 +1379,15 @@ void GameCommand_shuffleteams(float request) FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, LAMBDA( for ( ; ; ) { - i = bound(1, floor(random() * maxclients) + 1, maxclients); + int idx = bound(1, floor(random() * maxclients) + 1, maxclients); - if (shuffleteams_players[i]) + if (shuffleteams_players[idx]) { continue; // a player is already assigned to this slot } else { - shuffleteams_players[i] = etof(it); + shuffleteams_players[idx] = etof(it); break; } } @@ -1428,10 +1426,10 @@ void GameCommand_shuffleteams(float request) bprint("Successfully shuffled the players around randomly.\n"); // clear the buffers now - for (i = 0; i < SHUFFLETEAMS_MAX_PLAYERS; ++i) + for (int i = 0; i < SHUFFLETEAMS_MAX_PLAYERS; ++i) shuffleteams_players[i] = 0; - for (i = 0; i < SHUFFLETEAMS_MAX_TEAMS; ++i) + for (int i = 0; i < SHUFFLETEAMS_MAX_TEAMS; ++i) shuffleteams_teams[i] = 0; } else diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc index a414cd5ff..409674f0a 100644 --- a/qcsrc/server/mapvoting.qc +++ b/qcsrc/server/mapvoting.qc @@ -482,25 +482,23 @@ float MapVote_Finished(float mappos) void MapVote_CheckRules_1() { - int j; - - for(j = 0; j < mapvote_count; ++j) - if( mapvote_maps_flags[j] & GTV_AVAILABLE ) + for (int i = 0; i < mapvote_count; ++i) + if (mapvote_maps_flags[i] & GTV_AVAILABLE) { - //dprint("Map ", ftos(j), ": "); dprint(mapvote_maps[j], "\n"); - mapvote_selections[j] = 0; + //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n"); + mapvote_selections[i] = 0; } mapvote_voters = 0; - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( + FOREACH_CLIENT(IS_REAL_CLIENT(it), { ++mapvote_voters; - if(it.mapvote) + if (it.mapvote) { - j = it.mapvote - 1; - //dprint("Player ", it.netname, " vote = ", ftos(it.mapvote - 1), "\n"); - mapvote_selections[j] = mapvote_selections[j] + 1; + int idx = it.mapvote - 1; + //dprint("Player ", it.netname, " vote = ", ftos(idx), "\n"); + ++mapvote_selections[idx]; } - )); + }); } float MapVote_CheckRules_2() -- 2.39.2