View Single Post
Author Message
headline
SourceMod Moderator
Join Date: Mar 2015
Old 06-22-2018 , 00:01   Classes/Objects in SourcePawn
Reply With Quote #1

Introduction:
It's true that sourcepawn doesn't have objects, but that doesn't mean we can't make a construct that really seems like an object. This post will serve as a simple tutorial around how to do just that. While this method has been known for a while and is nothing new, I am writing this for those who are either unfamiliar with the language or haven't seen this before. Furthermore, I believe constructs like this can really help clean up lots of the code that floats around here and makes it easier to re-use code.

If you're unfamiliar with classes or object-oriented programming, you should read up on that before continuing.


Concept:
Since 1.7, methodmaps have existed in the language which allows us to attribute methods to a tag or type. With this possible, we are able to take an existing concept and add our own methods and define our own meanings to them. More on this later...

A StringMap is a data structure which attributes a key with a certain value. To access a value, you need the key. The key can be any string, and we can store any piece of data along side it. A StringMap can be visualized below with the left column being the key, and the right column being the value.



With these two concepts combined, we can take the base StringMap and add methods in it to grab our data for us, so all we have to do in the end is a method call. Here's an example of us creating a "Dog" object which holds it's name, age, and sex


Implementation:
PHP Code:
methodmap Dog StringMap {
    public 
Dog() {
        return 
view_as<Dog>(new StringMap()); // We'll create a StringMap, but call it a dog.
    
}
    
    public 
void SetName(const char[] name) {
        
this.SetString("name"name);
    }
    
    public 
void GetName(char[] bufferint maxlen) {
        
this.GetString("name"buffermaxlen);
    }
    
    public 
void SetAge(int age) {
        
this.SetValue("age"age);
    }
    
    public 
int GetAge() {
        
int age;
        
this.GetValue("age"age);
        return 
age;
    }
    
    public 
void SetSex(char sex) {
        
this.SetValue("sex"sex);
    }
    
    public 
char GetSex() {
        
char sex;
        
this.GetValue("sex"sex);
        return 
sex;
    }

Now later in our code, we can use the new Dog class like this.

PHP Code:
Dog dog = new Dog();
dog.SetName("Jack");
dog.SetAge(13);
dog.SetSex('M');


// use dog somehow, get the values back, do whatever
delete dog// CLOSE THE HANDLE 

This is a relatively easy concept for intermediate programmers, but for beginners this can seem daunting and that's fine. If you have questions feel free to ask below or even dabble in other OOP languages to get a feel for what object-oriented programming is good at accomplishing.


To finalize this I'd like to say that other sourcemod/sourcepawn projects have existed to accomplish this like Dynamic or my own SMObjects (which is basically the same as StringMap), but both are not-optimal and will only cause more problems or dependencies that are completely unnecessary. Using this method is faster, supported in core sourcemod, and requires no additional dependencies that other solutions will require.

Hope you learned something, if not, consider helping me make this tutorial better.

Last edited by headline; 07-03-2018 at 20:27.
headline is offline