Skip to content

Dynamic States (state)

I stumbled upon an old article by accident, but decided it still deserves attention. Translation and editing: DJ_WEST This article will help you work with states (state) in plugins. States can improve a plugin's performance, for example in situations where a function call needs to be made only once, or if you need to enable/disable forwards for certain events…

Coding·1 min read·PolarhighViews:14

I stumbled upon an old article by accident, but decided it still deserves attention.

Translation and editing: DJ_WEST

This article will help you work with states (state) in plugins. States can improve a plugin's performance, for example in situations where a function call needs to be made only once, or if you need to enable/disable forwards for certain events.

For a clearer example, consider the following code:

Pawn
#include <amxmodx>
#include <hamsandwich>

#define PLUGIN    "Automaton"
#define AUTHOR    "Albernaz o Carniceiro Demoniaco"
#define VERSION    "1.0"

new HamHook:HamHookSpawn

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)        
    
    // Начальное состояние называется: unregistered
    // Это означает, что у нас еще нет никаких регистраций forward'ов
    
    state unregistered;
}

// Как видно из данной функции, после имя функции и ее структуры в скобках <>
// указывается название состояния, при котором данная функция будет срабатывать
public enableHam() <unregistered>
{
    // Если текущее состояние = unregistered, то выполняем действия
   
    // Регистрируем хук на появление игрока и сохраняем указатель в HamHookSpawn
    HamHookSpawn = RegisterHam(Ham_Spawn, "player", "playerSpawn");

    // Выставляем текущее состояние в enabled
    state enabled;
}

// Как видно данная функция имеет такое же имя и структуру, как вышеуказанная
// только вызывается она при состоянии disabled
public enableHam() <disabled>
{
    // Если текущее состояние = disabled, то выполняем действия
    
    // Включаем forward - HamHookSpawn
    EnableHamForward(HamHookSpawn);    

    // Выставляем текущее состояние в enabled
    state enabled;
}

// Вызывается при состоянии enabled, но никакой код выполняться не будет
// Что-то вроде "заглушки" для определенного состояния
public enableHam() <enabled> {}

// Вызывается при состоянии unregistered или disabled
public disableHam() <unregistered, disabled> {}


public disableHam() <enabled>
{    
    // Если текущее состояние = enabled, то выполняем действия
    
    // Убираем forward - HamHookSpawn
    DisableHamForward(HamHookSpawn); 

    // Выставляем текущее состояние в disabled   
    state disabled;
}

// Функция, которая вызывается при появлении игрока
public playerSpawn(id)
{
    // код функции    
}

With this code we can now call enableHam() to enable the forward for player spawn and disableHam() to disable it. So what has changed? We no longer need to check, inside enableHam and disableHam, whether the handle in the HamHookSpawn variable exists and what the current state of the forward is (enabled or disabled).

Simplified version of the plugin:

Pawn
#include <amxmodx>
#include <hamsandwich>

#define PLUGIN    "Automaton"
#define AUTHOR    "Albernaz o Carniceiro Demoniaco"
#define VERSION    "1.0"

new HamHook:HamHookSpawn

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)                
    state unregistered;
}

public enableHam() <unregistered> state (HamHookSpawn = RegisterHam(Ham_Spawn,"player","playerSpawn") ) enabled;
public enableHam() <disabled> state (EnableHamForward(HamHookSpawn)) enabled;
public disableHam() <enabled> state (!DisableHamForward(HamHookSpawn)) disabled;
public enableHam() <> {}
public disableHam() <> {}

public playerSpawn(id)
{
    // код функции
}

And now the debug version of the plugin, for debugging how it works:

Pawn
#include <amxmodx>
#include <hamsandwich>

#define PLUGIN    "Automaton"
#define AUTHOR    "Albernaz o Carniceiro Demoniaco"
#define VERSION    "1.0"

new HamHook:HamHookSpawn

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)        
    
    register_clcmd("enable","enable");
    register_clcmd("disable","disable");
        
    state unregistered;
}

public enable()
{
    enableHam()
    return PLUGIN_HANDLED;
}

public disable()
{
    disableHam()
    return PLUGIN_HANDLED;
}

public enableHam() <unregistered>
{
    HamHookSpawn = RegisterHam(Ham_Spawn,"player","playerSpawn");
    state enabled
    
    server_print("Registering");
}

public enableHam() <disabled>
{
    EnableHamForward(HamHookSpawn);    
    state enabled;
    
    server_print("Enabling");
}

public disableHam() <enabled>
{    
    DisableHamForward(HamHookSpawn);    
    state disabled;
    
    server_print("Disabling");
}

public enableHam() <> 
{
    server_print("Already enabled");
}
public disableHam() <>
{
    server_print("Already disabled");
}

public playerSpawn(id)
{
    // код функции
}

Output of the debug version of the plugin in the server console:

C++
] enable
Registering
] enable 
Already enabled
] disable
Disabling
] disable 
Already disabled
] enable
Enabling
] enable 
Already enabled

Explanation of the statuses:
Registering - initial registration and enabling
Disabling - disabling
Enabling - enabling
Already enabled - already enabled
Already disabled - already disabled

Translation of the original: http://amx-x.ru/viewtopic.php?f=9&t=2025