[Plugin] GVar Plugin
#1

GVar Plugin

This plugin is an extension to the per-player variable (PVar) system introduced in SA-MP 0.3a with a few key differences:
  • Global variables (GVars) that are not linked to any player IDs
  • Presence in memory until explicit deletion with DeleteGVar
  • Much faster execution time than properties (see this post for benchmarks)
Changelog

GitHub Commit History

Refer to the CHANGES file the binary package for the full changelog.

Definitions

pawn Code:
#define GLOBAL_VARTYPE_NONE (0)
#define GLOBAL_VARTYPE_INT (1)
#define GLOBAL_VARTYPE_STRING (2)
#define GLOBAL_VARTYPE_FLOAT (3)
Natives

pawn Code:
native SetGVarInt(const name[], value, id = 0);
native GetGVarInt(const name[], id = 0);
native SetGVarString(const name[], const value[], id = 0);
native GetGVarString(const name[], dest[], maxlength = sizeof dest, id = 0);
native SetGVarFloat(const name[], Float:value, id = 0);
native Float:GetGVarFloat(const name[], id = 0);
native DeleteGVar(const name[], id = 0);
native GetGVarsUpperIndex(id = 0);
native GetGVarNameAtIndex(index, dest[], maxlength = sizeof dest, id = 0);
native GetGVarType(const name[], id = 0);
Instructions

Create a directory called "plugins" inside of the server directory if one does not already exist. Place the plugin file (gvar.dll or gvar.so) inside of this directory.

Add the following line to server.cfg so that the plugin will load the next time the server starts:

Windows:
Code:
plugins gvar.dll
Linux:
Code:
plugins gvar.so
On Windows, add gvar.inc to the pawno\include folder. Include this file in any of the scripts the server is running:

pawn Code:
#include <gvar>
Recompile the scripts with any desired natives and callbacks provided by the include file. Start the server.

Notes
  • Remember to delete GVars when they are no longer needed, particularly when a gamemode or filterscript exits.
  • The optional ID, like the player ID in PVars, must be unique.
  • GVar names are case-insensitive.
Download

The latest compiled binaries will always be here:

GitHub Releases Page

The source can be browsed here. This repository can also be cloned.

The Windows version requires the Microsoft Visual C++ 2010 Redistributable Package.
Reply
#2

Wow thank you very much for this .

Just one question. Why didn't you make it like in your streamer so:
Code:
native Streamer_SetIntData(type, {Text3D,_}:id, data, value);

native SetGVarInt(type, id, varname[], int_value);
Instead of enum used for 'data' parameter it would be varname. I think this would be the easiest way for us to work with them because atm we need ot format varname like "vehicle1.price".
Reply
#3

Assuming that the memory isn't an issue, isn't it slower than using pawn structures?


Anyway, good job, and thank you for helping samp community!




Mike.
Reply
#4

Amazing job again, Incognito!
Reply
#5

$ЂЯĢ: This wasn't really designed for complex data structures, though I do see your point. The absence of a player ID means that some other form of identification would be useful to have. I think it would work much better as an optional parameter, though, as it's not always needed:

pawn Code:
SetGVarInt(varname[], int_value, id = 0);
Therefore, rather than doing this:

pawn Code:
format(string, sizeof(string), "vehicle_%d_price", gVehicle);
SetGVarInt(string, 5000);
You could do this instead:

pawn Code:
SetGVarInt("vehicle_price", 5000, gVehicle);
I'll see about adding that parameter to the natives later, but it will require some additional checks.

Sma_X: Yes, it will be slower due to function overhead, but it consumes less memory (in most cases) and can be used for inter-script communication.
Reply
#6

Nice!
Reply
#7

I was thinking of something like this and what do you know


Very Nice! Keep up the good work
Reply
#8

-
Reply
#9

very nice, keep up the good work!
Reply
#10

Niceeeeee
Reply
#11

Quote:
Originally Posted by Incognito
...
Hmm, haven't even thought that way, but it seems like a good solution.

----------------------------------------------------------------------
I made some tests now.

pawn Код:
COMMAND:test(playerid,params[])
{
    new tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      SetPVarInt(playerid,"RandomID",i);
    }
    printf("tick #1: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      GetPVarInt(playerid,"RandomID");
    }
    printf("tick #2: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      SetGVarInt("RandomID",i);
    }
    printf("tick #3: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      GetGVarInt("RandomID");
    }
    printf("tick #4: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      SOMETHING[randomshit] = i;
    }
    printf("tick #5: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      i = SOMETHING[randomshit];
    }
    printf("tick #6: %d",GetTickCount() - tick);
    return 1;
}
Results:
[20:45:01] tick #1: 38
[20:45:01] tick #2: 33
[20:45:01] tick #3: 102
[20:45:01] tick #4: 100
[20:45:01] tick #5: 12
[20:45:01] tick #6: 2

