Не убиваются таймеры
#1

Долгое время использовал y_timers, но решил вернуть обычные таймеры.

В OnPlayerConnect:
PlayerInfo[playerid][pTimer] = SetTimerEx("PlayerTimer", 500, true, "i", playerid);

В OnPlayerDisconnect:
KillTimer(PlayerInfo[playerid][pTimer]);

При первом входе на сервер всё нормально. Но если перезайти, то таймеры начинаются выполняться в 2 раза быстрее. И так каждый раз в 2 раза быстрее.
Похоже на то, что таймер не убивается при выходе. А при входе создаётся еще один.

Почему так может быть?
Reply
#2

Самостоятельно вызвать OnPlayerDisconnect для каждого игрока при вызове перезагрузки.
Либо, если OnPlayerDisconnect изначально не был предназначен у вас для такого случая, вызвать те процедуры из этого callback, которые приведут к убийству таймера, сохранению данных и ещё чего-либо нужного.
Reply
#3

Quote:
Originally Posted by Mutha_X
View Post
Самостоятельно вызвать OnPlayerDisconnect для каждого игрока при вызове перезагрузки.
Либо, если OnPlayerDisconnect изначально не был предназначен у вас для такого случая, вызвать те процедуры из этого callback, которые приведут к убийству таймера, сохранению данных и ещё чего-либо нужного.
Не совсем понял чем мне это поможет. Проблема возникает не при перезагрузке. А при обычном релоге.
И судя по всему, таймер как раз и не убивается в OnPlayerDisconnect
Reply
#4

Отдебаж PlayerInfo[playerid][pTimer] до и после вызова KillTimer

Таймер зациклен, можно киллнуть его внутри него, если игрок отключен.
Reply
#5

Легче SetTimerEx("PlayerTimer", 500, false, "i", playerid);
public PlayerTimer(playerid)
{
if(!IsPlayerConnected(playerid)) return 0;
SetTimerEx("PlayerTimer", 500, false, "i", playerid);
return 1;
}

Или

public PlayerTimer(playerid)
{
if(!IsPlayerConnected(playerid)) return KillTimer(PlayerInfo[playerid][pTimer]);
return 1;
}
Reply
#6

А что мешает создать один таймер, который будет просчитывать игроков, и не заморачиваться ?
В теле таймера гнать цикл и проверять игроков на коннект итд. Не придётся ничего создавать и убивать таймер.
Reply
#7

Quote:
Originally Posted by Mexanizm93
View Post
А что мешает создать один таймер, который будет просчитывать игроков, и не заморачиваться ?
В теле таймера гнать цикл и проверять игроков на коннект итд. Не придётся ничего создавать и убивать таймер.
Ничего. Но слышал мнение, что это хуже с точки зрения производительности.
Reply
#8

Quote:
Originally Posted by Jasno
View Post
Легче SetTimerEx("PlayerTimer", 500, false, "i", playerid);
public PlayerTimer(playerid)
{
if(!IsPlayerConnected(playerid)) return 0;
SetTimerEx("PlayerTimer", 500, false, "i", playerid);
return 1;
}
Нормальная тема.
Reply
#9

Quote:
Originally Posted by OKStyle
View Post
Нормальная тема.
Этот вариант отлично работает. Спасибо тому, кто предложил.

Но всё же очень странно почему таймер не убивается.

Это даже в логах видно.

[19:06:23] PlayerTimer 0
[19:06:23] PlayerTimer 0
[19:06:24] PlayerTimer 0
[19:06:24] PlayerTimer 0
[19:06:24] PlayerTimer 0
[19:06:24] [part] Manuel_Moralez has left the server (0:1)
[19:06:24] PlayerTimer 0
[19:06:25] PlayerTimer 0
[19:06:25] PlayerTimer 0
[19:06:25] PlayerTimer 0
[19:06:25] PlayerTimer 0
[19:06:26] PlayerTimer 0
Reply
#10

возможно, где-то выше в OnPlayerDisconnect происходит runtime ошибка и выполнение паблика прерывается, поэтому таймер и не убивается. crashdetect стоит?
Reply
#11

Quote:
Originally Posted by OKStyle
Посмотреть сообщение
Нормальная тема.
Не очень. У меня из-за этого создавалось два односекундных таймера. Когда один игрок выходит, а другой успевает зайти под его слот.

Если решать костылями, то лучше добавить проверку на подключенность игрока в повторяющемся таймере, а сам таймер удалять не только при отключении, но и при подключении.

А в идеале решить это:

Quote:
Originally Posted by DartfoL
Посмотреть сообщение
возможно, где-то выше в OnPlayerDisconnect происходит runtime ошибка и выполнение паблика прерывается, поэтому таймер и не убивается. crashdetect стоит?
Reply
#12

Quote:
Originally Posted by DartfoL
Посмотреть сообщение
возможно, где-то выше в OnPlayerDisconnect происходит runtime ошибка и выполнение паблика прерывается, поэтому таймер и не убивается. crashdetect стоит?
Стоит. И выше там ничего нет.
Reply
#13

Quote:
Originally Posted by stabker
Посмотреть сообщение
Не очень. У меня из-за этого создавалось два односекундных таймера. Когда один игрок выходит, а другой успевает зайти под его слот.

Если решать костылями, то лучше добавить проверку на подключенность игрока в повторяющемся таймере, а сам таймер удалять не только при отключении, но и при подключении.

А в идеале решить это:
Можно использовать 2 вариант, да и такая проблема как создание 2 решается очень легко. Да и возникнуть она может только если сразу в OnPlayerConnect пихать, обычно апдейт пихают после авторизации/регистрации.
А вообще советую создать 1 таймер для всех игроков

public TimerAllPlayer()
{
for(new pid = -1; pid<GetPlayerPoolSize();pid++)
{
if(!IsPlayerConnected(pid)) continue;
//Код
}
return 1;
}
Reply
#14

Quote:
Originally Posted by Josipo
Посмотреть сообщение
Похоже на то, что таймер не убивается при выходе. А при входе создаётся еще один.

Почему так может быть?
Автор, не канифоль мозги, прологируй вызов убийства таймера. И введи доп. проверки при коннекте, удален ли таймер. Поносаветовали тут хурмы всякой, сразу чувствуется клуб теоретиков.
Reply
#15

Quote:
Originally Posted by Jasno
Посмотреть сообщение
А вообще советую создать 1 таймер для всех игроков

public TimerAllPlayer()
{
for(new pid = -1; pid<GetPlayerPoolSize();pid++)
{
if(!IsPlayerConnected(pid)) continue;
//Код
}
return 1;
}
Это вообще что за ужас?
Один совет лучше другого
Reply
#16

Quote:
Originally Posted by Jasno
Посмотреть сообщение
А вообще советую создать 1 таймер для всех игроков

public TimerAllPlayer()
{
for(new pid = -1; pid<GetPlayerPoolSize();pid++)
{
if(!IsPlayerConnected(pid)) continue;
//Код
}
return 1;
}
Если юзать глобальный таймер без foreach, то ни разу не лучше индивидуальных, а даже наоборот.
Reply
#17

Вайт красава разложил по полочкам
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)