+// =========================================================================
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// =========================================================================
+
#include <cpPlugins/ProcessObject.h>
-#include <cpPlugins/ParametersQtDialog.h>
-#include <itkProcessObject.h>
-#include <itkExceptionObject.h>
+#include <cpPlugins/DataObject.h>
+#include <cpPlugins/Pipeline.h>
+#include <boost/property_tree/ptree.hpp>
// -------------------------------------------------------------------------
-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 );
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
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( "<xmlattr>.name", this->GetName( ) );
+ xml.put( "<xmlattr>.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 )
{
}
}
// -------------------------------------------------------------------------
-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$