List of contents:
This package allows you to mimic foreach directive from other programming languages, to get all values in ds_xxx/array structure one ofter one, using just for loop, without using any ds_xxx_get() functions in GameMaker Studio 2:
for (each(variable, type); as(); iterate()) { show_debug_message(string(__key()) + ": " + string(__val())); }
It takes advantages of how for-loop works against reading ds_xxx/array structures:
for(a; b; c) {
d;
}
What most people forget about, is that b doesn't need to be an expression like i < 10, can just be a value, or return a value. So it can also be a script which returns 0/1.
Thanks to this, we can use scripts on for-loop syntax, as only middle one need to return something, and first/last are just executed without any aftermath:
It works with:
and can also be nested one into another.
In case of stacks, queues and priority lists, a copy of structure will be made, cause only way to get all elements is to remove them at those ds_xxx structures.
A ds_type_array
macro is defined in scripts, for better compatibility with other ds_type_xxx
variables. Remember it works only with this script int this case, as it's just a 0 value.
First argument needs to be a variable keeping an array, or id of ds_xx structure. The second one need to be a one of following types:
example:
var _array = [1, 2, 3, 4, 5]; for(each(_array, ds_type_array); .... // or _dsm = ds_map_create(); _dsm[? "a"] = 1; _dsm[? "b"] = 2; for(each(_dsm, ds_type_map); ....
It get's current value at current position of choosen structure.
If no arguments passed, current position/key can be get using _key() script and current value by
_val() functions.
If key and value arguments are passed as strings, then key and value will be additionally asigneed to
those values of current instance (doesn't need to exists before).
example:
var _array = [5, 4, 3, 2, 1]; for(each(_array, ds_type_array); as(); iterate()) { // _key() - returns 0, 1, 2... // _val() - returns 5, 4, 3... } // or var _array = [5, 4, 3, 2, 1]; var _sum = 0; for(each(_array, ds_type_array); as("position", "something"); iterate()) { // _key() / position - returns 0, 1, 2... // _val() / something - returns 5, 4, 3... _sum += something; }
It just moves to next element or pops from copied stack.
Returns current key. It will be a string in case of grids, in format X,Y.
Returns current value, in same type at which it was originally im structure (real, string, array, undefined).
Sets in what order priority loops should be returned. By default, on game start low priority (closer to 0) is
returned (so same as running this script with argument = 1).
It's remembered, so next foreach will use same
setting.
var dsp = ds_priority_create(); ds_priority_add(dsp, "a", 1); ds_priority_add(dsp, "b", 50); ds_priority_add(dsp, "c", 100); foreach_priority_low_as_first(1); for(each(dsp, ds_type_priority); as(); iterate()) { // _key() - returns 1, 50, 100 // _val() - returns "a", "b", "c" } foreach_priority_low_as_first(0); for(each(dsp, ds_type_priority); as(); iterate()) { // _key() - returns 100, 50, 1 // _val() - returns "b", "c", "a" }
Since you can put arrays into arrays, or ds_xxx into another ds_xxx, this package was made to work with nested structures. It automatically pushes structures into stacks, and garbage-collect values, so you can get back from nested ones to previous one.
var _array = [12, [5,10], [15,20], [30,40]]; for(each(_array, ds_type_array); as(); iterate()) { // _key() - returns 0, 1, 2, 3 // _val() - returns 12, [5, 10], [15, 20], [30, 40] if (is_array(_val()) { for(each(_val(), ds_type_array); as(); iterate()) { // _key() - returns 0, 1 / 0, 1 / 0, 1 // _val() - returns 5, 10 / 15, 20 / 30, 50 } } }
It defines all global variables needed internally by all other scripts (prefixed by _eachXXXXX). You never need to call this one anywhere, as thanks to gml_pragma() it's automatically called before GameStart event.