Pushistik↯❤
Команда форума
- Регистрация
- 6 Июл 2017
- Сообщения
- 393
- Реакции
- 97
- Баллы
- 28
[SourcePawn] Урок 8 - KeyValues
<= К содержаниюKeyValues (далее просто KV) - производный тип от Handle, который является особое дерево-подобную структуру и позволяет хранить данные в виде пар "ключ - значение", а так же вложенные разделы.
Вот пример как выглядит структура KeyValues:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
"param1" "value1"
"param2" "value2"
}
"key2"
{
"param1" "value1"
"param2" "value2"
"subkey1"
{
"param1" "value1"
"param2" "value2"
}
"subkey2"
{
"param1" "value1"
"param2" "value2"
}
}
"key3"
{
"param1" "value1"
"param2" "value2"
}
}
Для использования многострочных комментариев (/* */) нужно использовать SMC Parser (урок будет добавлен позже).
Прежде чем рассматривать методы для работы с KV введем несколько основных понятий.
- Указатель (или Курсор) - условное понятие (допустим стрелочка), которое указывает на текущую позицию в структуре.
Как только мы создали структуру, курсор находится на позиции 1.
Если мы перейдем в ключ "key1", то курсор откажется на позиции 2.
Если мы перейдем в ключ "key2", то курсор откажется на позиции 3 и так далее.
Если мы перейдем в ключ "key1", то курсор откажется на позиции 2.
Если мы перейдем в ключ "key2", то курсор откажется на позиции 3 и так далее.
Вот это всё - это значения.
- Ключ) - уникальный набор символов (как в примере key1, key2, key3, subkey1, subkey2, param1, param2).
- Секция) - Каждый обведенный блок отмеченный цифрой
Вот примеры:
По началу это кажется сложным но на примерах это намного проще.
Давайте рассмотрим основные методы для работы с KV, а потом займемся примерами.
- KeyValues - Создает объект типа KeyValues
PHP:
KeyValues hKeyValues = new KeyValues("GlobalKey");
- ExportToFile - Сохраняет KV структуру в файл
PHP:
char szPath[256]BuildPath(Path_SM, szPath, sizeof(szPath), "configs/test_kv.ini"); // Формируем путь к файлу hKeyValues.Rewind(); // Возвращаем указатель позиции в самое начало (подробнее - далее) hKeyValues.ExportToFile(szPath); // Сохраняем в файл
- ImportFromFile - Загружает KV структуру из файла
PHP:
char szPath[256]BuildPath(Path_SM, szPath, sizeof(szPath), "configs/test_kv.ini"); // Формируем путь к файлу KeyValues hKeyValues = new KeyValues("GlobalKey"); if(hKeyValues.ImportFromFile(szPath)) // Загружаем из файла { // Успешно загрузили }
- ImportFromString - Загружает KV структуру из строки
PHP:
KeyValues hKeyValues = new KeyValues("GlobalKey");if(hKeyValues.ImportFromString("\"GlobalKey\" { \"param1\" \"value1\" \"param2\" \"value2\" \"key1\" { \"param1\" \"value1\" \"param2\" \"value2\" } }")) // Загружаем из строки { // Успешно загрузили }
- Import - Клонирует KV структуру из другой KV структуры
К примеру есть hKeyValues с такой структурой:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
// <- указатель стоит здесь
"param1" "value1"
"param2" "value2"
}
}
И есть hKeyValues2 с такой структурой:
PHP:
"MyTestKv"
{
// <- указатель стоит здесь
"test_key1"
{
"param1" "value1"
"param2" "value2"
}
"test_key2"
{
"param1" "value1"
"param2" "value2"
}
}
PHP:
if(hKeyValues.Import(hKeyValues2)) // Клонируем
{
// Успешно
}
В результате в hKeyValues будет:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
"param1" "value1"
"param2" "value2"
"test_key1"
{
"param1" "value1"
"param2" "value2"
}
"test_key2"
{
"param1" "value1"
"param2" "value2"
}
}
}
- SetString - Записывает строку по ключу
К примеру есть hKeyValues с такой структурой:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
// <- указатель стоит здесь
"param1" "value1"
"param2" "value2"
}
}
PHP:
hKeyValues.SetString("test_key", "my_value"); // Ключ - "test_key", Значение - "my_value"
В результате в hKeyValues будет:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
"param1" "value1"
"param2" "value2"
"test_key" "my_value"
}
}
- SetNum - Записывает целочисленное значение по ключу
Возьмем KV из предыдущего примера
PHP:
hKeyValues.SetNum("test_key2", 10); // Ключ - "test_key2", Значение - 10
В результате в hKeyValues будет:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
"param1" "value1"
"param2" "value2"
"test_key" "my_value"
"test_key2" "10"
}
}
- SetFloat - Записывает дробное значение по ключу
Возьмем KV из предыдущего примера
PHP:
hKeyValues.SetFloat("test_key3", 5.7); // Ключ - "test_key3", Значение - 5.7
В результате в hKeyValues будет:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
"param1" "value1"
"param2" "value2"
"test_key" "my_value"
"test_key2" "10"
"test_key3" "5.7"
}
}
- SetColor - Записывает значение RGBA цвета по ключу
Возьмем KV из предыдущего примера
PHP:
hKeyValues.SetColor("test_key4", 128, 17, 32, 250); // Ключ - "test_key5", Значение - {128, 17, 32, 250}
В результате в hKeyValues будет:
PHP:
"GlobalKey"
{
"param1" "value1"
"param2" "value2"
"key1"
{
"param1" "value1"
"param2" "value2"
"test_key" "my_value"
"test_key2" "10"
"test_key3" "5.7"
"test_key4" "128 17 32 250"
}
}
- SetColor4 - Записывает значение RGBA цвета по ключу (В отличии от предыдущего метода - массивом)
Возьмем KV из предыдущего примера
PHP:int iColor[4] = {12, 35, 72, 230}; hKeyValues.SetColor4("test_key5", iColor); // Ключ - "test_key5", Значение - {12, 35, 72, 230}
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } }
- SetVector - Записывает значение вектора по ключу
Возьмем KV из предыдущего примера
PHP:float fVec[3] = {-12.0, 1650.0, 24224.5}; hKeyValues.SetVector("test_key6", fVec); // Ключ - "test_key5", Значение - {-12.0, 1650.0, 24224.5}
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" } }
- SetUInt64 - Записывает большое целочисленное значение по ключу
Возьмем KV из предыдущего примера
PHP:hKeyValues.SetUInt64("test_key7", {0x02C8CE06, 0xCE0602C8}); // Ключ - "test_key4", Значение - 2 4-х байтных числа
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
- GetString - Записывает строку по ключу
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
PHP:char szBuffer[256]; hKeyValues.GetString("test_key", szBuffer, sizeof(szBuffer)); // Результат: // szBuffer = "my_value"
- GetNum - Получает целочисленное значение по ключу
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" } }
PHP:int iValue = hKeyValues.GetNum("test_key2"); // Результат: // iValue = 10
- GetFloat - Получает дробное значение по ключу
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" } }
PHP:float fValue = hKeyValues.GetFloat("test_key3"); // Результат: // fValue = 5.7
- GetColor - Получает значение RGBA цвета по ключу
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" } }
PHP:int r, g, b, a; hKeyValues.GetColor("test_key4", r, g, b, a); // Результат: // r = 128 // g = 17 // b = 32 // a = 250
- GetColor4 - Получает значение RGBA цвета по ключу (Массив)
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" } }
PHP:int iColor[4]; hKeyValues.GetColor("test_key5", iColor); // Результат: // iColor[0] = 12 // iColor[1] = 35 // iColor[2] = 72 // iColor[3] = 230
- GetVector - Получает значение вектора по ключу
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" } }
PHP:float fVec[4]; hKeyValues.GetVector("test_key6", fVec); // Результат: // fVec[0] = -12.0 // fVec[1] = 1650.0 // fVec[2] = 24224.5
- GetUInt64 - Полуачет большое целочисленное значение по ключу
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
PHP:int iValue[2]; hKeyValues.GetUInt64("test_key7", iValue); // Результат: // iColor[0] = 12 // iColor[1] = 35 // iColor[2] = 72 // iColor[3] = 230
- Rewind - Возвращает указатель на позицию в самое начало структуры.
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель находится здесь "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
PHP:hKeyValues.Rewind();
PHP:"GlobalKey" { // <- теперь указатель находится здесь "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
- Перед сохранением структуры в файл
- Перед JumpToKey/GotoFirstSubKey (при условии что это не необходимо сделать относительно текущей позиции)
- После удаления ключа
- JumpToKey - Переходит к указанному ключу внутри текущей секции. Один из наиболее часто используемых методов.
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "key1" { // будем пытаться перейти сюда "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
PHP:if(hKeyValues.JumpToKey("key1")) // Попытка перейти к ключу "key1" { // Если ключ "key1" сущевствует - проверка будет пройдена. }
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель стоит здесь "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } }
PHP:// Вернем указатель в начало hKeyValues.Rewind(); if(hKeyValues.JumpToKey("key2", true)) // Попытка перейти к ключу "key2". Если 2-й аргумент true то при отсутствии ключа он будет создан. { hKeyValues.SetString("new_param", "new value"); }
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "param1" "value1" "param2" "value2" "test_key" "my_value" "test_key2" "10" "test_key3" "5.7" "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" "test_key6" "-12.0 1650.0 24224.5" "test_key7" "..." } "key2" // Этот ключ мы только что создали { // <- указатель стоит здесь "new_param" "new value" } }
- GotoFirstSubKey - Переходит к первому ключу внутри текущей секции.
- GotoNextKey - Переходит к следующему ключу в секции на уровень выше.
Возьмем KV:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "param1" "value1" "param2" "value2" } "key2" { "param1" "value1" "param2" "value2" } "key3" { "param1" "value1" "param2" "value2" } "key4" { "param1" "value1" "param2" "value2" } }
PHP:// Вернем указатель в начало hKeyValues.Rewind(); if(hKeyValues.GotoFirstSubKey()) // Переходим к первому ключу внутри "GlobalKey" { // тут мы попали в ключ "key1" do // Создаем цикл с послеусловием { // тут можем выполнять какие-то действия с ключем } while (hKeyValues.GotoNextKey()); // Условие продолжения цикла: До тех пор, пока можем перейти к следующему ключу // Это цикл поочередно пройдет по ключам: "key1" (тут мы уже и так стоим), "key2", "key3", "key4". }
- GoBack - Возвращает указатель на позицию на 1 уровень назад.
Возьмем KV:
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:hKeyValues.Rewind(); // Возвращаем указатель в начало hKeyValues.JumpToKey("key1"); // Переходим в ключ "key1" hKeyValues.JumpToKey("sub_key1"); // Переходим в ключ "sub_key1"
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { // <- теперь указатель находится здесь "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:hKeyValues.GoBack(); // Возвращаем указатель внутрь "key1" (т.е. на 1 уровень вверх) hKeyValues.JumpToKey("sub_key2"); // Переходим в ключ "sub_key2"
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { // <- теперь указатель находится здесь "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:hKeyValues.GoBack(); // Возвращаем указатель внутрь "key1" (т.е. на 1 уровень вверх) hKeyValues.GoBack(); // Возвращаем указатель внутрь "GlobalKey" (т.е. еще на 1 уровень вверх) hKeyValues.JumpToKey("key2"); // Переходим в ключ "key1"
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { // <- теперь указатель находится здесь "test_key2" "10" } }
- DeleteKey - Удаляет из структуры указанный ключ (и всё что в нем).
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { // <- указатель находится здесь "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:// В том положении, где сейчас находится указатель можно удалить только "key1" и "key2". // Сейчас мы хотим удалить "sub_key1". Для этого перейдем в "key1" if(hKeyValues.JumpToKey("key1")) // Проверка необходима чтобы убедиться что мы точно попали в ключ (т.е. что он сущевствует) { hKeyValues.DeleteKey("sub_key1"); // Удаляем ключ "sub_key1" }
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1" { // <- указатель находится здесь "test_key" "my_value" "test_key2" "10" "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:hKeyValues.Rewind(); // Возвращаем указатель в начало hKeyValues.DeleteKey("key1"); // Удаляем ключ "key1"
PHP:"GlobalKey" { // <- указатель находится здесь "param1" "value1" "param2" "value2" "key2" { "test_key2" "10" } }
- DeleteThis - Удаляет из структуры текущий ключ (и всё что в нем).
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { // <- указатель находится здесь "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:if(hKeyValues.JumpToKey("key1")) // Перейдем в "key1" { hKeyValues.DeleteThis(); // Удаляем ключ "key1" }
PHP:"GlobalKey" { // <- указатель находится здесь "param1" "value1" "param2" "value2" "key2" { "test_key2" "10" } }
- GetSectionName - Получает имя текущей секции (т.е. ключ где сейчас находится указатель)
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { // <- указатель находится здесь "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:char szBuffer[256]; hKeyValues.GetSectionName(szBuffer, sizeof(szBuffer)); // Результат: // szBuffer = "GlobalKey" hKeyValues.JumpToKey("key1"); hKeyValues.GetSectionName(szBuffer, sizeof(szBuffer)); // Результат: // szBuffer = "key1" hKeyValues.JumpToKey("sub_key2"); hKeyValues.GetSectionName(szBuffer, sizeof(szBuffer)); // Результат: // szBuffer = "sub_key2" hKeyValues.Rewind(); hKeyValues.JumpToKey("key4"); hKeyValues.GetSectionName(szBuffer, sizeof(szBuffer)); // Результат: // szBuffer = "GlobalKey" // А почему? А потому что "key4" не сущевствует и указатель останется в главной секции
- SetSectionName - Устанавливает имя текущей секции (т.е. ключ где сейчас находится указатель)
Возьмем KV из предыдущего примера:
PHP:"GlobalKey" { // <- указатель находится здесь "param1" "value1" "param2" "value2" "key1" { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
PHP:hKeyValues.JumpToKey("key1"); hKeyValues.JumpToKey("sub_key2"); hKeyValues.SetSectionName("sub_key2_new"); // Изменим имя "sub_key2" на "sub_key2_new" hKeyValues.GoBack(); // Вернемся в "key1" hKeyValues.SetSectionName("key1_new"); // Изменим имя "key1" на "key1_new" hKeyValues.Rewind();
PHP:"GlobalKey" { "param1" "value1" "param2" "value2" "key1_new" // Тут изменилось { "test_key" "my_value" "test_key2" "10" "sub_key1" { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } "sub_key2_new" // И тут изменилось { "test_key4" "128 17 32 250" "test_key5" "12 35 72 230" } } "key2" { "test_key2" "10" } }
<= К содержанию