00001 #include "AbstractProperty.h"
00002 #include "AbstractPropertyContainer.h"
00003 #include "Error.h"
00004 #include "Util.h"
00005 #include "XMLNode.h"
00006 #include "Factory.h"
00007 #include <typeinfo>
00008
00009 namespace RenderTools {
00010
00011 map< string, PropertyWeakPtr > AbstractProperty::s_paths;
00012 unsigned long AbstractProperty::s_counter = 0;
00013
00014 AbstractProperty::AbstractProperty( void ):
00015 m_semantic( NONE ),
00016 m_name( createName() ){
00017 }
00018
00019 void AbstractProperty::setName( const XMLNodePtr & xml ){
00020
00021 string name;
00022
00023 if( xml ){
00024 if( Factory::isRegisteredClass( xml->getTagName() ) ){
00025 if( xml->hasAttrib( "name" ) ){
00026 name = xml->getAttrib<string>( "name" );
00027 }
00028 else{
00029 name = createName();
00030 }
00031 }
00032 else{
00033 name = xml->getTagName();
00034 }
00035 }
00036 else{
00037 name = createName();
00038 }
00039
00040 setName( name );
00041 }
00042
00043 void AbstractProperty::setName( const string name ){
00044
00045 removePath();
00046
00047 m_name = name;
00048
00049 if( m_name == "" ){
00050 m_name = createName();
00051 }
00052
00053 storePath();
00054 }
00055
00056 void AbstractProperty::recalculatePath( void ){
00057 removePath();
00058 storePath();
00059 }
00060
00061 void AbstractProperty::removePath( void ){
00062
00063 map< string, PropertyWeakPtr >::iterator i1 = s_paths.begin();
00064 for( ; i1 != s_paths.end(); i1++ ){
00065 if( i1->second.lock().get() == this ){
00066 s_paths.erase( i1 );
00067 break;
00068 }
00069 }
00070
00071 }
00072
00073 void AbstractProperty::storePath( void ){
00074 m_path = tracePath();
00075 s_paths[ m_path ] = getWeakPtr< AbstractProperty >();
00076 }
00077
00078 #ifdef RT_PROFILER
00079 void AbstractProperty::beginProfiler( string name, string file, int line ){
00080 string decoratedName = m_name + "[" + name + "]";
00081
00082 map<string, Profiler *>::iterator i;
00083 Profiler * p = 0;
00084 if( ( i = m_profilers.find( decoratedName ) ) == m_profilers.end() ){
00085 p = new Profiler( decoratedName, file, line );
00086 m_profilers[ decoratedName ] = p;
00087 }
00088 else{
00089 p = i->second;
00090 }
00091 if( p ){
00092 p->begin();
00093 }
00094 else{
00095 Error::error( Error::NULL_POINTER, __FILE__, __LINE__ );
00096 }
00097 }
00098
00099 void Property::endProfiler( string name ){
00100 map<string, Profiler *>::iterator i;
00101 if( ( i = m_profilers.find( m_name + "[" + name + "]" ) ) == m_profilers.end() ){
00102 Error::error( Error::NULL_POINTER, __FILE__, __LINE__ );
00103 }
00104 else{
00105 i->second->end();
00106 }
00107 }
00108
00109 const map<string, Profiler *> & Property::getProfilers( void ){
00110 return( m_profilers );
00111 }
00112
00113 #endif
00114
00115 const string & AbstractProperty::getPath( void ) const {
00116 return( m_path );
00117 }
00118
00119 const string AbstractProperty::createName( const string prefix ){
00120 return( prefix + toString( s_counter++ ) );
00121 }
00122
00123 AbstractProperty::~AbstractProperty( void ){
00124
00126 removePath();
00127
00128 PropertyPtr thisPtr = getNullDeletingSharedPtr< AbstractProperty >();
00129
00130 if( m_owner.lock().get() ){
00131 m_owner.lock()->removeProperty( thisPtr, true );
00132 }
00133
00134 while( m_eventListeners.size() ){
00135 PropertyPtr listener = m_eventListeners[ 0 ].lock();
00136 if( listener ){
00137 listener->disconnect( thisPtr, true );
00138 }
00139 }
00140
00141 #ifdef RT_PROFILER
00142 map<string, Profiler *>::iterator i = m_profilers.begin();
00143 for( ; i != m_profilers.end(); i++ ){
00144 delete i->second;
00145 }
00146 m_profilers.clear();
00147 #endif
00148
00149 }
00150
00151 void AbstractProperty::clear( void ){
00152 s_paths.clear();
00153 }
00154
00155 const PropertyPtr AbstractProperty::find( const string path ){
00156 if( path == "" ){
00157 Error::error( Error::EMPTY_PATH, __FILE__, __LINE__ );
00158 }
00159 map< string, PropertyWeakPtr >::iterator i = s_paths.begin();
00160 for( ; i != s_paths.end(); i++ ){
00161 if( i->first.rfind( path ) != string::npos ){
00162 return( i->second.lock() );
00163 }
00164 }
00165 return( PropertyPtr() );
00166 }
00167
00168 const string AbstractProperty::find( const PropertyPtr & p ){
00169 map< string, PropertyWeakPtr >::iterator i = s_paths.begin();
00170 for( ; i != s_paths.end(); i++ ){
00171 if( i->second.lock() == p ){
00172 return( i->first );
00173 }
00174 }
00175 return( "" );
00176 }
00177
00178 const XMLNodePtr AbstractProperty::toXML( const XMLNodePtr & parent ) const {
00182 XMLNodePtr xml( new XMLNode( m_name ) );
00183 if( parent ){
00184 parent->addChild( xml );
00185 }
00186 xml->setAttrib<string>( "type", getTypeName() );
00187 xml->setAttrib<string>( "value", getValue() );
00188 return( xml );
00189 }
00190
00191 void AbstractProperty::sendPropertyEvent( const PropertyEvent & e ){
00192 onPropertyEvent( e );
00194 for( unsigned int i = 0; i < m_eventListeners.size(); i++ ){
00195 PropertyPtr listener = m_eventListeners[ i ].lock();
00196 if( listener ){
00197 listener->onPropertyEvent( e );
00198 }
00199 }
00200 }
00201
00202 void AbstractProperty::addEventListener( const PropertyPtr & p, bool send ){
00203 m_eventListeners.push_back( p );
00204 }
00205
00206 void AbstractProperty::removeEventListener( const PropertyPtr & p, bool send ){
00207 for( unsigned int i = 0; i < m_eventListeners.size(); i++ ){
00208 PropertyPtr listener = m_eventListeners[ i ].lock();
00209 if( listener == p ){
00210 m_eventListeners[ i ] = m_eventListeners[ m_eventListeners.size() - 1 ];
00211 m_eventListeners.pop_back();
00212 return;
00213 }
00214 }
00215 }
00216
00217 void AbstractProperty::connect( const PropertyPtr & p, bool send ){
00218 p->addEventListener( getSharedPtr< AbstractProperty >(), send );
00219 addEventListener( p, send );
00220 sendPropertyEvent( PropertyEvent( PropertyEvent::CONNECT, p ) );
00221 }
00222
00223 void AbstractProperty::disconnect( const PropertyPtr & p, bool send ){
00224 sendPropertyEvent( PropertyEvent( PropertyEvent::DISCONNECT, p ) );
00225 p->removeEventListener( getSharedPtr< AbstractProperty >(), send );
00226 removeEventListener( p, send );
00227 }
00228
00229 void AbstractProperty::onPropertyEvent( const PropertyEvent & e ){
00230
00231 }
00232
00233 void AbstractProperty::createProperties( void ){
00234
00235 }
00236
00237 void AbstractProperty::onInitialize( void ){
00238
00239 }
00240
00241 const string AbstractProperty::tracePath( void ) const {
00242 PropertyContainerPtr parent = getOwner();
00243 string path = m_name;
00244 vector< PropertyContainerPtr > visited;
00245 while( parent ){
00247 bool cycle = false;
00248 for( unsigned int i = 0; i < visited.size(); i++ ){
00249 if( visited[ i ] == parent ){
00250 cycle = true;
00251 break;
00252 }
00253 }
00254 if( cycle ){
00255 break;
00256 }
00257 path = ( parent->getName() == "" ? "" : ( parent->getName() + '.' ) ) + path;
00258 visited.push_back( parent );
00259 parent = parent->getOwner() == parent ? PropertyContainerPtr() : parent->getOwner();
00260 }
00261
00262 return( path );
00263 }
00264
00265 void AbstractProperty::setOwner( const PropertyContainerPtr & owner ){
00266
00268 removePath();
00269
00271 m_owner = owner;
00272
00274 storePath();
00275 }
00276
00277 const PropertyContainerPtr AbstractProperty::getOwner( void ) const {
00278 return( m_owner.lock() );
00279 }
00280
00281 const string & AbstractProperty::getName( void ) const {
00282 return( m_name );
00283 }
00284
00285 const string AbstractProperty::getTypeName( bool ofComponent ) const {
00286 return( "AbstractProperty" );
00287 }
00288
00289 const string AbstractProperty::getDecoratedName( bool includeType, bool asVector, int vectorElement, int component ) const {
00290 stringstream name;
00291 if( includeType ){
00292 string type = getTypeName( component >= 0 );
00293 if( asVector ){
00294 name << "vector<" << type << ">";
00295 }
00296 }
00297
00298 name << m_name;
00299
00300 if( vectorElement >= 0 ){
00301 if( isVector( ) ){
00302 name << '[' << vectorElement << ']';
00303 }
00304 }
00305 return( name.str() );
00306 }
00307
00308 AbstractProperty::SemanticMask AbstractProperty::getSemantic( void ) const {
00309 return( m_semantic );
00310 }
00311
00312 void AbstractProperty::setSemantic( SemanticMask semantic ){
00313 m_semantic = semantic;
00314 sendPropertyEvent( PropertyEvent( PropertyEvent::CHANGED, getSharedPtr< AbstractProperty >() ) );
00315 }
00316
00317 const string AbstractProperty::getValue( int vectorElement ) const {
00318 return( "" );
00319 }
00320
00321 bool AbstractProperty::setValue( const string value, int vectorElement ) {
00322 return( false );
00323 }
00324
00325 const void * AbstractProperty::getPointer( unsigned int offset ) const {
00326 return( 0 );
00327 }
00328
00329 unsigned int AbstractProperty::getNumVectorElements( void ) const {
00330 return( 0 );
00331 }
00332
00333 unsigned int AbstractProperty::getNumComponents( void ) const {
00334 return( 1 );
00335 }
00336
00337 bool AbstractProperty::isContainer( void ) const {
00338 return( false );
00339 }
00340
00341 bool AbstractProperty::isString( void ) const {
00342 return( false );
00343 }
00344
00345 bool AbstractProperty::isInteger( void ) const {
00346 return( false );
00347 }
00348
00349 bool AbstractProperty::isReal( void ) const {
00350 return( false );
00351 }
00352
00353 bool AbstractProperty::isBoolean( void ) const {
00354 return( false );
00355 }
00356
00357 bool AbstractProperty::isMatrix( void ) const {
00358 return( false );
00359 }
00360
00361 bool AbstractProperty::isEnum( void ) const {
00362 return( false );
00363 }
00364
00365 bool AbstractProperty::isMultiComponent( void ) const {
00366 return( false );
00367 }
00368
00369 bool AbstractProperty::isVector( void ) const {
00370 return( false );
00371 }
00372
00373 ostream & operator << ( ostream & os, const AbstractProperty & rhs ){
00374 return( os << rhs.getName() << "::" << rhs.getValue() );
00375 }
00376
00377 const istream & operator >> ( const istream & is, AbstractProperty & rhs ){
00378 string s( ( istreambuf_iterator<char>( is.rdbuf() ) ), istreambuf_iterator<char>( ) );
00379 rhs.setValue( s );
00380 return( is );
00381 }
00382
00383 };
00384