When you find you must perform the same loop logic in various places in your program, you may use a one-off for_expansion
to abstract the pattern.
For example, let’s say we have players
, a buffer array of Player
structs, and as players join over the network this array gets populated while player_count
is incremented. You will want to loop over the connected players in various places in your code, and each time you do you must use the same loop logic, which will be one of these:
// option (a)
for player_index: 0 .. player_count - 1 {
player := players[player_index];
// ...
}
// option (b)
for player, player_index: players {
if player_index >= player_count break;
// ...
}
Neither of these options are especially nice; there’s more noise than we’d like, and both take two lines to set up (allowing for the possibility of a mistaken omission, particularly with the second option).
We can use a for_expansion
to clean this up:
active_players: struct {};
for_expansion :: (_: *type_of(active_players), body: Code, flags: For_Flags) #expand {
for `it, `it_index: players {
if it_index >= player_count break;
#insert body;
}
}
Now, any time we want to loop over the active players we simply do this:
for player: active_players {
// ...
}