//============================================================================== // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //============================================================================== //============================================================================== // File: cObject.cpp // Project: Shooting Star // Author: Jarmo Hekkanen // Copyrights (c) 2003 2ndPoint ry (www.2ndpoint.fi) //------------------------------------------------------------------------------ // Revision history //============================================================================== //============================================================================== // Includes #include "cObject.hpp" #include "Debug.hpp" //------------------------------------------------------------------------------ // Namespaces using namespace ShootingStar; //============================================================================== list cObject::mObjects; list cObject::mGarbageObjects; bool cObject::mCleanUp = false; //! Constructor cObject::cObject (void): mReferenceCount (0), mAlive (false), mpParent (NULL) { mObjects.push_back (this); }; //! Destructor cObject::~cObject (void) { //dbgInfo () << GetID () << " Destructing\n"; }; void cObject::Kill (void) { mAlive = false; if ( mpParent != NULL ) { mpParent->mChildren.remove (this); mpParent = NULL; } list::iterator child = mChildren.begin (), temp; while ( child != mChildren.end () ) { temp = child; temp++; (*child)->Kill (); child = temp; } } void cObject::SetParent (cObject *pParent) { dbg::assertion (DBG_ASSERTION (pParent != this)); // Remove old parent if ( mpParent != NULL ) { mpParent->mChildren.remove (this); } // Set new parent mpParent = pParent; if ( pParent != NULL ) { pParent->mChildren.push_back (this); } } //! Add reference void cObject::AddReference (void) { dbg::assertion (DBG_ASSERTION (mReferenceCount >= 0)); mReferenceCount++; } //! Release reference void cObject::ReleaseReference (void) { if ( mCleanUp ) return; dbg::assertion (DBG_ASSERTION (mReferenceCount > 0)); mReferenceCount--; if ( mReferenceCount <= 0 ) { //dbgInfo () << GetID () << " reference count is zero\n"; mReferenceCount = -1; if ( IsAlive () ) Kill (); mObjects.remove (this); mGarbageObjects.push_back (this); } } void cObject::CollectGarbage (void) { //dbgInfo () << "Deleting " << mGarbageObjects.size () << " garbage objects" << endl; list::iterator object = mGarbageObjects.begin (); while ( object != mGarbageObjects.end () ) { delete *object; object++; } mGarbageObjects.clear (); } void cObject::CleanUp (void) { mCleanUp = true; CollectGarbage (); dbgInfo () << "Cleaning up " << mObjects.size () << " objects" << endl; list::iterator object = mObjects.begin (); while ( object != mObjects.end () ) { /*dbgInfo () << "Clearning up object: " << (*object)->GetID () << " ref count: " << (*object)->mReferenceCount << endl;*/ delete *object; object++; } mObjects.clear (); dbg::assertion (DBG_ASSERTION (mGarbageObjects.size () == 0)); dbgInfo () << "Cleaning done" << endl; mCleanUp = false; } //============================================================================== // EOF //==============================================================================