Перейти к содержанию
Авторизация  
#Kot

Работа с итераторами foreach.

Рекомендуемые сообщения

#Kot
Итераторы значительно повышают скорость перебора итераций в циклах(foreach отбрасывает лишние итерации). 
 
Код вывода лога: 
#include                                     <a_samp>
#include                                     <foreach>

new Iterator:vehicles_in_stream[MAX_PLAYERS]<MAX_VEHICLES>;

main(){}

public OnGameModeInit()
{
    Iter_Init(vehicles_in_stream);
    Iter_Add(vehicles_in_stream[ 0 ], 7);
    Iter_Add(vehicles_in_stream[ 0 ], 3);
    print("Для MAX_VEHICLE = 10:");
    for(new i = 0; i < 10; i++)
    {
        printf("i = %d",i);
    }
    print("foreach:");
    foreach(new i: vehicles_in_stream[ 0 ])
    {
        printf("i = %d",i);
    }
    return 1;
}  

 
Лог:
[19:30:50] При MAX_VEHICLE = 10:
[19:30:50] i = 0
[19:30:50] i = 1
[19:30:50] i = 2
[19:30:50] i = 3
[19:30:50] i = 4
[19:30:50] i = 5
[19:30:50] i = 6
[19:30:50] i = 7
[19:30:50] i = 8
[19:30:50] i = 9
[19:30:50] foreach:
[19:30:50] i = 3
[19:30:50] i = 7

 
Видно, что foreach автоматически отбросил ненужные id авто.
 
Работу итераторов мы рассмотрим на примере, т.к я считаю, что примеры отображают суть более наглядно. 
 
Работа с примером:
 
На каждом РП сервере мы можем встретить систему закрывания дверей автомобиля(/lock), в подавляющей части модов, что я видел в паблике, для поиска нужного id автомобиля используется цикл:
 
for(new i = 0; i < MAX_VEHICLES; i++)
Но, если подумать, зачем нам делать огромное кол-во лишних итераций в цикле, если нам нужны только автомобили, которые находятся в стрим зоне игрока? Именно в этой ситуации мы можем применить итераторы таким образом:
 
Создаём сам итератор:
new Iterator:vehicles_in_stream[MAX_PLAYERS]<MAX_VEHICLES>;

Далее нам необходимо объявить итератор при запуске мода(только для многомерных массивов):

public OnGameModeInit() 
{
    Iter_Init(vehicles_in_stream);
    return 1;
}  
Теперь мы должны внести значение в итератор при появлении автомобиля в стрим-зоне игрока. 
Для этого мы воспользуемся функцией Iter_Add(name, value). Если мы пытаемся внести невалидное значение, либо уже существующее, то сервер игнорирует это действие.
public OnVehicleStreamIn(vehicleid, forplayerid)//авто в стрим зоне игрока с id = forplayerid.
{
    Iter_Add(vehicles_in_stream[forplayerid], vehicleid);//внесли
    return 1;
}  
Авто пропадает из стрим зоны игрока, мы обязательно должны вынести ид авто из итератора, иначе у нас будут лишние итерации.
Для этого существует функция Iter_Remove(name, value)
public OnVehicleStreamOut(vehicleid, forplayerid)//авто покинуло стрим зону игрока с id = forplayerid. 
{
    Iter_Remove(vehicles_in_stream[forplayerid], vehicleid);//очистили
    return 1;
}  

Очищаем итератор при отключении:

public OnPlayerDisconnect(playerid, reason)
{
    if(Iter_Count(vehicles_in_stream[playerid]) != 0) Iter_Clear(vehicles_in_stream[playerid]);
        return 1;
}  

Дело сделано, теперь мы можем использовать циклы для автомобилей в стрим зоне в виде:

foreach(new i: vehicles_in_stream[playerid])
foreach автоматически отбросит лишние итерации.
 
 
Где ещё использовать? Использовать итераторы можно при работе, например,с чатами, где используются циклы с проверками игроков на команду/админку и т.п. 
Там же вы можете рассмотреть другие полезные функции, а так же ситуации, в которых можно использовать foreach, с примерами(я затронул лишь малую часть).
 
 
 
Любая критика приветствуется, аналогично с поправками.
 
Для тех, кто "в танке" - эта аптимизация, йоба.
 
Автор: Slaughter.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.