2013-08-07 21:45:56 -07:00
/*
2016-01-01 00:11:04 -08:00
* Copyright 2010 - 2016 Branimir Karadzic . All rights reserved .
* License : https : //github.com/bkaradzic/bgfx#license-bsd-2-clause
2013-08-07 21:45:56 -07:00
*/
2013-08-07 22:01:46 -07:00
# include <ctype.h> // isspace
2013-08-07 21:45:56 -07:00
# include <stdint.h>
# include <stdlib.h> // size_t
2013-08-07 22:01:46 -07:00
# include <string.h> // strlen
2015-02-09 20:12:46 -08:00
# include <bx/allocator.h>
2013-08-07 21:45:56 -07:00
# include <bx/hash.h>
2014-06-30 22:46:54 -07:00
# include <bx/tokenizecmd.h>
2013-08-07 21:45:56 -07:00
# include "dbg.h"
# include "cmd.h"
2015-02-08 10:25:53 -08:00
# include "entry_p.h"
2014-11-16 18:59:17 -08:00
2014-08-22 16:35:30 +02:00
# include <tinystl/allocator.h>
2014-11-16 18:59:17 -08:00
# include <tinystl/string.h>
2014-08-22 16:35:30 +02:00
# include <tinystl/unordered_map.h>
namespace stl = tinystl ;
2013-08-07 21:45:56 -07:00
struct CmdContext
{
CmdContext ( )
{
}
~ CmdContext ( )
{
}
void add ( const char * _name , ConsoleFn _fn , void * _userData )
{
uint32_t cmd = bx : : hashMurmur2A ( _name , ( uint32_t ) strlen ( _name ) ) ;
BX_CHECK ( m_lookup . end ( ) = = m_lookup . find ( cmd ) , " Command \" %s \" already exist. " , _name ) ;
Func fn = { _fn , _userData } ;
2014-08-22 16:35:30 +02:00
m_lookup . insert ( stl : : make_pair ( cmd , fn ) ) ;
2013-08-07 21:45:56 -07:00
}
void exec ( const char * _cmd )
{
for ( const char * next = _cmd ; ' \0 ' ! = * next ; _cmd = next )
{
char commandLine [ 1024 ] ;
uint32_t size = sizeof ( commandLine ) ;
int argc ;
char * argv [ 64 ] ;
2014-06-30 22:46:54 -07:00
next = bx : : tokenizeCommandLine ( _cmd , commandLine , size , argc , argv , BX_COUNTOF ( argv ) , ' \n ' ) ;
2013-08-07 21:45:56 -07:00
if ( argc > 0 )
{
int err = - 1 ;
uint32_t cmd = bx : : hashMurmur2A ( argv [ 0 ] , ( uint32_t ) strlen ( argv [ 0 ] ) ) ;
CmdLookup : : iterator it = m_lookup . find ( cmd ) ;
if ( it ! = m_lookup . end ( ) )
{
Func & fn = it - > second ;
err = fn . m_fn ( this , fn . m_userData , argc , argv ) ;
}
switch ( err )
{
case 0 :
break ;
case - 1 :
{
2014-11-16 18:59:17 -08:00
stl : : string tmp ( _cmd , next - _cmd - ( * next = = ' \0 ' ? 0 : 1 ) ) ;
2013-08-07 21:45:56 -07:00
DBG ( " Command '%s' doesn't exist. " , tmp . c_str ( ) ) ;
}
break ;
default :
{
2014-11-16 18:59:17 -08:00
stl : : string tmp ( _cmd , next - _cmd - ( * next = = ' \0 ' ? 0 : 1 ) ) ;
2013-08-07 21:45:56 -07:00
DBG ( " Failed '%s' err: %d. " , tmp . c_str ( ) , err ) ;
}
break ;
}
}
}
}
struct Func
{
ConsoleFn m_fn ;
void * m_userData ;
} ;
2014-08-22 16:35:30 +02:00
typedef stl : : unordered_map < uint32_t , Func > CmdLookup ;
2013-08-07 21:45:56 -07:00
CmdLookup m_lookup ;
} ;
2015-02-09 20:12:46 -08:00
static CmdContext * s_cmdContext ;
void cmdInit ( )
{
s_cmdContext = BX_NEW ( entry : : getAllocator ( ) , CmdContext ) ;
}
void cmdShutdown ( )
{
BX_DELETE ( entry : : getAllocator ( ) , s_cmdContext ) ;
}
2013-08-07 21:45:56 -07:00
void cmdAdd ( const char * _name , ConsoleFn _fn , void * _userData )
{
2015-02-09 20:12:46 -08:00
s_cmdContext - > add ( _name , _fn , _userData ) ;
2013-08-07 21:45:56 -07:00
}
void cmdExec ( const char * _cmd )
{
2015-02-09 20:12:46 -08:00
s_cmdContext - > exec ( _cmd ) ;
2013-08-07 21:45:56 -07:00
}