Raised This Month: $ Target: $400
 0% 

[TUT] Better Methodmaps tut


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
nergal
Veteran Member
Join Date: Apr 2012
Old 03-29-2015 , 14:50   [TUT] Better Methodmaps tut
Reply With Quote #1

the sourcepawn transitional syntax wiki [ https://wiki.alliedmods.net/SourcePa...itional_Syntax ] horribly explains methodmaps.

This tutorial will aim to give a better understanding, especially to beginners...

In a nutshell, Methodmaps are basically class-like functions for enums

According to Bailopan, "Methodmaps are syntactic transformations only. That is, x.y() on methodmap Z is transformed into a function call that looks like Z_y(x)." - https://forums.alliedmods.net/showpo...&postcount=365

As you can see, methodmaps can help make life a bit easier. Let's begin!

It should be known that methodmaps do not need to be attached to a enum to work. You can have a solo methodmap work by itself, but if you want custom types/tags, then you will be needing an enum.

Because methodmaps are similar to classes, the first part of a methodmap you need is a constructor!

Through messing around with the compiler and such, I've found that Constructors must always have the same name as the Methodmap they're operating from as well as having no identified return type! Constructors can also just do nothing lol! As long as you have a constructor at least.
PHP Code:
methodmap MapMethod
{
    public 
MapMethodint index //this is the constructor!
    
{
        return 
view_as<MapMethod>( index ); /*you must return the data as the methodmap. The data also cannot be an array
or the enum tag you're making the methodmap for or make the constructor do absolutely nothing.*/
    
}

Methodmaps can also have regular, normal functions be used inside them, like so!
PHP Code:
methodmap EntityWithHealth
{
    public 
void SetHealth(int value//normal function
    
{
        
SetEntProp(thisProp_Send"m_iHealth"value);
    }

Adding properties/accessors to your methodmap can make it that much simpler to accessing data. Properties have getters and setters so you can easily set their data and utilize it as soon as possible! properties do not have to have both getters and setters but it should definitely have getters.
PHP Code:
int iMoney 0;
/*
remember that methodmaps are not classes/structs so you need to create globals.
The purpose of the methodmap is to be the only modifier of these global variables
so that the code is more structured and controlled.
*/

methodmap Bank
{
    
property int Money //property!
    
{
        public 
get() { return iMoney; }
        public 
setint value ) { iMoney value; } //property is an int, so the data must be set with an int!
    
}

Then there's inheritance! You can make other methodmaps get the same data and handling as your initial methodmap!

Here's a good example. The parent methodmap has the money property while the child mtm has toys! Since the child mtm inherits from the parent mtm, that means you can use the "Money" accessor from the child mtm!
PHP Code:
int iMoney;
int iToys;
methodmap Parent
{
    
property int Money //has money!
    
{
        public 
get() { return iMoney; }
        public 
setint value ) { iMoney value; }
    }
}
methodmap Child Parent
{
    
property int Toys //has toys AND money :D
    
{
        public 
get() { return iToys; }
        public 
setint value ) { iToys value; }
    }

There's also stuff about inline methods but I've never used them but I just wanted to cover the beginner stuff.

The most important concept of methodmaps is the "this" name. The "this" name basically refers to whatever instance of the methodmap uses the available functions inside it. look at the final code below to see what I mean.

Here's the final product of what most realistic (custom) methodmaps would look like and how they are used!

PHP Code:

int iHealth
[MAXPLAYERS+1];
int iAmmo[MAXPLAYERS+1];
float flSpeed[MAXPLAYERS+1];

methodmap Playur
{
    public 
Playur(int playerindex//constructor
    
{
        return 
view_as<Playur>(playerindex); //make sure you do validity check on players
    
}
     
property int index 
    

        public 
get()                { return view_as<int>(this); } 
    }
    
property int Health
    
{
        public 
get() { return iHealth[this.index]; }
        public 
setint value ) { iHealth[this.index] = value; }
    }
    
property int Ammo
    
{
        public 
get() { return iAmmo[this.index]; }
        public 
setint value ) { iAmmo[this.index] = value; }
    }
    
property float Speed
    
{
        public 
get() { return flSpeed[this.index]; }
        public 
setfloat value ) { flSpeed[this.index] = value; }
    }
    public 
void GiveAmmo(int amount)
    {
        
this.Ammo += amount;
    }
    public 
void RemoveAmmo(int amount)
    {
        
this.Ammo -= amount;
    }
}

