R1KO
fuck society
- Сообщения
- 9,457
- Реакции
- 7,786
- Команда форума
- #1
[SourcePawn] Урок 5 - DataPack
<- К содержанию
DataPack - производный тип от Handle, который позволяет хранить данные различных типов.
Часто нужно передать в функцию несколько значений или же массив (строку), а функция может получать только 1 параметр. Такое встречается при работе с таймерами, запросами в базу, другими запросами, которым в обратный вызов необходимо передать нужные значения.
Поэтому DataPack используется чтобы записать в него данные, передать его в нужные функции, затем извлечь из него данные и уничтожить его.
У DataPack есть особенность - данные из него нужно извлекать в той же последовательности, в которой они были записаны.
Методы для работы с DataPack можно найти здесь DataPack · datapack · SourceMod Scripting API Reference
Рассмотрим их подробнее:
- Методы для работы с DataPack
- DataPack - Создает объект типа DataPack
PHP:DataPack hPack = new DataPack(); - Reset - Сбрасывает позицию считывания с DataPack, чтобы начать считывание/запись сначала
PHP:hPack.Reset(); // Сбросит позицию считывания hPack.Reset(true); // Сбросит позицию считывания и очистит DataPack - IsReadable - Возвращает логическое значение возможно ли считать данные из DataPack
PHP:int iValue = 0; if(hPack.IsReadable(4)) // В DataPack еще есть значение для считывания { iValue = hPack.ReadCell(); } - Position - Свойство, которое позволяет указывать/получать позицию для считывания.
При этом позиция определяется количеством байт записанных данных:
Результат:PHP:// Напишем простой плагин: public void OnPluginStart() { DataPack hPack = new DataPack(); LogMessage("Position: %i", hPack.Position); // Сейчас позиция = 0 hPack.WriteCell(5); // Запишет число 5. LogMessage("Position: %i", hPack.Position); // Каждый метод записи сперва записывает количество байт для записи, а затем данные // Значит чтобы записать число 5 (int) ему нужно 8 байт (2 раза по 4) // Сейчас позиция = 9 т.к. мы записали 8 байт и следующая запись будет начинаться с 9-го байта hPack.WriteFloat(7.5); LogMessage("Position: %i", hPack.Position); // Сейчас позиция = 18 hPack.WriteString("string"); LogMessage("Position: %i", hPack.Position); // 6 символов по 1 байт и еще 1 нулевой, обозначающий конец строки, и того 7 символов по 1 байту = 7 байт + 1 байт + 4 (размер) // Сейчас позиция = 30 hPack.WriteCell(1); LogMessage("Position: %i", hPack.Position); // Сейчас позиция = 39 hPack.Reset(); // Возвращаем позицию на 0 LogMessage("Position: %i", hPack.Position); int iValue = hPack.ReadCell(); LogMessage("Position: %i -> %i", hPack.Position, iValue); float fValue = hPack.ReadFloat(); LogMessage("Position: %i -> %.2f", hPack.Position, fValue); char szBuffer[256]; hPack.ReadString(szBuffer, sizeof(szBuffer)); LogMessage("Position: %i -> %s", hPack.Position, szBuffer); iValue = hPack.ReadCell(); LogMessage("Position: %i -> %i", hPack.Position, iValue); delete hPack; }
Визуально выглядит так:Position: 0
Position: 9
Position: 18
Position: 30
Position: 39
// Тут сбросили позицию на 0 и начали считывать
Position: 0
Position: 9 -> 5
Position: 18 -> 7.50
Position: 30 -> string
Position: 39 -> 1
Числа - это количество байтC-подобный:00 - Позиция 1 01 --\ 02 ---\ Значение = 4 (указывает что хранить будем значение размером 4 байта) 03 ---/ Размер = 4 байта (размер int) 04 --/ 05 --\ 06 ---\ Значение = 5 07 ---/ Размер = 4 байта (размер int) 08 --/ 09 - Позиция 2 10 --\ 11 ---\ Значение = 4 (указывает что хранить будем значение размером 4 байта) 12 ---/ Размер = 4 байта (размер int) 13 --/ 14 --\ 15 ---\ Значение = 7.5 16 ---/ Размер = 4 байта (размер float) 17 --/ 18 - Позиция 3 19 --\ 20 ---\ Значение = 7 (указывает что хранить будем 7 символов по 1 байт каждый) 21 ---/ Размер = 4 байта (размер int) 22 --/ 23 - Символ 's' 24 - Символ 't' 25 - Символ 'r' 26 - Символ 'i' 27 - Символ 'n' 28 - Символ 'g' 29 - Символ '\0' 30 - Позиция 4 31 --\ 32 ---\ Значение = 4 (указывает что хранить будем значение размером 4 байта) 33 ---/ Размер = 4 байта (размер int) 34 --/ 35 --\ 36 ---\ Значение = 1 37 ---/ Размер = 4 байта (размер float) 38 --/ 39 - Позиция 5
- DataPack - Создает объект типа DataPack
- Методы для записи в DataPack
- WriteCell - Записывает в DataPack ячейку (int, Handle и любое другое 4-х байтовое значение)
PHP:hPack.WriteCell(5); - WriteFloat - Записывает в DataPack число с плавающей точкой (дробное)
PHP:hPack.WriteFloat(7.3); - WriteString - Записывает в DataPack строку
PHP:hPack.WriteString("моя строка"); - WriteFunction - Записывает в DataPack указатель на функцию
PHP:function MyFunc = GetFunctionByName(null, "MyFunction"); if(MyFunc != INVALID_FUNCTION) { hPack.WriteFunction(MyFunc); }
- WriteCell - Записывает в DataPack ячейку (int, Handle и любое другое 4-х байтовое значение)
- Методы для чтения из DataPack
- ReadCell - Получает из DataPack ячейку
PHP:int iValue = hPack.ReadCell(); - ReadFloat - Получает из DataPack число с плавающей точкой (дробное)
PHP:float fValue = hPack.ReadFloat(); - ReadString - Получает из DataPack строку
PHP:char szBuffer[256]; hPack.ReadString(szBuffer, sizeof(szBuffer)); - ReadFunction - Полуачет из DataPack указатель на функцию
PHP:function MyFunc = hPack.ReadFunction(MyFunc);
- ReadCell - Получает из DataPack ячейку
PHP:
delete hPack;
Пример использования DataPack:
Передача DataPack в таймере:
PHP:
public void OnPluginStart()
{
DataPack hPack = new DataPack();
hPack.WriteCell(5);
hPack.WriteFloat(7.5);
hPack.WriteString("string");
CreateTimer(5.0, Timer_ReadDataPack, hPack);
}
public Action Timer_ReadDataPack(Handle hTimer, Handle hDataPack)
{
DataPack hPack = view_as<DataPack>(hDataPack); // Методы работают только с типом DataPack, а не Handle
hPack.Reset(); // Возвращаем позицию на 0
int iValue = hPack.ReadCell();
LogMessage("Position: %i -> %i", hPack.Position, iValue);
float fValue = hPack.ReadFloat();
LogMessage("Position: %i -> %.2f", hPack.Position, fValue);
char szBuffer[256];
hPack.ReadString(szBuffer, sizeof(szBuffer));
LogMessage("Position: %i -> %s", hPack.Position, szBuffer);
delete hPack;
}
Результат:
Position: 9 -> 5
Position: 18 -> 7.50
Position: 30 -> string
Последнее редактирование: