AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83)
-   -   [HOWTO] Using XVars (https://forums.alliedmods.net/showthread.php?t=138880)

Exolent[jNr] 09-23-2010 18:14

[HOWTO] Using XVars
 
2 Attachment(s)
About XVars
XVars are public variables that can be accessed across plugins.
They work and look like normal variables inside of the plugin creating them, but have to be accessed a different way in the other plugins.


Purpose:
XVars should be used instead of CVars when the variables need to be private to the plugins.
XVars cannot be changed from the server console or by any existing command unless a plugin is made for that purpose.
It basically provides security to variables.

If you have dynamic natives who's purpose is to only share a variable between plugins, XVars should be used instead.
Dynamic natives are a bit slower than using XVars (see Connor's post).


Creating:
When creating XVars, they need to be global and public.
What this means is that they should not be inside any function when created and must be prefixed with public instead of new or stock.

Example:
Code:
public ExampleXvarVariable; public bool:ExampleXvarBoolean = true; public Float:ExampleXvarFloat = 3.14;
Inside the plugin that created them, they work just like normal variables.
Assigning values and accessing values works just the same.

XVars only support cells (integers, floats, bools, etc.).
Arrays (including strings, since strings are arrays of characters) cannot be used with XVars.


Cross-Plugin:
When accessing XVars from another plugin, you have to use specific natives.

First, you need to get the XVar's unique identifier:
Code:
new g_pExampleXvarVariable; new g_pExampleXvarBoolean; new g_pExampleXvarFloat; public plugin_init( ) {     // get the XVar's unique identifier and store for usage throughout the plugin     g_pExampleXvarVariable = get_xvar_id( "ExampleXvarVariable" );         // check if the XVar is valid     if( g_pExampleXvarVariable == -1 )     {         set_fail_state( "XVar did not exist: ExampleXvarVariable" );     }         // repeat above for other 2 XVars }

If you are just interested in checking if the XVar is valid, you can do this:
Code:
public plugin_init( ) {     // check if the XVar is valid     if( !xvar_exists( "ExampleXvarVariable" ) )     {         set_fail_state( "XVar did not exist: ExampleXvarVariable" );     }         // repeat above for other 2 XVars }

To access an XVar's value, you can use these two natives:
Code:
// get integer value new iValue = get_xvar_num( g_pExampleXvarVariable ); // get boolean value new bool:bValue = bool:get_xvar_num( g_pExampleXvarBoolean ); // get float value new Float:flValue = get_xvar_float( g_pExampleXvarFloat );

To set an XVar's value, you can use these two natives:
Code:
// set integer value set_xvar_num( g_pExampleXvarVariable, 10 ); // set boolean value set_xvar_num( g_pExampelXvarBoolean, false ); // set float value set_xvar_float( g_pExampleXvarFloat, 19.6 );

For more information on the natives, read the funcwiki.

Note: The plugin creating the variable does not have to be above the other plugins that are accessing the variable in the plugins.ini.


Duplication:
Plugins can have the same public variables without compilation error or runtime error.
The only effect on this is where the value is being changed/retrieved.
The first plugin that creates the public variable is the plugin that will be affected by it's value and will send the value to other plugins with get_xvar_*().

Here is an example:
Code:
// This is plugin #1 in the plugins.ini #include < amxmodx > public DisplayRoundMessage; public plugin_init( ) {     register_plugin( "New Round Display", "0.0.1", "Exolent" );         register_event( "HLTV", "EventNewRound", "a", "1=0", "2=0" ); } public EventNewRound( ) {     if( DisplayRoundMessage )     {         client_print( 0, print_chat, "A new round has started!" );     } }
Code:
// This is plugin #2 in the plugins.ini #include < amxmodx > public DisplayRoundMessage; public plugin_init( ) {     register_plugin( "New Round Display", "0.0.1", "Exolent" );         register_event( "HLTV", "EventNewRound", "a", "1=0", "2=0" ); } public EventNewRound( ) {     if( DisplayRoundMessage )     {         client_print( 0, print_chat, "A new round has started!" );     } }
Yes, they are the same plugin so it's a weak example, but it gets the idea across.
Okay, so these 2 plugins have the same public variable.
If we had this plugin:
Code:
#include < amxmodx > public plugin_init( ) {     register_plugin( "New Round Display Enabler", "0.0.1", "Exolent" );         new pDisplayRoundMessage = get_xvar_id( "DisplayRoundMessage" );         if( pDisplayRoundMessage != -1 )     {         set_xvar_num( pDisplayRoundMessage, 1 );     } }
This would only affect the first plugin's variable and the second plugin would still not show the message.


Extra Notes:
My test files can be used if you need any more understanding of how they work.
xvar_holder.sma is above xvar_finder.sma in the plugins.ini.
The commands that mimic natives require the same arguments, just in command format.
Example: get_xvar_id1 "SomeXvarVariable"

All feedback and suggestions are welcome.

fysiks 09-23-2010 18:30

Re: [HOWTO] Using XVars
 
Excellent Exolent! Previously I had very little knowledge about these but I did get them to work by looking at other plugins. This will make it easier to use this neat feature.

Any idea on speed relative to cvars or pcvars? Just curious.

Exolent[jNr] 09-23-2010 18:54

Re: [HOWTO] Using XVars
 
Quote:

Originally Posted by fysiks (Post 1306984)
Any idea on speed relative to cvars or pcvars? Just curious.

No, I've never used the profiler or anything.
But since they aren't the same as cvars (Xvars being security to plugins only) I think the choice between the 2 should be based on how they are needed.

RedRobster 09-23-2010 22:57

Re: [HOWTO] Using XVars
 
Very useful stuff, thanks for the info.

ConnorMcLeod 09-24-2010 01:33

Re: [HOWTO] Using XVars
 
Quote:

Originally Posted by Exolent[jNr] (Post 1307004)
No, I've never used the profiler or anything.
But since they aren't the same as cvars (Xvars being security to plugins only) I think the choice between the 2 should be based on how they are needed.

I think that speed should be considered in some situations.


So, you said that set_xvar_XXX works only in the "main" plugin ?
Or is this the way to set an xvar from an outside plugin ?



Also, i think that native xvar_exists is useless when get_xvar_id does actually the same + returns the index.

Exolent[jNr] 09-24-2010 02:36

Re: [HOWTO] Using XVars
 
Quote:

Originally Posted by ConnorMcLeod (Post 1307225)
I think that speed should be considered in some situations.

True, but I said what I said because I could not give information about speed difference.

Quote:

Originally Posted by ConnorMcLeod (Post 1307225)
So, you said that set_xvar_XXX works only in the "main" plugin ?
Or is this the way to set an xvar from an outside plugin ?

The [get|set]_xvar_[num|float] work in the main plugin and the outside plugins.
However it is useless to use them in the main plugin since you have direct access to them.

Quote:

Originally Posted by ConnorMcLeod (Post 1307225)
Also, i think that native xvar_exists is useless when get_xvar_id does actually the same + returns the index.

You're right, but the native exists (remember this is in AMXX and cannot be changed) so it's more logical to use it rather than checking it's ID for -1.

abdul-rehman 09-24-2010 06:02

Re: [HOWTO] Using XVars
 
Thnx Exolant i didnt even know about these :D

ConnorMcLeod 09-24-2010 13:21

Re: [HOWTO] Using XVars
 
It appears that get_pcvar_num and get_xvar_num are executed with the same speed.
fake natives are slower.

Plugins 1 :
PHP Code:

#include <amxmodx>

#define VERSION "0.0.1"
#define PLUGIN "xvar profile 1"

public xvar1 10

public plugin_init()
{
    
register_plugin(PLUGINVERSION"ConnorMcLeod")
    
register_cvar("amx_cvar_test""1337")
}

public 
plugin_natives()
{
    
register_native("get_variable_test""get_variable_test")
}

public 
get_variable_test()
{
    return 
xvar1


Plugin 2 (profiled) :
PHP Code:

#include <amxmodx>

#define VERSION "0.0.1"
#define PLUGIN "xvar profile 2"

native get_variable_test()

public 
plugin_init()
{
    
register_plugin(PLUGINVERSION"ConnorMcLeod")
}

public 
plugin_cfg()
{
    new 
pcvar get_cvar_pointer("amx_cvar_test")
    new 
xvar get_xvar_id("xvar1")

    for(new 
ii<1000i++)
    {
        
get_pcvar_num(pcvar)
        
get_xvar_num(xvar)
        
get_variable_test()
    }



Dump :
Code:

date: Fri Sep 24 19:18:23 2010 map: de_aztec
type |                            name |      calls | time / min / max
-------------------------------------------------------------------
  n |                  register_plugin |          1 | 0.000001 / 0.000001 / 0.000001
  n |                get_cvar_pointer |          1 | 0.000001 / 0.000001 / 0.000001
  n |                      get_xvar_id |          1 | 0.000001 / 0.000001 / 0.000001
  n |                    get_pcvar_num |      1000 | 0.000180 / 0.000000 / 0.000000
  n |                    get_xvar_num |      1000 | 0.000179 / 0.000000 / 0.000000
  n |                get_variable_test |      1000 | 0.000245 / 0.000000 / 0.000001
  p |                      plugin_cfg |          1 | 0.000561 / 0.000561 / 0.000561
  p |                      plugin_init |          1 | 0.000001 / 0.000001 / 0.000001
0 natives, 0 public callbacks, 2 function calls were not executed.


Exolent[jNr] 09-24-2010 13:56

Re: [HOWTO] Using XVars
 
Quote:

Originally Posted by ConnorMcLeod (Post 1307575)
It appears that get_pcvar_num and get_xvar_num are executer with the same speed.
fake natives are slower.

Thanks for the useful info. It's been added to the first post.

Arkshine 09-24-2010 15:17

Re: [HOWTO] Using XVars
 
The speed is really trivial here and not worth to be mentioned. The choice should be more considering the user's preference or plugin design, not the speed. Just my opinion.


All times are GMT -4. The time now is 03:14.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.