public 
void OnClientPutInServer(int client)
{
    
Playur player Playur(client);
    if (
player.Health 1player.Health 100;
    if (
player.Ammo 1player.Ammo 50;
    if (
player.Speed 1.0player.Speed 300.0;

EDIT #1

another thing to introduce to the Methodmaps is the concept of "objectifying" them

Here's an example!
PHP Code:
methodmap MapMethod __nullable__
{
    ........

the methodmap is now nullable! Nullable methodmaps actually create objects compared to normal, non-nullable methodmaps!

with a nullable methodmap, you have to use "new" with its constructor!

like so!
PHP Code:
methodmap MapMethod __nullable__
{
    public 
MapMethod() //constructor
    
{
        
//code here
    
}
}

MapMethod Data = new MapMethod(); 
Here's a better full example from one of my own plugins, the Arm Chair General plugin that allows spectators to be more interactive with red or blue team....

PHP Code:
enum {
    
IsGen 0,
    
LeadingTeam
};

#define int(%1)            view_as<int>(%1)

int General[MAX][2];

methodmap Commander
{
    public 
Commander(int userid//constructor: It's less of a headache to use userids
    
{
        if ( 
IsValidClientuserid ) ) {
            return 
view_asCommander >( GetClientUserIduserid ) );
        }
        return 
view_asCommander >(-1);
    }

    
property int index
    
{
        public 
get()            { return GetClientOfUserIdint(this) ); }
    }
    
property int bIsGeneral
    
{
        public 
get()            { return Generalthis.index ][ IsGen ]; }
        public 
setint val )        { Generalthis.index ][ IsGen ] = val; }
    }
    
property int iLeadingTeam
    
{
        public 
get()            { return Generalthis.index ][ LeadingTeam ]; }
        public 
setint val )        { Generalthis.index ][ LeadingTeam ] = val; }
    }
}; 
Creating a methodmap out of natives!

.inc file
PHP Code:
methodmap NativeMap
{
    public 
native NativeMap();

    
property int MyIntProperty {
        public 
native get();
        public 
native set(const int val);
    }

    public 
native void MyMethodFunc();

implementation in the plugin that's exporting the native-based methodmap
PHP Code:
public APLRes AskPluginLoad2(Handle myselfbool latechar[] errorint err_max)
{  
    
CreateNative("NativeMap.NativeMap"Native_NativeMapInstance);

    
CreateNative("NativeMap.MyIntProperty.get"Native_GetMyIntProperty);
    
CreateNative("NativeMap.MyIntProperty.set"Native_SetMyIntProperty);
    
CreateNative("NativeMap.MyMethodFunc"Native_MyMethodFunc);
    
    return 
APLRes_Success;
}

public 
int Native_NativeMapInstance(Handle pluginint numParams)
{
    return 
GetNativeCell(1);
}
public 
int Native_GetMyIntProperty(Handle pluginint numParams)
{
    return 
Health[GetNativeCell(1)];    /* GetNativeCell(1) IS ALWAYS THE "this" parameter */
}
public 
int Native_SetMyIntProperty(Handle pluginint numParams)
{
    
Health[GetNativeCell(1)] = GetNativeCell(2);
}
public 
int Native_MyMethodFunc(Handle pluginint numParams)
{
    
CallBackFunc(GetNativeCell(1), GetNativeCell(2));
    
// Remember that GetNativeCell(1) is always the "this" parameter aka the first argument

__________________

Last edited by nergal; 12-13-2016 at 03:24.
nergal is offline
 


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 22:06.


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