AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Solved Optimized Plugin? (https://forums.alliedmods.net/showthread.php?t=308258)

ThatKidWhoGames 06-13-2018 09:42

Optimized Plugin?
 
Hello all!

I have coded a plugin and I want to know your guys' input as to if it is the most optimized way to perform what I want in the plugin. As you will probably be able to tell, it is a respawn timer plugin for TF2. I also want to know if passing the UserID to the timer/frame callback is also necessary (I believe it is but I could be wrong).

PHP Code:

#pragma semicolon 1
#define PLUGIN_VERSION "1.0.0"

#include <sourcemod>
#include <tf2_stocks>

Handle hTimer[MAXPLAYERS+1];
ConVar hConVars[5];
bool bEnablebBotsbCenterbHint;
int iTimeiTimeleft[MAXPLAYERS+1];

methodmap Player {
    public 
Player(int client) {
        return 
view_as<Player>(client);
    }

    
property int Index {
        public 
get() {
            return 
view_as<int>(this);
        }
    }

    
property int UserID {
        public 
get() {
            return 
GetClientUserId(this.Index);
        }
    }
    
    
property int Time {
        public 
get() {
            return 
iTimeleft[this.Index];
        }
        public 
set(int value) {
            
iTimeleft[this.Index] = value;
        }
    }

    
property bool Alive {
        public 
get() {
            return 
IsPlayerAlive(this.Index);
        }
    }

    
property bool Valid {
        public 
get() {
            return 
IsValidClient(this.Index);
        }
    }

    
property bool Fake {
        public 
get() {
            return 
IsFakeClient(this.Index);
        }
    }

    public 
void Respawn() {
        return 
TF2_RespawnPlayer(this.Index);
    }

    public 
void PrintText(const char[] bufferany ...) {
        
int len       strlen(buffer);
        
char[] format = new char[len];
        
VFormat(formatlenbuffer2);
        if (
bCenter)
            
PrintCenterText(this.Indexformat);
        if (
bHint)
            
PrintHintText(this.Indexformat);
    }

    public 
void DelTimer() {
        
DeleteTimer(this.Index);
    }
}

public 
Plugin myinfo = {
    
name        "[TF2] Respawn Timer",
    
author      "Sgt. Gremulock",
    
description "Respawn timer for TF2.",
    
version     PLUGIN_VERSION,
    
url         "grem-co.com"
};

public 
void OnPluginStart()
{
    
CreateConVar("sm_respawntimer_version"PLUGIN_VERSION"Plugin's version."FCVAR_NOTIFY|FCVAR_DONTRECORD);
    
hConVars[0] = CreateConVar("sm_respawntimer_enable""1""Enable/disable the plugin.\n(1 = Enable, 0 = Disable)"_true0.0true1.0);
    
hConVars[1] = CreateConVar("sm_respawntimer_bots""1""Enable/disable the respawn timer for bots.\n(1 = Enable, 0 = Disable)"_true0.0true1.0);
    
hConVars[2] = CreateConVar("sm_respawntimer_time""5""Time (in seconds) until player should respawn.\n(<1 = Instant (If value is <1, center & hint text will not display regardless of ConVar value.))"_true0.0);
    
hConVars[3] = CreateConVar("sm_respawntimer_center_text""1""Display center text for seconds remaining until respawn.\n(1 = Enable, 0 = Disable)"_true0.0true1.0);
    
hConVars[4] = CreateConVar("sm_respawntimer_hint_text""1""Display hint text for seconds remaining until respawn.\n(1 = Enable, 0 = Disable)"_true0.0true1.0);
    for (
int i 0sizeof(hConVars); i++)
        
hConVars[i].AddChangeHook(ConVarUpdate);
    
AutoExecConfig(true"RespawnTimer");
    
HookEvent("player_death"Event_PlayerDeath);
}

public 
void OnConfigsExecuted()
{
    
bEnable hConVars[0].BoolValue;
    
bBots    hConVars[1].BoolValue;
    
iTime    hConVars[2].IntValue;
    
bCenter hConVars[3].BoolValue;
    
bHint    hConVars[4].BoolValue;
}

public 
void ConVarUpdate(ConVar cvar, const char[] oldValue, const char[] newValue)
{
    if (
cvar == hConVars[0])
        
bEnable hConVars[0].BoolValue;
    if (
cvar == hConVars[1])
        
bBots hConVars[1].BoolValue;
    if (
cvar == hConVars[2])
        
iTime hConVars[2].IntValue;
    if (
cvar == hConVars[3])
        
bCenter hConVars[3].BoolValue;
    if (
cvar == hConVars[4])
        
bHint hConVars[4].BoolValue;
}

public 
void OnClientDisconnect(int client)
{
    
Player player Player(client);
    
player.Time   0;
    
player.DelTimer();
}

public 
void Event_PlayerDeath(Event event, const char[] namebool dontBroadcast)
{
    if (!
bEnable || event.GetInt("death_flags") & TF_DEATHFLAG_DEADRINGER)
        return;
    
Player player Player(GetClientOfUserId(event.GetInt("userid")));
    if (
player.Valid)
        if (!
iTime)
            
RequestFrame(Frame_Callbackplayer.UserID);
        else {
            
player.Time iTime;
            
player.PrintText("You will respawn in %i seconds"player.Time);
            
hTimer[player.Index] = CreateTimer(1.0Timer_Callbackplayer.UserIDTIMER_REPEAT);
        }
}

public 
Action Timer_Callback(Handle timerint userid)
{
    
Player player Player(GetClientOfUserId(userid));
    if (
player.Valid)
    {
        if (
player.Alive)
        {
            
hTimer[player.Index] = null;
            return 
Plugin_Stop;
        }

        if (!
player.Time)
        {
            
player.Respawn();
            
hTimer[player.Index] = null;
            return 
Plugin_Stop;
        }

        
player.Time--;
        
player.PrintText("You will respawn in %i seconds"player.Time);
        return 
Plugin_Continue;
    } else
        
player.DelTimer();
    return 
Plugin_Stop;
}

public 
void Frame_Callback(int userid)
{
    
Player player Player(GetClientOfUserId(userid));
    if (
player.Valid && !player.Alive)
        
player.Respawn();
}

stock bool IsValidClient(int client)
{
    return 
client && client <= MaxClients && IsClientInGame(client) && !(!bBots && IsFakeClient(client));
}

stock void DeleteTimer(int client)
{
    if (
hTimer[client])
    {
        
KillTimer(hTimer[client]);
        
hTimer[client] = null;
    }


Thanks!
Grant

Neuro Toxin 06-13-2018 12:40

Re: Optimized Plugin?
 
I would start off by noting you dont need ConVarUpdate anymore.

ConVar caches it's value and updates automatically.

Peace-Maker 06-13-2018 13:33

Re: Optimized Plugin?
 
Quote:

Originally Posted by Neuro Toxin (Post 2596758)
I would start off by noting you dont need ConVarUpdate anymore.

ConVar caches it's value and updates automatically.

What makes you think that? ConVar.BoolValue is still a native call just like GetConVarBool which might be expensive when done in a loop in a critical callback.

You can get rid of the DeleteTimer function and just do "delete hTimer[client];". "KillTimer" does exactly the same as "CloseHandle"/"delete" if you don't use its optional "autoClose" parameter. "delete" ignores null handles and sets the variable to null afterwards - all in one go!

ddhoward 06-13-2018 14:53

Re: Optimized Plugin?
 
Quote:

Originally Posted by Peace-Maker (Post 2596766)
What makes you think that?

https://forums.alliedmods.net/showth...63#post2316163

akcaliberg 06-13-2018 15:18

Re: Optimized Plugin?
 
Since a variable can only have a single value at a time, you should not keep comparing it with other values once you find a match.

So instead of doing:

PHP Code:

if(something == a) ...
if(
something == b) ...
if(
something == c) ... 

You should do:

PHP Code:

if(something == a) ...
else if(
something == b) ...
else if(
something == c) ... 

It will be even better if you use the switch statement:

PHP Code:

switch(something) {
   case 
a: {
      ...
   }
   case 
b: {
      ...
   }
   case 
c: {
      ...
   }



ThatKidWhoGames 06-13-2018 15:29

Re: Optimized Plugin?
 
Thanks guys!!

Psyk0tik 06-13-2018 19:02

Re: Optimized Plugin?
 
Yeah you really don't need to assign all the convar changes to booleans, cells, etc.

This:
PHP Code:

bool g_bEnabled;
ConVar g_cvEnabled[5];
g_bEnabled g_cvEnabled[0].BoolValue;
...
if (
g_bEnabled

Can be simplified to:
PHP Code:

ConVar g_cvEnabled[5];
...
if (
g_cvEnabled[0].BoolValue

As said on psychonic's post that ddhoward linked, convar values are already cached internally and do not need to be recached when their values are changed.

ThatKidWhoGames 06-13-2018 20:02

Re: Optimized Plugin?
 
Quote:

Originally Posted by Crasher_3637 (Post 2596807)
Yeah you really don't need to assign all the convar changes to booleans, cells, etc.

This:
PHP Code:

bool g_bEnabled;
ConVar g_cvEnabled[5];
g_bEnabled g_cvEnabled[0].BoolValue;
...
if (
g_bEnabled

Can be simplified to:
PHP Code:

ConVar g_cvEnabled[5];
...
if (
g_cvEnabled[0].BoolValue

As said on psychonic's post that ddhoward linked, convar values are already cached internally and do not need to be recached when their values are changed.

Thanks!

Peace-Maker 06-13-2018 20:22

Re: Optimized Plugin?
 
Quote:

Originally Posted by ddhoward (Post 2596776)

We're still talking about little optimizations here and switching to C++ code by calling the ConVar.IntValue native instead of just reading a variable in the vm memory is technically still more expensive. Native calls are pretty fast though and since the native is just returning a cached value this isn't really worth the effort. You just need to make a difference between "ConVar" (the sourcepawn methodmap) caching its value and the c++ structure backing it up in the SDK. sourcepawn isn't caching the value.


All times are GMT -4. The time now is 11:16.

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