X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FInterface%2FWorkspace.cxx;h=4fbcb2bbf3b154e11332f29b0a32cd7201630f95;hb=406ebd171557827b3fa0133073dd69780a6e3f6f;hp=9e8d4e1e7ab3d35ee94b332a7ff4fc0ee8a2816f;hpb=f654620df52b811be7bd263a1775c93d29c69a65;p=cpPlugins.git diff --git a/lib/cpPlugins/Interface/Workspace.cxx b/lib/cpPlugins/Interface/Workspace.cxx index 9e8d4e1..4fbcb2b 100644 --- a/lib/cpPlugins/Interface/Workspace.cxx +++ b/lib/cpPlugins/Interface/Workspace.cxx @@ -1,169 +1,357 @@ #include +#include + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Clear( ) +{ + this->m_Filters.clear( ); +} + +// ------------------------------------------------------------------------- +std::vector< std::string > cpPlugins::Interface::Workspace:: +GetFiltersNames( ) const +{ + std::vector< std::string > n; + for( auto i : this->m_Filters ) + n.push_back( i.first ); + return( n ); +} // ------------------------------------------------------------------------- cpPlugins::Interface::Workspace:: -Workspace( ) - : m_LastLoadedPlugin( "" ) +TFilter* cpPlugins::Interface::Workspace:: +GetFilter( const std::string& name ) { + auto i = this->m_Filters.find( name ); + if( i != this->m_Filters.end( ) ) + return( i->second.GetPointer( ) ); + else + return( NULL ); +} + +// ------------------------------------------------------------------------- +const cpPlugins::Interface::Workspace:: +TFilter* cpPlugins::Interface::Workspace:: +GetFilter( const std::string& name ) const +{ + auto i = this->m_Filters.find( name ); + if( i != this->m_Filters.end( ) ) + return( i->second.GetPointer( ) ); + else + return( NULL ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Workspace:: -~Workspace( ) +TWidget* cpPlugins::Interface::Workspace:: +GetWidget( const std::string& name ) +{ + TFilter* process = this->GetFilter( name ); + return( dynamic_cast< TWidget* >( process ) ); +} + +// ------------------------------------------------------------------------- +const cpPlugins::Interface::Workspace:: +TWidget* cpPlugins::Interface::Workspace:: +GetWidget( const std::string& name ) const +{ + const TFilter* process = this->GetFilter( name ); + return( dynamic_cast< const TWidget* >( process ) ); +} + +// ------------------------------------------------------------------------- +bool cpPlugins::Interface::Workspace:: +HasFilter( const std::string& name ) const { + return( this->m_Filters.find( name ) != this->m_Filters.end( ) ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Workspace:: -LoadPluginsPath( const std::string& path, bool r ) +HasWidget( const std::string& name ) const +{ + const TWidget* wdg = this->GetWidget( name ); + return( wdg != NULL ); +} + +// ------------------------------------------------------------------------- +cpPlugins::Interface::Workspace:: +TFilter* cpPlugins::Interface::Workspace:: +CreateFilter( + const std::string& category, const std::string& filter, + const std::string& name + ) { - // Load all plugins from given folder - std::list< std::string > files = - this->m_Interface.LoadFromFolder( path, r ); + typedef cpPlugins::Pipeline::Widget _TWidget; - // Update a simple track - bool ret = false; - if( files.size( ) > 0 ) + TFilter::Pointer o = this->m_Loader.CreateFilter( category, filter ); + if( o.IsNotNull( ) ) { - for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt ) - { - this->m_LoadedPlugins.insert( *fIt ); - this->m_LastLoadedPlugin = *fIt; + // Choose a name + std::string real_name = name; + while( this->GetFilter( real_name ) != NULL ) + real_name += std::string( "_" ); + o->SetPrintExecution( this->m_PrintExecution ); + o->SetName( real_name ); - } // rof - this->_UpdateLoadedPluginsInformation( ); - ret = true; + // Interactors + for( + auto i = this->m_Interactors.begin( ); + i != this->m_Interactors.end( ); + ++i + ) + o->AddInteractor( *i ); + + // Finish association + this->m_Filters[ real_name ] = o; } // fi - return( ret ); + return( o.GetPointer( ) ); +} + +// ------------------------------------------------------------------------- +cpPlugins::Interface::Workspace:: +TFilter* cpPlugins::Interface::Workspace:: +CreateFilter( const std::string& category, const std::string& filter ) +{ + return( this->CreateFilter( category, filter, filter ) ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Workspace:: -LoadPlugins( const std::string& fname ) +RenameFilter( const std::string& old_name, const std::string& new_name ) { - // Is it already loaded? - bool ret = true; - if( this->m_LoadedPlugins.find( fname ) == this->m_LoadedPlugins.end( ) ) + auto o = this->m_Filters.find( old_name ); + auto n = this->m_Filters.find( new_name ); + if( o != this->m_Filters.end( ) && n == this->m_Filters.end( ) ) { - // Was it succesfully loaded? - ret = this->m_Interface.Load( fname ); + // Rename filter + o->second->SetName( new_name ); + this->m_Filters[ new_name ] = o->second; + this->m_Filters.erase( o ); - // Update a simple track - if( ret ) - { - this->m_LoadedPlugins.insert( fname ); - this->m_LastLoadedPlugin = fname; - this->_UpdateLoadedPluginsInformation( ); + // Rename exposed ports + /* TODO + auto e = this->m_ExposedInputs.begin( ); + for( ; e != this->m_ExposedInputs.end( ); ++e ) + if( e->second.first == old_name ) + e->second.first = new_name; + e = this->m_ExposedOutputs.begin( ); + for( ; e != this->m_ExposedOutputs.end( ); ++e ) + if( e->second.first == old_name ) + e->second.first = new_name; + */ - } // fi + return( true ); + } + else + return( false ); +} - } // fi - return( ret ); +// ------------------------------------------------------------------------- +bool cpPlugins::Interface::Workspace:: +RemoveFilter( const std::string& name ) +{ + auto i = this->m_Filters.find( name ); + if( i != this->m_Filters.end( ) ) + { + i->second->Disconnect( ); + this->m_Filters.erase( i ); + return( true ); + } + else + return( false ); } // ------------------------------------------------------------------------- -const cpPlugins::Interface::Workspace:: -TStringContainer& cpPlugins::Interface::Workspace:: -GetLoadedPlugins( ) const +void cpPlugins::Interface::Workspace:: +SetPrintExecution( bool b ) { - return( this->m_LoadedPlugins ); + this->m_PrintExecution = b; + for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i ) + i->second->SetPrintExecution( b ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Workspace:: -GetLoadedPluginCategories( TStringContainer& categories ) const +PrintExecutionOn( ) { - categories.clear( ); - auto fIt = this->m_LoadedFilters.begin( ); - for( ; fIt != this->m_LoadedFilters.end( ); ++fIt ) - categories.insert( fIt->first ); + this->SetPrintExecution( true ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Workspace:: -GetLoadedPluginFilters( TStringContainer& filters ) const +PrintExecutionOff( ) { - filters.clear( ); - auto pIt = this->m_LoadedFilters.begin( ); - for( ; pIt != this->m_LoadedFilters.end( ); ++pIt ) - for( auto fIt = pIt->second.begin( ); fIt != pIt->second.end( ); ++fIt ) - filters.insert( *fIt ); + this->SetPrintExecution( true ); } // ------------------------------------------------------------------------- -const cpPlugins::Interface::Workspace:: -TStringContainer& cpPlugins::Interface::Workspace:: -GetLoadedPluginFilters( const std::string& category ) const +void cpPlugins::Interface::Workspace:: +AddInteractor( vtkRenderWindowInteractor* iren ) { - static const TStringContainer EMPTY; - auto pIt = this->m_LoadedFilters.find( category ); - if( pIt != this->m_LoadedFilters.end( ) ) - return( pIt->second ); - else - return( EMPTY ); + if( iren != NULL ) + { + this->m_Interactors.insert( iren ); + for( auto f : this->m_Filters ) + f.second->AddInteractor( iren ); + + } // fi } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Workspace:: -CreateFilter( const std::string& filter, const std::string& name ) +Connect( + const std::string& origin_filter, + const std::string& origin_output, + const std::string& destination_filter, + const std::string& destination_input + ) { - // Get or create new filter from name - auto vIt = this->m_Vertices.find( name ); - if( vIt == this->m_Vertices.end( ) ) + // Get filters and check pertinence + TFilter* origin = this->GetFilter( origin_filter ); + TFilter* destination = this->GetFilter( destination_filter ); + if( origin == NULL || destination == NULL ) + return( false ); + if( !( destination->HasInput( destination_input ) ) ) + return( false ); + if( !( origin->HasOutput( origin_output ) ) ) + return( false ); + + // Check if there is room for a new connection + bool ok = true; + if( destination->IsInputMultiple( destination_input ) ) { - TFilter::Pointer o = this->m_Interface.CreateObject( filter ); - if( o.IsNotNull( ) ) - { - o->SetName( name ); - this->m_Vertices[ name ] = o; - return( true ); - } - else - return( false ); + for( + unsigned int i = 0; + i < destination->GetInputSize( destination_input ); + ++i + ) + if( + destination->GetInput( destination_input, i )->GetSource( ) == origin + ) + ok = false; } else - return( true ); + ok = ( destination->GetInput( destination_input ) == NULL ); + if( ok ) + destination->AddInput( + destination_input, + origin->GetOutput( origin_output ) + ); + return( ok ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Workspace:: Connect( - const std::string& orig_filter, const std::string& dest_filter, - const std::string& output_name, const std::string& input_name + TDataObject* input, + const std::string& destination_filter, + const std::string& destination_input ) { - // Get filters - auto oIt = this->m_Vertices.find( orig_filter ); - if( oIt == this->m_Vertices.end( ) ) + // Get filters and check pertinence + if( input == NULL ) return( false ); - auto dIt = this->m_Vertices.find( dest_filter ); - if( dIt == this->m_Vertices.end( ) ) + TFilter* destination = this->GetFilter( destination_filter ); + if( destination == NULL ) return( false ); - TFilter* orig = dynamic_cast< TFilter* >( oIt->second.GetPointer( ) ); - TFilter* dest = dynamic_cast< TFilter* >( dIt->second.GetPointer( ) ); - if( orig == NULL || dest == NULL ) + if( !( destination->HasInput( destination_input ) ) ) return( false ); - // Real connection - dest->SetInput( input_name, orig->GetOutput< TData >( output_name ) ); - this->m_AdjMatrix[ orig_filter ][ dest_filter ].push_back( - TConnection( output_name, input_name ) - ); - return( false ); + // Check if there is room for a new connection + bool ok = true; + if( destination->IsInputMultiple( destination_input ) ) + { + for( + unsigned int i = 0; + i < destination->GetInputSize( destination_input ); + ++i + ) + if( + destination->GetInput( destination_input, i )->GetSource( ) == + input->GetSource( ) + ) + ok = false; + } + else + ok = ( destination->GetInput( destination_input ) == NULL ); + if( ok ) + destination->AddInput( + destination_input, + input + ); + return( ok ); } // ------------------------------------------------------------------------- -cpPlugins::Interface::Workspace:: -TParameters* cpPlugins::Interface::Workspace:: -GetParameters( const std::string& name ) +bool cpPlugins::Interface::Workspace:: +Disconnect( + const std::string& origin_filter, + const std::string& origin_output, + const std::string& destination_filter, + const std::string& destination_input + ) +{ + // Get filters and check pertinence + TFilter* origin = this->GetFilter( origin_filter ); + TFilter* destination = this->GetFilter( destination_filter ); + if( origin == NULL || destination == NULL ) + return( false ); + if( !( destination->HasInput( destination_input ) ) ) + return( false ); + if( !( origin->HasOutput( origin_output ) ) ) + return( false ); + + // Check if there is room for a new connection + bool ok = false; + unsigned int del_id = 0; + for( + unsigned int i = 0; + i < destination->GetInputSize( destination_input ); + ++i + ) + if( + destination->GetInput( destination_input, i )->GetSource( ) == origin + ) + { + ok = true; + del_id = i; + + } // fi + if( ok ) + destination->DisconnectInput( destination_input, del_id ); + return( ok ); +} + +// ------------------------------------------------------------------------- +/* +const cpPlugins::Interface::Workspace:: +TExposedPorts& cpPlugins::Interface::Workspace:: +GetExposedInputs( ) const +{ + return( this->m_ExposedInputs ); +} + +// ------------------------------------------------------------------------- +const cpPlugins::Interface::Workspace:: +TExposedPorts& cpPlugins::Interface::Workspace:: +GetExposedOutputs( ) const +{ + return( this->m_ExposedOutputs ); +} + +// ------------------------------------------------------------------------- +cpPlugins::Pipeline::DataObject* cpPlugins::Interface::Workspace:: +GetExposedOutput( const std::string& name ) { - auto vIt = this->m_Vertices.find( name ); - if( vIt != this->m_Vertices.end( ) ) + auto i = this->m_ExposedOutputs.find( name ); + if( i != this->m_ExposedOutputs.end( ) ) { - TFilter* f = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ); + auto f = this->GetFilter( i->second.first ); if( f != NULL ) - return( f->GetParameters( ) ); + return( f->GetOutput( i->second.second ) ); else return( NULL ); } @@ -172,17 +360,15 @@ GetParameters( const std::string& name ) } // ------------------------------------------------------------------------- -const cpPlugins::Interface::Workspace:: -TParameters* cpPlugins::Interface::Workspace:: -GetParameters( const std::string& name ) const +const cpPlugins::Pipeline::DataObject* cpPlugins::Interface::Workspace:: +GetExposedOutput( const std::string& name ) const { - auto vIt = this->m_Vertices.find( name ); - if( vIt != this->m_Vertices.end( ) ) + auto i = this->m_ExposedOutputs.find( name ); + if( i != this->m_ExposedOutputs.end( ) ) { - const TFilter* f = - dynamic_cast< const TFilter* >( vIt->second.GetPointer( ) ); + auto f = this->GetFilter( i->second.first ); if( f != NULL ) - return( f->GetParameters( ) ); + return( f->GetOutput( i->second.second ) ); else return( NULL ); } @@ -192,71 +378,261 @@ GetParameters( const std::string& name ) const // ------------------------------------------------------------------------- bool cpPlugins::Interface::Workspace:: -Reduce( const std::string& name ) +ExposeInput( + const std::string& name, + const std::string& filter, const std::string& filter_input + ) { + auto i = this->m_ExposedInputs.find( name ); + if( i == this->m_ExposedInputs.end( ) ) + { + this->m_ExposedInputs[ name ] = + std::pair< std::string, std::string >( filter, filter_input ); + return( true ); + } + else + return( false ); } // ------------------------------------------------------------------------- -std::string cpPlugins::Interface::Workspace:: -Execute( ) +bool cpPlugins::Interface::Workspace:: +ExposeOutput( + const std::string& name, + const std::string& filter, const std::string& filter_output + ) { - // Find sinks - std::set< std::string > sinks; - auto vIt = this->m_Vertices.begin( ); - for( ; vIt != this->m_Vertices.end( ); ++vIt ) - sinks.insert( vIt->first ); - auto mIt = this->m_AdjMatrix.begin( ); - for( ; mIt != this->m_AdjMatrix.end( ); ++mIt ) - sinks.erase( mIt->first ); + auto i = this->m_ExposedOutputs.find( name ); + if( i == this->m_ExposedOutputs.end( ) ) + { + this->m_ExposedOutputs[ name ] = + std::pair< std::string, std::string >( filter, filter_output ); + return( true ); + } + else + return( false ); +} - // Update sinks - std::string err = ""; - for( auto sIt = sinks.begin( ); sIt != sinks.end( ); ++sIt ) +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +HideInput( const std::string& name ) +{ + auto i = this->m_ExposedInputs.find( name ); + if( i != this->m_ExposedInputs.end( ) ) + this->m_ExposedInputs.erase( i ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +HideOutput( const std::string& name ) +{ + auto i = this->m_ExposedOutputs.find( name ); + if( i != this->m_ExposedOutputs.end( ) ) + this->m_ExposedOutputs.erase( i ); +} + +// ------------------------------------------------------------------------- +bool cpPlugins::Interface::Workspace:: +RenameExposedInput( + const std::string& old_name, const std::string& new_name + ) +{ + auto o = this->m_ExposedInputs.find( old_name ); + auto n = this->m_ExposedInputs.find( new_name ); + if( o != this->m_ExposedInputs.end( ) && n == this->m_ExposedInputs.end( ) ) { - std::string lerr = this->Execute( *sIt ); - if( lerr != "" ) - err += lerr + std::string( "\n" ); + this->m_ExposedInputs[ new_name ] = o->second; + this->m_ExposedInputs.erase( o ); + return( true ); + } + else + return( false ); +} - } // rof - return( err ); +// ------------------------------------------------------------------------- +bool cpPlugins::Interface::Workspace:: +RenameExposedOutput( + const std::string& old_name, const std::string& new_name + ) +{ + auto o = this->m_ExposedOutputs.find( old_name ); + auto n = this->m_ExposedOutputs.find( new_name ); + if( + o != this->m_ExposedOutputs.end( ) && n == this->m_ExposedOutputs.end( ) + ) + { + this->m_ExposedOutputs[ new_name ] = o->second; + this->m_ExposedOutputs.erase( o ); + return( true ); + } + else + return( false ); } // ------------------------------------------------------------------------- -std::string cpPlugins::Interface::Workspace:: -Execute( const std::string& name ) +std::vector< std::pair< std::string, std::string > > +cpPlugins::Interface::Workspace:: +GetConnections( + const std::string& origin, const std::string& destination + ) const { - // Get filter - auto vIt = this->m_Vertices.find( name ); - if( vIt == this->m_Vertices.end( ) ) - return( - std::string( "cpPlugins::Interface::Workspace: No filter \"" ) + - name + std::string( "\"" ) - ); - TFilter* f = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) ); - if( f == NULL ) - return( - std::string( "cpPlugins::Interface::Workspace: Vertex \"" ) + - name + std::string( "\" is not a filter." ) - ); + std::vector< std::pair< std::string, std::string > > conns; + auto orig = this->GetFilter( origin ); + auto dest = this->GetFilter( destination ); + if( orig != NULL && dest != NULL ) + { + auto outs = orig->GetOutputsNames( ); + auto ins = dest->GetInputsNames( ); + for( auto o = outs.begin( ); o != outs.end( ); ++o ) + { + for( auto i = ins.begin( ); i != ins.end( ); ++i ) + { + unsigned int nInputs = dest->GetInputSize( *i ); + for( unsigned j = 0; j < nInputs; ++j ) + { + auto od = orig->GetOutput( *o ); + auto id = dest->GetInput( *i, j ); + if( od != NULL && od == id ) + conns.push_back( + std::pair< std::string, std::string >( *o, *i ) + ); + + } // rof + + } // rof + + } // rof + + } // fi + return( conns ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Connect( + const std::string& orig_filter, const std::string& dest_filter, + const std::string& output_name, const std::string& input_name + ) +{ + auto o = this->GetFilter( orig_filter ); + auto d = this->GetFilter( dest_filter ); + if( o != NULL && d != NULL ) + { + try + { + d->AddInput( input_name, o->GetOutput( output_name ) ); + } + catch( std::exception& err ) + { + throw std::logic_error( + std::string( "Error connecting \"" ) + + output_name + std::string( "@" ) + orig_filter + + std::string( "\" with \"" ) + + input_name + std::string( "@" ) + dest_filter + + std::string( "\": " ) + + err.what( ) + ); - // Execute and return - return( f->Update( ) ); + } // yrt + + } // fi } // ------------------------------------------------------------------------- void cpPlugins::Interface::Workspace:: -_UpdateLoadedPluginsInformation( ) +Connect( + cpPlugins::Pipeline::DataObject* output, + const std::string& dest_filter, const std::string& input_name + ) +{ + auto d = this->GetFilter( dest_filter ); + if( d != NULL ) + d->AddInput( input_name, output ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Connect( + cpPlugins::Pipeline::DataObject* output, + const std::string& exposed_input_name + ) { - this->m_LoadedFilters.clear( ); - const TInterface::TClasses& cls = this->m_Interface.GetClasses( ); - for( auto i = cls.begin( ); i != cls.end( ); ++i ) + auto i = this->m_ExposedInputs.find( exposed_input_name ); + if( i != this->m_ExposedInputs.end( ) ) + this->Connect( output, i->second.first, i->second.second ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Disconnect( + const std::string& orig_filter, const std::string& dest_filter, + const std::string& output_name, const std::string& input_name + ) +{ + auto orig = this->GetFilter( orig_filter ); + auto dest = this->GetFilter( dest_filter ); + if( orig != NULL && dest != NULL ) { - TFilter::Pointer o = this->m_Interface.CreateObject( i->first ); - std::string name = o->GetClassName( ); - std::string category = o->GetClassCategory( ); - this->m_LoadedFilters[ category ].insert( name ); + auto out = orig->GetOutput( output_name ); + auto in = dest->GetInput( input_name ); + if( out != NULL && out == in ) + dest->SetInput( + input_name, ( cpPlugins::Pipeline::DataObject* )( NULL ) + ); + + } // fi +} - } // rof +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Disconnect( + const std::string& dest_filter, const std::string& input_name + ) +{ + throw std::logic_error( "Disconnect 1" ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Disconnect( const std::string& dest_filter ) +{ + throw std::logic_error( "Disconnect 2" ); +} +*/ + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Update( ) +{ + for( auto f = this->m_Filters.begin( ); f != this->m_Filters.end( ); ++f ) + f->second->Update( ); +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface::Workspace:: +Update( const std::string& name ) +{ + auto filter = this->GetFilter( name ); + if( filter != NULL ) + filter->Update( ); +} + +// ------------------------------------------------------------------------- +cpPlugins::Interface::Workspace:: +Workspace( ) + : Superclass( ), + m_PrintExecution( false ) +{ +} + +// ------------------------------------------------------------------------- +cpPlugins::Interface::Workspace:: +~Workspace( ) +{ + /* TODO + this->m_ExposedOutputs.clear( ); + this->m_ExposedInputs.clear( ); + */ + this->m_Filters.clear( ); } // eof - $RCSfile$