y_iterate - tutorial basic
#1

I have seen the two guides are of y_iterate, but I can not understand the basics, because the tutorials teach you a generalized form.

Could someone explain me the basic use of y_iterate ?, what is iterators and that sort of thing.
Reply
#2

Basically y_iterate/foreach iterator is just an array which holds taken indexes of another array (that array is of dynamic size, using y_malloc) (+ helper variable holding count of indexes held). y_iterate has few built-in iterators, and iterator functions.
The most common builtin iterator used is Player. Basically when a new player connects it adds his id this special array (and removes it when he disconnects).
pawn Code:
foreach(new playerid:Player) {
    printf("Player %d is currently connected", playerid);
}
You can create your own iterators. In example below I use #define to, well, define the size of the iterator, because I can keep all my defines in one place, and naming a number reduces number of "magic numbers" (too much number in that sentence).
pawn Code:
#define DescriptiveNameOfNumber 20

new Iter:MySpecialIterator<DescriptiveNameOfNumber>;
You just created an iterator with 20 slots. You have to add items to it manually. Say you're loading something from database/ini file/whatever - the code is mainly pseudo-code:
pawn Code:
new MySpecialData[DescriptiveNameOfNumber] = { -1, ... };

MyFunctionLoadingData() {
    for(new i = 0; i != rows; ++i) {
        MySpecialData[i] = fetch_data_from_source(i);
        Iter_Add(MySpecialIterator, i);
    }
}
Just like that you can now do:
pawn Code:
foreach(new index:MySpecialIterator) {
    printf("My special data at index %d holds", MySpecialData[i]);
}
Neat! There are also 2d-iterators:
pawn Code:
#define MAX_CELLPHONES_PER_PLAYER 2

new Iter:PlayerCellphones[MAX_PLAYERS]<MAX_CELLPHONES_PER_PLAYER>;
Unless you are using Zeex's compiler (which I guess you don't as you're a beginner), you must initialize it in OnGameModeInit (I can't remember ATM if main is good too, but just to be safe):
pawn Code:
public OnGameModeInit() {
    Iter_Init(PlayerCellphones);
}
Now let's say player wants to buy a cellphone, and you want to check if he has an empty slot:
pawn Code:
YCMD:buycell(playerid, params[], help) {
    if(Iter_Free(PlayerCellphones[playerid]) == cellmin) SCM(playerid, -1, "Sorry mate, no more cellphones for you!");
}
We use Iter_Free to check if there are empty slots. If not, the function will return cellmin (this is under discussion, but at the moment of writing that's the value you should use)/

Removing a value is as easy as
pawn Code:
Iter_Remove(YourIterator, index);
There's also Iter_Alloc (add at first free slot), Iter_Random (return random item from an iterator) and Iter_Clear (remove all values).

That's all the basics you need. For those of you more interested, there are some more things:
pawn Code:
new Iterator:PlayerCars<MAX_PLAYERS, MAX_VEHICLES>;
This iterator is used when you're sure that no two players can own the same vehicle - it decreases iterator size from MAX_PLAYERS * MAX_VEHICLES to MAX_PLAYERS + MAX_VEHICLES. For usage, I recommend reading through YSI unit tests.

There are iterator functions, which are really cool:
pawn Code:
foreach(new playerid:Reverse(Player)) //Reverse the array looping
foreach(new i:Powers(4)) //1, 4, 16, ...
You can write your own custom iterator functions, just look through iterators.inc. I don't exactly remember more than using @iterfunc, but there are live examples so I won't bother.

And of course, there is integration with other YSI libraries (basically just iterator functions, but builtin in other libraries). If you are using y_groups, you should be familiar with Group (now deperecated in favour of GroupMember):

pawn Code:
foreach(new player:GroupMember[MyGroup])
That's it. Reading YSI source (you don't need to know macro voodoo to do so, most of it is really clean code) is the best code reference.

My not-so-good tutorial, there's some code examples, not much changed since then http://misiur.github.io/2015/03/07/y...how-to-use-it/
Reply
#3

Misiur, what benefits have iteration? Is faster with much? I mean is like mysql or ini is method of stock?
And worth to transform your scripts to iteration if you don t have used?
Reply
#4

It's RAM vs CPU. So, having iterators takes few more bytes of RAM, in exchange for faster iterations. Say, you have 5 car slots for a player. Slots 0, 2 and 4 are taken. Normally you'd have to do something like
pawn Code:
for(new index = 0; index != sizeof PlayerCars[]; ++index) {
    if(PlayerCars[playerid][index] == INVALID_VEHICLE_ID) continue;
    //Now do something with the valid car
}
You'd have to use that pattern every time you worked on player cars, be it buying components, locking vehicle, etc. etc. That's prone to being forgotten. But if you use an iterator, you'll just use (not including adding and removing player cars to their slots).
pawn Code:
foreach(new index:PlayerCars[playerid]) //index will be 0, 2 and 4
As for converting whole gamemode: it depends. I won't recommend it, but the process itself is mostly painless. But when writing gm from ground up, I can recommend it as I use it extensively.

Quote:

I mean is like mysql or ini is method of stock?

I have no idea what that sentence means.
Reply
#5

http://web.archive.org/web/201403291...ad.php?t=92679

That is the thread I learned how to use foreach/y_iterate.
Reply
#6

Thank you. I'll read it carefully, if I have any questions, I will mention them.
Reply
#7

Can I be explain the use of Iter_SafeRemove ?, I know I explained in the post of ****** , but I do not see might not use or understand its functionality. Thanks
Reply
#8

Normally we use Iter_Remove to remove a value from an iterator. However if we want to remove a value inside a foreach loop, we should use Iter_SafeRemove otherwise it will just stop there and won't continue.
Reply
#9

Basically foreach uses the array slot to determine next iteration, when you remove one of the slots, it cleans the array slot so it can't find the next one, because of this you need to SafeRemove the slot when you are removing it inside a loop (for example removing all the houses in a loop).
Thats pretty much a casual way to explain it.
Reply
#10

Ok!

I have a doubt. All examples showing the use of multi dimensional iterators are car owners. What if car rent?, because I think it would have to create a three-dimensional array or at least several array to know if it is a rental car and to know who alkyl.

What it is done in this case ?.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)