Таймеры в SourcePawn

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
Таймеры в SourcePawn

Введение
Таймер позволяет задать интервал, после окончания которого можно будет выполнить определенную функцию.
Все функции таймера можно посмотреть в файле timers.inc (scripting/include)

Основы использования

Одноразовые таймеры
Данный таймер будет выполняться 1 раз
PHP:
public OnPluginStart()
{
	CreateTimer(5.0, LoadStuff);
}
 
public Action:LoadStuff(Handle:timer)
{
	PrintToServer("Loading stuff!");
}
Данный код будет писать в консоль сервера Loading stuff!, по прошествии 5 секунд

Повторяющиеся таймеры
Повторяющиеся таймеры могут выполняться бесконечное число раз через определенный промежуток времени
Например, отобразим сообщение пять раз через интервал равный трем секундам
PHP:
DoMessage()
{
	CreateTimer(3.0, PrintMsg, _, TIMER_REPEAT);
}
 
public Action:PrintMsg(Handle:timer)
{
	static NumPrinted = 0;
	if (NumPrinted++ >= 5)
	{
		PrintToServer("Warning! This is a message.");
		NumPrinted = 0;
 
		return Plugin_Stop;
	}
 
	return Plugin_Continue;
}
Plugin_Stop останавливает таймер, а PLUGIN_CONTINUE позволяет ему продолжать работать


Передача данных

Простые значения
Таймеры способны передавать значения в функцию обратного вызова. Это значение может быть любого типа.
Например, покажем сообщение игроку через 15 секунд после подключения на сервер
PHP:
#define MAX_PLAYERS 256
 
new Handle:WelcomeTimers[MAX_PLAYERS+1]
 
public OnClientPutInServer(client)
{
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client);
}
 
public OnClientDisconnect(client)
{
	if (WelcomeTimers[client] != INVALID_HANDLE)
	{
		KillTimer(WelcomeTimers[client]);
		WelcomeTimers[client] = INVALID_HANDLE;
	}
}
 
public Action:WelcomePlayer(Handle:timer, any:client)
{
	PrintToConsole(client, "Welcome to the server!");
	WelcomeTimers[client] = INVALID_HANDLE;
}

Пакеты данных

Пакеты данных Packable структур, которые могут быть использованы для проведения асинхронных данных (данные, которые должны быть сохранены и без упаковки позже). Они особенно полезны для таймеров. Следовательно, существует вспомогательная функция, называемая CreateDataTimer (), которая создает таймер с помощью дескриптора данных пакета. Handle создается и закрывается автоматически.

Приведенный выше пример был переписан так:
PHP:
#define MAX_PLAYERS 256
 
new Handle:WelcomeTimers[MAX_PLAYERS+1]
 
public OnClientPutInServer(client)
{
	new Handle:pack;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack);
	WritePackCell(pack, client);
	WritePackString(pack, "Welcome to the server!");
}
 
public OnClientDisconnect(client)
{
	if (WelcomeTimers[client] != INVALID_HANDLE)
	{
		KillTimer(WelcomeTimers[client]);
		WelcomeTimers[client] = INVALID_HANDLE;
	}
}
 
public Action:WelcomePlayer(Handle:timer, Handle:pack)
{
	decl String:str[128];
	new client;
 
	/* Set to the beginning and unpack it */
	ResetPack(pack);
	client = ReadPackCell(pack);
	ReadPackString(pack, str, sizeof(str));
 
	PrintToConsole(client, "%s", str);
	WelcomeTimers[client] = INVALID_HANDLE;
}

Примечания

Точность
Наименьший возможный интервал 0,1 секунды. Таймер имеют высокую точность (с плавающей запятой), но низкую точность, как текущее время на сервере.
Это имеет два последствия:
  • Если сервер стоит на паузе - таймер не будет работать.
  • Сервер не всегда будет повторять все в точном интервале

Смерть таймера
Все таймеры гарантированно будут убиты, когда:
  • Используется CloseHandle ();
  • Используется KillTimer ();
  • Используется Plugin_Stop в повторяющихся таймерах;
  • Используется TriggerTimer () в одноразовых таймерах;
  • Исполняется одноразовый таймер
При смерти таймера, если TIMER_HNDL_CLOSE установлено, то Handle будут закрыты с разрешениями, CloseHandle () используется по умолчанию. Так как таймер не может быть клонирован.

Оригинал
 
Последнее редактирование:
Сверху Снизу