I don't know anything about plugin programming, but could this be somehow speeded up a bit? GVars seem to be around three times slower than PVars.
Reply
#12

YES! I've been waiting for this for some time! Some seriously excellent work Incognito!

It's a shame about the speed of it, but it's oversee-able seeing as I'll need to be able to call variables externally. Once again, epic work.
Reply
#13

A nice release once again, I will sure use this thanks allot
Reply
#14

$ЂЯĢ: Possibly, but I don't know what accounts for the differences in run time. I'm sure PVars use a different type of implementation that may be more efficient in terms of speed. I could try creating a hash table, which is much faster than the sorted binary tree this plugin currently uses. That should effectively change the complexity for lookups from O(log n) to O(1). However, as your tests revealed, both PVars and GVars were dozens of times slower than arrays, so if you're scripting something that is absolutely time critical (most PAWN scripts aren't), I would recommend not using these functions at all.
Reply
#15

-
Reply
#16

You forgot half of your idea. Think about getting that value now and I'm sure you will quickly rip it out
Reply
#17

Quote:
Originally Posted by $ЂЯĢ
Quote:
Originally Posted by Incognito
...
Hmm, haven't even thought that way, but it seems like a good solution.

----------------------------------------------------------------------
I made some tests now.

pawn Код:
COMMAND:test(playerid,params[])
{
    new tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      SetPVarInt(playerid,"RandomID",i);
    }
    printf("tick #1: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      GetPVarInt(playerid,"RandomID");
    }
    printf("tick #2: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      SetGVarInt("RandomID",i);
    }
    printf("tick #3: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      GetGVarInt("RandomID");
    }
    printf("tick #4: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      SOMETHING[randomshit] = i;
    }
    printf("tick #5: %d",GetTickCount() - tick);
   
    tick = GetTickCount();
    for(new i=0; i<100000; i++)
    {
      i = SOMETHING[randomshit];
    }
    printf("tick #6: %d",GetTickCount() - tick);
    return 1;
}
Results:
[20:45:01] tick #1: 38
[20:45:01] tick #2: 33
[20:45:01] tick #3: 102
[20:45:01] tick #4: 100
[20:45:01] tick #5: 12
[20:45:01] tick #6: 2

I don't know anything about plugin programming, but could this be somehow speeded up a bit? GVars seem to be around three times slower than PVars.
Wow. Arrays blow PVar/GVar out of the water.

This plugin is useful but that speed difference is a dealbreaker. I'm better off using get/set/exist property.
Reply
#18

@nemesis99, will you be ever looping 100'000 times over something? Probably no. Looping through 500 players would still take only 0.51ms (0.00051s), and that's like nothing.


@Incognito, when you add additional 'id' parameter ... will it make any difference if you for example put in something with ID 1 or ID 100000 (I mean difference in speed or memory usage or whatever)?
Reply
#19

Quote:
Originally Posted by $ЂЯĢ
@nemesis99, will you be ever looping 100'000 times over something? Probably no. Looping through 500 players would still take only 0.51ms (0.00051s), and that's like nothing.
How about not looping at all? You didn't understand what I said.

You've also a lot to learn about efficiency. Read this for starters: Algorithmic Efficiency. While this plugin does have potential gains in the way of memory efficiency, SA:MP servers have bigger worries, namely, CPU utilization.
Reply
#20

Quote:
Originally Posted by nemesis99
Quote:
Originally Posted by $ЂЯĢ
@nemesis99, will you be ever looping 100'000 times over something? Probably no. Looping through 500 players would still take only 0.51ms (0.00051s), and that's like nothing.
How about not looping at all? You didn't understand what I said.

You've also a lot to learn about efficiency. Read this for starters: Algorithmic Efficiency. While this plugin does have potential gains in the way of memory efficiency, SA:MP servers have bigger worries, namely, CPU utilization.
The only thing you shouldn't do then is using it in onplayerupdate.

It is slower, yes, but it is not that slow that it is not worth using it.

and the good thing is that you can set a gvar in your gamemode and access it in all other scripts.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)