OBTRTTI.cpp

Go to the documentation of this file.
00001 #include <cstdarg>
00002 
00003 #include "OBTRTTI.h"
00004 
00005 using namespace std ;
00006 using namespace OBT ;
00007 
00008 //------------------------------------------------------------------------------------------
00009 // constructor
00010 //------------------------------------------------------------------------------------------
00011 RTTI::RTTI( TypeID typeID, const char* name, RegisterAttributesFunc registerFunc, unsigned int ancestorsCount, ... ) 
00012                         : 
00013 _typeID( typeID ),
00014 _typeName( name )
00015 {
00016         OBT_DBG_ASSERT( typeID != 0 ) ;
00017         OBT_DBG_ASSERT( name != 0 ) ;
00018 
00019         // register the inspectable attributes.
00020         if ( registerFunc != NULL )
00021         {
00022                 registerFunc() ;
00023         }
00024 
00025         // set the ancestors for this RTTI.
00026         if ( ancestorsCount != 0 )
00027         {
00028                 va_list marker;
00029                 // initialize variable arguments.
00030                 va_start( marker, ancestorsCount );
00031 
00032                 for ( unsigned int ancestor = 0; ancestor < ancestorsCount; ++ancestor )
00033                 {
00034                         RTTI* tmp( va_arg( marker, RTTI* ) ) ;
00035                         _baseClassesRTTI.push_back( tmp ) ;
00036                 }
00037                 va_end( marker ) ;
00038         }
00039 }
00040 
00041 //------------------------------------------------------------------------------------------
00042 // destructor
00043 //------------------------------------------------------------------------------------------
00044 RTTI::~RTTI()
00045 {
00046         std::vector< const AbstractAttribute* >::iterator ite( _attributes.begin() ) ;
00047         for ( ; ite != _attributes.end() ; ++ite )
00048         {
00049                 delete *ite ;
00050         }
00051 }
00052 
00053 //-------------------------------------------------------------------------
00054 // isDerivedFrom
00055 //-------------------------------------------------------------------------
00056 bool 
00057 RTTI::isDerivedFrom( const RTTI& rtti ) const
00058 {
00059         if( _typeID == rtti.getTypeID() )
00060         {
00061                 return true ;
00062         }
00063 
00064         // perform a depth-first search for an ancestor with typeID.
00065         std::vector< const RTTI* >::const_iterator ite( _baseClassesRTTI.begin() ) ;
00066         for ( ; ite != _baseClassesRTTI.end() ; ++ite )
00067         {
00068                 if ( ( *ite )->isDerivedFrom( rtti ) )
00069                 {
00070                         return true ;
00071                 }
00072         }
00073         return false;
00074 }
00075 
00076 //-------------------------------------------------------------------------
00077 // getAttribute
00078 //-------------------------------------------------------------------------
00079 const AbstractAttribute* 
00080 const RTTI::getAttribute( unsigned int attributeNumber ) const 
00081 {
00082         unsigned int attributesCount( 0 );
00083         std::vector< const RTTI* >::const_iterator ite( _baseClassesRTTI.begin() ) ;
00084         // get the ancestor actually owning the attribute (if it exists)
00085         for ( ; ite != _baseClassesRTTI.end() ; ++ite )
00086         {
00087                 attributesCount = ( *ite )->getAttributesCount() ;
00088                 if ( attributeNumber < attributesCount )
00089                 {
00090                         // found the right ancestor : get the attribute from it.
00091                         return ( *ite )->getAttribute( attributeNumber ) ;
00092                 }
00093                 else
00094                 {
00095                         // proceed to the next ancestor
00096                         attributeNumber -= attributesCount ;
00097                 }
00098         } 
00099         // the attribute actually belongs to this class, return it.
00100         return _attributes.at( attributeNumber ) ;
00101 }       
00102 
00103 //-------------------------------------------------------------------------
00104 // getAttribute
00105 //-------------------------------------------------------------------------
00106 const AbstractAttribute* const 
00107 RTTI::getAttribute( const char* name ) const 
00108 {
00109         std::string str( name ) ;
00110         std::vector< const AbstractAttribute* >::const_iterator ite( _attributes.begin() ) ;
00111         // look for the queried attribute in this instance.
00112         for ( ; ite != _attributes.end() ; ++ite )
00113         {
00114                 if ( ( *ite )->getName() == str )
00115                 {
00116                         return *ite ;
00117                 }
00118         }
00119 
00120         // attribute was not found : search through the ancestors tree.
00121         std::vector< const RTTI* >::const_iterator ancestorIte( _baseClassesRTTI.begin() ) ;
00122         for ( ; ancestorIte != _baseClassesRTTI.end() ; ++ancestorIte )
00123         {
00124                 const AbstractAttribute* const attribute( ( *ancestorIte )->getAttribute( name ) ) ;
00125                 if ( attribute != NULL )
00126                 {
00127                         return attribute ;
00128                 }
00129         }
00130         return NULL ;
00131 }

Generated on Wed Oct 1 11:34:05 2008 for OBT by  doxygen 1.5.3