[Include] PVar Arrays - dynamic per-player memory
#1

PVar Arrays

This include is based on PVars and can be used as per-player arrays with dynamic size.

Regular per-player arrays, such as

pawn Code:
new HouseKeys[MAX_PLAYERS][5];
must have a fixed size (5). It will always use MAX_PLAYERS * 5 cells of memory, even for slots that your script doesn't use.

PVar Arrays however, use memory only for slots that are used and don't need a max size limit.

Doing something like

pawn Code:
HouseKeys[playerid][2] = houseid;
is equivalent to

pawn Code:
SetPVarArrayInt(playerid, "HouseKeys", 2, houseid);
when using PVar Arrays.

You can also add data to the dynamic array, without knowing the index

pawn Code:
new slot = AddToPVarArrayInt(playerid, "HouseKeys", houseid);
The amount of elements you can have in the dynamic array is basically unlimited.

Looping all slots:

pawn Code:
PVA_Loop(playerid, "HouseKeys", i)
{
    if(GetPVarArrayInt(playerid, "HouseKeys", i) == houseid)
    {
        SendClientMessage(playerid, -1, "You have the keys for this house");
    }
}
PVar Arrays have all the properties that PVars have (shared across scripts, automatically deleted when player leaves the server etc).

PVar Arrays can be used to save house keys, vehicle IDs, phone numbers, notes etc.


Functions

Functions and examples of usage

SetPVarArrayInt(playerid, varname[], index, int_value)
pawn Code:
SetPVarArrayInt(playerid, "HouseKeys", 2, houseid);
GetPVarArrayInt(playerid, varname[], index)
pawn Code:
new houseid = GetPVarArrayInt(playerid, "HouseKeys", 2);
SetPVarArrayString(playerid, varname[], index, string_value[])
pawn Code:
SetPVarArrayString(playerid, "Notes", 1, "this a note");
GetPVarArrayString(playerid, varname[], index, string_return[], len)
pawn Code:
new notetext[128];
GetPVarArrayString(playerid, "Notes", 1, notetext, sizeof(notetext));
SetPVarArrayFloat(playerid, varname[], index, Float:float_value)
pawn Code:
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
SetPVarArrayFloat(playerid, "Pos", 0, x);
SetPVarArrayFloat(playerid, "Pos", 1, y);
SetPVarArrayFloat(playerid, "Pos", 2, z);
Float:GetPVarArrayFloat(playerid, varname[], index)
pawn Code:
new Float:x, Float:y, Float:z;
x = GetPVarArrayFloat(playerid, "Pos", 0);
y = GetPVarArrayFloat(playerid, "Pos", 1);
z = GetPVarArrayFloat(playerid, "Pos", 2);
IsPVarArraySlotUsed(playerid, varname[], index)
pawn Code:
if(!IsPVarArraySlotUsed(playerid, "HouseKeys", 2))
{
    SendClientMessage(playerid, -1, "You don't have a house key on slot 2");
}
GetPVarArraySize(playerid, varname[])
pawn Code:
new housekeys = GetPVarArraySize(playerid, "HouseKeys"); // returns the number of elements in "HouseKeys" array
printf("Player ID %d has %d house keys", playerid, housekeys);
AddToPVarArrayInt(playerid, varname[], int_value)
pawn Code:
new slot = AddToPVarArrayInt(playerid, "HouseKeys", houseid);
AddToPVarArrayString(playerid, varname[], string_value[])
pawn Code:
new slot = AddToPVarArrayString(playerid, "Notes", "another note");
AddToPVarArrayFloat(playerid, varname[], Float:float_value)
pawn Code:
new slot = AddToPVarArrayFloat(playerid, "Offsets", 123.456);
DeletePVarArray(playerid, varname[], index = -1)
pawn Code:
DeletePVarArray(playerid, "HouseKeys"); // deletes all house keys from player
pawn Code:
DeletePVarArray(playerid, "HouseKeys", 2); // deletes house key from slot 2
Notes

Variable names (varname[]) should not be longer than 50 characters.

Like regular arrays, PVar Array indexes start from 0 (0,1,2,3,...).

Download

http://pastebin.com/AshKExzY

1. Download the script from Pastebin
2. Rename it to "pvararray.inc"
3. Place it to ..\pawno\include\ folder
4. Include it in your script

pawn Code:
#include <pvararray>
Reply
#2

Nice idea! Never thought of it
Reply
#3

Awesome !
Reply
#4

Nice work!
Btw question: is it also limited to 800 variables per player?

EDIT: after viewing source i realized ur using regular pvar functions so it is limited.. :/
Reply
#5

Quote:
Originally Posted by Maxips2
View Post
Nice work!
Btw question: is it also limited to 800 variables per player?

EDIT: after viewing source i realized ur using regular pvar functions so it is limited.. :/
PVars have a limit? anyway don't you think thats alot -.^? That saves alot of memory..
Reply
#6

I don't think thats enough lol.
But I've recently come up with a simple solution which would "increase" the limit.
I'll let you know if you are interested.
Reply
#7

Nice, looks quite simple to use. And original idea, I'll give a try.
_________________________
Quote:
Originally Posted by Maxips2
View Post
I don't think thats enough lol.
But I've recently come up with a simple solution which would "increase" the limit.
I'll let you know if you are interested.
I think nobody will reach the max value, would be strange, 800 variables.
Reply
#8

800 is not so much when its being used in a RP gamemode.
Reply
#9

From thread name I was expecting some magic #emit based (or better - native plugin) mambo jumbo, and surprise, normal include by normal author. Me likey much, rep+
Reply
#10

PVars perform really poorly, I learned this early on when learning the ins and outs of SAMP scripting I can see this causing a lot of problems with looping functions. If anyone is thinking about using this I would stay away and keep with regular array definitions.
Reply
#11

That's an impressive set of functions, unfortunately I found a bug:

pawn Код:
PVA_Loop(playerid, "HouseKeys", i)
{
    PVA_Loop(playerid, "Houses", j)
    {
    }
}
If "HouseKeys" has more entries than "Houses", then "PVA_g_UpperIndex" will be incorrectly reset when the second loop starts and will cause the first loop to end early. Another, related, bug is that adding elements to the end of the array within the loop will not update the upper index and will not get looped.

"foreach" iterator with a bypass for both bugs:

pawn Код:
stock PVA@YSII_Ag(pid, str[], start)
{
    // "PVA_g_UpperIndex" should be "static", but isn't.
    PVA_g_UpperIndex = GetPVarArrayUpperIndex(pid, str);
    // "start" is initially "-1", so this works nicely.
    return GetPVarArrayNextIndex(pid, str, start + 1);
}
Use:

pawn Код:
foreach (new i : PVA(playerid, "HouseKeys"))
{
    foreach (new j : PVA(playerid, "Houses"))
    {
    }
}
Also, you should use assignments and "strcat" over "format" where possible:

pawn Код:
stock GetPVarArrayUpperIndex(playerid, varname[])
{
    PVA_g_VarName = "PVA_u_";
    strcat(PVA_g_VarName, varname);
    return GetPVarInt(playerid, PVA_g_VarName);
}
Much faster.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)