Как сделать лучше секундный таймер?
#1

Всем привет. У меня есть вот такой вот секундный таймер.
gamemodeinit
PHP код:
Timer[1] = gettime()+1
PHP код:
timglobal SetTimer"SuperTimer",100,true); 
PHP код:
forward SuperTimer();
public 
SuperTimer()
{
    new 
GetTime gettime();
    if(
Timer[1] <= GetTime && Timer[1] != 0)
    {
        
Timer[1] = GetTime+1
        
SecTimer();
    }

В SecTimer Большой код.
При онлайне 5 выполняется за 1-2 мс.
Как сделать оптимальней,чтобы при онлайне 300-500 люди себя комфортно чувствовали?
Reply
#2

Когда у тебя будет онлайн 300-500, то стоит попробывать некий foreach (я не использую пока что, но люди пишут, что помогает).
Код должен быть максимально продуман и в меру оптимизирован, чтобы не выполнялось лишних операций.
Если онлайн ниже 200, то не парься особо. И кстати ещё не стоит забывать о константе MAX_PLAYERS, нужно поставить ей столько, сколько реально нужно.
Reply
#3

Так форич и выполняется.
Так вот , а что если сделать , чтобы к каждому игроку присваивался собственный таймер (EX), при коннекте. А при дисконнекте - килялся.
Где-то видел, один человек писал.
Говорит,что если юзать так, как у меня, то увы , лаги бешеные будут.
Ну, #define MAX_PLAYERS (1000) , я раздефайнил и обратно задефайнил. Ничего лишнего не будет.
Reply
#4

Я иногда использую отдельный таймер для игрока:
PHP код:
new test_timerid[MAX_PLAYERS];
public 
OnPlayerConnect(playerid)
{
    
test_timerid[playerid] = SetTimerEx("FuncName"10001"d"playerid);
    
// время обновления таймера не обязательно делать именно 1000, можно и меньше,
    // ведь проверять одного игрока, можно и 250 поставить (4 раза в секунду будет выполняться)
}
public 
OnPlayerDisconnect(playeridreason)
{
    
KillTimer(test_timerid[playerid]);
}
forward FuncName(playerid);
public 
FuncName(playerid)
{
    
// какие-то действия

Quote:
Originally Posted by jakebat
Посмотреть сообщение
Ну, #define MAX_PLAYERS (1000) , я раздефайнил и обратно задефайнил. Ничего лишнего не будет.
Если у тебя например онлайн 50, то нафига оставлять константе 1000? 950 лишних итераций в циклах, лишнее выделение памяти для переменных и т.д.))
Reply
#5

Можно и не "киллять" таймер при выходе, а сделать так

PHP код:
public OnPlayerConnect(playerid

    
SetTimerEx("FuncName"1000false"d"playerid); 
}
forward FuncName(playerid); 
public 
FuncName(playerid

    if(!
IsPlayerConnected(playerid))
        return 
1;
    
// какие-то действия 
    
SetTimerEx("FuncName"1000false"d"playerid); 
    return 
1;

И когда игрок отключится, таймер сам себя "отключит"
Reply
#6

Quote:
Originally Posted by Eims
Посмотреть сообщение
Можно и не "киллять" таймер при выходе, а сделать так

PHP код:
public OnPlayerConnect(playerid

    
SetTimerEx("FuncName"1000false"d"playerid); 
}
forward FuncName(playerid); 
public 
FuncName(playerid

    if(!
IsPlayerConnected(playerid))
        return 
1;
    
// какие-то действия 
    
SetTimerEx("FuncName"1000false"d"playerid); 
    return 
1;

И когда игрок отключится, таймер сам себя "отключит"
вручную циклировать таймер... в то время когда его цикличность предусмотрена разработчиком.
зачем костыли, товарищ?
Reply
#7

Ну и смысл запускать рекурсию? Если есть функция повторения в самом таймере
Reply
#8

Quote:
Originally Posted by jakebat
Посмотреть сообщение
Ну и смысл запускать рекурсию? Если есть функция повторения в самом таймере
Написали же, чтобы не убивать таймер. Вполне себе вариант
Reply
#9

Если очень трудно убить таймер, то можно воспользоваться SetPlayerTimer из плагина samp-plugin-timerfix.
Reply
#10

Вариант Eims очень плох!
Не продуман.
При моментальном входе игрока на ID только вышедшего, работать будут два таймера на один ID.
А такое будет случаться 100% особенно на маленьких ID.
Reply
#11

Ну, как вариант можно сделать так:
public OnPlayerConnect(playerid)
{
SetTimerEx("FuncName", 1000, false, "dd", playerid, SetPVarInt(playerid, "Random", random(9999));
}

forward FuncName(playerid, rand);
public FuncName(playerid, rand)
{
if(!IsPlayerConnected(playerid) || GetPVarInt(playerid, "Random") != rand)
return 1;

// какие-то действия

SetTimerEx("FuncName", 1000, false, "dd", playerid, rand);
return 1;
}
Reply
#12

Quote:
Originally Posted by WestSide56
View Post
Ну, как вариант можно сделать так:
public OnPlayerConnect(playerid)
{
SetTimerEx("FuncName", 1000, false, "dd", playerid, SetPVarInt(playerid, "Random", random(9999));
}

forward FuncName(playerid, rand);
public FuncName(playerid, rand)
{
if(!IsPlayerConnected(playerid) || GetPVarInt(playerid, "Random") != rand)
return 1;

// какие-то действия

SetTimerEx("FuncName", 1000, false, "dd", playerid, rand);
return 1;
}
Это костыль какой-то. Проще уже запускать его заново при каждом финише, но вместе с этим и убивать его при дисконнекте. Для полной уверенности, так сказать.
Reply
#13

Костыль года
Reply
#14

Quote:
Originally Posted by OstGot
View Post
Это костыль какой-то. Проще уже запускать его заново при каждом финише, но вместе с этим и убивать его при дисконнекте. Для полной уверенности, так сказать.
Переподключиться могут успеть и тогда будет двойной таймер. А еще лучше использовать не рандом числа а GetTickCount().
Reply
#15

Я один не понял, чем плохо просто удалить повторяющийся таймер в OnPlayerDisconnect?
Reply
#16

Quote:
Originally Posted by stabker
View Post
Я один не понял, чем плохо просто удалить повторяющийся таймер в OnPlayerDisconnect?
Этот паблик не всегда срабатывает, очень редко но бывает
Reply
#17

Quote:
Originally Posted by WestSide56
View Post
Этот паблик не всегда срабатывает, очень редко но бывает
Можно уточнить, при каких обстоятельствах именно у вас это бывало?
Reply
#18

Quote:
Originally Posted by OstGot
View Post
Можно уточнить, при каких обстоятельствах именно у вас это бывало?
Скорей всего при выключении сервера, ахах.

PS: У меня никогда такого бага НЕ было, всегда OnPlayerDisconnect вызывался при выходе игрока.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)