/* $Id: attachableobject.hpp,v 1.15.2.1 2006/01/20 11:23:30 chfreund Exp $ */ #ifndef _ATTACHABLEOBJECT_HPP_ #define _ATTACHABLEOBJECT_HPP_ /******************************************************************************/ #include "global.hpp" #include "object.hpp" #include #include /******************************************************************************/ class AttachableObject : public Object { friend class AttachableRegistrar; public: AttachableObject() {} /******************************************************************************/ virtual ~AttachableObject( void ) { LOG( 5 ) INFO( "AttachableObject::~AttachableObject: detaching me (%p)\n", this ); detachFromAll(); LOG( 5 ) printAttachInfo( false ); LOG( 5 ) INFO( "AttachableObject::~AttachableObject: done\n" ); } /******************************************************************************/ bool attachTo( AttachableObject* const o ) { LOG( 5 ) INFO( "AttachableObject::attachTo: attaching me (%p)\n", this ); DBG( 4 ) { for( int i = 0; i < getNAttachedObjects(); i++ ) { if( ! CHECK( getAttachedObject( i ) != o, "AttachableObject::attachTo: attempt of double " "attachment: \"%s\" <-> \"%s\"\n", getIDString(), o->getIDString() ) ) return false; } } o->addAttachEntry( this ); addAttachEntry( o ); LOG( 5 ) printAttachInfo( true ); LOG( 5 ) INFO( "AttachableObject::attachTo: attaching done\n" ); return true; } /******************************************************************************/ bool detachFrom( AttachableObject* const o ) { LOG( 5 ) INFO( "AttachableObject::detachFrom: detaching...\n" ); const bool ret = removeAttachEntry( o ) && o->removeAttachEntry( this ); CHECK( ret, "AttachableObject::detachFrom: could not detach from other " "object\n" ); LOG( 5 ) printAttachInfo( false ); LOG( 5 ) INFO( "AttachableObject::detachFrom: detaching done\n" ); return ret; } /******************************************************************************/ bool detachFrom( const int i ) { return detachFrom( m_attachedTo[i] ); } /******************************************************************************/ void detachFromAll( void ) { // (hopefully) works with std:vector because loop index decrements for( int i = m_attachedTo.size()-1; i >= 0; i-- ) { detachFrom( i ); } } /******************************************************************************/ int getAttachedObjectIndex( const AttachableObject* const o ) const { for( unsigned int i = 0; i < m_attachedTo.size(); i++ ) { if( o == m_attachedTo[i] ) return i; } return -1; } /******************************************************************************/ int getNAttachedObjects( void ) const { return m_attachedTo.size(); } AttachableObject* getAttachedObject( const int i ) const { return m_attachedTo[i]; } void printAttachInfo( const bool withOwnID ) const; /******************************************************************************/ virtual void serialize( Uint8*& bufferPointer ) const; virtual void deserialize( Uint8*& bufferPointer ); virtual Uint32 getSerializeBufferSize() const; /******************************************************************************/ protected: virtual bool removeAttachEntry( const AttachableObject* const o ) { const int i = getAttachedObjectIndex( o ); if( i < 0 ) { CHECK( false, "AttachableObject::removeAttachEntry: don't " "know the other object\n" ); return false; } const std::vector::iterator iter = m_attachedTo.begin() + i; m_attachedTo.erase( iter ); return true; } /******************************************************************************/ private: void addAttachEntry( AttachableObject* const o ) { m_attachedTo.push_back( o ); } /******************************************************************************/ std::vector& getAttachedObjects( void ) { return m_attachedTo; } /******************************************************************************/ std::vector m_attachedTo; }; /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ class AttachableRegistrar { public: static AttachableRegistrar* getInstance( void ); static void deleteInstance(); Uint32 convertPtrToID( const AttachableObject* ptr ); bool registerID( const Uint32 id, AttachableObject* ptr ); bool startIDToPtrConversion( void ); void reset( void ); protected: AttachableRegistrar(); Uint32 m_nextID; std::map m_mapIDToPtr; std::map m_mapPtrToID; static AttachableRegistrar* m_instance; }; #endif // _ATTACHABLEOBJECT_HPP_