shape1
shape2
shape3
shape4
shape7
shape8

pVar`ы и с чем их едят


Статус
Закрыто для дальнейших ответов.

gegelo

Освоившийся
Пользователь
20.05.2015
183
24
0
Здравствуйте, пользователи форума Pawno-Crmp. Что же это такое?

Система персональных переменных (Per-player variables)

Код:
Многие думают, что при удалении pVar`a память освобождается, нет, это не так. Если вы не используете pVar`ы, то на сервере всё-равно выделяется память под них. При запуске сервера, резервируется определённое количество памяти. Когда вы создаёте pVar, часть этой памяти отдаётся под хранение записанных туда данных. Вы попользовались этими данными и удалили pVar. Память, что требовалась для хранения Ваших данных, не стала свободной для всего. Она освободилась для нового pVar. Вы не сможете отдать участок памяти, где хранилась информация о pVar, под массив или что-то ещё. Она предназначена исключительно для pVar.



Исходя из этого, следует, что глупо в pVar хранить информацию, которая будет востребована на протяжении всего нахождения игрока на сервере. Вот для временной информации pVar прекрасно подойдёт! Допустим, Вам нужно сохранить число, которое игрок ввёл как параметр для команды и вы сохранили его в pVar. Этот pVar занял свою ячейку в памяти (пусть это будет ячейка под номером 1). Далее Вы сохранили в pVar деньги игрока, дабы игрок смог через пол часа посмотреть то, насколько он смог разбогатеть (это уже будет pVar, который поместится в ячейку 2). Теперь Вы совершили все манипуляции с числом, что записывали в первый pVar и удалили его с помощью специальной функции DeletePVar. Пол часа ещё не прошло и второй pVar не задействован, поэтому удалять его мы не будем. Теперь нам понадобилось сохранить текущий уровень здоровья игрока. Мы создаём новый pVar и, по-идее, он должен занять ячейку под номером 3, ведь это совершенно новый pVar, который мы ещё не использовали ранее. Но нет, он займёт ячейку под номером 1, ведь до этого Вы удалили из неё pVar с числом.
"Так всё равно же выделяется память, как и в случае с массивами!" - скажете Вы. Но вот Вам простой пример:
/* Ситуация: 
Нам нужно временно хранить данные для дальнейшего использования. Всего пусть будет 2 разных случая.*/ 
//Вариант решения №1 
new array_1[MAX_PLAYERS]; 
new array_2[MAX_PLAYERS]; 
//... 
array_2[playerid] = 1; 
if(array_2[playerid] == 1)... 
//... 
array_1[playerid] = 98; 
if(array_1[playerid] == 65)... 

//Вариант решения №2 
new array_1[MAX_PLAYERS]; 
//... 
array_1[playerid] = 1; 
if(array_1[playerid] == 1)... 
//... 
array_1[playerid] = 98; 
if(array_1[playerid] == 65)... 

//Вариант решения №3 
SetPVarInt(playerid, "Array_1", 1); 
if(GetPVarInt(playerid, "Array_1") == 1) DeletePVar(playerid, "Array_1"); 
//... 
SetPVarInt(playerid, "Array_2", 98); 
if(GetPVarInt(playerid, "Array_2") == 65) DeletePVar(playerid, "Array_2");  

В первом случае мы создаём 2 массива по 500 ячеек и они хранятся в памяти сервера всегда.
Во втором случае мы создаём один массив на 500 ячеек и уже с ним работаем всё время. Это уже более похоже на pVar, но есть одно НО. Мы не сможем хранить в массиве одновременно несколько данных.
В третьем случае мы используем pVar, где каждый pVar имеет своё уникальное имя и использует ту память, что уже и так была зарезервирована сервером. Если бы мы имели возможность сохранять в одном массиве несколько данных одновременно, то это было бы похоже именно на второй вариант.
В общем, pVar хороши там, где данные не будут использоваться при каждом написании в чат или использовании команды . Поэтому использовать их надо с умом.

pVar можно представить следующим образом:

new player_variables_int[MAX_PLAYERS][30]; 
new player_variables_string[MAX_PLAYERS][30][500]; 
new Float: player_variables_float[MAX_PLAYERS][30]; 

И уже имена pVar давать в виде макросов. То есть:
#define player_health 0 
player_variables_float[playerid][player_health] = 100.0;  


Только вся разница в том, что в случае с pVar машина сама подсчитает для Вас то число ячеек, которое потребуется для хранения данных и выделить нужное количество данных из зарезервированного участка памяти, а не Вы это будете делать. Ну и зачем выделять столько памяти, когда это уже давно сделали за Вас?






Лично я вообще давно кинул в топку pVar`ы, только дело в том, что массивы одного скрипта недоступны для других фильтрскриптов, а pVar`ы доступны из всех запущенных скриптов. И ещё, судя по тестам, pVar`ы существенно медленнее обычных массивов, да и юзать массивы гораздо удобнее. C переменными в качестве строк работать проще, а pVar не надо контролировать при выходе. 





[spoiler=pVar]native SetPVarInt(playerid, varname[], int_value); - устанавливает значение для целого пвара
native GetPVarInt(playerid, varname[]); - возвращает значение целого пвара
native SetPVarString(playerid, varname[], string_value[]); - устанавливает значение строкового пвара
native GetPVarString(playerid, varname[], string_return[], len); - копирует значение строкового пвара в string_return
native SetPVarFloat(playerid, varname[], Float:float_value); - устанавливает значение вещественного пвара
native Float:GetPVarFloat(playerid, varname[]); - возвращает значение вещественного пвара
native DeletePVar(playerid, varname[]); - удаляет пвар

// Типы пваров
#define PLAYER_VARTYPE_NONE 0 - неизвестно
#define PLAYER_VARTYPE_INT 1 - целое число
#define PLAYER_VARTYPE_STRING 2 - строка
#define PLAYER_VARTYPE_FLOAT 3 - вещественное число

native GetPVarsUpperIndex(playerid); 
native GetPVarNameAtIndex(playerid, index, ret_varname[], ret_len); - узнает название пвара по его индексу (внутреннему номеру)
native GetPVarType(playerid, varname[]); - возвращает тип указанного пвара
Всем спасибо за внимание!

 
Последнее редактирование модератором:

gegelo

Освоившийся
Пользователь
20.05.2015
183
24
0
, ну тут я, как видите, немного обосновал их правильное использование и развеял некоторые "мифы".

 
Статус
Закрыто для дальнейших ответов.