|
|
|
/*==LICENSE==*
|
|
|
|
|
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools
|
|
|
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
Additional permissions under GNU GPL version 3 section 7
|
|
|
|
|
|
|
|
If you modify this Program, or any covered work, by linking or
|
|
|
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
|
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
|
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
|
|
(or a modified version of those libraries),
|
|
|
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
|
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
|
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
|
|
licensors of this Program grant you additional
|
|
|
|
permission to convey the resulting work. Corresponding Source for a
|
|
|
|
non-source form of such a combination shall include the source code for
|
|
|
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
|
|
work.
|
|
|
|
|
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
|
|
or by snail mail at:
|
|
|
|
Cyan Worlds, Inc.
|
|
|
|
14617 N Newport Hwy
|
|
|
|
Mead, WA 99021
|
|
|
|
|
|
|
|
*==LICENSE==*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// //
|
|
|
|
// pfConsoleCmd Functions //
|
|
|
|
// //
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "pfConsoleCmd.h"
|
|
|
|
#include "hsUtils.h"
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// pfConsoleCmdGroup Stuff /////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfConsoleCmdGroup *pfConsoleCmdGroup::fBaseCmdGroup = nil;
|
|
|
|
UInt32 pfConsoleCmdGroup::fBaseCmdGroupRef = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//// Constructor & Destructor ////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfConsoleCmdGroup::pfConsoleCmdGroup( char *name, char *parent )
|
|
|
|
{
|
|
|
|
Dummy();
|
|
|
|
DummyJunior();
|
|
|
|
DummyNet();
|
|
|
|
DummyAvatar();
|
|
|
|
#ifdef PLASMA_CCR_RELEASE
|
|
|
|
DummyCCR();
|
|
|
|
#endif // PLASMA_CCR_RELEASE
|
|
|
|
|
|
|
|
fNext = nil;
|
|
|
|
fPrevPtr = nil;
|
|
|
|
fCommands = nil;
|
|
|
|
fSubGroups = nil;
|
|
|
|
|
|
|
|
if( name == nil )
|
|
|
|
{
|
|
|
|
/// Create base
|
|
|
|
hsStrncpy( fName, "base", sizeof( fName ) );
|
|
|
|
fParentGroup = nil;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pfConsoleCmdGroup *group = GetBaseGroup();
|
|
|
|
|
|
|
|
if( parent != nil && parent[ 0 ] != 0 )
|
|
|
|
{
|
|
|
|
group = group->FindSubGroupRecurse( parent );
|
|
|
|
hsAssert( group != nil, "Trying to register group under nonexistant group!" );
|
|
|
|
}
|
|
|
|
|
|
|
|
hsStrncpy( fName, name, sizeof( fName ) );
|
|
|
|
group->AddSubGroup( this );
|
|
|
|
fParentGroup = group;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pfConsoleCmdGroup::~pfConsoleCmdGroup()
|
|
|
|
{
|
|
|
|
if( this != fBaseCmdGroup )
|
|
|
|
{
|
|
|
|
Unlink();
|
|
|
|
|
|
|
|
DecBaseCmdGroupRef();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//// GetBaseGroup ////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfConsoleCmdGroup *pfConsoleCmdGroup::GetBaseGroup( void )
|
|
|
|
{
|
|
|
|
if( fBaseCmdGroup == nil )
|
|
|
|
{
|
|
|
|
/// Initialize base group
|
|
|
|
fBaseCmdGroup = TRACKED_NEW pfConsoleCmdGroup( nil, nil );
|
|
|
|
}
|
|
|
|
|
|
|
|
return fBaseCmdGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// DecBaseCmdGroupRef //////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfConsoleCmdGroup::DecBaseCmdGroupRef( void )
|
|
|
|
{
|
|
|
|
fBaseCmdGroupRef--;
|
|
|
|
if( fBaseCmdGroupRef == 0 )
|
|
|
|
{
|
|
|
|
delete fBaseCmdGroup;
|
|
|
|
fBaseCmdGroup = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Add Functions ///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfConsoleCmdGroup::AddCommand( pfConsoleCmd *cmd )
|
|
|
|
{
|
|
|
|
cmd->Link( &fCommands );
|
|
|
|
fBaseCmdGroupRef++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfConsoleCmdGroup::AddSubGroup( pfConsoleCmdGroup *group )
|
|
|
|
{
|
|
|
|
group->Link( &fSubGroups );
|
|
|
|
fBaseCmdGroupRef++;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// FindCommand /////////////////////////////////////////////////////////////
|
|
|
|
// No longer recursive.
|
|
|
|
|
|
|
|
pfConsoleCmd *pfConsoleCmdGroup::FindCommand( char *name )
|
|
|
|
{
|
|
|
|
pfConsoleCmd *cmd;
|
|
|
|
|
|
|
|
|
|
|
|
hsAssert( name != nil, "nil name passed to FindCommand()" );
|
|
|
|
|
|
|
|
/// Only search locally
|
|
|
|
for( cmd = fCommands; cmd != nil; cmd = cmd->GetNext() )
|
|
|
|
{
|
|
|
|
if( strcmp( cmd->GetName(), name ) == 0 )
|
|
|
|
return cmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// FindNestedPartialCommand ////////////////////////////////////////////////
|
|
|
|
// Okay. YAFF. This one searches through the group and its children looking
|
|
|
|
// for a partial command based on the string given. The counter determines
|
|
|
|
// how many matches it skips before returning a match. (That way you can
|
|
|
|
// cycle through matches by sending 1 + the last counter every time).
|
|
|
|
|
|
|
|
pfConsoleCmd *pfConsoleCmdGroup::FindNestedPartialCommand( char *name, UInt32 *counter )
|
|
|
|
{
|
|
|
|
pfConsoleCmd *cmd;
|
|
|
|
pfConsoleCmdGroup *group;
|
|
|
|
|
|
|
|
|
|
|
|
hsAssert( name != nil, "nil name passed to FindNestedPartialCommand()" );
|
|
|
|
hsAssert( counter != nil, "nil counter passed to FindNestedPartialCommand()" );
|
|
|
|
|
|
|
|
// Try us
|
|
|
|
for( cmd = fCommands; cmd != nil; cmd = cmd->GetNext() )
|
|
|
|
{
|
|
|
|
if( _strnicmp( cmd->GetName(), name, strlen( name ) ) == 0 )
|
|
|
|
{
|
|
|
|
if( *counter == 0 )
|
|
|
|
return cmd;
|
|
|
|
|
|
|
|
(*counter)--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try children
|
|
|
|
for( group = fSubGroups; group != nil; group = group->GetNext() )
|
|
|
|
{
|
|
|
|
cmd = group->FindNestedPartialCommand( name, counter );
|
|
|
|
if( cmd != nil )
|
|
|
|
return cmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// FindSubGroup ////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfConsoleCmdGroup *pfConsoleCmdGroup::FindSubGroup( char *name )
|
|
|
|
{
|
|
|
|
pfConsoleCmdGroup *group;
|
|
|
|
|
|
|
|
|
|
|
|
hsAssert( name != nil, "nil name passed to FindSubGroup()" );
|
|
|
|
|
|
|
|
/// Only search locally
|
|
|
|
for( group = fSubGroups; group != nil; group = group->GetNext() )
|
|
|
|
{
|
|
|
|
if( strcmp( group->GetName(), name ) == 0 )
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// FindSubGroupRecurse /////////////////////////////////////////////////////
|
|
|
|
// Resurces through a string, finding the final subgroup that the string
|
|
|
|
// represents. Parses with spaces, _ or . as the separators. Copies string.
|
|
|
|
|
|
|
|
pfConsoleCmdGroup *pfConsoleCmdGroup::FindSubGroupRecurse( const char *name )
|
|
|
|
{
|
|
|
|
char *ptr, *string;
|
|
|
|
pfConsoleCmdGroup *group;
|
|
|
|
static char seps[] = " ._";
|
|
|
|
|
|
|
|
|
|
|
|
string = TRACKED_NEW char[ strlen( name ) + 1 ];
|
|
|
|
hsAssert( string != nil, "Cannot allocate string in FindSubGroupRecurse()" );
|
|
|
|
strcpy( string, name );
|
|
|
|
|
|
|
|
/// Scan for subgroups
|
|
|
|
group = pfConsoleCmdGroup::GetBaseGroup();
|
|
|
|
ptr = strtok( string, seps );
|
|
|
|
while( ptr != nil )
|
|
|
|
{
|
|
|
|
// Take this token and check to see if it's a group
|
|
|
|
group = group->FindSubGroup( ptr );
|
|
|
|
hsAssert( group != nil, "Invalid group name to FindSubGroupRecurse()" );
|
|
|
|
|
|
|
|
ptr = strtok( nil, seps );
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] string;
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// FindCommandNoCase ///////////////////////////////////////////////////////
|
|
|
|
// Case-insensitive version of FindCommand.
|
|
|
|
|
|
|
|
pfConsoleCmd *pfConsoleCmdGroup::FindCommandNoCase( char *name, UInt8 flags, pfConsoleCmd *start )
|
|
|
|
{
|
|
|
|
pfConsoleCmd *cmd;
|
|
|
|
|
|
|
|
|
|
|
|
hsAssert( name != nil, "nil name passed to FindCommandNoCase()" );
|
|
|
|
|
|
|
|
/// Only search locally
|
|
|
|
if( start == nil )
|
|
|
|
start = fCommands;
|
|
|
|
else
|
|
|
|
start = start->GetNext();
|
|
|
|
|
|
|
|
if( flags & kFindPartial )
|
|
|
|
{
|
|
|
|
for( cmd = start; cmd != nil; cmd = cmd->GetNext() )
|
|
|
|
{
|
|
|
|
if( _strnicmp( cmd->GetName(), name, strlen( name ) ) == 0 )
|
|
|
|
return cmd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for( cmd = start; cmd != nil; cmd = cmd->GetNext() )
|
|
|
|
{
|
|
|
|
if( stricmp( cmd->GetName(), name ) == 0 )
|
|
|
|
return cmd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// FindSubGroupNoCase //////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfConsoleCmdGroup *pfConsoleCmdGroup::FindSubGroupNoCase( char *name, UInt8 flags, pfConsoleCmdGroup *start )
|
|
|
|
{
|
|
|
|
pfConsoleCmdGroup *group;
|
|
|
|
|
|
|
|
|
|
|
|
hsAssert( name != nil, "nil name passed to FindSubGroupNoCase()" );
|
|
|
|
|
|
|
|
/// Only search locally
|
|
|
|
if( start == nil )
|
|
|
|
start = fSubGroups;
|
|
|
|
else
|
|
|
|
start = start->GetNext();
|
|
|
|
|
|
|
|
if( flags & kFindPartial )
|
|
|
|
{
|
|
|
|
for( group = start; group != nil; group = group->GetNext() )
|
|
|
|
{
|
|
|
|
if( _strnicmp( group->GetName(), name, strlen( name ) ) == 0 )
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for( group = start; group != nil; group = group->GetNext() )
|
|
|
|
{
|
|
|
|
if( stricmp( group->GetName(), name ) == 0 )
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Link & Unlink ///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfConsoleCmdGroup::Link( pfConsoleCmdGroup **prevPtr )
|
|
|
|
{
|
|
|
|
hsAssert( fNext == nil && fPrevPtr == nil, "Trying to link console group that's already linked!" );
|
|
|
|
|
|
|
|
fNext = *prevPtr;
|
|
|
|
if( *prevPtr )
|
|
|
|
(*prevPtr)->fPrevPtr = &fNext;
|
|
|
|
fPrevPtr = prevPtr;
|
|
|
|
*fPrevPtr = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfConsoleCmdGroup::Unlink( void )
|
|
|
|
{
|
|
|
|
hsAssert( fNext != nil || fPrevPtr != nil, "Trying to unlink console group that isn't linked!" );
|
|
|
|
|
|
|
|
if( fNext )
|
|
|
|
fNext->fPrevPtr = fPrevPtr;
|
|
|
|
*fPrevPtr = fNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int pfConsoleCmdGroup::IterateCommands(pfConsoleCmdIterator* t, int depth)
|
|
|
|
{
|
|
|
|
pfConsoleCmd *cmd;
|
|
|
|
|
|
|
|
cmd = this->GetFirstCommand();
|
|
|
|
while(cmd)
|
|
|
|
{
|
|
|
|
t->ProcessCmd(cmd,depth);
|
|
|
|
cmd = cmd->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
pfConsoleCmdGroup *grp;
|
|
|
|
|
|
|
|
grp = this->GetFirstSubGroup();
|
|
|
|
while(grp)
|
|
|
|
{
|
|
|
|
if(t->ProcessGroup(grp, depth))
|
|
|
|
grp->IterateCommands(t, depth+1);
|
|
|
|
grp = grp->GetNext();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// pfConsoleCmd Functions //////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
char pfConsoleCmd::fSigTypes[ kNumTypes ][ 8 ] = { "int", "float", "bool", "string", "char", "void", "..." };
|
|
|
|
|
|
|
|
pfConsoleCmd::pfConsoleCmd( char *group, char *name, char *paramList, char *help,
|
|
|
|
pfConsoleCmdPtr func, hsBool localOnly )
|
|
|
|
{
|
|
|
|
fNext = nil;
|
|
|
|
fPrevPtr = nil;
|
|
|
|
|
|
|
|
fFunction = func;
|
|
|
|
fLocalOnly = localOnly;
|
|
|
|
|
|
|
|
hsStrncpy( fName, name, sizeof( fName ) );
|
|
|
|
fHelpString = help;
|
|
|
|
|
|
|
|
ICreateSignature( paramList );
|
|
|
|
Register( group, name );
|
|
|
|
}
|
|
|
|
|
|
|
|
pfConsoleCmd::~pfConsoleCmd()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
for( i = 0; i < fSigLabels.GetCount(); i++ )
|
|
|
|
{
|
|
|
|
if( fSigLabels[ i ] != nil )
|
|
|
|
delete [] fSigLabels[ i ];
|
|
|
|
}
|
|
|
|
Unregister();
|
|
|
|
|
|
|
|
fSignature.Reset();
|
|
|
|
fSigLabels.Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//// ICreateSignature ////////////////////////////////////////////////////////
|
|
|
|
// Creates the signature and sig labels based on the given string.
|
|
|
|
|
|
|
|
void pfConsoleCmd::ICreateSignature( char *paramList )
|
|
|
|
{
|
|
|
|
static char seps[] = " :-";
|
|
|
|
|
|
|
|
char params[ 256 ];
|
|
|
|
char *ptr, *nextPtr, *tok, *tok2;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
/// Simple check
|
|
|
|
if( paramList == nil )
|
|
|
|
{
|
|
|
|
fSignature.Push( kAny );
|
|
|
|
fSigLabels.Push( (char *)nil );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// So we can do stuff to it
|
|
|
|
hsAssert( strlen( paramList ) < sizeof( params ), "Make the (#*$& params string larger!" );
|
|
|
|
hsStrcpy( params, paramList );
|
|
|
|
|
|
|
|
fSignature.Empty();
|
|
|
|
fSigLabels.Empty();
|
|
|
|
|
|
|
|
/// Loop through all the types given in the list
|
|
|
|
ptr = params;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/// Find break
|
|
|
|
nextPtr = strchr( ptr, ',' );
|
|
|
|
if( nextPtr != nil )
|
|
|
|
{
|
|
|
|
*nextPtr = 0;
|
|
|
|
nextPtr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Do this param
|
|
|
|
tok = strtok( ptr, seps );
|
|
|
|
if( tok == nil && ptr == params )
|
|
|
|
break;
|
|
|
|
|
|
|
|
hsAssert( tok != nil, "Bad parameter list for console command!" );
|
|
|
|
tok2 = strtok( nil, seps );
|
|
|
|
|
|
|
|
if( tok2 != nil )
|
|
|
|
{
|
|
|
|
// Type and label: assume label second
|
|
|
|
fSigLabels.Push( hsStrcpy( tok2 ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fSigLabels.Push( (char *)nil );
|
|
|
|
|
|
|
|
// Find type
|
|
|
|
for( i = 0; i < kNumTypes; i++ )
|
|
|
|
{
|
|
|
|
if( strcmp( fSigTypes[ i ], tok ) == 0 )
|
|
|
|
{
|
|
|
|
fSignature.Push( (UInt8)i );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hsAssert( i < kNumTypes, "Bad parameter type in console command parameter list!" );
|
|
|
|
|
|
|
|
} while( ( ptr = nextPtr ) != nil );
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Register ////////////////////////////////////////////////////////////////
|
|
|
|
// Finds the group this command should be in and registers it with that
|
|
|
|
// group.
|
|
|
|
|
|
|
|
void pfConsoleCmd::Register( char *group, char *name )
|
|
|
|
{
|
|
|
|
pfConsoleCmdGroup *g;
|
|
|
|
|
|
|
|
|
|
|
|
if( group == nil || group[ 0 ] == 0 )
|
|
|
|
{
|
|
|
|
g = pfConsoleCmdGroup::GetBaseGroup();
|
|
|
|
g->AddCommand( this );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g = pfConsoleCmdGroup::FindSubGroupRecurse( group );
|
|
|
|
hsAssert( g != nil, "Trying to register command under nonexistant group!" );
|
|
|
|
g->AddCommand( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
fParentGroup = g;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Unregister //////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfConsoleCmd::Unregister( void )
|
|
|
|
{
|
|
|
|
Unlink();
|
|
|
|
pfConsoleCmdGroup::DecBaseCmdGroupRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Execute /////////////////////////////////////////////////////////////////
|
|
|
|
// Run da thing!
|
|
|
|
|
|
|
|
void pfConsoleCmd::Execute( Int32 numParams, pfConsoleCmdParam *params, void (*PrintFn)( const char * ) )
|
|
|
|
{
|
|
|
|
fFunction( numParams, params, PrintFn );
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Link & Unlink ///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfConsoleCmd::Link( pfConsoleCmd **prevPtr )
|
|
|
|
{
|
|
|
|
hsAssert( fNext == nil && fPrevPtr == nil, "Trying to link console command that's already linked!" );
|
|
|
|
|
|
|
|
fNext = *prevPtr;
|
|
|
|
if( *prevPtr )
|
|
|
|
(*prevPtr)->fPrevPtr = &fNext;
|
|
|
|
fPrevPtr = prevPtr;
|
|
|
|
*fPrevPtr = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfConsoleCmd::Unlink( void )
|
|
|
|
{
|
|
|
|
hsAssert( fNext != nil || fPrevPtr != nil, "Trying to unlink console command that isn't linked!" );
|
|
|
|
|
|
|
|
if( fNext )
|
|
|
|
fNext->fPrevPtr = fPrevPtr;
|
|
|
|
*fPrevPtr = fNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// GetSigEntry /////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
UInt8 pfConsoleCmd::GetSigEntry( UInt8 i )
|
|
|
|
{
|
|
|
|
if( fSignature.GetCount() == 0 )
|
|
|
|
return kNone;
|
|
|
|
|
|
|
|
if( i < fSignature.GetCount() )
|
|
|
|
{
|
|
|
|
if( fSignature[ i ] == kEtc )
|
|
|
|
return kAny;
|
|
|
|
|
|
|
|
return fSignature[ i ];
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fSignature[ fSignature.GetCount() - 1 ] == kEtc )
|
|
|
|
return kAny;
|
|
|
|
|
|
|
|
return kNone;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// GetSignature ////////////////////////////////////////////////////////////
|
|
|
|
// Gets the signature of the command as a string. Format is:
|
|
|
|
// name [ type param [, type param ... ] ]
|
|
|
|
// WARNING: uses a static buffer, so don't rely on the contents if you call
|
|
|
|
// it more than once! (You shouldn't need to, though)
|
|
|
|
|
|
|
|
const char *pfConsoleCmd::GetSignature( void )
|
|
|
|
{
|
|
|
|
static char string[ 256 ];
|
|
|
|
|
|
|
|
int i;
|
|
|
|
char pStr[ 128 ];
|
|
|
|
|
|
|
|
|
|
|
|
strcpy( string, fName );
|
|
|
|
for( i = 0; i < fSignature.GetCount(); i++ )
|
|
|
|
{
|
|
|
|
if( fSigLabels[ i ] == nil )
|
|
|
|
sprintf( pStr, "%s", fSigTypes[ fSignature[ i ] ] );
|
|
|
|
else
|
|
|
|
sprintf( pStr, "%s %s", fSigTypes[ fSignature[ i ] ], fSigLabels[ i ] );
|
|
|
|
|
|
|
|
hsAssert( strlen( string ) + strlen( pStr ) + 2 < sizeof( string ), "Not enough room for signature string" );
|
|
|
|
strcat( string, ( i > 0 ) ? ", " : " " );
|
|
|
|
|
|
|
|
strcat( string, pStr );
|
|
|
|
}
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// pfConsoleCmdParam Functions /////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//// Conversion Functions ////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
const int & pfConsoleCmdParam::IToInt( void ) const
|
|
|
|
{
|
|
|
|
hsAssert( fType == kInt || fType == kAny, "Trying to use a non-int parameter as an int!" );
|
|
|
|
|
|
|
|
static int i;
|
|
|
|
if( fType == kAny )
|
|
|
|
{
|
|
|
|
hsAssert( fValue.s != nil, "Weird parameter during conversion" );
|
|
|
|
i = atoi( fValue.s );
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fValue.i;
|
|
|
|
}
|
|
|
|
|
|
|
|
const float & pfConsoleCmdParam::IToFloat( void ) const
|
|
|
|
{
|
|
|
|
hsAssert( fType == kFloat || fType == kAny, "Trying to use a non-float parameter as a float!" );
|
|
|
|
|
|
|
|
static float f;
|
|
|
|
if( fType == kAny )
|
|
|
|
{
|
|
|
|
hsAssert( fValue.s != nil, "Weird parameter during conversion" );
|
|
|
|
f = (float)atof( fValue.s );
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fValue.f;
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool & pfConsoleCmdParam::IToBool( void ) const
|
|
|
|
{
|
|
|
|
hsAssert( fType == kBool || fType == kAny, "Trying to use a non-bool parameter as a bool!" );
|
|
|
|
|
|
|
|
static bool b;
|
|
|
|
if( fType == kAny )
|
|
|
|
{
|
|
|
|
hsAssert( fValue.s != nil, "Weird parameter during conversion" );
|
|
|
|
if( atoi( fValue.s ) > 0 || stricmp( fValue.s, "true" ) == 0 )
|
|
|
|
b = true;
|
|
|
|
else
|
|
|
|
b = false;
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fValue.b;
|
|
|
|
}
|
|
|
|
|
|
|
|
const pfConsoleCmdParam::CharPtr & pfConsoleCmdParam::IToString( void ) const
|
|
|
|
{
|
|
|
|
hsAssert( fType == kString || fType == kAny, "Trying to use a non-string parameter as a string!" );
|
|
|
|
|
|
|
|
return fValue.s;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char & pfConsoleCmdParam::IToChar( void ) const
|
|
|
|
{
|
|
|
|
hsAssert( fType == kChar || fType == kAny, "Trying to use a non-char parameter as a char!" );
|
|
|
|
|
|
|
|
static char c;
|
|
|
|
if( fType == kAny )
|
|
|
|
{
|
|
|
|
hsAssert( fValue.s != nil, "Weird parameter during conversion" );
|
|
|
|
c = fValue.s[ 0 ];
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fValue.c;
|
|
|
|
}
|
|
|
|
|