mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-19 19:35:26 +00:00
Merge branch 'development' into style-cleanup
Conflicts: Engine/source/console/astNodes.cpp Engine/source/console/codeBlock.cpp Engine/source/console/compiledEval.cpp Engine/source/ts/collada/colladaAppMesh.cpp Engine/source/ts/tsShape.cpp Engine/source/ts/tsShapeConstruct.cpp
This commit is contained in:
commit
33ff180593
2053 changed files with 172002 additions and 69530 deletions
|
|
@ -38,3 +38,507 @@ const ColorI ColorI::BLACK( 0, 0, 0 );
|
|||
const ColorI ColorI::RED( 255, 0, 0 );
|
||||
const ColorI ColorI::GREEN( 0, 255, 0 );
|
||||
const ColorI ColorI::BLUE( 0, 0, 255 );
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
#ifndef _STRINGUNIT_H_
|
||||
#include "core/strings/stringUnit.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
|
||||
#include "console/consoleInternal.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef HashTable<StringTableEntry, ColorF> typeNameToColorFHash;
|
||||
typedef HashTable<StringTableEntry, ColorI> typeNameToColorIHash;
|
||||
typedef HashTable<ColorF, StringTableEntry> typeColorFToNameHash;
|
||||
typedef HashTable<ColorI, StringTableEntry> typeColorIToNameHash;
|
||||
|
||||
static typeNameToColorFHash mNameToColorF;
|
||||
static typeNameToColorIHash mNameToColorI;
|
||||
static typeColorFToNameHash mColorFToName;
|
||||
static typeColorIToNameHash mColorIToName;
|
||||
|
||||
#define DEFAULT_UNKNOWN_STOCK_COLOR_NAME "White"
|
||||
|
||||
MODULE_BEGIN( StockColors )
|
||||
|
||||
MODULE_INIT_AFTER( GFX )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
// Create the stock colors.
|
||||
StockColor::create();
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
// Destroy the stock colors.
|
||||
StockColor::destroy();
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StockColorItem StockColorTable[] =
|
||||
{
|
||||
StockColorItem( "InvisibleBlack", 0, 0, 0, 0 ),
|
||||
StockColorItem( "TransparentWhite", 255, 255, 255, 0 ),
|
||||
StockColorItem( "AliceBlue", 240, 248, 255 ),
|
||||
StockColorItem( "AntiqueWhite", 250, 235, 215 ),
|
||||
StockColorItem( "Aqua", 0, 255, 255 ),
|
||||
StockColorItem( "Aquamarine", 127, 255, 212 ),
|
||||
StockColorItem( "Azure", 240, 255, 255 ),
|
||||
StockColorItem( "Beige", 245, 245, 220 ),
|
||||
StockColorItem( "Bisque", 255, 228, 196 ),
|
||||
StockColorItem( "Black", 0, 0, 0, 255 ),
|
||||
StockColorItem( "BlanchedAlmond", 255, 235, 205, 255 ),
|
||||
StockColorItem( "Blue", 0, 0, 255 ),
|
||||
StockColorItem( "BlueViolet", 138, 43, 226 ),
|
||||
StockColorItem( "Brown", 165, 42, 42, 255 ),
|
||||
StockColorItem( "BurlyWood", 222, 184, 135 ),
|
||||
StockColorItem( "CadetBlue", 95, 158, 160 ),
|
||||
StockColorItem( "Chartreuse", 127, 255, 0 ),
|
||||
StockColorItem( "Chocolate", 210, 105, 30 ),
|
||||
StockColorItem( "Coral", 255, 127, 80 ),
|
||||
StockColorItem( "CornflowerBlue", 100, 149, 237 ),
|
||||
StockColorItem( "Cornsilk", 255, 248, 220 ),
|
||||
StockColorItem( "Crimson", 220, 20, 60 ),
|
||||
StockColorItem( "Cyan", 0, 255, 255 ),
|
||||
StockColorItem( "DarkBlue", 0, 0, 139 ),
|
||||
StockColorItem( "DarkCyan", 0, 139, 139 ),
|
||||
StockColorItem( "DarkGoldenrod", 184, 134, 11 ),
|
||||
StockColorItem( "DarkGray", 169, 169, 169),
|
||||
StockColorItem( "DarkGreen", 0, 100, 0 ),
|
||||
StockColorItem( "DarkKhaki", 189, 183, 107 ),
|
||||
StockColorItem( "DarkMagenta", 139, 0, 139 ),
|
||||
StockColorItem( "DarkOliveGreen", 85, 107, 47 ),
|
||||
StockColorItem( "DarkOrange", 255, 140, 0 ),
|
||||
StockColorItem( "DarkOrchid", 153, 50, 204 ),
|
||||
StockColorItem( "DarkRed", 139, 0, 0 ),
|
||||
StockColorItem( "DarkSalmon", 233, 150, 122 ),
|
||||
StockColorItem( "DarkSeaGreen", 143, 188, 139 ),
|
||||
StockColorItem( "DarkSlateBlue", 72, 61, 139 ),
|
||||
StockColorItem( "DarkSlateGray", 47, 79, 79 ),
|
||||
StockColorItem( "DarkTurquoise", 0, 206, 209 ),
|
||||
StockColorItem( "DarkViolet", 148, 0, 211 ),
|
||||
StockColorItem( "DeepPink", 255, 20, 147 ),
|
||||
StockColorItem( "DeepSkyBlue", 0, 191, 255 ),
|
||||
StockColorItem( "DimGray", 105, 105, 105 ),
|
||||
StockColorItem( "DodgerBlue", 30, 144, 255 ),
|
||||
StockColorItem( "Firebrick", 178, 34, 34 ),
|
||||
StockColorItem( "FloralWhite", 255, 250, 240 ),
|
||||
StockColorItem( "ForestGreen", 34, 139, 34 ),
|
||||
StockColorItem( "Fuchsia", 255, 0, 255 ),
|
||||
StockColorItem( "Gainsboro", 220, 220, 220 ),
|
||||
StockColorItem( "GhostWhite", 248, 248, 255 ),
|
||||
StockColorItem( "Gold", 255, 215, 0 ),
|
||||
StockColorItem( "Goldenrod", 218, 165, 32 ),
|
||||
StockColorItem( "Gray", 128, 128, 128 ),
|
||||
StockColorItem( "Green", 0, 128, 0 ),
|
||||
StockColorItem( "GreenYellow", 173, 255, 47 ),
|
||||
StockColorItem( "Honeydew", 240, 255, 24 ),
|
||||
StockColorItem( "HotPink", 255, 105, 180 ),
|
||||
StockColorItem( "IndianRed", 205, 92, 92 ),
|
||||
StockColorItem( "Indigo", 75, 0, 130 ),
|
||||
StockColorItem( "Ivory", 255, 255, 240 ),
|
||||
StockColorItem( "Khaki", 240, 230, 140 ),
|
||||
StockColorItem( "Lavender", 230, 230, 250 ),
|
||||
StockColorItem( "LavenderBlush", 255, 240, 245 ),
|
||||
StockColorItem( "LawnGreen", 124, 252, 0 ),
|
||||
StockColorItem( "LemonChiffon", 255, 250, 205 ),
|
||||
StockColorItem( "LightBlue", 173, 216, 230 ),
|
||||
StockColorItem( "LightCoral", 240, 128, 128 ),
|
||||
StockColorItem( "LightCyan", 224, 255, 255),
|
||||
StockColorItem( "LightGoldenrodYellow", 250, 250, 210 ),
|
||||
StockColorItem( "LightGray", 211, 211, 211),
|
||||
StockColorItem( "LightGreen", 144, 238, 144 ),
|
||||
StockColorItem( "LightPink", 255, 182, 193 ),
|
||||
StockColorItem( "LightSalmon", 255, 160, 122 ),
|
||||
StockColorItem( "LightSeaGreen", 32, 178, 170 ),
|
||||
StockColorItem( "LightSkyBlue",135, 206, 250 ),
|
||||
StockColorItem( "LightSlateGray", 119, 136, 153 ),
|
||||
StockColorItem( "LightSteelBlue", 176, 196, 222 ),
|
||||
StockColorItem( "LightYellow", 255, 255, 224 ),
|
||||
StockColorItem( "Lime", 0, 255, 0 ),
|
||||
StockColorItem( "LimeGreen", 50, 205, 50 ),
|
||||
StockColorItem( "Linen", 250, 240, 230 ),
|
||||
StockColorItem( "Magenta", 255, 0, 255 ),
|
||||
StockColorItem( "Maroon", 128, 0, 0 ),
|
||||
StockColorItem( "MediumAquamarine", 102, 205, 170 ),
|
||||
StockColorItem( "MediumBlue", 0, 0, 205 ),
|
||||
StockColorItem( "MediumOrchid", 186, 85, 211 ),
|
||||
StockColorItem( "MediumPurple", 147, 112, 219 ),
|
||||
StockColorItem( "MediumSeaGreen", 60, 179, 113 ),
|
||||
StockColorItem( "MediumSlateBlue", 123, 104, 238 ),
|
||||
StockColorItem( "MediumSpringGreen", 0, 250, 154 ),
|
||||
StockColorItem( "MediumTurquoise", 72, 209, 204 ),
|
||||
StockColorItem( "MediumVioletRed", 199, 21, 133 ),
|
||||
StockColorItem( "MidnightBlue", 25, 25, 112 ),
|
||||
StockColorItem( "MintCream", 245, 255, 250 ),
|
||||
StockColorItem( "MistyRose", 255, 228, 225 ),
|
||||
StockColorItem( "Moccasin", 255, 228, 181 ),
|
||||
StockColorItem( "NavajoWhite", 255, 222, 173 ),
|
||||
StockColorItem( "Navy", 0, 0, 128 ),
|
||||
StockColorItem( "OldLace", 253, 245, 230 ),
|
||||
StockColorItem( "Olive", 128, 128, 0 ),
|
||||
StockColorItem( "OliveDrab", 107, 142, 35 ),
|
||||
StockColorItem( "Orange", 255, 165, 0 ),
|
||||
StockColorItem( "OrangeRed", 255, 69, 0 ),
|
||||
StockColorItem( "Orchid", 218, 112, 214 ),
|
||||
StockColorItem( "PaleGoldenrod", 238, 232, 170 ),
|
||||
StockColorItem( "PaleGreen", 152, 251, 152 ),
|
||||
StockColorItem( "PaleTurquoise", 175, 238, 238 ),
|
||||
StockColorItem( "PaleVioletRed", 219, 112, 147 ),
|
||||
StockColorItem( "PapayaWhip", 255, 239, 213 ),
|
||||
StockColorItem( "PeachPuff", 255, 218, 185 ),
|
||||
StockColorItem( "Peru", 205, 133, 63 ),
|
||||
StockColorItem( "Pink", 55, 192, 203 ),
|
||||
StockColorItem( "Plum", 221, 160, 221 ),
|
||||
StockColorItem( "PowderBlue", 176, 224, 230 ),
|
||||
StockColorItem( "Purple", 128, 0, 128 ),
|
||||
StockColorItem( "Red", 255, 0, 0 ),
|
||||
StockColorItem( "RosyBrown", 188, 143, 143 ),
|
||||
StockColorItem( "RoyalBlue", 65, 105, 225 ),
|
||||
StockColorItem( "SaddleBrown", 139, 69, 19 ),
|
||||
StockColorItem( "Salmon", 250, 128, 114 ),
|
||||
StockColorItem( "SandyBrown", 244, 164, 96 ),
|
||||
StockColorItem( "SeaGreen", 46, 139, 87 ),
|
||||
StockColorItem( "SeaShell", 255, 245, 238 ),
|
||||
StockColorItem( "Sienna", 160, 82, 45 ),
|
||||
StockColorItem( "Silver", 192, 192, 192 ),
|
||||
StockColorItem( "SkyBlue", 135, 206, 235 ),
|
||||
StockColorItem( "SlateBlue", 106, 90, 205 ),
|
||||
StockColorItem( "SlateGray", 112, 128, 144 ),
|
||||
StockColorItem( "Snow", 255, 250, 250 ),
|
||||
StockColorItem( "SpringGreen", 0, 255, 127 ),
|
||||
StockColorItem( "SteelBlue", 70, 130, 180 ),
|
||||
StockColorItem( "Tan", 210, 180, 140 ),
|
||||
StockColorItem( "Teal", 0, 128, 128 ),
|
||||
StockColorItem( "Thistle", 216, 191, 216 ),
|
||||
StockColorItem( "Tomato", 255, 99, 71 ),
|
||||
StockColorItem( "Turquoise", 64, 224, 208 ),
|
||||
StockColorItem( "Violet", 238, 130, 238 ),
|
||||
StockColorItem( "Wheat", 245, 222, 179 ),
|
||||
StockColorItem( "White", 255, 255, 255 ),
|
||||
StockColorItem( "WhiteSmoke", 245, 245, 245 ),
|
||||
StockColorItem( "Yellow", 255, 255, 0 ),
|
||||
StockColorItem( "YellowGreen", 154, 205, 50 )
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static bool stockColorsCreated = false;
|
||||
|
||||
void StockColor::create( void )
|
||||
{
|
||||
// Finish if already created.
|
||||
if ( stockColorsCreated )
|
||||
return;
|
||||
|
||||
// Fetch stock color count.
|
||||
const S32 stockColorCount = sizeof(StockColorTable) / sizeof(StockColorItem);
|
||||
|
||||
// Insert all stock colors.
|
||||
for( S32 index = 0; index < stockColorCount; ++index )
|
||||
{
|
||||
// Fetch stock color item.
|
||||
StockColorItem& stockColor = StockColorTable[index];
|
||||
|
||||
// Fetch stock color item.
|
||||
StringTableEntry colorName = StringTable->insert( stockColor.mColorName );
|
||||
|
||||
// Insert stock color mappings.
|
||||
mNameToColorF.insertUnique(colorName, stockColor.mColorF);
|
||||
mNameToColorI.insertUnique(colorName, stockColor.mColorI);
|
||||
mColorFToName.insertUnique(stockColor.mColorF, colorName);
|
||||
mColorIToName.insertUnique(stockColor.mColorI, colorName);
|
||||
}
|
||||
|
||||
// Flag as created.
|
||||
stockColorsCreated = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void StockColor::destroy( void )
|
||||
{
|
||||
// Finish if not created.
|
||||
if ( !stockColorsCreated )
|
||||
return;
|
||||
|
||||
// Clear stock color mappings.
|
||||
mNameToColorF.clear();
|
||||
mNameToColorI.clear();
|
||||
mColorFToName.clear();
|
||||
mColorIToName.clear();
|
||||
|
||||
// Flag as not created.
|
||||
stockColorsCreated = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool StockColor::isColor( const char* pStockColorName )
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal( pStockColorName != NULL, "Cannot fetch a NULL stock color name." );
|
||||
|
||||
// Fetch color name.
|
||||
StringTableEntry colorName = StringTable->insert( pStockColorName );
|
||||
|
||||
// Find if color name exists or not.
|
||||
return mNameToColorF.find( colorName ) != mNameToColorF.end();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const ColorF& StockColor::colorF( const char* pStockColorName )
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal( pStockColorName != NULL, "Cannot fetch a NULL stock color name." );
|
||||
|
||||
// Fetch color name.
|
||||
StringTableEntry colorName = StringTable->insert( pStockColorName );
|
||||
|
||||
// Find stock color.
|
||||
typeNameToColorFHash::Iterator colorItr = mNameToColorF.find( colorName );
|
||||
|
||||
// Return color if found.
|
||||
if ( colorItr != mNameToColorF.end() )
|
||||
return colorItr->value;
|
||||
|
||||
// Warn.
|
||||
Con::warnf( "Could not find stock color name '%s'.", pStockColorName );
|
||||
|
||||
// Return default stock color.
|
||||
return mNameToColorF.find( DEFAULT_UNKNOWN_STOCK_COLOR_NAME )->value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const ColorI& StockColor::colorI( const char* pStockColorName )
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal( pStockColorName != NULL, "Cannot fetch a NULL stock color name." );
|
||||
|
||||
// Fetch color name.
|
||||
StringTableEntry colorName = StringTable->insert( pStockColorName );
|
||||
|
||||
// Find stock color.
|
||||
typeNameToColorIHash::Iterator colorItr = mNameToColorI.find( colorName );
|
||||
|
||||
// Return color if found.
|
||||
if ( colorItr != mNameToColorI.end() )
|
||||
return colorItr->value;
|
||||
|
||||
// Warn.
|
||||
Con::warnf( "Could not find stock color name '%s'.", colorName );
|
||||
|
||||
// Return default stock color.
|
||||
return mNameToColorI.find( DEFAULT_UNKNOWN_STOCK_COLOR_NAME )->value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry StockColor::name( const ColorF& color )
|
||||
{
|
||||
// Find stock color name.
|
||||
typeColorFToNameHash::Iterator colorNameItr = mColorFToName.find( color );
|
||||
|
||||
// Return name if found.
|
||||
if ( colorNameItr != mColorFToName.end() )
|
||||
return colorNameItr->value;
|
||||
|
||||
// Return empty string.
|
||||
return StringTable->EmptyString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry StockColor::name( const ColorI& color )
|
||||
{
|
||||
// Find stock color name.
|
||||
typeColorIToNameHash::Iterator colorNameItr = mColorIToName.find( color );
|
||||
|
||||
// Return name if found.
|
||||
if ( colorNameItr != mColorIToName.end() )
|
||||
return colorNameItr->value;
|
||||
|
||||
// Return empty string.
|
||||
return StringTable->EmptyString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
S32 StockColor::getCount( void )
|
||||
{
|
||||
return sizeof(StockColorTable) / sizeof(StockColorItem);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const StockColorItem* StockColor::getColorItem( const S32 index )
|
||||
{
|
||||
// Fetch stock color count.
|
||||
const S32 stockColorCount = StockColor::getCount();
|
||||
|
||||
// Is the stock color index in range?
|
||||
if ( index < 0 || index >= stockColorCount )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf("StockColor::getName() - Specified color index '%d' is out of range. Range is 0 to %d.", index, stockColorCount-1 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return color name.
|
||||
return &(StockColorTable[index]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ColorF::ColorF( const char* pStockColorName )
|
||||
{
|
||||
// Set stock color.
|
||||
*this = StockColor::colorF( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ColorF::set( const char* pStockColorName )
|
||||
{
|
||||
// Set stock color.
|
||||
*this = StockColor::colorF( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const ColorF& ColorF::StockColor( const char* pStockColorName )
|
||||
{
|
||||
return StockColor::colorF( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry ColorF::StockColor( void )
|
||||
{
|
||||
// Return stock color name.
|
||||
return StockColor::name( *this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ColorI::ColorI( const char* pStockColorName )
|
||||
{
|
||||
// Set stock color.
|
||||
*this = StockColor::colorI( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ColorI::set( const char* pStockColorName )
|
||||
{
|
||||
// Set stock color.
|
||||
*this = StockColor::colorI( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const ColorI& ColorI::StockColor( const char* pStockColorName )
|
||||
{
|
||||
return StockColor::colorI( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry ColorI::StockColor( void )
|
||||
{
|
||||
// Return stock color name.
|
||||
return StockColor::name( *this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( getStockColorCount, S32, 1, 1, "() - Gets a count of available stock colors.\n"
|
||||
"@return A count of available stock colors." )
|
||||
{
|
||||
return StockColor::getCount();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( getStockColorName, const char*, 2, 2, "(stockColorIndex) - Gets the stock color name at the specified index.\n"
|
||||
"@param stockColorIndex The zero-based index of the stock color name to retrieve.\n"
|
||||
"@return The stock color name at the specified index or nothing if the string is invalid." )
|
||||
{
|
||||
// Fetch stock color index.
|
||||
const S32 stockColorIndex = dAtoi(argv[1]);
|
||||
|
||||
// Fetch the color item.
|
||||
const StockColorItem* pColorItem = StockColor::getColorItem( stockColorIndex );
|
||||
|
||||
return pColorItem == NULL ? NULL : pColorItem->getColorName();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( isStockColor, bool, 2, 2, "(stockColorName) - Gets whether the specified name is a stock color or not.\n"
|
||||
"@param stockColorName - The stock color name to test for.\n"
|
||||
"@return Whether the specified name is a stock color or not.\n" )
|
||||
{
|
||||
// Fetch stock color name.
|
||||
const char* pStockColorName = argv[1];
|
||||
|
||||
// Return whether this is a stock color name or not.
|
||||
return StockColor::isColor( pStockColorName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( getStockColorF, const char*, 2, 2, "(stockColorName) - Gets a floating-point-based stock color by name.\n"
|
||||
"@param stockColorName - The stock color name to retrieve.\n"
|
||||
"@return The stock color that matches the specified color name. Returns nothing if the color name is not found.\n" )
|
||||
{
|
||||
// Fetch stock color name.
|
||||
const char* pStockColorName = argv[1];
|
||||
|
||||
// Return nothing if stock color name is invalid.
|
||||
if ( !StockColor::isColor( pStockColorName ) )
|
||||
return StringTable->EmptyString();
|
||||
|
||||
// Fetch stock color.
|
||||
const ColorF& color = StockColor::colorF( pStockColorName );
|
||||
|
||||
// Format stock color.
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 256, "%g %g %g %g", color.red, color.green, color.blue, color.alpha);
|
||||
return(returnBuffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( getStockColorI, const char*, 2, 2, "(stockColorName) - Gets a byte-based stock color by name.\n"
|
||||
"@param stockColorName - The stock color name to retrieve.\n"
|
||||
"@return The stock color that matches the specified color name. Returns nothing if the color name is not found.\n" )
|
||||
{
|
||||
// Fetch stock color name.
|
||||
const char* pStockColorName = argv[1];
|
||||
|
||||
// Return nothing if stock color name is invalid.
|
||||
if ( !StockColor::isColor( pStockColorName ) )
|
||||
return StringTable->EmptyString();
|
||||
|
||||
// Fetch stock color.
|
||||
const ColorI& color = StockColor::colorI( pStockColorName );
|
||||
|
||||
// Format stock color.
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 256, "%d %d %d %d", color.red, color.green, color.blue, color.alpha);
|
||||
return(returnBuffer);
|
||||
}
|
||||
|
|
@ -49,11 +49,18 @@ class ColorF
|
|||
const F32 in_b,
|
||||
const F32 in_a = 1.0f);
|
||||
|
||||
ColorF( const char* pStockColorName );
|
||||
|
||||
void set(const F32 in_r,
|
||||
const F32 in_g,
|
||||
const F32 in_b,
|
||||
const F32 in_a = 1.0f);
|
||||
|
||||
void set( const char* pStockColorName );
|
||||
|
||||
static const ColorF& StockColor( const char* pStockColorName );
|
||||
StringTableEntry StockColor( void );
|
||||
|
||||
ColorF& operator*=(const ColorF& in_mul); // Can be useful for lighting
|
||||
ColorF operator*(const ColorF& in_mul) const;
|
||||
ColorF& operator+=(const ColorF& in_rAdd);
|
||||
|
|
@ -123,6 +130,8 @@ class ColorI
|
|||
const U8 in_a = U8(255));
|
||||
ColorI(const ColorI& in_rCopy, const U8 in_a);
|
||||
|
||||
ColorI( const char* pStockColorName );
|
||||
|
||||
void set(const U8 in_r,
|
||||
const U8 in_g,
|
||||
const U8 in_b,
|
||||
|
|
@ -131,6 +140,11 @@ class ColorI
|
|||
void set(const ColorI& in_rCopy,
|
||||
const U8 in_a);
|
||||
|
||||
void set( const char* pStockColorName );
|
||||
|
||||
static const ColorI& StockColor( const char* pStockColorName );
|
||||
StringTableEntry StockColor( void );
|
||||
|
||||
ColorI& operator*=(const F32 in_mul);
|
||||
ColorI operator*(const F32 in_mul) const;
|
||||
|
||||
|
|
@ -175,6 +189,53 @@ class ColorI
|
|||
static const ColorI BLUE;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class StockColorItem
|
||||
{
|
||||
private:
|
||||
StockColorItem() {}
|
||||
|
||||
public:
|
||||
StockColorItem( const char* pName, const U8 red, const U8 green, const U8 blue, const U8 alpha = 255 )
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal( pName != NULL, "Stock color name cannot be NULL." );
|
||||
|
||||
// Set stock color.
|
||||
// NOTE:- We'll use the char pointer here. We can yet use the string-table unfortunately.
|
||||
mColorName = pName;
|
||||
mColorI.set( red, green, blue, alpha );
|
||||
mColorF = mColorI;
|
||||
}
|
||||
|
||||
inline const char* getColorName( void ) const { return mColorName; }
|
||||
inline const ColorF& getColorF( void ) const { return mColorF; }
|
||||
inline const ColorI& getColorI( void ) const { return mColorI; }
|
||||
|
||||
const char* mColorName;
|
||||
ColorF mColorF;
|
||||
ColorI mColorI;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class StockColor
|
||||
{
|
||||
public:
|
||||
static bool isColor( const char* pStockColorName );
|
||||
static const ColorF& colorF( const char* pStockColorName );
|
||||
static const ColorI& colorI( const char* pStockColorName );
|
||||
static StringTableEntry name( const ColorF& color );
|
||||
static StringTableEntry name( const ColorI& color );
|
||||
|
||||
static S32 getCount( void );
|
||||
static const StockColorItem* getColorItem( const S32 index );
|
||||
|
||||
static void create( void );
|
||||
static void destroy( void );
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-------------------------------------- INLINES (ColorF)
|
||||
//
|
||||
|
|
|
|||
|
|
@ -343,8 +343,9 @@ DefineEngineMethod( FileObject, peekLine, const char*, (),,
|
|||
|
||||
"@return String containing the line of data that was just peeked\n")
|
||||
{
|
||||
char *line = Con::getReturnBuffer( 512 );
|
||||
object->peekLine( (U8*)line, 512 );
|
||||
static const U32 bufSize = 512;
|
||||
char *line = Con::getReturnBuffer( bufSize );
|
||||
object->peekLine( (U8*)line, bufSize );
|
||||
return line;
|
||||
}
|
||||
|
||||
|
|
@ -493,9 +494,9 @@ ConsoleMethod( FileObject, writeObject, void, 3, 4, "FileObject.writeObject(SimO
|
|||
return;
|
||||
}
|
||||
|
||||
char *objName = NULL;
|
||||
const char *objName = NULL;
|
||||
if( argc == 4 )
|
||||
objName = (char*)argv[3];
|
||||
objName = (const char*)argv[3];
|
||||
|
||||
object->writeObject( obj, (const U8*)objName );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,8 +113,9 @@ const char * StreamObject::readLine()
|
|||
if(mStream == NULL)
|
||||
return NULL;
|
||||
|
||||
char *buffer = Con::getReturnBuffer(256);
|
||||
mStream->readLine((U8 *)buffer, 256);
|
||||
static const U32 bufSize = 256;
|
||||
char *buffer = Con::getReturnBuffer(bufSize);
|
||||
mStream->readLine((U8 *)buffer, bufSize);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ U32 _StringTable::hashString(const char* str)
|
|||
char c;
|
||||
while((c = *str++) != 0) {
|
||||
ret <<= 1;
|
||||
ret ^= sgHashTable[static_cast<U32>(c)];
|
||||
ret ^= sgHashTable[static_cast<U8>(c)];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ U32 _StringTable::hashStringn(const char* str, S32 len)
|
|||
char c;
|
||||
while((c = *str++) != 0 && len--) {
|
||||
ret <<= 1;
|
||||
ret ^= sgHashTable[static_cast<U32>(c)];
|
||||
ret ^= sgHashTable[static_cast<U8>(c)];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -195,8 +195,11 @@ StringTableEntry _StringTable::lookupn(const char* val, S32 len, const bool cas
|
|||
}
|
||||
|
||||
//--------------------------------------
|
||||
void _StringTable::resize(const U32 newSize)
|
||||
void _StringTable::resize(const U32 _newSize)
|
||||
{
|
||||
/// avoid a possible 0 division
|
||||
const U32 newSize = _newSize ? _newSize : 1;
|
||||
|
||||
Node *head = NULL, *walk, *temp;
|
||||
U32 i;
|
||||
// reverse individual bucket lists
|
||||
|
|
|
|||
|
|
@ -532,3 +532,32 @@ const char* dStristr( const char* str1, const char* str2 )
|
|||
{
|
||||
return dStristr( const_cast< char* >( str1 ), str2 );
|
||||
}
|
||||
|
||||
int dStrrev(char* str)
|
||||
{
|
||||
int l=dStrlen(str)-1; //get the string length
|
||||
for(int x=0;x < l;x++,l--)
|
||||
{
|
||||
str[x]^=str[l]; //triple XOR Trick
|
||||
str[l]^=str[x]; //for not using a temp
|
||||
str[x]^=str[l];
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
int dItoa(int n, char s[])
|
||||
{
|
||||
int i, sign;
|
||||
|
||||
if ((sign = n) < 0) /* record sign */
|
||||
n = -n; /* make n positive */
|
||||
i = 0;
|
||||
do { /* generate digits in reverse order */
|
||||
s[i++] = n % 10 + '0'; /* get next digit */
|
||||
} while ((n /= 10) > 0); /* delete it */
|
||||
if (sign < 0)
|
||||
s[i++] = '-';
|
||||
s[i] = '\0';
|
||||
dStrrev(s);
|
||||
return dStrlen(s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,6 +217,9 @@ bool dStrEndsWith(const char* str1, const char* str2);
|
|||
|
||||
char* dStripPath(const char* filename);
|
||||
|
||||
int dStrrev(char* str);
|
||||
int dItoa(int n, char s[]);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// standard I/O functions [defined in platformString.cpp]
|
||||
|
||||
|
|
|
|||
|
|
@ -47,10 +47,12 @@ public:
|
|||
: mHitCount( 0 )
|
||||
#endif
|
||||
{ };
|
||||
virtual ~_TorqueThreadStatic() { }
|
||||
|
||||
static const U32 getListIndex(){ return mListIndex; }
|
||||
|
||||
virtual void *getMemInstPtr() = 0;
|
||||
virtual const void *getConstMemInstPtr() const = 0;
|
||||
virtual const dsize_t getMemInstSize() const = 0;
|
||||
|
||||
#ifdef TORQUE_ENABLE_THREAD_STATIC_METRICS
|
||||
|
|
@ -142,6 +144,7 @@ private:
|
|||
public:
|
||||
TorqueThreadStatic( T instanceVal ) : mInstance( instanceVal ) {}
|
||||
virtual void *getMemInstPtr() { return &mInstance; }
|
||||
virtual const void *getConstMemInstPtr() const { return &mInstance; }
|
||||
|
||||
// I am not sure these are needed, and I don't want to create confusing-to-debug code
|
||||
#if 0
|
||||
|
|
@ -180,7 +183,7 @@ public: \
|
|||
_##name##TorqueThreadStatic() : TorqueThreadStatic<type>( initalvalue ) {} \
|
||||
virtual const dsize_t getMemInstSize() const { return sizeof( type ); } \
|
||||
type &_cast() { return *reinterpret_cast<type *>( getMemInstPtr() ); } \
|
||||
const type &_const_cast() const { return *reinterpret_cast<const type *>( getMemInstPtr() ); } \
|
||||
const type &_const_cast() const { return *reinterpret_cast<const type *>( getConstMemInstPtr() ); } \
|
||||
}; \
|
||||
static _##name##TorqueThreadStatic name##TorqueThreadStatic; \
|
||||
static _TorqueThreadStaticReg _##name##TTSReg( reinterpret_cast<_TorqueThreadStatic *>( & name##TorqueThreadStatic ) )
|
||||
|
|
|
|||
|
|
@ -43,15 +43,21 @@ static Process* _theOneProcess = NULL; ///< the one instance of the Process clas
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Process::requestShutdown()
|
||||
void Process::requestShutdown(S32 status)
|
||||
{
|
||||
Process::get()._RequestShutdown = true;
|
||||
Process::get()._ReturnStatus = status;
|
||||
}
|
||||
|
||||
S32 Process::getReturnStatus()
|
||||
{
|
||||
return Process::get()._ReturnStatus;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Process::Process()
|
||||
: _RequestShutdown( false )
|
||||
: _RequestShutdown( false ), _ReturnStatus( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public:
|
|||
static bool processEvents();
|
||||
|
||||
/// Ask the processEvents() function to shutdown.
|
||||
static void requestShutdown();
|
||||
static void requestShutdown(S32 status = 0);
|
||||
|
||||
|
||||
static void notifyInit(Delegate<bool()> del, F32 order = PROCESS_DEFAULT_ORDER)
|
||||
|
|
@ -96,6 +96,11 @@ public:
|
|||
get()._signalProcess.notify(del,order);
|
||||
}
|
||||
|
||||
static void notify(SignalSlot<void()> &slot, F32 order = PROCESS_DEFAULT_ORDER)
|
||||
{
|
||||
get()._signalProcess.notify(slot,order);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void notify(T func, F32 order = PROCESS_DEFAULT_ORDER)
|
||||
{
|
||||
|
|
@ -144,6 +149,9 @@ public:
|
|||
/// Trigger the registered shutdown functions
|
||||
static bool shutdown();
|
||||
|
||||
/// get the current return status code we've been asked to end with.
|
||||
static S32 getReturnStatus();
|
||||
|
||||
private:
|
||||
friend class StandardMainLoop;
|
||||
|
||||
|
|
@ -162,6 +170,7 @@ private:
|
|||
Signal<bool()> _signalShutdown;
|
||||
|
||||
bool _RequestShutdown;
|
||||
S32 _ReturnStatus;
|
||||
};
|
||||
|
||||
/// Register a command line handling function.
|
||||
|
|
|
|||
189
Engine/source/core/util/journal/test/journalTest.cpp
Normal file
189
Engine/source/core/util/journal/test/journalTest.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/journal/journaledSignal.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
FIXTURE(Journal)
|
||||
{
|
||||
public:
|
||||
// Used for basic API test.
|
||||
struct receiver
|
||||
{
|
||||
U16 lastTriggerValue;
|
||||
void trigger(U16 msg)
|
||||
{
|
||||
lastTriggerValue = msg;
|
||||
}
|
||||
};
|
||||
|
||||
// Used for non-basic test.
|
||||
typedef JournaledSignal<void(U32, U16)> EventA;
|
||||
typedef JournaledSignal<void(U8, S8)> EventB;
|
||||
typedef JournaledSignal<void(U32, S32)> EventC;
|
||||
|
||||
// Root, non-dynamic signal receiver.
|
||||
struct multiReceiver {
|
||||
U32 recvA, recvB, recvC;
|
||||
|
||||
EventA *dynamicA;
|
||||
EventB *dynamicB;
|
||||
EventC *dynamicC;
|
||||
|
||||
void receiverRoot(U8 msg)
|
||||
{
|
||||
if(msg==1)
|
||||
{
|
||||
dynamicA = new EventA();
|
||||
dynamicA->notify(this, &multiReceiver::receiverA);
|
||||
}
|
||||
|
||||
if(msg==2)
|
||||
{
|
||||
dynamicB = new EventB();
|
||||
dynamicB->notify(this, &multiReceiver::receiverB);
|
||||
}
|
||||
|
||||
if(msg==3)
|
||||
{
|
||||
dynamicC = new EventC();
|
||||
dynamicC->notify(this, &multiReceiver::receiverC);
|
||||
}
|
||||
}
|
||||
|
||||
void receiverA(U32, U16 d)
|
||||
{
|
||||
recvA += d;
|
||||
}
|
||||
|
||||
void receiverB(U8, S8 d)
|
||||
{
|
||||
recvB += d;
|
||||
}
|
||||
|
||||
void receiverC(U32, S32 d)
|
||||
{
|
||||
recvC += d;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
TEST_FIX(Journal, BasicAPI)
|
||||
{
|
||||
receiver rec;
|
||||
rec.lastTriggerValue = 0;
|
||||
|
||||
// Set up a journaled signal to test with.
|
||||
JournaledSignal<void(U16)> testEvent;
|
||||
testEvent.notify(&rec, &receiver::trigger);
|
||||
|
||||
// Initialize journal recording and fire off some events...
|
||||
Journal::Record("test.jrn");
|
||||
ASSERT_TRUE(Journal::IsRecording());
|
||||
|
||||
testEvent.trigger(16);
|
||||
testEvent.trigger(17);
|
||||
testEvent.trigger(18);
|
||||
|
||||
EXPECT_EQ(rec.lastTriggerValue, 18)
|
||||
<< "Should encounter last triggered value (18).";
|
||||
|
||||
Journal::Stop();
|
||||
ASSERT_FALSE(Journal::IsRecording());
|
||||
|
||||
// Clear it...
|
||||
rec.lastTriggerValue = 0;
|
||||
|
||||
// and play back - should get same thing.
|
||||
Journal::Play("test.jrn");
|
||||
|
||||
// Since we fired 3 events, it should take three loops.
|
||||
EXPECT_TRUE(Journal::PlayNext()) << "Should be two more events.";
|
||||
EXPECT_TRUE(Journal::PlayNext()) << "Should be one more event.";
|
||||
EXPECT_FALSE(Journal::PlayNext()) << "Should be no more events.";
|
||||
|
||||
EXPECT_EQ(rec.lastTriggerValue, 18)
|
||||
<< "Should encounter last journaled value (18).";
|
||||
}
|
||||
|
||||
TEST_FIX(Journal, DynamicSignals)
|
||||
{
|
||||
multiReceiver rec;
|
||||
|
||||
// Reset our state values.
|
||||
rec.recvA = rec.recvB = rec.recvC = 0;
|
||||
|
||||
// Set up a signal to start with.
|
||||
JournaledSignal<void(U8)> testEvent;
|
||||
testEvent.notify(&rec, &multiReceiver::receiverRoot);
|
||||
|
||||
// Initialize journal recording and fire off some events...
|
||||
Journal::Record("test.jrn");
|
||||
ASSERT_TRUE(Journal::IsRecording());
|
||||
|
||||
testEvent.trigger(1);
|
||||
rec.dynamicA->trigger(8, 100);
|
||||
testEvent.trigger(2);
|
||||
rec.dynamicA->trigger(8, 8);
|
||||
rec.dynamicB->trigger(9, 'a');
|
||||
testEvent.trigger(3);
|
||||
SAFE_DELETE(rec.dynamicB); // Test a deletion.
|
||||
rec.dynamicC->trigger(8, 1);
|
||||
rec.dynamicC->trigger(8, 1);
|
||||
|
||||
// Did we end up with expected values? Check before clearing.
|
||||
EXPECT_EQ(rec.recvA, 108) << "recvA wasn't 108 - something broken in signals?";
|
||||
EXPECT_EQ(rec.recvB, 'a') << "recvB wasn't 'a' - something broken in signals?";
|
||||
EXPECT_EQ(rec.recvC, 2) << "recvC wasn't 2 - something broken in signals?";
|
||||
|
||||
// Reset our state values.
|
||||
rec.recvA = rec.recvB = rec.recvC = 0;
|
||||
|
||||
// And kill the journal...
|
||||
Journal::Stop();
|
||||
|
||||
// Also kill our remaining dynamic signals.
|
||||
SAFE_DELETE(rec.dynamicA);
|
||||
SAFE_DELETE(rec.dynamicB);
|
||||
SAFE_DELETE(rec.dynamicC);
|
||||
|
||||
// Play back - should get same thing.
|
||||
Journal::Play("test.jrn");
|
||||
|
||||
// Since we fired 8 events, it should take 7+1=8 loops.
|
||||
for(S32 i = 0; i < 7; i++)
|
||||
{
|
||||
EXPECT_TRUE(Journal::PlayNext())
|
||||
<< "Should be more events.";
|
||||
}
|
||||
|
||||
EXPECT_FALSE(Journal::PlayNext())
|
||||
<< "Should be no more events.";
|
||||
|
||||
EXPECT_EQ(rec.recvA, 108) << "recvA wasn't 108 - something broken in journal?";
|
||||
EXPECT_EQ(rec.recvB, 'a') << "recvB wasn't 'a' - something broken in journal?";
|
||||
EXPECT_EQ(rec.recvC, 2) << "recvC wasn't 2 - something broken in journal?";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
|
|
@ -20,37 +20,41 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "unit/test.h"
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/journal/process.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
using namespace UnitTesting;
|
||||
|
||||
CreateUnitTest(TestingProcess, "Journal/Process")
|
||||
FIXTURE(Process)
|
||||
{
|
||||
// How many ticks remaining?
|
||||
U32 _remainingTicks;
|
||||
|
||||
// Callback for process list.
|
||||
void process()
|
||||
public:
|
||||
U32 remainingTicks;
|
||||
void notification()
|
||||
{
|
||||
if(_remainingTicks==0)
|
||||
if(remainingTicks == 0)
|
||||
Process::requestShutdown();
|
||||
|
||||
_remainingTicks--;
|
||||
remainingTicks--;
|
||||
}
|
||||
};
|
||||
|
||||
void run()
|
||||
TEST_FIX(Process, BasicAPI)
|
||||
{
|
||||
// We'll run 30 ticks, then quit.
|
||||
remainingTicks = 30;
|
||||
|
||||
// Register with the process list.
|
||||
Process::notify(this, &ProcessFixture::notification);
|
||||
|
||||
// And do 30 notifies, making sure we end on the 30th.
|
||||
for(S32 i = 0; i < 30; i++)
|
||||
{
|
||||
// We'll run 30 ticks, then quit.
|
||||
_remainingTicks = 30;
|
||||
|
||||
// Register with the process list.
|
||||
Process::notify(this, &TestingProcess::process);
|
||||
|
||||
// And do 30 notifies, making sure we end on the 30th.
|
||||
for(S32 i=0; i<30; i++)
|
||||
test(Process::processEvents(), "Should quit after 30 ProcessEvents() calls - not before!");
|
||||
test(!Process::processEvents(), "Should quit after the 30th ProcessEvent() call!");
|
||||
EXPECT_TRUE(Process::processEvents())
|
||||
<< "Should quit after 30 ProcessEvents() calls - not before!";
|
||||
}
|
||||
};
|
||||
|
||||
EXPECT_FALSE(Process::processEvents())
|
||||
<< "Should quit after the 30th ProcessEvent() call!";
|
||||
|
||||
Process::remove(this, &ProcessFixture::notification);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "unit/test.h"
|
||||
#include "core/util/journal/journaledSignal.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
using namespace UnitTesting;
|
||||
|
||||
CreateUnitTest(TestsJournalRecordAndPlayback, "Journal/Basic")
|
||||
{
|
||||
U32 _lastTriggerValue;
|
||||
|
||||
void triggerReceiver(U16 msg)
|
||||
{
|
||||
_lastTriggerValue = msg;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
// Reset the last trigger value just in case...
|
||||
_lastTriggerValue = 0;
|
||||
|
||||
// Set up a journaled signal to test with.
|
||||
JournaledSignal<void(U16)> testEvent;
|
||||
|
||||
testEvent.notify(this, &TestsJournalRecordAndPlayback::triggerReceiver);
|
||||
|
||||
// Initialize journal recording and fire off some events...
|
||||
Journal::Record("test.jrn");
|
||||
|
||||
testEvent.trigger(16);
|
||||
testEvent.trigger(17);
|
||||
testEvent.trigger(18);
|
||||
|
||||
test(_lastTriggerValue == 18, "Should encounter last triggered value (18).");
|
||||
|
||||
Journal::Stop();
|
||||
|
||||
// Clear it...
|
||||
_lastTriggerValue = 0;
|
||||
|
||||
// and play back - should get same thing.
|
||||
Journal::Play("test.jrn");
|
||||
|
||||
// Since we fired 3 events, it should take three loops.
|
||||
test(Journal::PlayNext(), "Should be two more events.");
|
||||
test(Journal::PlayNext(), "Should be one more event.");
|
||||
test(!Journal::PlayNext(), "Should be no more events.");
|
||||
|
||||
test(_lastTriggerValue == 18, "Should encounter last journaled value (18).");
|
||||
}
|
||||
};
|
||||
|
||||
CreateUnitTest(TestsJournalDynamicSignals, "Journal/DynamicSignals")
|
||||
{
|
||||
typedef JournaledSignal<void(U32, U16)> EventA;
|
||||
typedef JournaledSignal<void(U8, S8)> EventB;
|
||||
typedef JournaledSignal<void(U32, S32)> EventC;
|
||||
|
||||
EventA *dynamicA;
|
||||
EventB *dynamicB;
|
||||
EventC *dynamicC;
|
||||
|
||||
// Root, non-dynamic signal receiver.
|
||||
void receiverRoot(U8 msg)
|
||||
{
|
||||
if(msg==1)
|
||||
{
|
||||
dynamicA = new EventA();
|
||||
dynamicA->notify(this, &TestsJournalDynamicSignals::receiverA);
|
||||
}
|
||||
|
||||
if(msg==2)
|
||||
{
|
||||
dynamicB = new EventB();
|
||||
dynamicB->notify(this, &TestsJournalDynamicSignals::receiverB);
|
||||
}
|
||||
|
||||
if(msg==3)
|
||||
{
|
||||
dynamicC = new EventC();
|
||||
dynamicC->notify(this, &TestsJournalDynamicSignals::receiverC);
|
||||
}
|
||||
}
|
||||
|
||||
U32 recvA, recvB, recvC;
|
||||
|
||||
void receiverA(U32, U16 d)
|
||||
{
|
||||
recvA += d;
|
||||
}
|
||||
|
||||
void receiverB(U8, S8 d)
|
||||
{
|
||||
recvB += d;
|
||||
}
|
||||
|
||||
void receiverC(U32, S32 d)
|
||||
{
|
||||
recvC += d;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
// Reset our state values.
|
||||
recvA = recvB = recvC = 0;
|
||||
|
||||
// Set up a signal to start with.
|
||||
JournaledSignal<void(U8)> testEvent;
|
||||
testEvent.notify(this, &TestsJournalDynamicSignals::receiverRoot);
|
||||
|
||||
// Initialize journal recording and fire off some events...
|
||||
Journal::Record("test.jrn");
|
||||
|
||||
testEvent.trigger(1);
|
||||
dynamicA->trigger(8, 100);
|
||||
testEvent.trigger(2);
|
||||
dynamicA->trigger(8, 8);
|
||||
dynamicB->trigger(9, 'a');
|
||||
testEvent.trigger(3);
|
||||
SAFE_DELETE(dynamicB); // Test a deletion.
|
||||
dynamicC->trigger(8, 1);
|
||||
dynamicC->trigger(8, 1);
|
||||
|
||||
// Did we end up with expected values? Check before clearing.
|
||||
test(recvA == 108, "recvA wasn't 108 - something broken in signals?");
|
||||
test(recvB == 'a', "recvB wasn't 'a' - something broken in signals?");
|
||||
test(recvC == 2, "recvC wasn't 2 - something broken in signals?");
|
||||
|
||||
// Reset our state values.
|
||||
recvA = recvB = recvC = 0;
|
||||
|
||||
// And kill the journal...
|
||||
Journal::Stop();
|
||||
|
||||
// Also kill our remaining dynamic signals.
|
||||
SAFE_DELETE(dynamicA);
|
||||
SAFE_DELETE(dynamicB);
|
||||
SAFE_DELETE(dynamicC);
|
||||
|
||||
// Play back - should get same thing.
|
||||
Journal::Play("test.jrn");
|
||||
|
||||
// Since we fired 8 events, it should take 7+1=8 loops.
|
||||
for(S32 i=0; i<7; i++)
|
||||
test(Journal::PlayNext(), "Should be more events.");
|
||||
test(!Journal::PlayNext(), "Should be no more events.");
|
||||
|
||||
test(recvA == 108, "recvA wasn't 108 - something broken in journal?");
|
||||
test(recvB == 'a', "recvB wasn't 'a' - something broken in journal?");
|
||||
test(recvC == 2, "recvC wasn't 2 - something broken in journal?");
|
||||
}
|
||||
};
|
||||
|
|
@ -154,7 +154,7 @@ void MD5Final( unsigned char digest[16], MD5Context* ctx)
|
|||
MD5Transform(ctx->buf, (int *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
memset(ctx, 0, sizeof(MD5Context)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ String& String::operator=(const String &src)
|
|||
|
||||
String& String::operator+=(const StringChar *src)
|
||||
{
|
||||
if( src == NULL && !*src )
|
||||
if( src == NULL || !*src )
|
||||
return *this;
|
||||
|
||||
// Append the given string into a new string
|
||||
|
|
|
|||
|
|
@ -46,19 +46,19 @@ class FixedSizeVector
|
|||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; mArray[ 7 ] = h; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; mArray[ 7 ] = h; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h, const T& i )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; mArray[ 7 ] = h; mArray[ 8 ] = i; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; mArray[ 7 ] = h; mArray[ 8 ] = i; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h, const T& i, const T& j )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h, const T& i, const T& j, const T& k )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; mArray[ 10 ] = k; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; mArray[ 10 ] = k; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h, const T& i, const T& j, const T& k, const T& l )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; mArray[ 10 ] = k; mArray[ 11 ] = l; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; mArray[ 10 ] = k; mArray[ 11 ] = l; }
|
||||
FixedSizeVector( const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h, const T& i, const T& j, const T& k, const T& l, const T& m )
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ]; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; mArray[ 10 ] = k; mArray[ 11 ] = l; mArray[ 12 ] =m; }
|
||||
{ mArray[ 0 ] = a; mArray[ 1 ] = b; mArray[ 2 ] = c; mArray[ 3 ] = d; mArray[ 4 ] = e; mArray[ 5 ] = f; mArray[ 6 ] = g; mArray[ 7 ] = h; mArray[ 8 ] = i; mArray[ 9 ] = j; mArray[ 10 ] = k; mArray[ 11 ] = l; mArray[ 12 ] =m; }
|
||||
|
||||
U32 size() const { return SIZE; }
|
||||
bool empty() const { return ( SIZE == 0 ); }
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ public:
|
|||
{
|
||||
mList.next = mList.prev = &mList;
|
||||
mList.order = 0.5f;
|
||||
mTriggerNext = NULL;
|
||||
}
|
||||
|
||||
~SignalBase();
|
||||
|
|
@ -77,6 +76,8 @@ protected:
|
|||
|
||||
void insert(DelegateLink* node, F32 order);
|
||||
void unlink();
|
||||
|
||||
virtual ~DelegateLink() {}
|
||||
};
|
||||
|
||||
DelegateLink mList;
|
||||
|
|
@ -92,6 +93,78 @@ protected:
|
|||
Vector<DelegateLink*> mTriggerNext;
|
||||
};
|
||||
|
||||
template<typename Signature> class SignalBaseT;
|
||||
|
||||
/// Class for handle automatic diconnect form Signal when destroyed
|
||||
template< typename Signature >
|
||||
class SignalSlot
|
||||
{
|
||||
public:
|
||||
typedef Delegate< Signature > DelegateSig;
|
||||
typedef SignalBaseT< Signature > SignalSig;
|
||||
|
||||
SignalSlot() : mSignal(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~SignalSlot()
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
|
||||
const DelegateSig& getDelegate() { return mDlg; }
|
||||
|
||||
/// setDelegate disconect form Signal old delegate and connect new delegate
|
||||
template<typename X>
|
||||
void setDelegate( const X &fn ) { setDelegate( DelegateSig( fn ) ); }
|
||||
|
||||
template<typename X, typename Y>
|
||||
void setDelegate( const X &ptr, const Y &fn ) { setDelegate( DelegateSig( ptr, fn ) ); }
|
||||
|
||||
void setDelegate( const DelegateSig &dlg)
|
||||
{
|
||||
SignalSig* signal = mSignal;
|
||||
if( isConnected() )
|
||||
disconnect();
|
||||
|
||||
mDlg = dlg;
|
||||
if( signal && mDlg )
|
||||
signal->notify( mDlg );
|
||||
}
|
||||
|
||||
/// is connected to Signal
|
||||
bool isConnected() const { return mSignal; }
|
||||
|
||||
/// disconnect from Signal
|
||||
void disconnect()
|
||||
{
|
||||
if( mSignal )
|
||||
{
|
||||
SignalSig *oldSignal = mSignal;
|
||||
mSignal = NULL;
|
||||
oldSignal->remove( mDlg );
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class SignalBaseT< Signature >;
|
||||
|
||||
void _setSignal(SignalSig *sig)
|
||||
{
|
||||
mSignal = sig;
|
||||
}
|
||||
|
||||
SignalSig* _getSignal() const { return mSignal; }
|
||||
|
||||
DelegateSig mDlg;
|
||||
SignalSig *mSignal;
|
||||
|
||||
private:
|
||||
SignalSlot( const SignalSlot&) {}
|
||||
SignalSlot& operator=( const SignalSlot&) {}
|
||||
};
|
||||
|
||||
template<typename Signature> class SignalBaseT : public SignalBase
|
||||
{
|
||||
public:
|
||||
|
|
@ -163,6 +236,18 @@ public:
|
|||
notify(dlg, order);
|
||||
}
|
||||
|
||||
void notify( SignalSlot<Signature> &slot, F32 order = 0.5f)
|
||||
{
|
||||
if( !slot.getDelegate() )
|
||||
return;
|
||||
|
||||
if( slot.isConnected() )
|
||||
slot.disconnect();
|
||||
|
||||
slot._setSignal( this );
|
||||
mList.insert( new SlotLinkImpl(slot), order );
|
||||
}
|
||||
|
||||
template <class T,class U>
|
||||
void remove(T obj,U func)
|
||||
{
|
||||
|
|
@ -198,6 +283,23 @@ protected:
|
|||
DelegateLinkImpl(DelegateSig dlg) : mDelegate(dlg) {}
|
||||
};
|
||||
|
||||
struct SlotLinkImpl : public DelegateLinkImpl
|
||||
{
|
||||
SlotLinkImpl(SignalSlot<Signature>& slot) : mSlot( &slot ), DelegateLinkImpl( slot.getDelegate() )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~SlotLinkImpl()
|
||||
{
|
||||
if( mSlot )
|
||||
mSlot->_setSignal( NULL );
|
||||
}
|
||||
|
||||
protected:
|
||||
SignalSlot<Signature> *mSlot;
|
||||
};
|
||||
|
||||
DelegateSig & getDelegate(SignalBase::DelegateLink * link)
|
||||
{
|
||||
return ((DelegateLinkImpl*)link)->mDelegate;
|
||||
|
|
|
|||
40
Engine/source/core/util/test/pathTest.cpp
Normal file
40
Engine/source/core/util/test/pathTest.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/path.h"
|
||||
|
||||
TEST(MakeRelativePath, MakeRelativePath)
|
||||
{
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/"), "burg/file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/file.png", "art/interiors/burg/"), "../file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/file.png", "art/interiors/burg/"), "../../file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("file.png", "art/interiors/burg/"), "../../../file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/burg/"), "file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/camp/file.png", "art/interiors/burg/"), "../camp/file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/shapes/"), "../interiors/burg/file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("levels/den/file.png", "art/interiors/burg/"), "../../../levels/den/file.png");
|
||||
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/dts/burg/"), "../../interiors/burg/file.png");
|
||||
};
|
||||
|
||||
#endif
|
||||
332
Engine/source/core/util/test/strTest.cpp
Normal file
332
Engine/source/core/util/test/strTest.cpp
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/str.h"
|
||||
#include "core/util/tVector.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "core/strings/unicode.h"
|
||||
|
||||
/// This is called Str, not String, because googletest doesn't let you use both
|
||||
/// TEST(x) and TEST_FIX(x). So this fixture is called Str, to match the StrTest
|
||||
/// struct, and the remaining fixture-les tests are named String.
|
||||
FIXTURE(Str)
|
||||
{
|
||||
protected:
|
||||
struct StrTest
|
||||
{
|
||||
const UTF8* mData;
|
||||
const UTF16* mUTF16;
|
||||
U32 mLength;
|
||||
|
||||
StrTest() : mData( 0 ), mUTF16( 0 ) {}
|
||||
StrTest( const char* str )
|
||||
: mData( str ), mLength( str ? dStrlen( str ) : 0 ), mUTF16( NULL )
|
||||
{
|
||||
if( str )
|
||||
mUTF16 = convertUTF8toUTF16( mData );
|
||||
}
|
||||
~StrTest()
|
||||
{
|
||||
if( mUTF16 )
|
||||
delete [] mUTF16;
|
||||
}
|
||||
};
|
||||
|
||||
Vector< StrTest* > mStrings;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
mStrings.push_back( new StrTest( NULL ) );
|
||||
mStrings.push_back( new StrTest( "" ) );
|
||||
mStrings.push_back( new StrTest( "Torque" ) );
|
||||
mStrings.push_back( new StrTest( "TGEA" ) );
|
||||
mStrings.push_back( new StrTest( "GarageGames" ) );
|
||||
mStrings.push_back( new StrTest( "TGB" ) );
|
||||
mStrings.push_back( new StrTest( "games" ) );
|
||||
mStrings.push_back( new StrTest( "engine" ) );
|
||||
mStrings.push_back( new StrTest( "rocks" ) );
|
||||
mStrings.push_back( new StrTest( "technology" ) );
|
||||
mStrings.push_back( new StrTest( "Torque 3D" ) );
|
||||
mStrings.push_back( new StrTest( "Torque 2D" ) );
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
for( U32 i = 0; i < mStrings.size(); ++ i )
|
||||
delete mStrings[ i ];
|
||||
mStrings.clear();
|
||||
}
|
||||
};
|
||||
|
||||
#define EACH_STRING(i) \
|
||||
for( U32 i = 0; i < mStrings.size(); ++ i )
|
||||
#define EACH_PAIR(i, j) \
|
||||
for( U32 i = 0; i < mStrings.size(); ++ i ) \
|
||||
for( U32 j = 0; j < mStrings.size(); ++ j )
|
||||
|
||||
TEST_FIX(Str, Test1)
|
||||
{
|
||||
EACH_STRING(i)
|
||||
{
|
||||
StrTest& data = *mStrings[i];
|
||||
String str( data.mData );
|
||||
String str16( data.mUTF16 );
|
||||
|
||||
EXPECT_TRUE( str.length() == data.mLength );
|
||||
EXPECT_TRUE( str.size() == data.mLength + 1 );
|
||||
EXPECT_TRUE( str.isEmpty() || str.length() > 0 );
|
||||
EXPECT_TRUE( str.length() == str16.length() );
|
||||
EXPECT_TRUE( str.size() == str16.size() );
|
||||
|
||||
EXPECT_TRUE( dMemcmp( str.utf16(), str16.utf16(), str.length() * sizeof( UTF16 ) ) == 0 );
|
||||
EXPECT_TRUE( !data.mData || dMemcmp( str.utf16(), data.mUTF16, str.length() * sizeof( UTF16 ) ) == 0 );
|
||||
EXPECT_TRUE( !data.mData || dMemcmp( str16.utf8(), data.mData, str.length() ) == 0 );
|
||||
|
||||
EXPECT_TRUE( !data.mData || dStrcmp( str.utf8(), data.mData ) == 0 );
|
||||
EXPECT_TRUE( !data.mData || dStrcmp( str.utf16(), data.mUTF16 ) == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FIX(Str, Test2)
|
||||
{
|
||||
EACH_STRING(i)
|
||||
{
|
||||
StrTest& data = *mStrings[i];
|
||||
String str( data.mData );
|
||||
|
||||
EXPECT_TRUE( str == str );
|
||||
EXPECT_FALSE( str != str );
|
||||
EXPECT_FALSE( str < str );
|
||||
EXPECT_FALSE( str > str );
|
||||
EXPECT_TRUE( str.equal( str ) );
|
||||
EXPECT_TRUE( str.equal( str, String::NoCase ) );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FIX(Str, Test3)
|
||||
{
|
||||
EACH_PAIR(i, j)
|
||||
{
|
||||
StrTest& d1 = *mStrings[i];
|
||||
StrTest& d2 = *mStrings[j];
|
||||
|
||||
if( &d1 != &d2 )
|
||||
EXPECT_TRUE( String( d1.mData ) != String( d2.mData )
|
||||
|| ( String( d1.mData ).isEmpty() && String( d2.mData ).isEmpty() ) );
|
||||
else
|
||||
EXPECT_TRUE( String( d1.mData ) == String( d2.mData ) );
|
||||
}
|
||||
}
|
||||
|
||||
TEST(String, Empty)
|
||||
{
|
||||
EXPECT_TRUE( String().length() == 0 );
|
||||
EXPECT_TRUE( String( "" ).length() == 0 );
|
||||
EXPECT_TRUE( String().size() == 1 );
|
||||
EXPECT_TRUE( String( "" ).size() == 1 );
|
||||
EXPECT_TRUE( String().isEmpty() );
|
||||
EXPECT_TRUE( String( "" ).isEmpty() );
|
||||
}
|
||||
|
||||
TEST(String, Trim)
|
||||
{
|
||||
EXPECT_TRUE( String( " Foobar Barfoo \n\t " ).trim() == String( "Foobar Barfoo" ) );
|
||||
EXPECT_TRUE( String( "Foobar" ).trim() == String( "Foobar" ) );
|
||||
EXPECT_TRUE( String( " " ).trim().isEmpty() );
|
||||
}
|
||||
|
||||
TEST(String, Compare)
|
||||
{
|
||||
String str( "Foobar" );
|
||||
|
||||
EXPECT_TRUE( str.compare( "Foo", 3 ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "bar", 3, String::NoCase | String::Right ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "foo", 3, String::NoCase ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "BAR", 3, String::NoCase | String::Right ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "Foobar" ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "Foo" ) != 0 );
|
||||
EXPECT_TRUE( str.compare( "foobar", 0, String::NoCase ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "FOOBAR", 0, String::NoCase ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "Foobar", 0, String::Right ) == 0 );
|
||||
EXPECT_TRUE( str.compare( "foobar", 0, String::NoCase | String::Right ) == 0 );
|
||||
}
|
||||
|
||||
TEST(String, Order)
|
||||
{
|
||||
Vector< String > strs;
|
||||
|
||||
strs.push_back( "a" );
|
||||
strs.push_back( "a0" );
|
||||
strs.push_back( "a1" );
|
||||
strs.push_back( "a1a" );
|
||||
strs.push_back( "a1b" );
|
||||
strs.push_back( "a2" );
|
||||
strs.push_back( "a10" );
|
||||
strs.push_back( "a20" );
|
||||
|
||||
for( U32 i = 0; i < strs.size(); ++ i )
|
||||
{
|
||||
for( U32 j = 0; j < i; ++ j )
|
||||
{
|
||||
EXPECT_TRUE( strs[ j ] < strs[ i ] );
|
||||
EXPECT_TRUE( strs[ i ] > strs[ j ] );
|
||||
|
||||
EXPECT_TRUE( !( strs[ j ] > strs[ i ] ) );
|
||||
EXPECT_TRUE( !( strs[ i ] < strs[ i ] ) );
|
||||
|
||||
EXPECT_TRUE( strs[ j ] <= strs[ i ] );
|
||||
EXPECT_TRUE( strs[ i ] >= strs[ j ] );
|
||||
}
|
||||
|
||||
EXPECT_TRUE( !( strs[ i ] < strs[ i ] ) );
|
||||
EXPECT_TRUE( !( strs[ i ] > strs[ i ] ) );
|
||||
EXPECT_TRUE( strs[ i ] <= strs[ i ] );
|
||||
EXPECT_TRUE( strs[ i ] >= strs[ i ] );
|
||||
|
||||
for( U32 j = i + 1; j < strs.size(); ++ j )
|
||||
{
|
||||
EXPECT_TRUE( strs[ j ] > strs[ i ] );
|
||||
EXPECT_TRUE( strs[ i ] < strs[ j ] );
|
||||
|
||||
EXPECT_TRUE( !( strs[ j ] < strs[ i ] ) );
|
||||
EXPECT_TRUE( !( strs[ i ] > strs[ j ] ) );
|
||||
|
||||
EXPECT_TRUE( strs[ j ] >= strs[ i ] );
|
||||
EXPECT_TRUE( strs[ i ] <= strs[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO
|
||||
TEST(String, Find)
|
||||
{
|
||||
}
|
||||
|
||||
TEST(String, Insert)
|
||||
{
|
||||
// String.insert( Pos, Char )
|
||||
EXPECT_TRUE( String( "aa" ).insert( 1, 'c' ) == String( "aca" ) );
|
||||
|
||||
// String.insert( Pos, String )
|
||||
EXPECT_TRUE( String( "aa" ).insert( 1, "cc" ) == String( "acca" ) );
|
||||
EXPECT_TRUE( String( "aa" ).insert( 1, String( "cc" ) ) == String( "acca" ) );
|
||||
|
||||
// String.insert( Pos, String, Len )
|
||||
EXPECT_TRUE( String( "aa" ).insert( 1, "ccdddd", 2 ) == String( "acca" ) );
|
||||
}
|
||||
|
||||
TEST(String, Erase)
|
||||
{
|
||||
EXPECT_TRUE( String( "abba" ).erase( 1, 2 ) == String( "aa" ) );
|
||||
EXPECT_TRUE( String( "abba" ).erase( 0, 4 ).isEmpty() );
|
||||
}
|
||||
|
||||
TEST(String, Replace)
|
||||
{
|
||||
// String.replace( Pos, Len, String )
|
||||
EXPECT_TRUE( String( "abba" ).replace( 1, 2, "ccc" ) == String( "accca" ) );
|
||||
EXPECT_TRUE( String( "abba" ).replace( 1, 2, String( "ccc" ) ) == String( "accca" ) );
|
||||
EXPECT_TRUE( String( "abba" ).replace( 0, 4, "" ).isEmpty() );
|
||||
EXPECT_TRUE( String( "abba" ).replace( 2, 2, "c" ) == String( "abc" ) );
|
||||
|
||||
// String.replace( Char, Char )
|
||||
EXPECT_TRUE( String().replace( 'a', 'b' ).isEmpty() );
|
||||
EXPECT_TRUE( String( "ababc" ).replace( 'a', 'b' ) == String( "bbbbc" ) );
|
||||
EXPECT_TRUE( String( "ababc" ).replace( 'd', 'e' ) == String( "ababc" ) );
|
||||
|
||||
// String.replace( String, String )
|
||||
EXPECT_TRUE( String().replace( "foo", "bar" ).isEmpty() );
|
||||
EXPECT_TRUE( String( "foobarfoo" ).replace( "foo", "bar" ) == String( "barbarbar" ) );
|
||||
EXPECT_TRUE( String( "foobar" ).replace( "xx", "yy" ) == String( "foobar" ) );
|
||||
EXPECT_TRUE( String( "foofoofoo" ).replace( "foo", "" ).isEmpty() );
|
||||
}
|
||||
|
||||
TEST(String, SubStr)
|
||||
{
|
||||
EXPECT_TRUE( String( "foobar" ).substr( 0, 3 ) == String( "foo" ) );
|
||||
EXPECT_TRUE( String( "foobar" ).substr( 3 ) == String( "bar" ) );
|
||||
EXPECT_TRUE( String( "foobar" ).substr( 2, 2 ) == String( "ob" ) );
|
||||
EXPECT_TRUE( String( "foobar" ).substr( 2, 0 ).isEmpty() );
|
||||
EXPECT_TRUE( String( "foobar" ).substr( 0, 6 ) == String( "foobar" ) );
|
||||
}
|
||||
|
||||
TEST(String, ToString)
|
||||
{
|
||||
EXPECT_TRUE( String::ToString( U32( 1 ) ) == String( "1" ) );
|
||||
EXPECT_TRUE( String::ToString( S32( -1 ) ) == String( "-1" ) );
|
||||
EXPECT_TRUE( String::ToString( F32( 1.01 ) ) == String( "1.01" ) );
|
||||
EXPECT_TRUE( String::ToString( "%s%i", "foo", 1 ) == String( "foo1" ) );
|
||||
}
|
||||
|
||||
TEST(String, CaseConversion)
|
||||
{
|
||||
EXPECT_TRUE( String::ToLower( "foobar123." ) == String( "foobar123." ) );
|
||||
EXPECT_TRUE( String::ToLower( "FOOBAR123." ) == String( "foobar123." ) );
|
||||
EXPECT_TRUE( String::ToUpper( "barfoo123." ) == String( "BARFOO123." ) );
|
||||
EXPECT_TRUE( String::ToUpper( "BARFOO123." ) == String( "BARFOO123." ) );
|
||||
}
|
||||
|
||||
TEST(String, Concat)
|
||||
{
|
||||
EXPECT_TRUE( String( "foo" ) + String( "bar" ) == String( "foobar" ) );
|
||||
EXPECT_TRUE( String() + String( "bar" ) == String( "bar" ) );
|
||||
EXPECT_TRUE( String( "foo" ) + String() == String( "foo" ) );
|
||||
EXPECT_TRUE( String() + String() == String() );
|
||||
EXPECT_TRUE( String( "fo" ) + 'o' == String( "foo" ) );
|
||||
EXPECT_TRUE( 'f' + String( "oo" ) == String( "foo" ) );
|
||||
EXPECT_TRUE( String( "foo" ) + "bar" == String( "foobar" ) );
|
||||
EXPECT_TRUE( "foo" + String( "bar" ) == String( "foobar" ) );
|
||||
}
|
||||
|
||||
TEST(String, Hash)
|
||||
{
|
||||
EXPECT_TRUE( String( "foo" ).getHashCaseSensitive() == String( "foo" ).getHashCaseSensitive() );
|
||||
EXPECT_TRUE( String( "foo" ).getHashCaseSensitive() != String( "bar" ).getHashCaseSensitive() );
|
||||
EXPECT_TRUE( String( "foo" ).getHashCaseInsensitive() == String( "FOO" ).getHashCaseInsensitive() );
|
||||
}
|
||||
|
||||
TEST(String, Intern)
|
||||
{
|
||||
EXPECT_TRUE( String( "foo" ).intern().isSame( String( "foo" ).intern() ) );
|
||||
EXPECT_TRUE( !String( "foo" ).intern().isSame( String( "bar" ).intern() ) );
|
||||
EXPECT_TRUE( !String( "foo" ).intern().isSame( String( "Foo" ).intern() ) );
|
||||
EXPECT_TRUE( String( "foo" ).intern() == String( "foo" ).intern() );
|
||||
EXPECT_TRUE( String( "foo" ).intern() != String( "bar" ).intern() );
|
||||
EXPECT_TRUE( String( "foo" ).intern().isInterned() );
|
||||
}
|
||||
|
||||
TEST(StringBuilder, StringBuilder)
|
||||
{
|
||||
StringBuilder str;
|
||||
|
||||
str.append( 'f' );
|
||||
str.append( "oo" );
|
||||
str.append( String( "ba" ) );
|
||||
str.append( "rfajskfdj", 1 );
|
||||
str.format( "%s", "barfoo" );
|
||||
|
||||
EXPECT_TRUE( str.end() == String( "foobarbarfoo" ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
129
Engine/source/core/util/test/swizzleTest.cpp
Normal file
129
Engine/source/core/util/test/swizzleTest.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "platform/platform.h"
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/swizzle.h"
|
||||
#include "math/mRandom.h"
|
||||
|
||||
class TestStruct
|
||||
{
|
||||
private:
|
||||
static U32 smIdx;
|
||||
U32 mIdx;
|
||||
U32 mData;
|
||||
|
||||
public:
|
||||
TestStruct( const S32 data = -1 ) : mData( data ), mIdx( smIdx++ ) {};
|
||||
|
||||
dsize_t Idx() const { return mIdx; }
|
||||
|
||||
U32 Data() const { return mData; }
|
||||
void Data(U32 val) { mData = val; }
|
||||
};
|
||||
|
||||
U32 TestStruct::smIdx = 0;
|
||||
|
||||
TEST(Swizzle, Swizzle)
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
// Debugger-Observable Functionality Tests
|
||||
//------------------------------------------------------------------------
|
||||
U8 simpleBuffer[] = { 0, 1, 2, 3 };
|
||||
U8 simpleTest[] = { 0, 1, 2, 3 };
|
||||
|
||||
#define RESET_SIMPLE() dMemcpy( simpleTest, simpleBuffer, sizeof( simpleBuffer ) )
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// No-switch test
|
||||
dsize_t noSwzl4[] = { 0, 1, 2, 3 };
|
||||
Swizzle<U8,4> noSwizzle4( noSwzl4 );
|
||||
|
||||
noSwizzle4.InPlace( simpleTest, sizeof( simpleTest ) );
|
||||
EXPECT_EQ( dMemcmp( simpleTest, simpleBuffer, sizeof( simpleBuffer ) ), 0 )
|
||||
<< "No-switch test failed!";
|
||||
RESET_SIMPLE();
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// No-brainer RGBA->BGRA test
|
||||
dsize_t bgraSwzl[] = { 2, 1, 0, 3 };
|
||||
Swizzle<U8,4> bgraSwizzle( bgraSwzl );
|
||||
|
||||
U8 bgraTest[] = { 2, 1, 0, 3 };
|
||||
bgraSwizzle.InPlace( simpleTest, sizeof( simpleTest ) );
|
||||
EXPECT_EQ( dMemcmp( simpleTest, bgraTest, sizeof( bgraTest ) ), 0 )
|
||||
<< "U8 RGBA->BGRA test failed";
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Reverse test
|
||||
bgraSwizzle.InPlace( simpleTest, sizeof( simpleTest ) );
|
||||
EXPECT_EQ( dMemcmp( simpleTest, simpleBuffer, sizeof( simpleBuffer ) ), 0 )
|
||||
<< "U8 RGBA->BGRA reverse test failed";
|
||||
|
||||
RESET_SIMPLE();
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Object support test
|
||||
Swizzle<TestStruct,4> bgraObjSwizzle( bgraSwzl );
|
||||
{
|
||||
U32 objIdx[] = { 0, 1, 2, 3 };
|
||||
|
||||
FrameTemp<TestStruct> objTest( sizeof( objIdx ) / sizeof( U32 ) );
|
||||
FrameTemp<U32> randData( sizeof( objIdx ) / sizeof( U32 ) );
|
||||
|
||||
bool same = true;
|
||||
|
||||
for( U32 i = 0; i < sizeof( objIdx ) / sizeof( U32 ); i++ )
|
||||
{
|
||||
// Make random data and assign it
|
||||
randData[i] = gRandGen.randI();
|
||||
objTest[i].Data( randData[i] );
|
||||
|
||||
// Continue object sanity check
|
||||
same &= ( objTest[i].Idx() == objIdx[i] );
|
||||
}
|
||||
|
||||
EXPECT_TRUE( same )
|
||||
<< "Test object failed to be competent";
|
||||
|
||||
bgraObjSwizzle.InPlace( ~objTest, sizeof( TestStruct ) * ( sizeof( objIdx ) / sizeof( U32 ) ) );
|
||||
same = true;
|
||||
|
||||
for( U32 i = 0; i < sizeof( objIdx ) / sizeof( U32 ); i++ )
|
||||
same &= ( objTest[i].Idx() == bgraTest[i] ) && ( objTest[i].Data() == randData[ (U32)bgraTest[ i ] ] );
|
||||
|
||||
EXPECT_TRUE( same )
|
||||
<< "Object RGBA->BGRA test failed.";
|
||||
|
||||
bgraObjSwizzle.InPlace( ~objTest, sizeof( TestStruct ) * ( sizeof( objIdx ) / sizeof( U32 ) ) );
|
||||
same = true;
|
||||
|
||||
for( U32 i = 0; i < sizeof( objIdx ) / sizeof( U32 ); i++ )
|
||||
same &= ( objTest[i].Idx() == objIdx[i] ) && ( objTest[i].Data() == randData[i] );
|
||||
|
||||
EXPECT_TRUE( same )
|
||||
<< "Object RGBA->BGRA reverse test failed.";
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
|
|
@ -20,35 +20,30 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "unit/test.h"
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/tFixedSizeDeque.h"
|
||||
|
||||
|
||||
using namespace UnitTesting;
|
||||
|
||||
#define TEST( x ) test( ( x ), "FAIL: " #x )
|
||||
|
||||
CreateUnitTest( TestFixedSizeDeque, "Util/FixedSizeDeque" )
|
||||
TEST(FixedSizeDeque, FixedSizeDeque)
|
||||
{
|
||||
void run()
|
||||
{
|
||||
enum { DEQUE_SIZE = 3 };
|
||||
FixedSizeDeque< U32 > deque( DEQUE_SIZE );
|
||||
enum { DEQUE_SIZE = 3 };
|
||||
FixedSizeDeque< U32 > deque( DEQUE_SIZE );
|
||||
|
||||
TEST( deque.capacity() == DEQUE_SIZE );
|
||||
TEST( deque.size() == 0 );
|
||||
EXPECT_EQ( deque.capacity(), DEQUE_SIZE );
|
||||
EXPECT_EQ( deque.size(), 0 );
|
||||
|
||||
deque.pushFront( 1 );
|
||||
TEST( deque.capacity() == ( DEQUE_SIZE - 1 ) );
|
||||
TEST( deque.size() == 1 );
|
||||
TEST( !deque.isEmpty() );
|
||||
deque.pushFront( 1 );
|
||||
EXPECT_EQ( deque.capacity(), ( DEQUE_SIZE - 1 ) );
|
||||
EXPECT_EQ( deque.size(), 1 );
|
||||
EXPECT_FALSE( deque.isEmpty() );
|
||||
|
||||
deque.pushBack( 2 );
|
||||
TEST( deque.capacity() == ( DEQUE_SIZE - 2 ) );
|
||||
TEST( deque.size() == 2 );
|
||||
deque.pushBack( 2 );
|
||||
EXPECT_EQ( deque.capacity(), ( DEQUE_SIZE - 2 ) );
|
||||
EXPECT_EQ( deque.size(), 2 );
|
||||
|
||||
TEST( deque.popFront() == 1 );
|
||||
TEST( deque.popFront() == 2 );
|
||||
TEST( deque.isEmpty() );
|
||||
}
|
||||
EXPECT_EQ( deque.popFront(), 1 );
|
||||
EXPECT_EQ( deque.popFront(), 2 );
|
||||
EXPECT_TRUE( deque.isEmpty() );
|
||||
};
|
||||
|
||||
#endif
|
||||
125
Engine/source/core/util/test/tVectorTest.cpp
Normal file
125
Engine/source/core/util/test/tVectorTest.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef TORQUE_TESTS_ENABLED
|
||||
#include "testing/unitTesting.h"
|
||||
#include "core/util/tVector.h"
|
||||
|
||||
// Define some test data used below.
|
||||
FIXTURE(Vector)
|
||||
{
|
||||
public:
|
||||
struct Dtor
|
||||
{
|
||||
bool* ptr;
|
||||
Dtor() {} // Needed for vector increment.
|
||||
Dtor(bool* ptr): ptr(ptr) {}
|
||||
~Dtor()
|
||||
{
|
||||
*ptr = true;
|
||||
}
|
||||
};
|
||||
|
||||
static const S32 ints[];
|
||||
static const U32 length;
|
||||
static S32 QSORT_CALLBACK sortInts(const S32* a, const S32* b)
|
||||
{
|
||||
S32 av = *a;
|
||||
S32 bv = *b;
|
||||
|
||||
if (av < bv)
|
||||
return -1;
|
||||
else if (av > bv)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
const S32 VectorFixture::ints[] = {0, 10, 2, 3, 14, 4, 12, 6, 16, 7, 8, 1, 11, 5, 13, 9, 15};
|
||||
const U32 VectorFixture::length = sizeof(VectorFixture::ints) / sizeof(S32);
|
||||
|
||||
TEST_FIX(Vector, Allocation)
|
||||
{
|
||||
Vector<S32> *vector = new Vector<S32>;
|
||||
for (S32 i = 0; i < 1000; i++)
|
||||
vector->push_back(10000 + i);
|
||||
|
||||
// Erase the first element, 500 times.
|
||||
for (S32 i = 0; i < 500; i++)
|
||||
vector->erase(U32(0));
|
||||
|
||||
vector->compact();
|
||||
|
||||
EXPECT_EQ(vector->size(), 500) << "Vector was unexpectedly short!";
|
||||
|
||||
delete vector;
|
||||
}
|
||||
|
||||
TEST_FIX(Vector, Deallocation)
|
||||
{
|
||||
bool dtorVals[10];
|
||||
Vector<Dtor> v;
|
||||
|
||||
// Only add the first 9 entries; the last is populated below.
|
||||
for (U32 i = 0; i < 9; i++)
|
||||
v.push_back(Dtor(&dtorVals[i]));
|
||||
|
||||
// Fill the values array with false so we can test for destruction.
|
||||
for (U32 i = 0; i < 10; i++)
|
||||
dtorVals[i] = false;
|
||||
|
||||
v.decrement();
|
||||
EXPECT_TRUE(dtorVals[8]) << "Vector::decrement failed to call destructor";
|
||||
|
||||
v.decrement(2);
|
||||
EXPECT_TRUE(dtorVals[7]) << "Vector::decrement failed to call destructor";
|
||||
EXPECT_TRUE(dtorVals[6]) << "Vector::decrement failed to call destructor";
|
||||
|
||||
v.pop_back();
|
||||
EXPECT_TRUE(dtorVals[5]) << "Vector::pop_back failed to call destructor";
|
||||
|
||||
v.increment();
|
||||
v.last() = Dtor(&dtorVals[9]);
|
||||
v.clear();
|
||||
|
||||
// All elements should have been destructed.
|
||||
for (U32 i = 0; i < 10; i++)
|
||||
EXPECT_TRUE(dtorVals[i])
|
||||
<< "Element " << i << "'s destructor was not called";
|
||||
}
|
||||
|
||||
TEST_FIX(Vector, Sorting)
|
||||
{
|
||||
Vector<S32> v;
|
||||
|
||||
for(U32 i = 0; i < length; i++)
|
||||
v.push_back(ints[i]);
|
||||
|
||||
v.sort(sortInts);
|
||||
|
||||
for(U32 i = 0; i < length - 1; i++)
|
||||
EXPECT_TRUE(v[i] <= v[i + 1])
|
||||
<< "Element " << i << " was not in sorted order";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "unit/test.h"
|
||||
#include "core/util/path.h"
|
||||
|
||||
using namespace UnitTesting;
|
||||
|
||||
#define TEST( x ) test( ( x ), "FAIL: " #x )
|
||||
|
||||
CreateUnitTest(TestPathMakeRelativePath, "Core/Util/Path/MakeRelativePath")
|
||||
{
|
||||
void run()
|
||||
{
|
||||
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/") == "burg/file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("art/interiors/file.png", "art/interiors/burg/") == "../file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("art/file.png", "art/interiors/burg/") == "../../file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("file.png", "art/interiors/burg/") == "../../../file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/burg/") == "file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("art/interiors/camp/file.png", "art/interiors/burg/") == "../camp/file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/shapes/") == "../interiors/burg/file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("levels/den/file.png", "art/interiors/burg/") == "../../../levels/den/file.png");
|
||||
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/dts/burg/") == "../../interiors/burg/file.png");
|
||||
}
|
||||
};
|
||||
|
|
@ -1,358 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "unit/test.h"
|
||||
#include "core/util/str.h"
|
||||
#include "core/util/tVector.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "core/strings/unicode.h"
|
||||
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
|
||||
using namespace UnitTesting;
|
||||
|
||||
#define TEST( x ) test( ( x ), "FAIL: " #x )
|
||||
#define XTEST( t, x ) t->test( ( x ), "FAIL: " #x )
|
||||
|
||||
CreateUnitTest( TestString, "Util/String" )
|
||||
{
|
||||
struct StrTest
|
||||
{
|
||||
const UTF8* mData;
|
||||
const UTF16* mUTF16;
|
||||
U32 mLength;
|
||||
|
||||
StrTest() : mData( 0 ), mUTF16( 0 ) {}
|
||||
StrTest( const char* str )
|
||||
: mData( str ), mLength( str ? dStrlen( str ) : 0 ), mUTF16( NULL )
|
||||
{
|
||||
if( str )
|
||||
mUTF16 = convertUTF8toUTF16( mData );
|
||||
}
|
||||
~StrTest()
|
||||
{
|
||||
if( mUTF16 )
|
||||
delete [] mUTF16;
|
||||
}
|
||||
};
|
||||
|
||||
Vector< StrTest* > mStrings;
|
||||
|
||||
template< class T >
|
||||
void runTestOnStrings()
|
||||
{
|
||||
for( U32 i = 0; i < mStrings.size(); ++ i )
|
||||
T::run( this, *mStrings[ i ] );
|
||||
}
|
||||
template< class T >
|
||||
void runPairwiseTestOnStrings()
|
||||
{
|
||||
for( U32 i = 0; i < mStrings.size(); ++ i )
|
||||
for( U32 j = 0; j < mStrings.size(); ++ j )
|
||||
T::run( this, *mStrings[ i ], *mStrings[ j ] );
|
||||
}
|
||||
|
||||
struct Test1
|
||||
{
|
||||
static void run( TestString* test, StrTest& data )
|
||||
{
|
||||
String str( data.mData );
|
||||
String str16( data.mUTF16 );
|
||||
|
||||
XTEST( test, str.length() == data.mLength );
|
||||
XTEST( test, str.size() == data.mLength + 1 );
|
||||
XTEST( test, str.isEmpty() || str.length() > 0 );
|
||||
XTEST( test, str.length() == str16.length() );
|
||||
XTEST( test, str.size() == str16.size() );
|
||||
|
||||
XTEST( test, dMemcmp( str.utf16(), str16.utf16(), str.length() * sizeof( UTF16 ) ) == 0 );
|
||||
XTEST( test, !data.mData || dMemcmp( str.utf16(), data.mUTF16, str.length() * sizeof( UTF16 ) ) == 0 );
|
||||
XTEST( test, !data.mData || dMemcmp( str16.utf8(), data.mData, str.length() ) == 0 );
|
||||
|
||||
XTEST( test, !data.mData || dStrcmp( str.utf8(), data.mData ) == 0 );
|
||||
XTEST( test, !data.mData || dStrcmp( str.utf16(), data.mUTF16 ) == 0 );
|
||||
}
|
||||
};
|
||||
|
||||
struct Test2
|
||||
{
|
||||
static void run( TestString* test, StrTest& data )
|
||||
{
|
||||
String str( data.mData );
|
||||
|
||||
XTEST( test, str == str );
|
||||
XTEST( test, !( str != str ) );
|
||||
XTEST( test, !( str < str ) );
|
||||
XTEST( test, !( str > str ) );
|
||||
XTEST( test, str.equal( str ) );
|
||||
XTEST( test, str.equal( str, String::NoCase ) );
|
||||
}
|
||||
};
|
||||
|
||||
struct Test3
|
||||
{
|
||||
static void run( TestString* test, StrTest& d1, StrTest& d2 )
|
||||
{
|
||||
if( &d1 != &d2 )
|
||||
XTEST( test, String( d1.mData ) != String( d2.mData )
|
||||
|| ( String( d1.mData ).isEmpty() && String( d2.mData ).isEmpty() ) );
|
||||
else
|
||||
XTEST( test, String( d1.mData ) == String( d2.mData ) );
|
||||
}
|
||||
};
|
||||
|
||||
void testEmpty()
|
||||
{
|
||||
TEST( String().length() == 0 );
|
||||
TEST( String( "" ).length() == 0 );
|
||||
TEST( String().size() == 1 );
|
||||
TEST( String( "" ).size() == 1 );
|
||||
TEST( String().isEmpty() );
|
||||
TEST( String( "" ).isEmpty() );
|
||||
}
|
||||
|
||||
void testTrim()
|
||||
{
|
||||
TEST( String( " Foobar Barfoo \n\t " ).trim() == String( "Foobar Barfoo" ) );
|
||||
TEST( String( "Foobar" ).trim() == String( "Foobar" ) );
|
||||
TEST( String( " " ).trim().isEmpty() );
|
||||
}
|
||||
|
||||
void testCompare()
|
||||
{
|
||||
String str( "Foobar" );
|
||||
|
||||
TEST( str.compare( "Foo", 3 ) == 0 );
|
||||
TEST( str.compare( "bar", 3, String::NoCase | String::Right ) == 0 );
|
||||
TEST( str.compare( "foo", 3, String::NoCase ) == 0 );
|
||||
TEST( str.compare( "BAR", 3, String::NoCase | String::Right ) == 0 );
|
||||
TEST( str.compare( "Foobar" ) == 0 );
|
||||
TEST( str.compare( "Foo" ) != 0 );
|
||||
TEST( str.compare( "foobar", 0, String::NoCase ) == 0 );
|
||||
TEST( str.compare( "FOOBAR", 0, String::NoCase ) == 0 );
|
||||
TEST( str.compare( "Foobar", 0, String::Right ) == 0 );
|
||||
TEST( str.compare( "foobar", 0, String::NoCase | String::Right ) == 0 );
|
||||
}
|
||||
|
||||
void testOrder()
|
||||
{
|
||||
Vector< String > strs;
|
||||
|
||||
strs.push_back( "a" );
|
||||
strs.push_back( "a0" );
|
||||
strs.push_back( "a1" );
|
||||
strs.push_back( "a1a" );
|
||||
strs.push_back( "a1b" );
|
||||
strs.push_back( "a2" );
|
||||
strs.push_back( "a10" );
|
||||
strs.push_back( "a20" );
|
||||
|
||||
for( U32 i = 0; i < strs.size(); ++ i )
|
||||
{
|
||||
for( U32 j = 0; j < i; ++ j )
|
||||
{
|
||||
TEST( strs[ j ] < strs[ i ] );
|
||||
TEST( strs[ i ] > strs[ j ] );
|
||||
|
||||
TEST( !( strs[ j ] > strs[ i ] ) );
|
||||
TEST( !( strs[ i ] < strs[ i ] ) );
|
||||
|
||||
TEST( strs[ j ] <= strs[ i ] );
|
||||
TEST( strs[ i ] >= strs[ j ] );
|
||||
}
|
||||
|
||||
TEST( !( strs[ i ] < strs[ i ] ) );
|
||||
TEST( !( strs[ i ] > strs[ i ] ) );
|
||||
TEST( strs[ i ] <= strs[ i ] );
|
||||
TEST( strs[ i ] >= strs[ i ] );
|
||||
|
||||
for( U32 j = i + 1; j < strs.size(); ++ j )
|
||||
{
|
||||
TEST( strs[ j ] > strs[ i ] );
|
||||
TEST( strs[ i ] < strs[ j ] );
|
||||
|
||||
TEST( !( strs[ j ] < strs[ i ] ) );
|
||||
TEST( !( strs[ i ] > strs[ j ] ) );
|
||||
|
||||
TEST( strs[ j ] >= strs[ i ] );
|
||||
TEST( strs[ i ] <= strs[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testFind()
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void testInsert()
|
||||
{
|
||||
// String.insert( Pos, Char )
|
||||
TEST( String( "aa" ).insert( 1, 'c' ) == String( "aca" ) );
|
||||
|
||||
// String.insert( Pos, String )
|
||||
TEST( String( "aa" ).insert( 1, "cc" ) == String( "acca" ) );
|
||||
TEST( String( "aa" ).insert( 1, String( "cc" ) ) == String( "acca" ) );
|
||||
|
||||
// String.insert( Pos, String, Len )
|
||||
TEST( String( "aa" ).insert( 1, "ccdddd", 2 ) == String( "acca" ) );
|
||||
}
|
||||
|
||||
void testErase()
|
||||
{
|
||||
TEST( String( "abba" ).erase( 1, 2 ) == String( "aa" ) );
|
||||
TEST( String( "abba" ).erase( 0, 4 ).isEmpty() );
|
||||
}
|
||||
|
||||
void testReplace()
|
||||
{
|
||||
// String.replace( Pos, Len, String )
|
||||
TEST( String( "abba" ).replace( 1, 2, "ccc" ) == String( "accca" ) );
|
||||
TEST( String( "abba" ).replace( 1, 2, String( "ccc" ) ) == String( "accca" ) );
|
||||
TEST( String( "abba" ).replace( 0, 4, "" ).isEmpty() );
|
||||
TEST( String( "abba" ).replace( 2, 2, "c" ) == String( "abc" ) );
|
||||
|
||||
// String.replace( Char, Char )
|
||||
TEST( String().replace( 'a', 'b' ).isEmpty() );
|
||||
TEST( String( "ababc" ).replace( 'a', 'b' ) == String( "bbbbc" ) );
|
||||
TEST( String( "ababc" ).replace( 'd', 'e' ) == String( "ababc" ) );
|
||||
|
||||
// String.replace( String, String )
|
||||
TEST( String().replace( "foo", "bar" ).isEmpty() );
|
||||
TEST( String( "foobarfoo" ).replace( "foo", "bar" ) == String( "barbarbar" ) );
|
||||
TEST( String( "foobar" ).replace( "xx", "yy" ) == String( "foobar" ) );
|
||||
TEST( String( "foofoofoo" ).replace( "foo", "" ).isEmpty() );
|
||||
}
|
||||
|
||||
void testSubstr()
|
||||
{
|
||||
TEST( String( "foobar" ).substr( 0, 3 ) == String( "foo" ) );
|
||||
TEST( String( "foobar" ).substr( 3 ) == String( "bar" ) );
|
||||
TEST( String( "foobar" ).substr( 2, 2 ) == String( "ob" ) );
|
||||
TEST( String( "foobar" ).substr( 2, 0 ).isEmpty() );
|
||||
TEST( String( "foobar" ).substr( 0, 6 ) == String( "foobar" ) );
|
||||
}
|
||||
|
||||
void testToString()
|
||||
{
|
||||
TEST( String::ToString( U32( 1 ) ) == String( "1" ) );
|
||||
TEST( String::ToString( S32( -1 ) ) == String( "-1" ) );
|
||||
TEST( String::ToString( F32( 1.01 ) ) == String( "1.01" ) );
|
||||
TEST( String::ToString( "%s%i", "foo", 1 ) == String( "foo1" ) );
|
||||
}
|
||||
|
||||
void testCaseConversion()
|
||||
{
|
||||
TEST( String::ToLower( "foobar123." ) == String( "foobar123." ) );
|
||||
TEST( String::ToLower( "FOOBAR123." ) == String( "foobar123." ) );
|
||||
TEST( String::ToUpper( "barfoo123." ) == String( "BARFOO123." ) );
|
||||
TEST( String::ToUpper( "BARFOO123." ) == String( "BARFOO123." ) );
|
||||
}
|
||||
|
||||
void testConcat()
|
||||
{
|
||||
TEST( String( "foo" ) + String( "bar" ) == String( "foobar" ) );
|
||||
TEST( String() + String( "bar" ) == String( "bar" ) );
|
||||
TEST( String( "foo" ) + String() == String( "foo" ) );
|
||||
TEST( String() + String() == String() );
|
||||
TEST( String( "fo" ) + 'o' == String( "foo" ) );
|
||||
TEST( 'f' + String( "oo" ) == String( "foo" ) );
|
||||
TEST( String( "foo" ) + "bar" == String( "foobar" ) );
|
||||
TEST( "foo" + String( "bar" ) == String( "foobar" ) );
|
||||
}
|
||||
|
||||
void testHash()
|
||||
{
|
||||
TEST( String( "foo" ).getHashCaseSensitive() == String( "foo" ).getHashCaseSensitive() );
|
||||
TEST( String( "foo" ).getHashCaseSensitive() != String( "bar" ).getHashCaseSensitive() );
|
||||
TEST( String( "foo" ).getHashCaseInsensitive() == String( "FOO" ).getHashCaseInsensitive() );
|
||||
}
|
||||
|
||||
void testIntern()
|
||||
{
|
||||
TEST( String( "foo" ).intern().isSame( String( "foo" ).intern() ) );
|
||||
TEST( !String( "foo" ).intern().isSame( String( "bar" ).intern() ) );
|
||||
TEST( !String( "foo" ).intern().isSame( String( "Foo" ).intern() ) );
|
||||
TEST( String( "foo" ).intern() == String( "foo" ).intern() );
|
||||
TEST( String( "foo" ).intern() != String( "bar" ).intern() );
|
||||
TEST( String( "foo" ).intern().isInterned() );
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
mStrings.push_back( new StrTest( NULL ) );
|
||||
mStrings.push_back( new StrTest( "" ) );
|
||||
mStrings.push_back( new StrTest( "Torque" ) );
|
||||
mStrings.push_back( new StrTest( "TGEA" ) );
|
||||
mStrings.push_back( new StrTest( "GarageGames" ) );
|
||||
mStrings.push_back( new StrTest( "TGB" ) );
|
||||
mStrings.push_back( new StrTest( "games" ) );
|
||||
mStrings.push_back( new StrTest( "engine" ) );
|
||||
mStrings.push_back( new StrTest( "rocks" ) );
|
||||
mStrings.push_back( new StrTest( "technology" ) );
|
||||
mStrings.push_back( new StrTest( "Torque 3D" ) );
|
||||
mStrings.push_back( new StrTest( "Torque 2D" ) );
|
||||
|
||||
runTestOnStrings< Test1 >();
|
||||
runTestOnStrings< Test2 >();
|
||||
|
||||
runPairwiseTestOnStrings< Test3 >();
|
||||
|
||||
testEmpty();
|
||||
testTrim();
|
||||
testCompare();
|
||||
testOrder();
|
||||
testFind();
|
||||
testInsert();
|
||||
testReplace();
|
||||
testErase();
|
||||
testSubstr();
|
||||
testToString();
|
||||
testCaseConversion();
|
||||
testConcat();
|
||||
testHash();
|
||||
testIntern();
|
||||
|
||||
for( U32 i = 0; i < mStrings.size(); ++ i )
|
||||
delete mStrings[ i ];
|
||||
mStrings.clear();
|
||||
}
|
||||
};
|
||||
|
||||
CreateUnitTest( TestStringBuilder, "Util/StringBuilder" )
|
||||
{
|
||||
void run()
|
||||
{
|
||||
StringBuilder str;
|
||||
|
||||
str.append( 'f' );
|
||||
str.append( "oo" );
|
||||
str.append( String( "ba" ) );
|
||||
str.append( "rfajskfdj", 1 );
|
||||
str.format( "%s", "barfoo" );
|
||||
|
||||
TEST( str.end() == String( "foobarbarfoo" ) );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !TORQUE_SHIPPING
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "unit/test.h"
|
||||
#include "console/console.h"
|
||||
#include "core/util/tVector.h"
|
||||
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
|
||||
using namespace UnitTesting;
|
||||
|
||||
#define TEST( x ) test( ( x ), "FAIL: " #x )
|
||||
#define XTEST( t, x ) t->test( ( x ), "FAIL: " #x )
|
||||
|
||||
CreateUnitTest( TestVector, "Util/Vector" )
|
||||
{
|
||||
bool dtorVals[ 10 ];
|
||||
struct Dtor
|
||||
{
|
||||
bool* ptr;
|
||||
Dtor() {}
|
||||
Dtor( bool* ptr )
|
||||
: ptr( ptr ) { *ptr = false; }
|
||||
~Dtor()
|
||||
{
|
||||
*ptr = true;
|
||||
}
|
||||
};
|
||||
void testDestruction()
|
||||
{
|
||||
Vector< Dtor > v;
|
||||
|
||||
for( U32 i = 0; i < 9; ++ i )
|
||||
v.push_back( Dtor( &dtorVals[ i ] ) );
|
||||
|
||||
v.decrement();
|
||||
v.decrement( 2 );
|
||||
v.pop_back();
|
||||
v.increment();
|
||||
v.last() = Dtor( &dtorVals[ 9 ] );
|
||||
v.clear();
|
||||
|
||||
TEST( dtorVals[ 0 ] );
|
||||
TEST( dtorVals[ 1 ] );
|
||||
TEST( dtorVals[ 2 ] );
|
||||
TEST( dtorVals[ 3 ] );
|
||||
TEST( dtorVals[ 4 ] );
|
||||
TEST( dtorVals[ 5 ] );
|
||||
TEST( dtorVals[ 6 ] );
|
||||
TEST( dtorVals[ 7 ] );
|
||||
TEST( dtorVals[ 8 ] );
|
||||
TEST( dtorVals[ 9 ] );
|
||||
}
|
||||
|
||||
static S32 QSORT_CALLBACK sortInts( const S32* a, const S32* b )
|
||||
{
|
||||
S32 av = *a;
|
||||
S32 bv = *b;
|
||||
|
||||
if( av < bv )
|
||||
return -1;
|
||||
else if( av > bv )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void testSort()
|
||||
{
|
||||
Vector< S32 > v;
|
||||
|
||||
v.push_back( 0 );
|
||||
v.push_back( 10 );
|
||||
v.push_back( 2 );
|
||||
v.push_back( 3 );
|
||||
v.push_back( 14 );
|
||||
v.push_back( 4 );
|
||||
v.push_back( 12 );
|
||||
v.push_back( 6 );
|
||||
v.push_back( 16 );
|
||||
v.push_back( 7 );
|
||||
v.push_back( 8 );
|
||||
v.push_back( 1 );
|
||||
v.push_back( 11 );
|
||||
v.push_back( 5 );
|
||||
v.push_back( 13 );
|
||||
v.push_back( 9 );
|
||||
v.push_back( 15 );
|
||||
|
||||
v.sort( sortInts );
|
||||
|
||||
TEST( v[ 0 ] == 0 );
|
||||
TEST( v[ 1 ] == 1 );
|
||||
TEST( v[ 2 ] == 2 );
|
||||
TEST( v[ 3 ] == 3 );
|
||||
TEST( v[ 4 ] == 4 );
|
||||
TEST( v[ 5 ] == 5 );
|
||||
TEST( v[ 6 ] == 6 );
|
||||
TEST( v[ 7 ] == 7 );
|
||||
TEST( v[ 8 ] == 8 );
|
||||
TEST( v[ 9 ] == 9 );
|
||||
TEST( v[ 10 ] == 10 );
|
||||
TEST( v[ 11 ] == 11 );
|
||||
TEST( v[ 12 ] == 12 );
|
||||
TEST( v[ 13 ] == 13 );
|
||||
TEST( v[ 14 ] == 14 );
|
||||
TEST( v[ 15 ] == 15 );
|
||||
TEST( v[ 16 ] == 16 );
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
testSort();
|
||||
testDestruction();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
#include "core/crc.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "core/util/zip/zipArchive.h"
|
||||
|
|
@ -194,3 +194,4 @@ private:
|
|||
return ret;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "unit/test.h"
|
||||
|
|
@ -250,3 +250,4 @@ private:
|
|||
return ret;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "core/util/zip/zipArchive.h"
|
||||
#include "core/util/zip/unitTests/zipTest.h"
|
||||
|
|
@ -242,3 +242,4 @@ bail:
|
|||
return ret;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
|
@ -944,12 +944,22 @@ bool ReadFile(const Path &inPath, void *&outData, U32 &outSize, bool inNullTermi
|
|||
if ( inNullTerminate )
|
||||
{
|
||||
outData = new char [outSize+1];
|
||||
if( !outData )
|
||||
{
|
||||
// out of memory
|
||||
return false;
|
||||
}
|
||||
sizeRead = fileR->read(outData, outSize);
|
||||
static_cast<char *>(outData)[outSize] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
outData = new char [outSize];
|
||||
if( !outData )
|
||||
{
|
||||
// out of memory
|
||||
return false;
|
||||
}
|
||||
sizeRead = fileR->read(outData, outSize);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue