mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-22 21:04:14 +00:00
Add basecmd from old engine. Add basecmd_stats command
This commit is contained in:
parent
ae5257c654
commit
0561ac2076
@ -108,6 +108,8 @@ engine/client/vgui/vgui_draw.h
|
||||
engine/client/vid_common.c
|
||||
engine/client/vid_common.h
|
||||
engine/client/vox.h
|
||||
engine/common/base_cmd.c
|
||||
engine/common/base_cmd.h
|
||||
engine/common/build.c
|
||||
engine/common/cfgscript.c
|
||||
engine/common/cmd.c
|
||||
|
@ -83,6 +83,8 @@ client_t cl;
|
||||
client_static_t cls;
|
||||
clgame_static_t clgame;
|
||||
|
||||
void CL_InternetServers_f( void );
|
||||
|
||||
//======================================================================
|
||||
int CL_Active( void )
|
||||
{
|
||||
|
229
engine/common/base_cmd.c
Normal file
229
engine/common/base_cmd.c
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
base_cmd.c - command & cvar hashmap. Insipred by Doom III
|
||||
Copyright (C) 2016 a1batross
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "base_cmd.h"
|
||||
|
||||
// TODO: use another hash function, as COM_HashKey depends on string length
|
||||
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
|
||||
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_FindInBucket
|
||||
|
||||
Find base command in bucket
|
||||
============
|
||||
*/
|
||||
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = bucket;
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
|
||||
i = i->next );
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_GetBucket
|
||||
|
||||
Get bucket which contain basecmd by given name
|
||||
============
|
||||
*/
|
||||
base_command_hashmap_t *BaseCmd_GetBucket( const char *name )
|
||||
{
|
||||
return hashed_cmds[ COM_HashKey( name, HASH_SIZE ) ];
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Find
|
||||
|
||||
Find base command in hashmap
|
||||
============
|
||||
*/
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *found = BaseCmd_FindInBucket( base, type, name );
|
||||
|
||||
if( found )
|
||||
return found->basecmd;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Find
|
||||
|
||||
Find every type of base command and write into arguments
|
||||
============
|
||||
*/
|
||||
void BaseCmd_FindAll(const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar)
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *i = base;
|
||||
|
||||
ASSERT( cmd && alias && cvar );
|
||||
|
||||
*cmd = *alias = *cvar = NULL;
|
||||
|
||||
for( ; i; i = i->next )
|
||||
{
|
||||
if( !Q_stricmp( i->name, name ) )
|
||||
{
|
||||
switch( i->type )
|
||||
{
|
||||
case HM_CMD:
|
||||
*cmd = i->basecmd;
|
||||
break;
|
||||
case HM_CMDALIAS:
|
||||
*alias = i->basecmd;
|
||||
break;
|
||||
case HM_CVAR:
|
||||
*cvar = i->basecmd;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Insert
|
||||
|
||||
Add new typed base command to hashmap
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const char *name )
|
||||
{
|
||||
uint hash = COM_HashKey( name, HASH_SIZE );
|
||||
base_command_hashmap_t *elem;
|
||||
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) );
|
||||
elem->basecmd = basecmd;
|
||||
elem->type = type;
|
||||
elem->name = name;
|
||||
elem->next = hashed_cmds[hash];
|
||||
hashed_cmds[hash] = elem;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Replace
|
||||
|
||||
Used in case, when basecmd has been registered, but gamedll wants to register it's own
|
||||
============
|
||||
*/
|
||||
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = BaseCmd_GetBucket( name );
|
||||
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ) ; // filter out
|
||||
i = i->next );
|
||||
|
||||
if( !i )
|
||||
{
|
||||
MsgDev( D_ERROR, "BaseCmd_Replace: couldn't find %s\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
i->basecmd = basecmd;
|
||||
i->name = name; // may be freed after
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Remove
|
||||
|
||||
Remove base command from hashmap
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Remove( base_command_type_e type, const char *name )
|
||||
{
|
||||
uint hash = COM_HashKey( name, HASH_SIZE );
|
||||
base_command_hashmap_t *i, *prev;
|
||||
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i &&
|
||||
( Q_strcmp( i->name, name ) || i->type != type); // filter out
|
||||
prev = i, i = i->next );
|
||||
|
||||
if( !i )
|
||||
{
|
||||
MsgDev( D_ERROR, "Couldn't find %s in buckets\n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
if( prev )
|
||||
prev->next = i->next;
|
||||
else
|
||||
hashed_cmds[hash] = i->next;
|
||||
|
||||
Z_Free( i );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Init
|
||||
|
||||
initialize base command hashmap system
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Init( void )
|
||||
{
|
||||
memset( hashed_cmds, 0, sizeof( hashed_cmds ) );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Stats_f
|
||||
|
||||
============
|
||||
*/
|
||||
void BaseCmd_Stats_f( void )
|
||||
{
|
||||
int i, minsize = 99999, maxsize = -1, empty = 0;
|
||||
|
||||
for( i = 0; i < HASH_SIZE; i++ )
|
||||
{
|
||||
base_command_hashmap_t *hm;
|
||||
int len = 0;
|
||||
|
||||
// count bucket length
|
||||
for( hm = hashed_cmds[i]; hm; hm = hm->next, len++ );
|
||||
|
||||
if( len == 0 )
|
||||
{
|
||||
empty++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( len < minsize )
|
||||
minsize = len;
|
||||
|
||||
if( len > maxsize )
|
||||
maxsize = len;
|
||||
}
|
||||
|
||||
Con_Printf( "Base command stats:\n");
|
||||
Con_Printf( "Bucket minimal length: %d\n", minsize );
|
||||
Con_Printf( "Bucket maximum length: %d\n", maxsize );
|
||||
Con_Printf( "Empty buckets: %d\n", empty );
|
||||
}
|
58
engine/common/base_cmd.h
Normal file
58
engine/common/base_cmd.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
base_cmd.h - command & cvar hashmap. Insipred by Doom III
|
||||
Copyright (C) 2016 a1batross
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef BASE_CMD_H
|
||||
#define BASE_CMD_H
|
||||
|
||||
// TODO: Find cases when command hashmap works incorrect
|
||||
// and maybe disable it
|
||||
#define XASH_HASHED_VARS
|
||||
|
||||
#ifdef XASH_HASHED_VARS
|
||||
|
||||
typedef enum base_command_type
|
||||
{
|
||||
HM_DONTCARE = 0,
|
||||
HM_CVAR,
|
||||
HM_CMD,
|
||||
HM_CMDALIAS
|
||||
} base_command_type_e;
|
||||
|
||||
typedef void base_command_t;
|
||||
|
||||
typedef struct base_command_hashmap_s
|
||||
{
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
const char *name; // key for searching
|
||||
base_command_type_e type; // type for faster searching
|
||||
struct base_command_hashmap_s *next;
|
||||
} base_command_hashmap_t;
|
||||
|
||||
|
||||
void BaseCmd_Init( void );
|
||||
base_command_hashmap_t *BaseCmd_GetBucket( const char *name );
|
||||
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name );
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
|
||||
void BaseCmd_FindAll( const char *name,
|
||||
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );
|
||||
void BaseCmd_Insert ( base_command_type_e type, base_command_t *basecmd, const char *name );
|
||||
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name ); // only if same name
|
||||
void BaseCmd_Remove ( base_command_type_e type, const char *name );
|
||||
void BaseCmd_Stats_f( void ); // to be registered later
|
||||
|
||||
#endif // XASH_HASHED_VARS
|
||||
|
||||
#endif // BASE_CMD_H
|
@ -16,6 +16,7 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "server.h"
|
||||
#include "base_cmd.h"
|
||||
|
||||
#define MAX_CMD_BUFFER 32768
|
||||
#define MAX_CMD_LINE 2048
|
||||
@ -380,6 +381,10 @@ void Cmd_Alias_f( void )
|
||||
if( prev ) prev->next = a;
|
||||
else cmd_alias = a;
|
||||
a->next = cur;
|
||||
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_Insert( HM_CMDALIAS, a, a->name );
|
||||
#endif
|
||||
}
|
||||
|
||||
// copy the rest of the command line
|
||||
@ -425,6 +430,9 @@ static void Cmd_UnAlias_f ( void )
|
||||
{
|
||||
if( !Q_strcmp( s, a->name ))
|
||||
{
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_Remove( HM_CMDALIAS, a->name );
|
||||
#endif
|
||||
if( a == cmd_alias )
|
||||
cmd_alias = a->next;
|
||||
if( p ) p->next = a->next;
|
||||
@ -722,6 +730,10 @@ void Cmd_RemoveCommand( const char *cmd_name )
|
||||
|
||||
if( !Q_strcmp( cmd_name, cmd->name ))
|
||||
{
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_Remove( HM_CMD, cmd->name );
|
||||
#endif
|
||||
|
||||
*back = cmd->next;
|
||||
|
||||
if( cmd->name )
|
||||
@ -768,6 +780,9 @@ Cmd_Exists
|
||||
*/
|
||||
qboolean Cmd_Exists( const char *cmd_name )
|
||||
{
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
return BaseCmd_Find( HM_CMD, cmd_name ) != NULL;
|
||||
#else
|
||||
cmd_t *cmd;
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
@ -776,6 +791,7 @@ qboolean Cmd_Exists( const char *cmd_name )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -860,8 +876,9 @@ A complete command line has been parsed, so try to execute it
|
||||
*/
|
||||
void Cmd_ExecuteString( char *text )
|
||||
{
|
||||
cmd_t *cmd;
|
||||
cmdalias_t *a;
|
||||
cmd_t *cmd = NULL;
|
||||
cmdalias_t *a = NULL;
|
||||
convar_t *cvar = NULL;
|
||||
char command[MAX_CMD_LINE];
|
||||
char *pcmd = command;
|
||||
int len = 0;
|
||||
@ -916,9 +933,22 @@ void Cmd_ExecuteString( char *text )
|
||||
|
||||
if( !Cmd_Argc( )) return; // no tokens
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_FindAll( cmd_argv[0],
|
||||
(base_command_t**)&cmd,
|
||||
(base_command_t**)&a,
|
||||
(base_command_t**)&cvar );
|
||||
#endif
|
||||
|
||||
if( !host.apply_game_config )
|
||||
{
|
||||
// check aliases
|
||||
if( a ) // already found in basecmd
|
||||
{
|
||||
Cbuf_InsertText( a->value );
|
||||
return;
|
||||
}
|
||||
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
@ -933,6 +963,12 @@ void Cmd_ExecuteString( char *text )
|
||||
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
|
||||
{
|
||||
// check functions
|
||||
if( cmd && cmd->function ) // already found in basecmd
|
||||
{
|
||||
cmd->function();
|
||||
return;
|
||||
}
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
@ -944,7 +980,7 @@ void Cmd_ExecuteString( char *text )
|
||||
}
|
||||
|
||||
// check cvars
|
||||
if( Cvar_Command( )) return;
|
||||
if( Cvar_Command( cvar )) return;
|
||||
|
||||
if( host.apply_game_config )
|
||||
return; // don't send nothing to server: we is a server!
|
||||
@ -1125,4 +1161,8 @@ void Cmd_Init( void )
|
||||
Cmd_AddCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
|
||||
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );
|
||||
#endif
|
||||
}
|
||||
|
@ -13,8 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <math.h> // fabs...
|
||||
#include "common.h"
|
||||
#include "math.h" // fabs...
|
||||
#include "base_cmd.h"
|
||||
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cmd_scripting;
|
||||
@ -690,10 +691,8 @@ Cvar_Command
|
||||
Handles variable inspection and changing from the console
|
||||
============
|
||||
*/
|
||||
qboolean Cvar_Command( void )
|
||||
qboolean Cvar_Command( convar_t *v )
|
||||
{
|
||||
convar_t *v;
|
||||
|
||||
// special case for setup opengl configuration
|
||||
if( host.apply_opengl_config )
|
||||
{
|
||||
@ -702,7 +701,8 @@ qboolean Cvar_Command( void )
|
||||
}
|
||||
|
||||
// check variables
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
if( !v ) // already found in basecmd
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
if( !v ) return false;
|
||||
|
||||
// perform a variable print or set
|
||||
|
@ -66,7 +66,7 @@ const char *Cvar_VariableString( const char *var_name );
|
||||
void Cvar_WriteVariables( file_t *f, int group );
|
||||
void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_Command( void );
|
||||
qboolean Cvar_Command( convar_t *v );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
|
@ -822,6 +822,9 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
// init host state machine
|
||||
COM_InitHostState();
|
||||
|
||||
// init hashed commands
|
||||
BaseCmd_Init();
|
||||
|
||||
// startup cmds and cvars subsystem
|
||||
Cmd_Init();
|
||||
Cvar_Init();
|
||||
|
Loading…
x
Reference in New Issue
Block a user