mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-23 00:23:46 +00:00
Merge pull request #1532 from GarageGames/pr/1143
[CLONE] More consolefunctions #1143
This commit is contained in:
commit
794f1b9536
7 changed files with 706 additions and 0 deletions
|
|
@ -202,6 +202,26 @@ DefineConsoleFunction( getRealTime, S32, (), , "()"
|
|||
return Platform::getRealMilliseconds();
|
||||
}
|
||||
|
||||
ConsoleFunction( getLocalTime, const char *, 1, 1, "Return the current local time as: weekday month day year hour min sec.\n\n"
|
||||
"Local time is platform defined.")
|
||||
{
|
||||
Platform::LocalTime lt;
|
||||
Platform::getLocalTime(lt);
|
||||
|
||||
static const U32 bufSize = 128;
|
||||
char *retBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(retBuffer, bufSize, "%d %d %d %d %02d %02d %02d",
|
||||
lt.weekday,
|
||||
lt.month + 1,
|
||||
lt.monthday,
|
||||
lt.year + 1900,
|
||||
lt.hour,
|
||||
lt.min,
|
||||
lt.sec);
|
||||
|
||||
return retBuffer;
|
||||
}
|
||||
|
||||
ConsoleFunctionGroupEnd(Platform);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
#include "console/consoleInternal.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/ast.h"
|
||||
|
||||
#ifndef _CONSOLFUNCTIONS_H_
|
||||
#include "console/consoleFunctions.h"
|
||||
#endif
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
#include "core/strings/unicode.h"
|
||||
|
|
@ -32,6 +37,7 @@
|
|||
#include "console/compiler.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "core/util/journal/journal.h"
|
||||
#include "gfx/gfxEnums.h"
|
||||
#include "core/util/uuid.h"
|
||||
|
||||
// This is a temporary hack to get tools using the library to
|
||||
|
|
@ -41,6 +47,132 @@ bool LinkConsoleFunctions = false;
|
|||
// Buffer for expanding script filenames.
|
||||
static char scriptFilenameBuffer[1024];
|
||||
|
||||
bool isInt(const char* str)
|
||||
{
|
||||
int len = dStrlen(str);
|
||||
if(len <= 0)
|
||||
return false;
|
||||
|
||||
// Ignore whitespace
|
||||
int start = 0;
|
||||
for(int i = start; i < len; i++)
|
||||
if(str[i] != ' ')
|
||||
{
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i = start; i < len; i++)
|
||||
switch(str[i])
|
||||
{
|
||||
case '+': case '-':
|
||||
if(i != 0)
|
||||
return false;
|
||||
break;
|
||||
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0':
|
||||
break;
|
||||
case ' ': // ignore whitespace
|
||||
for(int j = i+1; j < len; j++)
|
||||
if(str[j] != ' ')
|
||||
return false;
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isFloat(const char* str, bool sciOk = false)
|
||||
{
|
||||
int len = dStrlen(str);
|
||||
if(len <= 0)
|
||||
return false;
|
||||
|
||||
// Ingore whitespace
|
||||
int start = 0;
|
||||
for(int i = start; i < len; i++)
|
||||
if(str[i] != ' ')
|
||||
{
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
|
||||
bool seenDot = false;
|
||||
int eLoc = -1;
|
||||
for(int i = 0; i < len; i++)
|
||||
switch(str[i])
|
||||
{
|
||||
case '+': case '-':
|
||||
if(sciOk)
|
||||
{
|
||||
//Haven't found e or scientific notation symbol
|
||||
if(eLoc == -1)
|
||||
{
|
||||
//only allowed in beginning
|
||||
if(i != 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if not right after the e
|
||||
if(i != (eLoc + 1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//only allowed in beginning
|
||||
if(i != 0)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0':
|
||||
break;
|
||||
case 'e': case 'E':
|
||||
if(!sciOk)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
//already saw it so can't have 2
|
||||
if(eLoc != -1)
|
||||
return false;
|
||||
|
||||
eLoc = i;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if(seenDot | (sciOk && eLoc != -1))
|
||||
return false;
|
||||
seenDot = true;
|
||||
break;
|
||||
case ' ': // ignore whitespace
|
||||
for(int j = i+1; j < len; j++)
|
||||
if(str[j] != ' ')
|
||||
return false;
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidIP(const char* ip)
|
||||
{
|
||||
unsigned b1, b2, b3, b4;
|
||||
unsigned char c;
|
||||
int rc = dSscanf(ip, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c);
|
||||
if (rc != 4 && rc != 5) return false;
|
||||
if ((b1 | b2 | b3 | b4) > 255) return false;
|
||||
if (dStrspn(ip, "0123456789.") < dStrlen(ip)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidPort(U16 port)
|
||||
{
|
||||
return (port >= 0 && port <=65535);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// String Functions.
|
||||
|
|
@ -235,6 +367,40 @@ DefineConsoleFunction( strlen, S32, ( const char* str ),,
|
|||
return dStrlen( str );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DefineConsoleFunction( strlenskip, S32, ( const char* str, const char* first, const char* last ),,
|
||||
"Calculate the length of a string in characters, skipping everything between and including first and last.\n"
|
||||
"@param str A string.\n"
|
||||
"@param first First character to look for to skip block of text.\n"
|
||||
"@param last Second character to look for to skip block of text.\n"
|
||||
"@return The length of the given string skipping blocks of text between characters.\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
const UTF8* pos = str;
|
||||
U32 size = 0;
|
||||
U32 length = dStrlen(str);
|
||||
bool count = true;
|
||||
|
||||
//loop through each character counting each character, skipping tags (anything with < followed by >)
|
||||
for(U32 i = 0; i < length; i++, pos++)
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
if(*pos == first[0])
|
||||
count = false;
|
||||
else
|
||||
size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(*pos == last[0])
|
||||
count = true;
|
||||
}
|
||||
}
|
||||
|
||||
return S32(size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( strstr, S32, ( const char* string, const char* substring ),,
|
||||
|
|
@ -281,6 +447,33 @@ DefineConsoleFunction( strpos, S32, ( const char* haystack, const char* needle,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( strposr, S32, ( const char* haystack, const char* needle, S32 offset ), ( 0 ),
|
||||
"Find the start of @a needle in @a haystack searching from right to left beginning at the given offset.\n"
|
||||
"@param haystack The string to search.\n"
|
||||
"@param needle The string to search for.\n"
|
||||
"@return The index at which the first occurrence of @a needle was found in @a heystack or -1 if no match was found.\n\n"
|
||||
"@tsexample\n"
|
||||
"strposr( \"b ab\", \"b\", 1 ) // Returns 2.\n"
|
||||
"@endtsexample\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
U32 sublen = dStrlen( needle );
|
||||
U32 strlen = dStrlen( haystack );
|
||||
S32 start = strlen - offset;
|
||||
|
||||
if(start < 0 || start > strlen)
|
||||
return -1;
|
||||
|
||||
if (start + sublen > strlen)
|
||||
start = strlen - sublen;
|
||||
for(; start >= 0; start--)
|
||||
if(!dStrncmp(haystack + start, needle, sublen))
|
||||
return start;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( ltrim, const char*, ( const char* str ),,
|
||||
"Remove leading whitespace from the string.\n"
|
||||
"@param str A string.\n"
|
||||
|
|
@ -627,6 +820,18 @@ DefineConsoleFunction( stripTrailingNumber, String, ( const char* str ),,
|
|||
return String::GetTrailingNumber( str, suffix );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( getFirstNumber, String, ( const char* str ),,
|
||||
"Get the first occuring number from @a str.\n"
|
||||
"@param str The string from which to read out the first number.\n"
|
||||
"@return String representation of the number or "" if no number.\n\n")
|
||||
{
|
||||
U32 start;
|
||||
U32 end;
|
||||
return String::GetFirstNumber(str, start, end);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( isspace, bool, ( const char* str, S32 index ),,
|
||||
|
|
@ -811,6 +1016,110 @@ DefineConsoleFunction( strrchrpos, S32, ( const char* str, const char* chr, S32
|
|||
return index;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( strToggleCaseToWords, const char*, ( const char* str ),,
|
||||
"Parse a Toggle Case word into separate words.\n"
|
||||
"@param str The string to parse.\n"
|
||||
"@return new string space separated.\n\n"
|
||||
"@tsexample\n"
|
||||
"strToggleCaseToWords( \"HelloWorld\" ) // Returns \"Hello World\".\n"
|
||||
"@endtsexample\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
String newStr;
|
||||
for(S32 i = 0; str[i]; i++)
|
||||
{
|
||||
//If capitol add a space
|
||||
if(i != 0 && str[i] >= 65 && str[i] <= 90)
|
||||
newStr += " ";
|
||||
|
||||
newStr += str[i];
|
||||
}
|
||||
|
||||
return Con::getReturnBuffer(newStr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Warning: isInt and isFloat are very 'strict' and might need to be adjusted to allow other values. //seanmc
|
||||
DefineConsoleFunction( isInt, bool, ( const char* str),,
|
||||
"Returns true if the string is an integer.\n"
|
||||
"@param str The string to test.\n"
|
||||
"@return true if @a str is an integer and false if not\n\n"
|
||||
"@tsexample\n"
|
||||
"isInt( \"13\" ) // Returns true.\n"
|
||||
"@endtsexample\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
return isInt(str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( isFloat, bool, ( const char* str, bool sciOk), (false),
|
||||
"Returns true if the string is a float.\n"
|
||||
"@param str The string to test.\n"
|
||||
"@param sciOk Test for correct scientific notation and accept it (ex. 1.2e+14)"
|
||||
"@return true if @a str is a float and false if not\n\n"
|
||||
"@tsexample\n"
|
||||
"isFloat( \"13.5\" ) // Returns true.\n"
|
||||
"@endtsexample\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
return isFloat(str, sciOk);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( isValidPort, bool, ( const char* str),,
|
||||
"Returns true if the string is a valid port number.\n"
|
||||
"@param str The string to test.\n"
|
||||
"@return true if @a str is a port and false if not\n\n"
|
||||
"@tsexample\n"
|
||||
"isValidPort( \"8080\" ) // Returns true.\n"
|
||||
"@endtsexample\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
if(isInt(str))
|
||||
{
|
||||
U16 port = dAtous(str);
|
||||
return isValidPort(port);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( isValidIP, bool, ( const char* str),,
|
||||
"Returns true if the string is a valid ip address, excepts localhost.\n"
|
||||
"@param str The string to test.\n"
|
||||
"@return true if @a str is a valid ip address and false if not\n\n"
|
||||
"@tsexample\n"
|
||||
"isValidIP( \"localhost\" ) // Returns true.\n"
|
||||
"@endtsexample\n"
|
||||
"@ingroup Strings" )
|
||||
{
|
||||
if(dStrcmp(str, "localhost") == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return isValidIP(str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Torque won't normally add another string if it already exists with another casing,
|
||||
// so this forces the addition. It should be called once near the start, such as in main.cs.
|
||||
ConsoleFunction(addCaseSensitiveStrings,void,2,0,"[string1, string2, ...]"
|
||||
"Adds case sensitive strings to the StringTable.")
|
||||
{
|
||||
for(int i = 1; i < argc; i++)
|
||||
StringTable->insert(argv[i], true);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Field Manipulators.
|
||||
//=============================================================================
|
||||
|
|
@ -829,6 +1138,7 @@ DefineConsoleFunction( getWord, const char*, ( const char* text, S32 index ),,
|
|||
"@endtsexample\n\n"
|
||||
"@see getWords\n"
|
||||
"@see getWordCount\n"
|
||||
"@see getToken\n"
|
||||
"@see getField\n"
|
||||
"@see getRecord\n"
|
||||
"@ingroup FieldManip" )
|
||||
|
|
@ -852,6 +1162,7 @@ DefineConsoleFunction( getWords, const char*, ( const char* text, S32 startIndex
|
|||
"@endtsexample\n\n"
|
||||
"@see getWord\n"
|
||||
"@see getWordCount\n"
|
||||
"@see getTokens\n"
|
||||
"@see getFields\n"
|
||||
"@see getRecords\n"
|
||||
"@ingroup FieldManip" )
|
||||
|
|
@ -876,6 +1187,7 @@ DefineConsoleFunction( setWord, const char*, ( const char* text, S32 index, cons
|
|||
"setWord( \"a b c d\", 2, \"f\" ) // Returns \"a b f d\"\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see getWord\n"
|
||||
"@see setToken\n"
|
||||
"@see setField\n"
|
||||
"@see setRecord\n"
|
||||
"@ingroup FieldManip" )
|
||||
|
|
@ -895,6 +1207,7 @@ DefineConsoleFunction( removeWord, const char*, ( const char* text, S32 index ),
|
|||
"@tsexample\n"
|
||||
"removeWord( \"a b c d\", 2 ) // Returns \"a b d\"\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see removeToken\n"
|
||||
"@see removeField\n"
|
||||
"@see removeRecord\n"
|
||||
"@ingroup FieldManip" )
|
||||
|
|
@ -912,6 +1225,7 @@ DefineConsoleFunction( getWordCount, S32, ( const char* text ),,
|
|||
"@tsexample\n"
|
||||
"getWordCount( \"a b c d e\" ) // Returns 5\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see getTokenCount\n"
|
||||
"@see getFieldCount\n"
|
||||
"@see getRecordCount\n"
|
||||
"@ingroup FieldManip" )
|
||||
|
|
@ -921,6 +1235,49 @@ DefineConsoleFunction( getWordCount, S32, ( const char* text ),,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineFunction( monthNumToStr, String, ( S32 num, bool abbreviate ), (false),
|
||||
"@brief returns month as a word given a number or \"\" if number is bad"
|
||||
"@return month as a word given a number or \"\" if number is bad"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
switch(num)
|
||||
{
|
||||
case 1: return abbreviate ? "Jan" : "January"; break;
|
||||
case 2: return abbreviate ? "Feb" : "February"; break;
|
||||
case 3: return abbreviate ? "Mar" : "March"; break;
|
||||
case 4: return abbreviate ? "Apr" : "April"; break;
|
||||
case 5: return "May"; break;
|
||||
case 6: return abbreviate ? "Jun" : "June"; break;
|
||||
case 7: return abbreviate ? "Jul" : "July"; break;
|
||||
case 8: return abbreviate ? "Aug" : "August"; break;
|
||||
case 9: return abbreviate ? "Sep" : "September"; break;
|
||||
case 10: return abbreviate ? "Oct" : "October"; break;
|
||||
case 11: return abbreviate ? "Nov" : "November"; break;
|
||||
case 12: return abbreviate ? "Dec" : "December"; break;
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
DefineEngineFunction( weekdayNumToStr, String, ( S32 num, bool abbreviate ), (false),
|
||||
"@brief returns weekday as a word given a number or \"\" if number is bad"
|
||||
"@return weekday as a word given a number or \"\" if number is bad"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
switch(num)
|
||||
{
|
||||
case 0: return abbreviate ? "Sun" : "Sunday"; break;
|
||||
case 1: return abbreviate ? "Mon" : "Monday"; break;
|
||||
case 2: return abbreviate ? "Tue" : "Tuesday"; break;
|
||||
case 3: return abbreviate ? "Wed" : "Wednesday"; break;
|
||||
case 4: return abbreviate ? "Thu" : "Thursday"; break;
|
||||
case 5: return abbreviate ? "Fri" : "Friday"; break;
|
||||
case 6: return abbreviate ? "Sat" : "Saturday"; break;
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( getField, const char*, ( const char* text, S32 index ),,
|
||||
"Extract the field at the given @a index in the newline and/or tab separated list in @a text.\n"
|
||||
"Fields in @a text must be separated by newlines and/or tabs.\n"
|
||||
|
|
@ -1242,6 +1599,114 @@ DefineConsoleFunction( nextToken, const char*, ( const char* str1, const char* t
|
|||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( getToken, const char*, ( const char* text, const char* delimiters, S32 index ),,
|
||||
"Extract the substring at the given @a index in the @a delimiters separated list in @a text.\n"
|
||||
"@param text A @a delimiters list of substrings.\n"
|
||||
"@param delimiters Character or characters that separate the list of substrings in @a text.\n"
|
||||
"@param index The zero-based index of the substring to extract.\n"
|
||||
"@return The substring at the given index or \"\" if the index is out of range.\n\n"
|
||||
"@tsexample\n"
|
||||
"getToken( \"a b c d\", \" \", 2 ) // Returns \"c\"\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see getTokens\n"
|
||||
"@see getTokenCount\n"
|
||||
"@see getWord\n"
|
||||
"@see getField\n"
|
||||
"@see getRecord\n"
|
||||
"@ingroup FieldManip" )
|
||||
{
|
||||
return Con::getReturnBuffer( StringUnit::getUnit(text, index, delimiters));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( getTokens, const char*, ( const char* text, const char* delimiters, S32 startIndex, S32 endIndex ), ( -1 ),
|
||||
"Extract a range of substrings separated by @a delimiters at the given @a startIndex onwards thru @a endIndex.\n"
|
||||
"@param text A @a delimiters list of substrings.\n"
|
||||
"@param delimiters Character or characters that separate the list of substrings in @a text.\n"
|
||||
"@param startIndex The zero-based index of the first substring to extract from @a text.\n"
|
||||
"@param endIndex The zero-based index of the last substring to extract from @a text. If this is -1, all words beginning "
|
||||
"with @a startIndex are extracted from @a text.\n"
|
||||
"@return A string containing the specified range of substrings from @a text or \"\" if @a startIndex "
|
||||
"is out of range or greater than @a endIndex.\n\n"
|
||||
"@tsexample\n"
|
||||
"getTokens( \"a b c d\", \" \", 1, 2, ) // Returns \"b c\"\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see getToken\n"
|
||||
"@see getTokenCount\n"
|
||||
"@see getWords\n"
|
||||
"@see getFields\n"
|
||||
"@see getRecords\n"
|
||||
"@ingroup FieldManip" )
|
||||
{
|
||||
if( endIndex < 0 )
|
||||
endIndex = 1000000;
|
||||
|
||||
return Con::getReturnBuffer( StringUnit::getUnits( text, startIndex, endIndex, delimiters ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( setToken, const char*, ( const char* text, const char* delimiters, S32 index, const char* replacement ),,
|
||||
"Replace the substring in @a text separated by @a delimiters at the given @a index with @a replacement.\n"
|
||||
"@param text A @a delimiters list of substrings.\n"
|
||||
"@param delimiters Character or characters that separate the list of substrings in @a text.\n"
|
||||
"@param index The zero-based index of the substring to replace.\n"
|
||||
"@param replacement The string with which to replace the substring.\n"
|
||||
"@return A new string with the substring at the given @a index replaced by @a replacement or the original "
|
||||
"string if @a index is out of range.\n\n"
|
||||
"@tsexample\n"
|
||||
"setToken( \"a b c d\", \" \", 2, \"f\" ) // Returns \"a b f d\"\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see getToken\n"
|
||||
"@see setWord\n"
|
||||
"@see setField\n"
|
||||
"@see setRecord\n"
|
||||
"@ingroup FieldManip" )
|
||||
{
|
||||
return Con::getReturnBuffer( StringUnit::setUnit( text, index, replacement, delimiters) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( removeToken, const char*, ( const char* text, const char* delimiters, S32 index ),,
|
||||
"Remove the substring in @a text separated by @a delimiters at the given @a index.\n"
|
||||
"@param text A @a delimiters list of substrings.\n"
|
||||
"@param delimiters Character or characters that separate the list of substrings in @a text.\n"
|
||||
"@param index The zero-based index of the word in @a text.\n"
|
||||
"@return A new string with the substring at the given index removed or the original string if @a index is "
|
||||
"out of range.\n\n"
|
||||
"@tsexample\n"
|
||||
"removeToken( \"a b c d\", \" \", 2 ) // Returns \"a b d\"\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see removeWord\n"
|
||||
"@see removeField\n"
|
||||
"@see removeRecord\n"
|
||||
"@ingroup FieldManip" )
|
||||
{
|
||||
return Con::getReturnBuffer( StringUnit::removeUnit( text, index, delimiters ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( getTokenCount, S32, ( const char* text, const char* delimiters),,
|
||||
"Return the number of @a delimiters substrings in @a text.\n"
|
||||
"@param text A @a delimiters list of substrings.\n"
|
||||
"@param delimiters Character or characters that separate the list of substrings in @a text.\n"
|
||||
"@return The number of @a delimiters substrings in @a text.\n\n"
|
||||
"@tsexample\n"
|
||||
"getTokenCount( \"a b c d e\", \" \" ) // Returns 5\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see getWordCount\n"
|
||||
"@see getFieldCount\n"
|
||||
"@see getRecordCount\n"
|
||||
"@ingroup FieldManip" )
|
||||
{
|
||||
return StringUnit::getUnitCount( text, delimiters );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Tagged Strings.
|
||||
//=============================================================================
|
||||
|
|
@ -2597,3 +3062,10 @@ DefineEngineFunction( isToolBuild, bool, (),,
|
|||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
DefineEngineFunction( getMaxDynamicVerts, S32, (),,
|
||||
"Get max number of allowable dynamic vertices in a single vertex buffer.\n\n"
|
||||
"@return the max number of allowable dynamic vertices in a single vertex buffer" )
|
||||
{
|
||||
return MAX_DYNAMIC_VERTS / 2;
|
||||
}
|
||||
16
Engine/source/console/consoleFunctions.h
Normal file
16
Engine/source/console/consoleFunctions.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _CONSOLFUNCTIONS_H_
|
||||
#define _CONSOLFUNCTIONS_H_
|
||||
|
||||
#ifndef _STRINGFUNCTIONS_H_
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#endif
|
||||
|
||||
bool isInt(const char* str);
|
||||
|
||||
bool isFloat(const char* str);
|
||||
|
||||
bool isValidIP(const char* ip);
|
||||
|
||||
bool isValidPort(U16 port);
|
||||
|
||||
#endif
|
||||
|
|
@ -152,11 +152,20 @@ inline U32 dAtoui(const char *str, U32 base = 10)
|
|||
return strtoul(str, NULL, base);
|
||||
}
|
||||
|
||||
inline U16 dAtous(const char *str, U32 base = 10)
|
||||
{
|
||||
return strtoul(str, NULL, base);
|
||||
}
|
||||
|
||||
inline F32 dAtof(const char *str)
|
||||
{
|
||||
return strtof(str, NULL);
|
||||
}
|
||||
|
||||
inline F64 dAtod(const char *str)
|
||||
{
|
||||
return strtod(str, NULL);
|
||||
}
|
||||
|
||||
inline char dToupper(const char c)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1628,3 +1628,103 @@ String String::GetTrailingNumber(const char* str, S32& number)
|
|||
|
||||
return base.substr(0, p - base.c_str());
|
||||
}
|
||||
|
||||
String String::GetFirstNumber(const char* str, U32& startPos, U32& endPos)
|
||||
{
|
||||
// Check for trivial strings
|
||||
if (!str || !str[0])
|
||||
return String::EmptyString;
|
||||
|
||||
// Find the number at the end of the string
|
||||
String base(str);
|
||||
const char* p = base.c_str();
|
||||
const char* end = base.c_str() + base.length() - 1;
|
||||
bool dec = false;
|
||||
startPos = 0;
|
||||
|
||||
//Check if we are just a digit
|
||||
if(p == end && isdigit(*p))
|
||||
return base;
|
||||
|
||||
//Look for the first digit
|
||||
while ((p != end) && (dIsspace(*p) || !isdigit(*p)))
|
||||
{
|
||||
p++;
|
||||
startPos++;
|
||||
}
|
||||
|
||||
//Handle if we are at the end and found nothing
|
||||
if(p == end && !isdigit(*p))
|
||||
return "";
|
||||
|
||||
//update our end position at least to the start of our number
|
||||
endPos = startPos;
|
||||
|
||||
//Backup our ptr
|
||||
const char* backup = p;
|
||||
|
||||
//Check for any negative or decimal values
|
||||
if(startPos > 0)
|
||||
{
|
||||
p--;
|
||||
startPos--;
|
||||
if(*p == '.')
|
||||
{
|
||||
dec = true;
|
||||
|
||||
//ignore any duplicate periods
|
||||
while ((p != base.c_str()) && (*p == '.'))
|
||||
{
|
||||
p--;
|
||||
startPos--;
|
||||
}
|
||||
|
||||
//Found a decimal lets still check for negative sign
|
||||
if(startPos > 0)
|
||||
{
|
||||
p--;
|
||||
startPos--;
|
||||
if((*p != '-') && (*p != '_'))
|
||||
{
|
||||
startPos++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((*p != '-') && (*p != '_'))
|
||||
{
|
||||
//go back to where we where cause no decimal or negative sign found
|
||||
startPos++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
//Restore where we were
|
||||
p = backup;
|
||||
|
||||
//look for the end of the digits
|
||||
bool justFoundDec = false;
|
||||
while (p != end)
|
||||
{
|
||||
if(*p == '.')
|
||||
{
|
||||
if(dec && !justFoundDec)
|
||||
break;
|
||||
else
|
||||
{
|
||||
dec = true;
|
||||
justFoundDec = true;
|
||||
}
|
||||
}
|
||||
else if(!isdigit(*p))
|
||||
break;
|
||||
else if(justFoundDec)
|
||||
justFoundDec = false;
|
||||
|
||||
p++;
|
||||
endPos++;
|
||||
}
|
||||
|
||||
U32 len = (!isdigit(*p)) ? endPos - startPos : (endPos + 1) - startPos;
|
||||
return base.substr(startPos, len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ public:
|
|||
static String ToUpper(const String &string);
|
||||
|
||||
static String GetTrailingNumber(const char* str, S32& number);
|
||||
static String GetFirstNumber(const char* str, U32& startPos, U32& endPos);
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -660,6 +660,66 @@ DefineConsoleFunction( VectorScale, VectorF, ( VectorF a, F32 scalar ),,
|
|||
{
|
||||
return a * scalar;
|
||||
}
|
||||
DefineConsoleFunction( VectorMul, VectorF, ( VectorF a, VectorF b ),,
|
||||
"Multiplies two vectors.\n"
|
||||
"@param a The first vector.\n"
|
||||
"@param b The second vector.\n"
|
||||
"@return The vector @a a * @a b.\n\n"
|
||||
"@tsexample\n"
|
||||
"//-----------------------------------------------------------------------------\n"
|
||||
"//\n"
|
||||
"// VectorMul( %a, %b );\n"
|
||||
"//\n"
|
||||
"// The multiplication of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
|
||||
"//\n"
|
||||
"// a * b = ( ax * bx, ay * by, az * bz )\n"
|
||||
"//\n"
|
||||
"//-----------------------------------------------------------------------------\n\n"
|
||||
|
||||
"%a = \"1 0 0\";\n"
|
||||
"%b = \"0 1 0\";\n\n"
|
||||
|
||||
"// %r = \"( 1 * 0, 0 * 1, 0 * 0 )\";\n"
|
||||
"// %r = \"0 0 0\";\n"
|
||||
"%r = VectorMul( %a, %b );\n"
|
||||
"@endtsexample\n\n"
|
||||
"@ingroup Vectors" )
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
DefineConsoleFunction( VectorDiv, VectorF, ( VectorF a, VectorF b ),,
|
||||
"Divide two vectors.\n"
|
||||
"@param a The first vector.\n"
|
||||
"@param b The second vector.\n"
|
||||
"@return The vector @a a / @a b.\n\n"
|
||||
"@tsexample\n"
|
||||
"//-----------------------------------------------------------------------------\n"
|
||||
"//\n"
|
||||
"// VectorDiv( %a, %b );\n"
|
||||
"//\n"
|
||||
"// The division of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
|
||||
"//\n"
|
||||
"// a * b = ( ax / bx, ay / by, az / bz )\n"
|
||||
"//\n"
|
||||
"//-----------------------------------------------------------------------------\n\n"
|
||||
|
||||
"%a = \"1 1 1\";\n"
|
||||
"%b = \"2 2 2\";\n\n"
|
||||
|
||||
"// %r = \"( 1 / 2, 1 / 2, 1 / 2 )\";\n"
|
||||
"// %r = \"0.5 0.5 0.5\";\n"
|
||||
"%r = VectorDiv( %a, %b );\n"
|
||||
"@endtsexample\n\n"
|
||||
"@ingroup Vectors" )
|
||||
{
|
||||
//this is kind of bad, but so is dividing by 0
|
||||
if(b.x == 0) b.x = 0.000001f;
|
||||
if(b.y == 0) b.y = 0.000001f;
|
||||
if(b.z == 0) b.z = 0.000001f;
|
||||
|
||||
return a / b;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -790,6 +850,34 @@ DefineConsoleFunction( VectorDist, F32, ( VectorF a, VectorF b ),,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( VectorMidPoint, VectorF, ( VectorF a, VectorF b ),,
|
||||
"Gets the midpoint between the two vectors.\n"
|
||||
"@param a The first vector.\n"
|
||||
"@param b The second vector.\n"
|
||||
"@return The vector (@a a + @a b) / 2.\n\n"
|
||||
"@tsexample\n"
|
||||
"//-----------------------------------------------------------------------------\n"
|
||||
"//\n"
|
||||
"// VectorMidPoint( %a, %b );\n"
|
||||
"//\n"
|
||||
"// The midpoint of vector a, (ax, ay, az), and vector b, (bx, by, bz) is:\n"
|
||||
"//\n"
|
||||
"// (a + b)/2 = ( (ax + bx) /2, ay + by) /2, (az + bz) /2 )\n"
|
||||
"//\n"
|
||||
"//-----------------------------------------------------------------------------\n"
|
||||
// "%a = \"1 0 0\";\n"
|
||||
// "%b = \"0 1 0\";\n\n"
|
||||
// "// %r = \"( 1 + 0, 0 + 1, 0 + 0 )\";\n"
|
||||
// "// %r = \"1 1 0\";\n"
|
||||
// "%r = VectorAdd( %a, %b );\n"
|
||||
"@endtsexample\n\n"
|
||||
"@ingroup Vectors")
|
||||
{
|
||||
return (a + b)/2.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineConsoleFunction( VectorLen, F32, ( VectorF v ),,
|
||||
"Calculate the magnitude of the given vector.\n"
|
||||
"@param v A vector.\n"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue