From 18ba0646c0fcf707ed897729902b4af4ea3bccf3 Mon Sep 17 00:00:00 2001 From: LuisAntonRebollo Date: Sun, 25 May 2014 16:50:19 +0200 Subject: [PATCH] Increased stability Torqu3D: unit-tests running without a crash. See the console.log after ran unitTest_runTests( "", true ). @signmotion --- Engine/source/T3D/debris.cpp | 13 ++++++++-- Engine/source/T3D/fx/explosion.cpp | 7 ++++++ Engine/source/T3D/fx/splash.cpp | 14 +++++++++-- Engine/source/T3D/physics/physicsDebris.cpp | 9 ++++++- Engine/source/T3D/projectile.cpp | 7 ++++++ Engine/source/T3D/vehicles/vehicleBlocker.cpp | 6 +++++ .../core/util/journal/test/testJournal.cpp | 12 +++++++++ .../core/util/journal/test/testProcess.cpp | 2 ++ .../gui/editor/inspector/dynamicGroup.cpp | 3 +++ Engine/source/gui/editor/inspector/field.cpp | 2 +- Engine/source/gui/editor/inspector/group.cpp | 2 +- .../gui/editor/inspector/variableField.cpp | 6 +++++ Engine/source/platform/test/testNet.cpp | 10 ++++++-- Engine/source/scene/sceneManager.cpp | 4 ++- Engine/source/sfx/sfxSource.h | 2 +- Engine/source/sfx/sfxSystem.cpp | 3 ++- Engine/source/unit/test.cpp | 5 ++++ Engine/source/unit/tests/testComponents.cpp | 25 +++++++++++++------ 18 files changed, 113 insertions(+), 19 deletions(-) diff --git a/Engine/source/T3D/debris.cpp b/Engine/source/T3D/debris.cpp index 78526b7ad..c7b5fc42b 100644 --- a/Engine/source/T3D/debris.cpp +++ b/Engine/source/T3D/debris.cpp @@ -511,6 +511,12 @@ bool Debris::onAdd() return false; } + if( !mDataBlock ) + { + Con::errorf("Debris::onAdd - Fail - No datablock"); + return false; + } + // create emitters for( int i=0; iremoveObjectFromScene(this); - getContainer()->removeObject(this); + if( getSceneManager() ) + getSceneManager()->removeObjectFromScene(this); + + if( getContainer() ) + getContainer()->removeObject(this); Parent::onRemove(); } diff --git a/Engine/source/T3D/fx/explosion.cpp b/Engine/source/T3D/fx/explosion.cpp index b84efad3f..5e06d738d 100644 --- a/Engine/source/T3D/fx/explosion.cpp +++ b/Engine/source/T3D/fx/explosion.cpp @@ -771,6 +771,7 @@ bool ExplosionData::preload(bool server, String &errorStr) //-------------------------------------- // Explosion::Explosion() + : mDataBlock( NULL ) { mTypeMask |= ExplosionObjectType | LightObjectType; @@ -831,6 +832,12 @@ bool Explosion::onAdd() if ( !conn || !Parent::onAdd() ) return false; + if( !mDataBlock ) + { + Con::errorf("Explosion::onAdd - Fail - No datablok"); + return false; + } + mDelayMS = mDataBlock->delayMS + sgRandom.randI( -mDataBlock->delayVariance, mDataBlock->delayVariance ); mEndingMS = mDataBlock->lifetimeMS + sgRandom.randI( -mDataBlock->lifetimeVariance, mDataBlock->lifetimeVariance ); diff --git a/Engine/source/T3D/fx/splash.cpp b/Engine/source/T3D/fx/splash.cpp index 7a3eda0f9..1558f2dbc 100644 --- a/Engine/source/T3D/fx/splash.cpp +++ b/Engine/source/T3D/fx/splash.cpp @@ -303,6 +303,7 @@ bool SplashData::preload(bool server, String &errorStr) // Splash //-------------------------------------------------------------------------- Splash::Splash() + : mDataBlock( NULL ) { dMemset( mEmitterList, 0, sizeof( mEmitterList ) ); @@ -353,6 +354,12 @@ bool Splash::onAdd() if(!conn || !Parent::onAdd()) return false; + if( !mDataBlock ) + { + Con::errorf("Splash::onAdd - Fail - No datablock"); + return false; + } + mDelayMS = mDataBlock->delayMS + sgRandom.randI( -mDataBlock->delayVariance, mDataBlock->delayVariance ); mEndingMS = mDataBlock->lifetimeMS + sgRandom.randI( -mDataBlock->lifetimeVariance, mDataBlock->lifetimeVariance ); @@ -408,8 +415,11 @@ void Splash::onRemove() ringList.clear(); - getSceneManager()->removeObjectFromScene(this); - getContainer()->removeObject(this); + if( getSceneManager() ) + getSceneManager()->removeObjectFromScene(this); + + if( getContainer() ) + getContainer()->removeObject(this); Parent::onRemove(); } diff --git a/Engine/source/T3D/physics/physicsDebris.cpp b/Engine/source/T3D/physics/physicsDebris.cpp index 38549980a..ba9c7e4b6 100644 --- a/Engine/source/T3D/physics/physicsDebris.cpp +++ b/Engine/source/T3D/physics/physicsDebris.cpp @@ -311,7 +311,8 @@ PhysicsDebris* PhysicsDebris::create( PhysicsDebrisData *datablock, } PhysicsDebris::PhysicsDebris() - : mLifetime( 0.0f ), + : mDataBlock( NULL ), + mLifetime( 0.0f ), mShapeInstance( NULL ), mWorld( NULL ), mInitialLinVel( Point3F::Zero ) @@ -342,6 +343,12 @@ bool PhysicsDebris::onAdd() if ( !Parent::onAdd() ) return false; + if( !mDataBlock ) + { + Con::errorf("PhysicsDebris::onAdd - Fail - No datablock"); + return false; + } + // If it has a fixed lifetime then calculate it. if ( mDataBlock->lifetime > 0.0f ) { diff --git a/Engine/source/T3D/projectile.cpp b/Engine/source/T3D/projectile.cpp index 86886c2b5..ccf9a7505 100644 --- a/Engine/source/T3D/projectile.cpp +++ b/Engine/source/T3D/projectile.cpp @@ -550,6 +550,7 @@ S32 ProjectileData::scaleValue( S32 value, bool down ) // Projectile::Projectile() : mPhysicsWorld( NULL ), + mDataBlock( NULL ), mCurrPosition( 0, 0, 0 ), mCurrVelocity( 0, 0, 1 ), mSourceObjectId( -1 ), @@ -697,6 +698,12 @@ bool Projectile::onAdd() if(!Parent::onAdd()) return false; + if( !mDataBlock ) + { + Con::errorf("Projectile::onAdd - Fail - Not datablock"); + return false; + } + if (isServerObject()) { ShapeBase* ptr; diff --git a/Engine/source/T3D/vehicles/vehicleBlocker.cpp b/Engine/source/T3D/vehicles/vehicleBlocker.cpp index e85d44ff9..a31969d1b 100644 --- a/Engine/source/T3D/vehicles/vehicleBlocker.cpp +++ b/Engine/source/T3D/vehicles/vehicleBlocker.cpp @@ -71,6 +71,12 @@ bool VehicleBlocker::onAdd() mObjBox.minExtents.set(-mDimensions.x, -mDimensions.y, 0); mObjBox.maxExtents.set( mDimensions.x, mDimensions.y, mDimensions.z); + if( !mObjBox.isValidBox() ) + { + Con::errorf("VehicleBlocker::onAdd - Fail - No valid object box"); + return false; + } + resetWorldBox(); setRenderTransform(mObjToWorld); diff --git a/Engine/source/core/util/journal/test/testJournal.cpp b/Engine/source/core/util/journal/test/testJournal.cpp index 404f7637e..9bf13fbf2 100644 --- a/Engine/source/core/util/journal/test/testJournal.cpp +++ b/Engine/source/core/util/journal/test/testJournal.cpp @@ -48,6 +48,12 @@ CreateUnitTest(TestsJournalRecordAndPlayback, "Journal/Basic") // Initialize journal recording and fire off some events... Journal::Record("test.jrn"); + if( !Journal::IsRecording() ) + { + test(false, "Fail"); + return; + } + testEvent.trigger(16); testEvent.trigger(17); testEvent.trigger(18); @@ -132,6 +138,12 @@ CreateUnitTest(TestsJournalDynamicSignals, "Journal/DynamicSignals") // Initialize journal recording and fire off some events... Journal::Record("test.jrn"); + if( !Journal::IsRecording() ) + { + test(false, "Fail"); + return; + } + testEvent.trigger(1); dynamicA->trigger(8, 100); testEvent.trigger(2); diff --git a/Engine/source/core/util/journal/test/testProcess.cpp b/Engine/source/core/util/journal/test/testProcess.cpp index 1dc847b34..0f8da95a5 100644 --- a/Engine/source/core/util/journal/test/testProcess.cpp +++ b/Engine/source/core/util/journal/test/testProcess.cpp @@ -52,5 +52,7 @@ CreateUnitTest(TestingProcess, "Journal/Process") 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!"); + + Process::remove(this, &TestingProcess::process); } }; \ No newline at end of file diff --git a/Engine/source/gui/editor/inspector/dynamicGroup.cpp b/Engine/source/gui/editor/inspector/dynamicGroup.cpp index 9f2285cfb..1e9d19caf 100644 --- a/Engine/source/gui/editor/inspector/dynamicGroup.cpp +++ b/Engine/source/gui/editor/inspector/dynamicGroup.cpp @@ -98,6 +98,9 @@ static S32 QSORT_CALLBACK compareEntries(const void* a,const void* b) //----------------------------------------------------------------------------- bool GuiInspectorDynamicGroup::inspectGroup() { + if( !mParent ) + return false; + // clear the first responder if it's set mStack->clearFirstResponder(); diff --git a/Engine/source/gui/editor/inspector/field.cpp b/Engine/source/gui/editor/inspector/field.cpp index ce5b0a560..5dd9e6c25 100644 --- a/Engine/source/gui/editor/inspector/field.cpp +++ b/Engine/source/gui/editor/inspector/field.cpp @@ -455,7 +455,7 @@ void GuiInspectorField::setInspectorProfile() { GuiControlProfile *profile = NULL; - if( mInspector->getNumInspectObjects() > 1 ) + if( mInspector && (mInspector->getNumInspectObjects() > 1) ) { if( !hasSameValueInAllObjects() ) Sim::findObject( "GuiInspectorMultiFieldDifferentProfile", profile ); diff --git a/Engine/source/gui/editor/inspector/group.cpp b/Engine/source/gui/editor/inspector/group.cpp index 7a52e7ca3..b272032ff 100644 --- a/Engine/source/gui/editor/inspector/group.cpp +++ b/Engine/source/gui/editor/inspector/group.cpp @@ -230,7 +230,7 @@ void GuiInspectorGroup::clearFields() bool GuiInspectorGroup::inspectGroup() { // We can't inspect a group without a target! - if( !mParent->getNumInspectObjects() ) + if( !mParent || !mParent->getNumInspectObjects() ) return false; // to prevent crazy resizing, we'll just freeze our stack for a sec.. diff --git a/Engine/source/gui/editor/inspector/variableField.cpp b/Engine/source/gui/editor/inspector/variableField.cpp index 810ba45a7..f773722e0 100644 --- a/Engine/source/gui/editor/inspector/variableField.cpp +++ b/Engine/source/gui/editor/inspector/variableField.cpp @@ -50,6 +50,12 @@ GuiInspectorVariableField::~GuiInspectorVariableField() bool GuiInspectorVariableField::onAdd() { + if( !mInspector ) + { + Con::errorf("GuiInspectorVariableField::onAdd - Fail - No inspector"); + return false; + } + setInspectorProfile(); // Hack: skip our immediate parent diff --git a/Engine/source/platform/test/testNet.cpp b/Engine/source/platform/test/testNet.cpp index 7be6b8a03..ae2a0c226 100644 --- a/Engine/source/platform/test/testNet.cpp +++ b/Engine/source/platform/test/testNet.cpp @@ -87,8 +87,8 @@ CreateUnitTest( TestTCPRequest, "Platform/Net/TCPRequest") // Open a TCP connection to garagegames.com mSocket = Net::openConnectTo("ip:72.246.107.193:80"); - - while(Process::processEvents()) + U32 limit = Platform::getRealMilliseconds() + (5*1000); + while(Process::processEvents() && (Platform::getRealMilliseconds() < limit) ) ; // Unhook from the signals. @@ -176,6 +176,12 @@ CreateUnitTest( TestTCPRequestJournal, "Platform/Net/JournalTCPRequest") { Journal::Record("journalTCP.jrn"); + if( !Journal::IsRecording() ) + { + test(0, "Failed."); + return; + } + makeRequest(); S32 bytesRead = mDataRecved; diff --git a/Engine/source/scene/sceneManager.cpp b/Engine/source/scene/sceneManager.cpp index fa6721ac7..d07e9fb9a 100644 --- a/Engine/source/scene/sceneManager.cpp +++ b/Engine/source/scene/sceneManager.cpp @@ -605,6 +605,7 @@ bool SceneManager::addObjectToScene( SceneObject* object ) void SceneManager::removeObjectFromScene( SceneObject* obj ) { + AssertFatal( obj, "SceneManager::removeObjectFromScene - Object is not declared" ); AssertFatal( obj->getSceneManager() == this, "SceneManager::removeObjectFromScene - Object not part of SceneManager" ); // Notify the object. @@ -613,7 +614,8 @@ void SceneManager::removeObjectFromScene( SceneObject* obj ) // Remove the object from the container. - getContainer()->removeObject( obj ); + if( getContainer() ) + getContainer()->removeObject( obj ); // Remove the object from the zoning system. diff --git a/Engine/source/sfx/sfxSource.h b/Engine/source/sfx/sfxSource.h index 83e31d0d2..e47b179d0 100644 --- a/Engine/source/sfx/sfxSource.h +++ b/Engine/source/sfx/sfxSource.h @@ -434,7 +434,7 @@ class SFXSource : public SimGroup virtual bool isVirtualized() const { return false; } /// Returns true if this is a looping source. - bool isLooping() const { return mDescription->mIsLooping; } + bool isLooping() const { return mDescription.isValid() && mDescription->mIsLooping; } /// @} diff --git a/Engine/source/sfx/sfxSystem.cpp b/Engine/source/sfx/sfxSystem.cpp index c43a44b2f..4c3d1fdca 100644 --- a/Engine/source/sfx/sfxSystem.cpp +++ b/Engine/source/sfx/sfxSystem.cpp @@ -686,7 +686,8 @@ void SFXSystem::_onRemoveSource( SFXSource* source ) if( dynamic_cast< SFXSound* >( source ) ) { SFXSoundVector::iterator iter = find( mSounds.begin(), mSounds.end(), static_cast< SFXSound* >( source ) ); - mSounds.erase_fast( iter ); + if( iter != mSounds.end() ) + mSounds.erase_fast( iter ); mStatNumSounds = mSounds.size(); } diff --git a/Engine/source/unit/test.cpp b/Engine/source/unit/test.cpp index 5e6438639..050425687 100644 --- a/Engine/source/unit/test.cpp +++ b/Engine/source/unit/test.cpp @@ -29,6 +29,8 @@ #include "unit/test.h" +#include "core/util/journal/process.h" + namespace UnitTesting { @@ -275,6 +277,9 @@ bool TestRun::test(const char* module, bool skipInteractive) Platform::setCurrentDirectory(cwdSave); + // sanity check for avoid Process::requestShutdown() called on some tests + Process::processEvents(); + // And indicate our failure situation in the return value. return !_failureCount; } diff --git a/Engine/source/unit/tests/testComponents.cpp b/Engine/source/unit/tests/testComponents.cpp index 12297bb08..b4a78ca39 100644 --- a/Engine/source/unit/tests/testComponents.cpp +++ b/Engine/source/unit/tests/testComponents.cpp @@ -91,9 +91,17 @@ public: // for this functionality later void unit_test( UnitTest *test ) { + AssertFatal(test, "CachedInterfaceExampleComponent::unit_test - NULL UnitTest"); + + if( !test ) + return; + test->test( mpU32 != NULL, "Pointer to dependent interface is NULL" ); - test->test( *(*mpU32) & ( 1 << 24 ), "Pointer to interface data is bogus." ); - test->test( *(*mpU32) != *mMyId, "Two of me have the same ID, bad!" ); + if( mpU32 ) + { + test->test( *(*mpU32) & ( 1 << 24 ), "Pointer to interface data is bogus." ); + test->test( *(*mpU32) != *mMyId, "Two of me have the same ID, bad!" ); + } } }; @@ -130,13 +138,16 @@ CreateUnitTest(TestComponentInterfacing, "Components/Composition") test( componentB->getOwner() == testComponent, "testComponent did not properly set the mOwner field of componentB to NULL." ); // Register the object with the simulation, kicking off the interface registration - test( testComponent->registerObject(), "Failed to register testComponent" ); + const bool registered = testComponent->registerObject(); + test( registered, "Failed to register testComponent" ); // Interface tests - componentA->unit_test( this ); - componentB->unit_test( this ); - - testComponent->deleteObject(); + if( registered ) + { + componentA->unit_test( this ); + componentB->unit_test( this ); + testComponent->deleteObject(); + } test( m.check(), "Component composition test leaked memory." ); }