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:
Daniel Buckmaster 2014-12-15 12:15:55 +11:00
commit 33ff180593
2053 changed files with 172002 additions and 69530 deletions

View file

@ -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);
}

View file

@ -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)
//

View file

@ -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 );
}

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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]

View file

@ -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 ) )

View file

@ -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 )
{
}

View file

@ -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.

View 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

View file

@ -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

View file

@ -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?");
}
};

View file

@ -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 */
}

View file

@ -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

View file

@ -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 ); }

View file

@ -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;

View 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

View 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

View 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

View file

@ -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

View 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

View file

@ -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");
}
};

View file

@ -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

View file

@ -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

View file

@ -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;
}
};
*/

View file

@ -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;
}
};
*/

View file

@ -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;
}
};
*/

View file

@ -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);
}