Передача данных в таймер

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
Как передать в таймер 2 объекта что ли, не знаю как назвать)
Например, клиента мы может передать так
PHP:
#include <sourcemod>

public OnClientConnected(client)
{
	CreateTimer(1.0, Timer, client);
}

public Action:Timer(Handle:timer, any:client)
{
	PrintToChat(client, "Ваше имя: %N", client);
}
А как тут?
PHP:
#include <sourcemod>

public OnClientConnected(client)
{
	decl String:name[50];
	GetClientName(client, name, sizeof(name));
	
	// Что сюда писать? Как передать name ??
	CreateTimer(1.0, Timer, client);
}

// Тоже самое
public Action:Timer(Handle:timer, any:client)
{
	PrintToChat(client, "Ваше имя: %s", name);
}
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
CreateDataTimer, с записью в датапак нужных параметров? Или не пойдет?

UPD: Собственно пример из GrenadeTrails...
PHP:
public OnEntityCreated(Entity, const String:Classname[])
{
........
		new Handle:datapack = INVALID_HANDLE;
		CreateDataTimer(0.0, projectile, datapack, TIMER_FLAG_NO_MAPCHANGE);
		WritePackCell(datapack, Entity);
		WritePackString(datapack, Classname);
		ResetPack(datapack);
}
public Action:projectile(Handle:timer, Handle:datapack)
{
...
	new Entity=ReadPackCell(datapack);
	new String:Classname[32];
	ReadPackString(datapack, Classname, sizeof(Classname));
....
}
 

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
Не совсем понял, если, к примеру, у нас 2 строки и 2 интовых числа, то как?
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Не совсем понял, если, к примеру, у нас 2 строки и 2 интовых числа, то как?

По логике вещей что записал то и берешь, в том же порядке. Например так (не тестировал понятное дело, только идея). Кстати, имена переменных не обязательно должны совпадать
PHP:
public OnEntityCreated(Entity, const String:Classname[])
{
........
		new Handle:datapack = INVALID_HANDLE;
		CreateDataTimer(0.0, projectile, datapack, TIMER_FLAG_NO_MAPCHANGE);
		WritePackCell(datapack, FirstIntVar);
		WritePackCell(datapack, SecondIntVar);
		WritePackString(datapack, FirstStringVar);
		WritePackString(datapack, SecondStringVar);
		ResetPack(datapack);
}
public Action:projectile(Handle:timer, Handle:datapack)
{
...
	new Int1=ReadPackCell(datapack);
	new Int2=ReadPackCell(datapack);
	new String:String1[32];
	new String:String2[32];
	ReadPackString(datapack, String1, sizeof(String1));
	ReadPackString(datapack, String2, sizeof(String2));
....
}
Опять же, не важно какой порядок, можно например записать вначале инт и строрку, и потом второй инт и вторую строку
WritePackCell(datapack, FirstIntVar);
WritePackString(datapack, FirstStringVar);
WritePackCell(datapack, SecondIntVar);
WritePackString(datapack, SecondStringVar);
Главное в таком же порядке, в каком было передано, в том и считать в функции. (то есть если был инт-строка-инт-строка, то и считывать надо Cell, String, Cell, String).
Традиционно стараются указывать в порядке использования в вызываемой функции.
(Кроме Cell и String есть Float с подобным Cell синтаксисом)
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
PHP:
CreateTimer(1.0, Timer, client);
public Action:Timer(Handle:timer, any:i)

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

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Ну, есть ведь KeyValues, в которых имя это ключ, имя переменной, куда помещается то не важно, а вот в запросе то надо указывать имя.. А тут просто считывание по порядку, имен нет.

Мне вот интерестно как ведёт себя этот хендл датапака, если убить таймер. Врятли флаг TIMER_DATA_HNDL_CLOSE закрывает передаваемый хендл при убийстве таймера. Кстати, если передаёте хендл, то указывайте выше упомянутый флаг или делайте CloseHandle(datapack); в коллбеке таймера.
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Мне вот интерестно как ведёт себя этот хендл датапака, если убить таймер. Врятли флаг TIMER_DATA_HNDL_CLOSE закрывает передаваемый хендл при убийстве таймера. Кстати, если передаёте хендл, то указывайте выше упомянутый флаг или делайте CloseHandle(datapack); в коллбеке таймера.

Note that, unlike with CreateTimer(), you do not need to call CloseHandle() on the created datapack, even if TIMER_DATA_HNDL_CLOSE is not specified.
Так что не нужно совсем...
А вот если убить таймер.. Хм, надо попробовать сделать разные команды на создание таймера, убийство таймера и убийство датапака и посмотреть, будет ли материться что несуществущий хендл...
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Так что не нужно совсем...
А вот если убить таймер.. Хм, надо попробовать сделать разные команды на создание таймера, убийство таймера и убийство датапака и посмотреть, будет ли материться что несуществущий хендл...

C-подобный:
stock Handle:CreateDataTimer(Float:interval, Timer:func, &Handle:datapack, flags=0)
{
	datapack = CreateDataPack();
	flags |= [COLOR="Red"][B]TIMER_DATA_HNDL_CLOSE[/B][/COLOR];
	return CreateTimer(interval, func, datapack, flags);
}
Уловил?
Вобщем, не безопасно передавать подобные хендлы в таймеры, в том случае, если вы в каком-то месте эти таймеры убиваете. За пару недель может наплодится солидно левых объектов в памяти.
 

FrozDark

Участник
Сообщения
1,769
Реакции
2,050
флаг TIMER_DATA_HNDL_CLOSE убивает передаваемый datapack. Убивает по истечение времени или если таймер убит вручную через KillTimer, datapack безопасно будет уничтожен
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
флаг TIMER_DATA_HNDL_CLOSE убивает передаваемый datapack. Убивает по истечение времени или если таймер убит вручную через KillTimer, datapack безопасно будет уничтожен

Если верить логике, то Handle - это всего лиш указатель на некую структуру. Если создать датапак, присвоить указатель какой-нибудь глобальной переменной, запустить и убить таймер, то почему тогда после убийства таймера указатель из глобальной переменной всё ещё указывает на читабельный датапак? А если таймер сработал, то выплывает наша любимая ошибка INVALID HANDLE. То-есть флаг работает корректно только после срабатывания таймера.
 

FrozDark

Участник
Сообщения
1,769
Реакции
2,050
если ты убиваешь таймер с помощью CloseHandle, то новости печальные

PHP:
KillTimer

Syntax:
native KillTimer(Handle:timer, bool:autoClose=false);

Usage:
 autoClose			If autoClose is true, the data that was passed to CreateTimer() will be closed as a handle if TIMER_DATA_HNDL_CLOSE was not specified.
Notes:
Kills a timer. Use this instead of CloseHandle() if you need more options.
 
Сверху Снизу