X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=sidebyside;f=lib%2FcpPlugins%2FProcessObject.cxx;h=0c6b45cb3ae9fe691294a43eacab68b81e1339a3;hb=2e142df11d6f312a2a2b5097b8da73571ed523e8;hp=a30ef5212c7a35dbefc883f17fd15bdd4fdfc421;hpb=e9f2b7e99e640987da99456a10a5b797225442fb;p=cpPlugins.git diff --git a/lib/cpPlugins/ProcessObject.cxx b/lib/cpPlugins/ProcessObject.cxx index a30ef52..0c6b45c 100644 --- a/lib/cpPlugins/ProcessObject.cxx +++ b/lib/cpPlugins/ProcessObject.cxx @@ -1,54 +1,123 @@ +// ========================================================================= +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ========================================================================= + #include -#include -#include -#include +#include +#include +#include // ------------------------------------------------------------------------- -cpPlugins::Parameters* cpPlugins::ProcessObject:: -GetParameters( ) +const std::string& cpPlugins::ProcessObject:: +GetName( ) const { - return( &( this->m_Parameters ) ); + return( this->m_Name ); } // ------------------------------------------------------------------------- -const cpPlugins::Parameters* cpPlugins::ProcessObject:: -GetParameters( ) const +void cpPlugins::ProcessObject:: +SetName( const std::string& name ) { - return( &( this->m_Parameters ) ); + if( this->m_Name != name ) + { + this->m_Name = name; + this->Modified( ); + } // end if } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: -SetITK( itk::LightObject* o ) +Print( std::ostream& o ) const { - // Polymorphism: do nothing -> this is a filter!!! + this->Superclass::Print( o ); + this->TParameters::Print( o ); } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: -SetVTK( vtkObjectBase* o ) +SetPipeline( cpPlugins::Pipeline* p ) { - // Polymorphism: do nothing -> this is a filter!!! + if( p != NULL ) + this->m_Pipeline = p->CastWeakPtr< cpPlugins::Pipeline >( ); + else + this->m_Pipeline.reset( ); } // ------------------------------------------------------------------------- -std::set< std::string > cpPlugins::ProcessObject:: -GetInputsNames( ) const +void cpPlugins::ProcessObject:: +SetInput( const std::string& name, cpPlugins::DataObject* data ) +{ + TInputs::iterator i = this->m_Inputs.find( name ); + if( i != this->m_Inputs.end( ) ) + { + if( !( i->second.Set( data ) ) ) + cpPluginsErrorMacro( + this, << "Input \"" << name << "\" does not match to input data." + ); + } + else + cpPluginsErrorMacro( + this, << "Input \"" << name << "\" does not belong to this filter." + ); +} + +// ------------------------------------------------------------------------- +cpPlugins::DataObject* cpPlugins::ProcessObject:: +GetInput( const std::string& name, const unsigned int id ) +{ + TInputs::iterator i = this->m_Inputs.find( name ); + if( i != this->m_Inputs.end( ) ) + { + if( id < i->second.Count( ) ) + return( i->second.Get( id ) ); + else + cpPluginsErrorMacro( + this, << "Input \"" << name << "\" does have enough inputs." + ); + } + else + cpPluginsErrorMacro( + this, << "Input \"" << name << "\" does not belong to this filter." + ); +} + +// ------------------------------------------------------------------------- +const cpPlugins::DataObject* cpPlugins::ProcessObject:: +GetInput( const std::string& name, const unsigned int id ) const +{ + TInputs::const_iterator i = this->m_Inputs.find( name ); + if( i != this->m_Inputs.end( ) ) + { + if( id < i->second.Count( ) ) + return( i->second.Get( id ) ); + else + cpPluginsErrorMacro( + this, << "Input \"" << name << "\" does have enough inputs." + ); + } + else + cpPluginsErrorMacro( + this, << "Input \"" << name << "\" does not belong to this filter." + ); +} + +// ------------------------------------------------------------------------- +bool cpPlugins::ProcessObject:: +HasInput( const std::string& name ) const { - std::set< std::string > names; - for( auto i = this->m_Inputs.begin( ); i != this->m_Inputs.end( ); ++i ) - names.insert( i->first ); - return( names ); + TInputs::const_iterator i = this->m_Inputs.find( name ); + return( i != this->m_Inputs.end( ) ); } // ------------------------------------------------------------------------- std::set< std::string > cpPlugins::ProcessObject:: -GetOutputsNames( ) const +GetInputsNames( ) const { - std::set< std::string > names; - for( auto i = this->m_Outputs.begin( ); i != this->m_Outputs.end( ); ++i ) - names.insert( i->first ); - return( names ); + std::set< std::string > n; + TInputs::const_iterator i = this->m_Inputs.begin( ); + for( ; i != this->m_Inputs.end( ); ++i ) + n.insert( i->first ); + return( n ); } // ------------------------------------------------------------------------- @@ -60,209 +129,252 @@ GetNumberOfInputs( ) const // ------------------------------------------------------------------------- unsigned int cpPlugins::ProcessObject:: -GetNumberOfOutputs( ) const +GetNumberOfInputs( const std::string& name ) const { - return( this->m_Outputs.size( ) ); + TInputs::const_iterator i = this->m_Inputs.find( name ); + if( i != this->m_Inputs.end( ) ) + return( i->second.Count( ) ); + else + return( 0 ); } // ------------------------------------------------------------------------- -cpPlugins:: -OutputPort& cpPlugins::ProcessObject:: -GetOutputPort( const std::string& id ) +std::set< std::string > cpPlugins::ProcessObject:: +GetAllInputsNames( ) const { - static OutputPort null_port; - auto i = this->m_Outputs.find( id ); - if( i == this->m_Outputs.end( ) ) - { - null_port = NULL; - return( null_port ); - } - else - return( i->second ); + std::set< std::string > r = this->GetInputsNames( ); + std::set< std::string > iScalar = this->GetInValueNames( ); + std::set< std::string > iSet = this->GetInSetNames( ); + std::set< std::string > iSequence = this->GetInSequenceNames( ); + for( const std::string& s: iScalar ) + r.insert( s ); + for( const std::string& s: iSet ) + r.insert( s ); + for( const std::string& s: iSequence ) + r.insert( s ); + + return( r ); } // ------------------------------------------------------------------------- -const cpPlugins:: -OutputPort& cpPlugins::ProcessObject:: -GetOutputPort( const std::string& id ) const +std::set< std::string > cpPlugins::ProcessObject:: +GetAllOutputsNames( ) const { - static const OutputPort null_port; - auto i = this->m_Outputs.find( id ); - if( i == this->m_Outputs.end( ) ) - return( null_port ); - else - return( i->second ); + std::set< std::string > r = this->GetOutValueNames( ); + std::set< std::string > oSet = this->GetOutSetNames( ); + std::set< std::string > oSequence = this->GetOutSequenceNames( ); + for( const std::string& s: oSet ) + r.insert( s ); + for( const std::string& s: oSequence ) + r.insert( s ); + + return( r ); } // ------------------------------------------------------------------------- bool cpPlugins::ProcessObject:: -SetInputPort( const std::string& id, const OutputPort& port ) +GetExecutionDebug( ) const { - auto i = this->m_Inputs.find( id ); - if( i != this->m_Inputs.end( ) ) + return( this->m_ExecutionDebug ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::ProcessObject:: +SetExecutionDebug( bool d ) +{ + this->m_ExecutionDebug = d; +} + +// ------------------------------------------------------------------------- +void cpPlugins::ProcessObject:: +ExecutionDebugOn( ) +{ + this->SetExecutionDebug( true ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::ProcessObject:: +ExecutionDebugOff( ) +{ + this->SetExecutionDebug( false ); +} + +// ------------------------------------------------------------------------- +const double& cpPlugins::ProcessObject:: +GetLastDuration( ) const +{ + return( this->m_LastDuration ); +} + +// ------------------------------------------------------------------------- +bool cpPlugins::ProcessObject:: +IsUpdated( const TTimeStamp& d ) const +{ + bool ok = this->Superclass::IsUpdated( d ); + if( ok ) { - if( i->second.GetPointer( ) != port.GetPointer( ) ) + for( const TInputs::value_type& i: this->m_Inputs ) { - i->second = port; - this->Modified( ); + for( unsigned long j = 0; j < i.second.Count( ); ++j ) + { + const cpPlugins::DataObject* dObj = i.second.Get( j ); + if( dObj != NULL ) + ok &= dObj->IsUpdated( d ); + + } // end for + } // end for + } // end if + return( ok ); +} - } // fi - return( true ); - } - else - return( false ); +// ------------------------------------------------------------------------- +void cpPlugins::ProcessObject:: +Modified( ) +{ + this->m_LastDuration = -1; + this->Superclass::Modified( ); } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: -DisconnectInputs( ) +ModifiedInValue( const std::string& name ) { - auto i = this->m_Inputs.begin( ); - for( ; i != this->m_Inputs.end( ); ++i ) - i->second = NULL; + // WARNING: Synch parameters in cpPlugins::Pipeline this->Modified( ); } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: -DisconnectOutputs( ) +ModifiedInSet( const std::string& name ) { - auto i = this->m_Outputs.begin( ); - for( ; i != this->m_Outputs.end( ); ++i ) - if( i->second.IsValid( ) ) - i->second->DisconnectFromPipeline( ); + // WARNING: Synch parameters in cpPlugins::Pipeline this->Modified( ); } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: -Disconnect( ) +ModifiedInSequence( const std::string& name ) { - this->DisconnectInputs( ); - this->DisconnectOutputs( ); + // WARNING: Synch parameters in cpPlugins::Pipeline + this->Modified( ); } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: -Modified( ) const +ModifiedOutValue( const std::string& name ) { - this->Superclass::Modified( ); - this->m_LastExecutionSpan = -1; + // WARNING: Synch parameters in cpPlugins::Pipeline + this->Modified( ); } // ------------------------------------------------------------------------- -itk::ModifiedTimeType cpPlugins::ProcessObject:: -GetMTime( ) const +void cpPlugins::ProcessObject:: +ModifiedOutSet( const std::string& name ) { - auto params_time = this->m_Parameters.GetMTime( ); - auto filter_time = this->Superclass::GetMTime( ); - return( ( params_time > filter_time )? params_time: filter_time ); + // WARNING: Synch parameters in cpPlugins::Pipeline + this->Modified( ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::ProcessObject:: +ModifiedOutSequence( const std::string& name ) +{ + // WARNING: Synch parameters in cpPlugins::Pipeline + this->Modified( ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::ProcessObject:: +ModifiedChoice( const std::string& name ) +{ + // WARNING: Synch parameters in cpPlugins::Pipeline + this->Modified( ); } // ------------------------------------------------------------------------- void cpPlugins::ProcessObject:: Update( ) { - // Force upstream updates - auto i = this->m_Inputs.begin( ); - bool need_to_update = this->m_CouldHaveExplicitReExecution; - need_to_update &= this->m_ExplicitReExecution; - for( ; i != this->m_Inputs.end( ); ++i ) + bool is_updated = this->IsUpdated( ); + is_updated &= this->TParameters::Update( ); + + // Check inputs + for( TInputs::value_type i: this->m_Inputs ) { - bool iv = i->second.IsValid( ); - bool ir = i->second.IsRequired( ); - if( !iv && ir ) - this->_Error( - std::string( "Required input \"" ) + i->first + - std::string( "\" is not valid." ) - ); - if( iv ) + if( i.second.IsValid( ) ) { - Self* src = dynamic_cast< Self* >( i->second->GetSource( ) ); - if( src != NULL ) + for( unsigned long j = 0; j < i.second.Count( ); ++j ) { - need_to_update |= ( this->m_LastExecutionTime < src->GetMTime( ) ); - src->Update( ); - - } // fi - - } // fi - - } // rof - - // Current update - if( this->m_LastExecutionTime < this->GetMTime( ) || need_to_update ) + cpPlugins::DataObject* dObj = i.second.Get( j ); + if( dObj ) + { + if( !( dObj->IsUpdated( ) ) ) + { + dObj->Update( ); + is_updated = false; + + } // end if + } // end if + } // end for + } // end if + } // end for + + // Allow some updates in particular cases (i.e. Functors) + is_updated &= this->_BeforeUpdate( ); + + // Update outputs + if( !is_updated ) { - if( this->m_PrintExecution && this->m_PrintExecutionStream != NULL ) + if( this->m_ExecutionDebug ) { - *( this->m_PrintExecutionStream ) - << "cpPlugins: Updating \"" - << this->GetClassCategory( ) << ":" << this->GetClassName( ) - << "\"... "; - this->m_PrintExecutionStream->flush( ); - - } // fi - - auto t_start = cpPlugins_CHRONO; + *( this->m_OutStream ) + << "Executing node \"" << this->GetName( ) << "\"... " + << std::ends; + this->m_OutStream->flush( ); + } // end if + std::chrono::steady_clock::time_point start = + std::chrono::steady_clock::now( ); this->_GenerateData( ); - auto t_end = cpPlugins_CHRONO; - this->m_LastExecutionSpan = long( t_end - t_start ); - this->m_LastExecutionTime = this->GetMTime( ); - - if( this->m_PrintExecution && this->m_PrintExecutionStream != NULL ) + std::chrono::steady_clock::time_point end = + std::chrono::steady_clock::now( ); + this->m_LastDuration = + double( + std::chrono::duration_cast< std::chrono::microseconds >( + end - start + ).count( ) + ) * 1e-6; + if( this->m_ExecutionDebug ) { - *( this->m_PrintExecutionStream ) + *( this->m_OutStream ) << "done in " - << double( this->m_LastExecutionSpan ) / double( 1000 ) - << " s." << std::endl; - - } // fi - - } // fi -} - -// ------------------------------------------------------------------------- -cpPlugins::ParametersQtDialog* cpPlugins::ProcessObject:: -CreateQtDialog( ) -{ -#ifdef cpPlugins_QT4 - ParametersQtDialog* dlg = NULL; - if( QApplication::instance( ) != NULL ) - { - dlg = new ParametersQtDialog( ); - dlg->setProcessObject( this ); - - } // fi - return( dlg ); -#else // cpPlugins_QT4 - return( NULL ); -#endif // cpPlugins_QT4 -} - -// ------------------------------------------------------------------------- -bool cpPlugins::ProcessObject:: -IsInteractive( ) -{ - return( false ); + << this->m_LastDuration << " s" + << std::endl; + this->m_OutStream->flush( ); + } // end if + this->_SynchTime( ); + } // end if } // ------------------------------------------------------------------------- +template< > void cpPlugins::ProcessObject:: -SetInteractionObjects( const std::vector< void* >& objs ) +SaveXML( boost::property_tree::ptree* node ) const { - // Do nothing + boost::property_tree::ptree xml; + xml.put( ".name", this->GetName( ) ); + xml.put( ".class", this->GetClassName( ) ); + this->TParameters::SaveXML( &xml ); + node->add_child( "pipeline.node", xml ); } // ------------------------------------------------------------------------- cpPlugins::ProcessObject:: ProcessObject( ) : Superclass( ), - m_CouldHaveExplicitReExecution( false ), - m_ExplicitReExecution( false ), - m_LastExecutionTime( 0 ), - m_LastExecutionSpan( -1 ), - m_PrintExecution( false ), - m_PrintExecutionStream( &( std::cout ) ) + TParameters( ), + m_OutStream( &std::cout ), + m_ExecutionDebug( false ), + m_LastDuration( -1 ) { } @@ -273,30 +385,10 @@ cpPlugins::ProcessObject:: } // ------------------------------------------------------------------------- -void cpPlugins::ProcessObject:: -_AddInput( const std::string& name, bool required ) -{ - auto i = this->m_Inputs.find( name ); - if( i == this->m_Inputs.end( ) ) - { - this->m_Inputs[ name ] = InputPort( required ); - this->Modified( ); - - } // fi -} - -// ------------------------------------------------------------------------- -void cpPlugins::ProcessObject:: -_Error( const std::string& error ) +bool cpPlugins::ProcessObject:: +_BeforeUpdate( ) { - if( error != "" ) - { - itkExceptionMacro( - "Error: \"" << this->GetClassCategory( ) << "::" << - this->GetClassName( ) << "\": " << error - ); - - } // fi + return( true ); } // eof - $RCSfile$