]> Creatis software - cpPlugins.git/commitdiff
...
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Thu, 10 Mar 2016 00:04:19 +0000 (19:04 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Thu, 10 Mar 2016 00:04:19 +0000 (19:04 -0500)
18 files changed:
appli/PipelineEditor/PipelineEditor.cxx
appli/PipelineEditor/PipelineEditor.h
appli/PipelineEditor/main.cxx
appli/bash/cpPlugins_HostCreator.cxx
appli/examples/CMakeLists.txt
appli/examples/example_LoadPluginsDirectory.cxx [new file with mode: 0644]
appli/examples/example_LoadPluginsFile.cxx
appli/examples/example_ReadWriteImage.cxx
appli/examples/example_ReadWriteImageWithWorkspace.cxx
cmake/CMakeLists.txt
cmake/cpPluginsConfig.cmake.in [new file with mode: 0644]
lib/ItkVtkGlue/itkImageToVTKImageFilter.h
lib/ItkVtkGlue/itkVTKImageToImageFilter.h
lib/cpExtensions/QT/SimpleMPRWidget.cxx
lib/cpPlugins/Image.h
lib/cpPlugins/Interface.cxx
lib/cpPlugins/Interface.h
plugins/cpPluginsIO/ImageWriter.cxx

index 139ae71904225969505138c29010678228eae114..fcd3f421ec5727b6f9ae1e9c8af045031a554c20 100644 (file)
     this, SLOT( _Button##BUTTON( ) )                    \
     )
 
+// -------------------------------------------------------------------------
+bool PipelineEditor_Blocker::
+eventFilter( QObject* obj, QEvent* event )
+{
+  return( true ); // -> Block all events
+  /* NOTE: correct implementation:
+     switch( event->type( ) )
+     {
+     //list event you want to prevent here ...
+     case QEvent::KeyPress:
+     case QEvent::KeyRelease:
+     case QEvent::MouseButtonRelease:
+     case QEvent::MouseButtonPress:
+     case QEvent::MouseButtonDblClick:
+     //...
+     return( true );
+     } // hctiws
+     return( this->QObject::eventFilter( obj, event ) );
+  */
+}
+
 // -------------------------------------------------------------------------
 PipelineEditor::
-PipelineEditor( int argc, char* argv[], QWidget* parent )
+PipelineEditor( int argc, char* argv[], QApplication* app, QWidget* parent )
   : QMainWindow( parent ),
     m_UI( new Ui::PipelineEditor ),
+    m_Application( app ),
     m_Workspace( NULL ),
     m_PluginsPath( "." )
 {
@@ -91,7 +113,8 @@ PipelineEditor::
 {
   if( this->m_Workspace != NULL )
     delete this->m_Workspace;
-  delete this->m_UI;
+  // TODO: this causes a segfault (?)
+  // delete this->m_UI;
 }
 
 // -------------------------------------------------------------------------
@@ -123,6 +146,7 @@ _LoadPluginsFromPath( const std::string& path )
 void PipelineEditor::
 _UpdateLoadedPlugins( )
 {
+  this->_Block( );
   auto filters = this->m_Interface.GetFilters( );
   if( filters.size( ) == 0 )
   {
@@ -159,7 +183,7 @@ _UpdateLoadedPlugins( )
     {
       QList< QTreeWidgetItem* > filter_items =
         this->m_UI->LoadedPlugins->findItems(
-          fIt->first.c_str( ), Qt::MatchExactly | Qt::MatchRecursive
+          fIt->c_str( ), Qt::MatchExactly | Qt::MatchRecursive
           );
       auto fiIt = filter_items.begin( );
       auto found_fiIt = filter_items.end( );
@@ -170,12 +194,30 @@ _UpdateLoadedPlugins( )
       // Add filter
       if( found_fiIt == filter_items.end( ) )
         QTreeWidgetItem* filter = new QTreeWidgetItem(
-          cat, QStringList( fIt->first.c_str( ) )
+          cat, QStringList( fIt->c_str( ) )
           );
 
     } // rof
 
   } // rof
+  this->_UnBlock( );
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::
+_Block( )
+{
+  this->m_Application->setOverrideCursor( Qt::WaitCursor );
+  this->m_Application->installEventFilter( &( this->m_Blocker ) );
+}
+
+// -------------------------------------------------------------------------
+void PipelineEditor::
+_UnBlock( )
+{
+  while( this->m_Application->overrideCursor( ) )
+    this->m_Application->restoreOverrideCursor( );
+  this->m_Application->removeEventFilter( &( this->m_Blocker ) );
 }
 
 // -------------------------------------------------------------------------
@@ -258,8 +300,8 @@ _ActionOpenWorkspace( )
   dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
   if( !( dlg.exec( ) ) )
     return;
-  std::string fname = dlg.selectedFiles( ).at( 0 ).toStdString( );
 
+  std::string fname = dlg.selectedFiles( ).at( 0 ).toStdString( );
   if( this->m_Workspace != NULL )
     delete this->m_Workspace;
   this->m_Workspace = new cpPlugins::Workspace( );
@@ -316,7 +358,9 @@ _ExecFilter( const std::string& filter_name )
   if( this->m_Workspace != NULL )
   {
     // Update filter, if needed
+    this->_Block( );
     std::string err = this->m_Workspace->Execute( filter_name );
+    this->_UnBlock( );
     if( err != "" )
       QMessageBox::critical(
         this,
@@ -356,7 +400,9 @@ _ShowFilterOutput(
             this->m_UI->Viewer->SetDataColor( data_name, 1, 0, 0 );
           else
             this->m_UI->Viewer->SetMainImage( data_name );
+          this->_Block( );
           this->m_UI->Viewer->ShowData( data_name );
+          this->_UnBlock( );
 
         } // fi
       }
index ffeeafdfae61ff88f10d0d1b6f32e9f593dc3bd0..81a6d3dc1b9109952783088a418fe6b7dd6b4e3f 100644 (file)
@@ -2,10 +2,35 @@
 #define __PIPELINEEDITOR__H__
 
 // Qt stuff
+#include <QApplication>
 #include <QMainWindow>
 #include <cpPlugins/Interface.h>
 #include <cpPlugins/Workspace.h>
 
+/**
+ */
+class PipelineEditor_Blocker
+  : public QObject
+{
+protected:
+  virtual bool eventFilter( QObject* obj, QEvent* event ) override;
+};
+
+/*
+  class PipelineEditor;
+  struct PipelineEditor_Application
+  {
+  QApplication           Application;
+  PipelineEditor         Window;
+  PipelineEditor_Blocker Blocker;
+  PipelineEditor_Application( int argc, char* argv[] );
+  void Show( );
+  int Exec( );
+  void Block( );
+  void UnBlock( );
+  };
+*/
+
 // -------------------------------------------------------------------------
 namespace Ui
 {
@@ -21,18 +46,21 @@ class PipelineEditor
 
 public:
   typedef PipelineEditor Self;
-  typedef QMainWindow      Superclass;
+  typedef QMainWindow    Superclass;
 
 public:
   explicit PipelineEditor(
     int argc, char* argv[],
-    QWidget* parent = 0
+    QApplication* app,
+    QWidget* parent = NULL
     );
   virtual ~PipelineEditor( );
 
 protected:
   void _LoadPluginsFromPath( const std::string& path );
   void _UpdateLoadedPlugins( );
+  void _Block( );
+  void _UnBlock( );
 
 protected slots:
   void _ButtonLoadPluginsFile( );
@@ -45,10 +73,12 @@ protected slots:
     );
 
 private:
-  Ui::PipelineEditor*   m_UI;
-  cpPlugins::Workspace* m_Workspace;
-  cpPlugins::Interface  m_Interface;
-  std::string           m_PluginsPath;
+  Ui::PipelineEditor*    m_UI;
+  QApplication*          m_Application;
+  PipelineEditor_Blocker m_Blocker;
+  cpPlugins::Workspace*  m_Workspace;
+  cpPlugins::Interface   m_Interface;
+  std::string            m_PluginsPath;
 };
 
 #endif // __CPPIPELINEEDITOR__H__
index 2013a69e742fc50e73f700bbf75df83a2c22081e..0914eceab21238932692c899e50f26edaacb1c38 100644 (file)
@@ -6,9 +6,8 @@
 int main( int argc, char* argv[] )
 {
   QApplication a( argc, argv );
-  PipelineEditor w( argc, argv, NULL );
+  PipelineEditor w( argc, argv, &a );
   w.show( );
-
   return( a.exec( ) );
 }
 
index 67212714e93b2160845abb6d47dea7edc2deaa68..ee11adf24c667c3453baca007f984d2c88f88c46 100644 (file)
@@ -117,25 +117,14 @@ int main( int argc, char* argv[] )
   // Write access function
   out_stream
     << "extern \"C\" std::map< std::string, std::set< std::string > > "
-    << "LoadedFilters( )" << std::endl << "{" << std::endl
+    << "cpPlugins_LoadedFilters( )" << std::endl << "{" << std::endl
     << "  std::map< std::string, std::set< std::string > > classes;"
     << std::endl;
-  int i = 0;
   for( auto iIt = info.begin( ); iIt != info.end( ); ++iIt )
-  {
     for( auto jIt = iIt->second.begin( ); jIt != iIt->second.end( ); ++jIt )
-    {
       out_stream
-        << "  auto f" << i << " = "
-        << jIt->second << "::" << jIt->first
-        << "::New( );" << std::endl
-        << "  classes[ f" << i << "->GetClassCategory( ) ].insert( "
-        << "f" << i << "->GetClassName( ) );" << std::endl;
-      i++;
-
-    } // rof
-
-  } // rof
+        << "  classes[ \"" << iIt->first
+        << "\" ].insert( \"" << jIt->first << "\" );" << std::endl;
   out_stream
     << "  return( classes );" << std::endl
     << "}" << std::endl << std::endl;
index 020c854f7b9d197f1ef81d66b89713e9281e9769..752c62b7acf74a4284788acca52f5d803731a0de 100644 (file)
@@ -1,6 +1,7 @@
 SET(
   examples_SOURCES
   example_LoadPluginsFile
+  example_LoadPluginsDirectory
   example_ReadWriteImage
   example_ReadWriteImageWithWorkspace
   )
diff --git a/appli/examples/example_LoadPluginsDirectory.cxx b/appli/examples/example_LoadPluginsDirectory.cxx
new file mode 100644 (file)
index 0000000..cdda427
--- /dev/null
@@ -0,0 +1,41 @@
+#include <iostream>
+#include <cpPlugins/Interface.h>
+
+int main( int argc, char* argv[] )
+{
+  if( argc < 2 )
+  {
+    std::cerr << "Usage: " << argv[ 0 ] << " plugins_libraries" << std::endl;
+    return( 1 );
+
+  } // fi
+
+  // Load interface
+  cpPlugins::Interface interface;
+  for( int i = 1; i < argc; ++i )
+  {
+    try
+    {
+      interface.LoadPluginFile( argv[ i ] );
+    }
+    catch( ... )
+    {
+    } // yrt
+
+  } // rof
+
+  // Show loaded filters
+  auto filters = interface.GetFilters( );
+  for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt )
+  {
+    std::cout << "Category: " << cIt->first << std::endl;
+    for( auto nIt = cIt->second.begin( ); nIt != cIt->second.end( ); ++nIt )
+      std::cout
+        << "\tFilter: " << *nIt
+        << std::endl;
+
+  } // rof
+  return( 0 );
+}
+
+// eof - $RCSfile$
index e43f3834b0e78e559d384700f34eeeceb51219ee..ddef1706c063d34f77c452f6044e6ef43b875358 100644 (file)
@@ -19,12 +19,12 @@ int main( int argc, char* argv[] )
   catch( std::exception& err )
   {
     std::cerr
-      << "Interface load failed on \"" << argv[ 1 ] << "\": "
+      << "Error caught:"
       << err.what( )
       << std::endl;
     return( 1 );
 
-  } // fi
+  } // yrt
 
   // Show loaded filters
   auto filters = interface.GetFilters( );
@@ -33,8 +33,7 @@ int main( int argc, char* argv[] )
     std::cout << "Category: " << cIt->first << std::endl;
     for( auto nIt = cIt->second.begin( ); nIt != cIt->second.end( ); ++nIt )
       std::cout
-        << "\tFilter: " << nIt->first
-        << " (" << nIt->second << ")"
+        << "\tFilter: " << *nIt
         << std::endl;
 
   } // rof
index 50b8f43f1a251dcff3c6abcbbeb23b3fc76a2691..3eb89d82fb0d6531448b57aa3675ed779f6212f8 100644 (file)
@@ -72,7 +72,7 @@ int main( int argc, char* argv[] )
     for( int i = 2; i < argc - 1; ++i )
       reader_params->AddToOpenFileNameList( "FileNames", argv[ i ] );
     auto writer_params = writer->GetParameters( );
-    writer_params->SetOpenFileName( "FileName", argv[ argc - 1 ] );
+    writer_params->SetSaveFileName( "FileName", argv[ argc - 1 ] );
 
     // Connect filters
     writer->SetInput( "Input", reader->GetOutput( "Output" ) );
index 9a82138f46d1e7bd8b910b5097cdd99fa47b15a0..630744ac3df7297d4dcbc43d1a4489ec124d5dde 100644 (file)
@@ -42,7 +42,7 @@ int main( int argc, char* argv[] )
   for( int i = 2; i < argc - 1; ++i )
     reader_params->AddToOpenFileNameList( "FileNames", argv[ i ] );
   auto writer_params = writer->GetParameters( );
-  writer_params->SetOpenFileName( "FileName", argv[ argc - 1 ] );
+  writer_params->SetSaveFileName( "FileName", argv[ argc - 1 ] );
 
   // Execute
   std::string err = workspace.Execute( );
index 4b26944f8459c5a6dbbaa6107b5cab68d2f1c39c..7db97e9d701a2f1d8db503b199919175a0dca6ac 100644 (file)
@@ -1 +1,17 @@
+CONFIGURE_FILE(
+  cpPluginsConfig.cmake.in
+  ${PROJECT_BINARY_DIR}/cpPluginsConfig.cmake
+  @ONLY
+  )
+
+## ========================
+## -- Installation rules --
+## ========================
+
+INSTALL(
+  FILES
+  ${PROJECT_BINARY_DIR}/cpPluginsConfig.cmake
+  DESTINATION share/cmake
+  )
+
 ## eof - $RCSfile$
diff --git a/cmake/cpPluginsConfig.cmake.in b/cmake/cpPluginsConfig.cmake.in
new file mode 100644 (file)
index 0000000..734e990
--- /dev/null
@@ -0,0 +1,112 @@
+# ===================================
+# -- Some configurations variables --
+# ===================================
+
+SET(USE_QT4 "@QT4_FOUND@")
+
+# =======================
+# -- Find dependencies --
+# =======================
+
+# Find ITK and VTK
+SET(ITK_DIR @ITK_DIR@)
+FIND_PACKAGE(ITK REQUIRED)
+INCLUDE(${ITK_USE_FILE})
+
+SET(VTK_DIR @VTK_DIR@)
+FIND_PACKAGE(VTK REQUIRED)
+INCLUDE(${VTK_USE_FILE})
+
+# Do not use itk-vtk glue --> problems ahead!!!
+IF(ITKVtkGlue_LOADED)
+  MESSAGE(FATAL_ERROR "ITKVtkGlue module is available. Please re-compile your ITK without it. It could lead to nasty compilation problems... Just waiting for Kitware to solve it.")
+ENDIF(ITKVtkGlue_LOADED)
+
+IF(USE_QT4 EQUAL "1")
+  SET(QT_QMAKE_EXECUTABLE @QT_QMAKE_EXECUTABLE@)
+  FIND_PACKAGE(Qt4 REQUIRED)
+  INCLUDE(${QT_USE_FILE})
+
+  ## Check for required vtk-qt4 modules
+  SET(
+    vtk_required_modules
+    vtkGUISupportQt
+    vtkGUISupportQtOpenGL
+    )
+  FOREACH(vtk_module ${vtk_required_modules})
+    IF(NOT ${vtk_module}_LOADED)
+      MESSAGE(
+        FATAL_ERROR
+        "${vtk_module} module is required but not available."
+        )
+    ENDIF(NOT ${vtk_module}_LOADED)
+  ENDFOREACH(vtk_module)
+ENDIF(USE_QT4 EQUAL "1")
+
+
+# =========================
+# -- Include directories --
+# =========================
+
+INCLUDE_DIRECTORIES(
+  @PROJECT_SOURCE_DIR@/lib
+  @PROJECT_SOURCE_DIR@/lib/third_party
+  @PROJECT_SOURCE_DIR@/lib/ItkVtkGlue
+  @PROJECT_BINARY_DIR@/lib
+  @PROJECT_BINARY_DIR@/lib/third_party
+  @PROJECT_BINARY_DIR@/lib/ItkVtkGlue
+  @CMAKE_INSTALL_PREFIX@/include
+  @CMAKE_INSTALL_PREFIX@/include/third_party
+  @CMAKE_INSTALL_PREFIX@/include/ItkVtkGlue
+  )
+
+# =========================
+# -- Library directories --
+# =========================
+
+IF(MSVC)
+  LINK_DIRECTORIES(
+    @PROJECT_BINARY_DIR@/$(ConfigurationName)
+    @CMAKE_INSTALL_PREFIX@/bin
+    @CMAKE_INSTALL_PREFIX@/lib
+    )
+ELSE(MSVC)
+  LINK_DIRECTORIES(
+    @PROJECT_BINARY_DIR@
+    @CMAKE_INSTALL_PREFIX@/bin
+    @CMAKE_INSTALL_PREFIX@/lib
+    )
+ENDIF(MSVC)
+
+# ===================
+# -- Library names --
+# ===================
+
+SET(cpExtensions_LIBRARY cpExtensions)
+SET(cpPlugins_LIBRARY cpPlugins)
+
+# ======================
+# -- Executable names --
+# ======================
+
+IF(MSVC)
+  FIND_PROGRAM(
+    cpPlugins_HostCreator_APP
+    NAMES cpPlugins_HostCreator
+    HINTS /usr /usr/local
+    PATHS @CMAKE_INSTALL_PREFIX@/bin @PROJECT_BINARY_DIR@/Debug @PROJECT_BINARY_DIR@/Release @PROJECT_BINARY_DIR@/MinSizeRel @PROJECT_BINARY_DIR@/RelWithDebInfo
+    PATH_SUFFIXES bin sbin
+    DOC "Where is cpPlugins_HostCreator?"
+    )
+ELSE(MSVC)
+  FIND_PROGRAM(
+    cpPlugins_HostCreator_APP
+    NAMES cpPlugins_HostCreator
+    HINTS /usr /usr/local
+    PATHS @CMAKE_INSTALL_PREFIX@/bin @PROJECT_BINARY_DIR@
+    PATH_SUFFIXES bin sbin
+    DOC "Where is cpPlugins_HostCreator?"
+    )
+ENDIF(MSVC)
+
+## eof - $RCSfile$
index 9390eb87782d0a710758f4f3bab4596135bbe1e6..0fc27ac6f5d127e4b6d93f9ca40b354f9ea468d8 100644 (file)
@@ -95,8 +95,8 @@ protected:
   virtual ~ImageToVTKImageFilter();
 
 private:
-  ImageToVTKImageFilter(const Self&) ITK_DELETE_FUNCTION;
-  void operator=(const Self&) ITK_DELETE_FUNCTION;
+  ImageToVTKImageFilter(const Self&) = delete;
+  void operator=(const Self&) = delete;
 
   ExporterFilterPointer       m_Exporter;
   vtkImageImport *            m_Importer;
index b4427c8355857e69da67b4d0ab285d64f9c80de3..2bb90d4f22e21789ba7e384b4d3bcfe58527da8c 100644 (file)
@@ -83,8 +83,8 @@ protected:
   virtual ~VTKImageToImageFilter();
 
 private:
-  VTKImageToImageFilter(const Self&) ITK_DELETE_FUNCTION;
-  void operator=(const Self&) ITK_DELETE_FUNCTION;
+  VTKImageToImageFilter(const Self&) = delete;
+  void operator=(const Self&) = delete;
 
   typedef vtkSmartPointer<vtkImageExport> ImageExportPointer;
   ImageExportPointer m_Exporter;
index 62b92961f849085c0d37804565a73641544f6d4b..fa0214c47c9d304a98ce52a1bc9342341182e431 100644 (file)
@@ -58,7 +58,8 @@ SimpleMPRWidget( QWidget* parent )
 cpExtensions::QT::SimpleMPRWidget::
 ~SimpleMPRWidget( )
 {
-  delete this->m_UI;
+  // TODO: this causes a segfault (?)
+  // delete this->m_UI;
 }
 
 // -------------------------------------------------------------------------
index fa7c7c366ea8706c3eb4b8210649b843493aaf61..2bdde709d7a01f920f84dc7830afdba9f83f25da 100644 (file)
@@ -13,20 +13,23 @@ namespace cpPlugins
     : public DataObject
   {
   public:
-    typedef Image      Self;
-    typedef DataObject Superclass;
+    typedef Image                           Self;
+    typedef DataObject                      Superclass;
+    typedef itk::SmartPointer< Self >       Pointer;
+    typedef itk::SmartPointer< const Self > ConstPointer;
 
   public:
+    itkNewMacro( Self );
+    itkTypeMacro( Image, DataObject );
     cpPlugins_Id_Macro( Image, Object );
 
   public:
-    Image( );
-    virtual ~Image( );
-
     virtual void SetITK( itk::LightObject* o ) override;
     virtual void SetVTK( vtkObjectBase* o ) override;
 
   protected:
+    Image( );
+    virtual ~Image( );
 
     template< unsigned int D >
       inline bool _ITK_2_VTK_0( itk::LightObject* o );
index de6d63116e6c0b2b35bf58c1c4f9d0ba2bf72de5..0ee1faf9911aea516acf2fbe49c3d57a7c744930 100644 (file)
@@ -1,15 +1,10 @@
 #include <cpPlugins/Interface.h>
 
-#include <map>
-#include <set>
-#include <string>
-
 #ifdef cpPlugins_SYS_WINDOWS
 #else // cpPlugins_SYS_WINDOWS
 #  include <dlfcn.h>
 #endif // cpPlugins_SYS_WINDOWS
 
-
 // -------------------------------------------------------------------------
 cpPlugins::Interface::
 Interface( )
@@ -35,84 +30,75 @@ GetFilters( )
 void cpPlugins::Interface::
 LoadPluginFile( const std::string& filename )
 {
+  // Open library with its canonical path name
   auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
-  void* hnd = NULL;
-  std::map< std::string, std::set< std::string > > filters;
-#ifdef cpPlugins_SYS_WINDOWS
-  // TODO:
-#else // cpPlugins_SYS_WINDOWS
-
-  // Try to load canonical filename and clean error messages
-  hnd = dlopen( canonical_fn.c_str( ), RTLD_NOW | RTLD_GLOBAL );
+  void* hnd = Self::_DLOpen( canonical_fn );
   if( hnd == NULL )
     throw std::runtime_error(
       std::string( "cpPlugins::Interface: Could not load library \"" ) +
       canonical_fn +
       std::string( "\"" )
       );
-  dlerror( );
 
-  // Init plugins
-  typedef const std::map< std::string, std::set< std::string > > ( *func_t )( );
-  auto func = ( func_t ) dlsym( hnd, "LoadedFilters" );
-  const char* func_error = dlerror( );
-  if( func_error != NULL )
-  {
-    dlclose( hnd );
-    throw std::runtime_error(
-      std::string( "cpPlugins::Interface: Library \"" ) +
-      canonical_fn +
-      std::string( "\" not recognized as a cpPlugins library." )
-      );
+  // Load filters
+  TFilters filters = Self::_DLGetFilters( hnd );
 
-  } // fi
-  filters = func( );
-#endif // cpPlugins_SYS_WINDOWS
-  if( hnd != NULL )
+  // Save the loaded filters info
+  bool save_handler = false;
+  for( auto catIt = filters.begin( ); catIt != filters.end( ); ++catIt )
   {
-    // Save the loaded filters names
-    for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt )
+    // Check if the filter is completely new
+    auto act_catIt = this->m_Filters.find( catIt->first );
+    for(
+      auto clsIt = catIt->second.begin( );
+      clsIt != catIt->second.end( );
+      ++clsIt
+      )
     {
-      auto colIt = this->m_Filters.find( cIt->first );
-      for( auto fIt = cIt->second.begin( ); fIt != cIt->second.end( ); ++fIt )
+      bool new_filter = true;
+      if( act_catIt != this->m_Filters.end( ) )
+        new_filter =
+          ( act_catIt->second.find( *clsIt ) == act_catIt->second.end( ) );
+
+      // Ok, it is new
+      if( new_filter )
       {
-        bool found = false;
-        if( colIt != this->m_Filters.end( ) )
+        // Update filters container
+        TCreator creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
+        if( creator != NULL )
         {
-          auto rowIt = colIt->second.find( *fIt );
-          if( rowIt != colIt->second.end( ) )
-            found = true;
+          this->m_DynFilters[ catIt->first][ *clsIt ] =
+            TDynFunc( canonical_fn, creator );
+          this->m_Filters[ catIt->first ].insert( *clsIt );
+          save_handler = true;
 
         } // fi
-        if( !found )
-          this->m_Filters[ cIt->first ][ *fIt ] = canonical_fn;
 
-      } // rof
+      } // fi
 
     } // rof
 
-    // Save the hnd
-    this->m_Plugins[ canonical_fn ] = hnd;
-  }
+  } // rof
+
+  // Keep dynlib handler, if needed
+  if( save_handler )
+    this->m_DynLibraries[ canonical_fn ] = hnd;
   else
-    throw std::runtime_error(
-      "cpPlugins::Interface: Operative system not yet supported."
-      );
+    Self::_DLClose( hnd );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::
 UnloadAll( )
 {
-  auto pIt = this->m_Plugins.begin( );
-  for( ; pIt != this->m_Plugins.end( ); ++pIt )
-  {
-#ifdef cpPlugins_SYS_WINDOWS
-#else // cpPlugins_SYS_WINDOWS
-    dlclose( pIt->second );
-#endif // cpPlugins_SYS_WINDOWS
-  } // rof
-  this->m_Plugins.clear( );
+  for(
+    auto d = this->m_DynLibraries.begin( );
+    d != this->m_DynLibraries.end( );
+    ++d
+    )
+    Self::_DLClose( d->second );
+  this->m_DynLibraries.clear( );
+  this->m_DynFilters.clear( );
   this->m_Filters.clear( );
 }
 
@@ -120,38 +106,91 @@ UnloadAll( )
 cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
 Create( const std::string& category, const std::string& name )
 {
-  cpPlugins::ProcessObject::Pointer filter;
-  auto cIt = this->m_Filters.find( category );
-  if( cIt != this->m_Filters.end( ) )
+  cpPlugins::ProcessObject::Pointer filter = NULL;
+  auto catIt = this->m_DynFilters.find( category );
+  if( catIt != this->m_DynFilters.end( ) )
   {
-    auto nIt = cIt->second.find( name );
-    if( nIt != cIt->second.end( ) )
-    {
-      auto pIt = this->m_Plugins.find( nIt->second );
-      if( pIt != this->m_Plugins.end( ) )
-      {
+    auto clsIt = catIt->second.find( name );
+    if( clsIt != catIt->second.end( ) )
+      filter = clsIt->second.second( );
+
+  } // fi
+  return( filter );
+}
+
+// -------------------------------------------------------------------------
+void* cpPlugins::Interface::
+_DLOpen( const std::string& fname )
+{
+  void* hnd = NULL;
 #ifdef cpPlugins_SYS_WINDOWS
+  // TODO:
 #else // cpPlugins_SYS_WINDOWS
-        std::string func_name = category + "_" + name;
-        typedef cpPlugins::ProcessObject::Pointer ( *func_t )( );
-        auto func = ( func_t ) dlsym( pIt->second, func_name.c_str( ) );
-        if( func == NULL )
-        {
-          throw std::runtime_error(
-            std::string( "cpPlugins::Interface: Class \"" ) +
-            category + std::string( ":" ) + name +
-            std::string( "\" does not have a valid creator function." )
-            );
-
-        } // fi
-        filter = func( );
+  hnd = dlopen( fname.c_str( ), RTLD_NOW | RTLD_GLOBAL );
+  dlerror( );
 #endif // cpPlugins_SYS_WINDOWS
-      } // fi
+  return( hnd );
+}
 
-    } // fi
+// -------------------------------------------------------------------------
+cpPlugins::Interface::
+TFilters cpPlugins::Interface::
+_DLGetFilters( void* hnd )
+{
+  TFilters filters;
+#ifdef cpPlugins_SYS_WINDOWS
+  // TODO:
+#else // cpPlugins_SYS_WINDOWS
+  typedef const TFilters ( *f_t )( );
+  auto f = ( f_t ) dlsym( hnd, "cpPlugins_LoadedFilters" );
+  const char* err = dlerror( );
+  if( err != NULL )
+  {
+    dlclose( hnd );
+    throw std::runtime_error(
+      std::string(
+        "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
+        ) + std::string( err )
+      );
 
   } // fi
-  return( filter );
+  filters = f( );
+#endif // cpPlugins_SYS_WINDOWS
+  return( filters );
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Interface::
+TCreator cpPlugins::Interface::
+_DLGetCreator(
+  void* hnd, const std::string& category, const std::string& name
+  )
+{
+  TCreator c = NULL;
+  std::string func_name = category + "_" + name;
+#ifdef cpPlugins_SYS_WINDOWS
+  // TODO:
+#else // cpPlugins_SYS_WINDOWS
+  c = ( TCreator )dlsym( hnd, func_name.c_str( ) );
+  if( c == NULL )
+    throw std::runtime_error(
+      std::string( "cpPlugins::Interface: Class \"" ) +
+      category + std::string( ":" ) + name +
+      std::string( "\" does not have a valid creator function." )
+      );
+#endif // cpPlugins_SYS_WINDOWS
+  return( c );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::
+_DLClose( void* hnd )
+{
+#ifdef cpPlugins_SYS_WINDOWS
+  // TODO:
+#else // cpPlugins_SYS_WINDOWS
+  dlclose( hnd );
+#endif // cpPlugins_SYS_WINDOWS
 }
 
 // eof - $RCSfile$
index 7c860db3b584e81f6d2d8208a931a5d14c6f3ff2..61ddf3ba76f7b8fd6c46e84b46669af4d3576e20 100644 (file)
@@ -4,6 +4,7 @@
 #include <cpPlugins/Config.h>
 #include <cpPlugins/ProcessObject.h>
 #include <map>
+#include <set>
 #include <string>
 
 namespace cpPlugins
@@ -13,8 +14,14 @@ namespace cpPlugins
   class cpPlugins_EXPORT Interface
   {
   public:
-    typedef std::map< std::string, std::string > TStringRow;
-    typedef std::map< std::string, TStringRow >  TFilters;
+    typedef Interface Self;
+
+    typedef cpPlugins::ProcessObject::Pointer ( *TCreator )( );
+    typedef std::pair< std::string, TCreator >               TDynFunc;
+    typedef std::map< std::string, TDynFunc >                TDynFilter;
+    typedef std::map< std::string, TDynFilter >              TDynFilters;
+    typedef std::map< std::string, void* >                   TDynLibraries;
+    typedef std::map< std::string, std::set< std::string > > TFilters;
 
   public:
     Interface( );
@@ -30,8 +37,17 @@ namespace cpPlugins
       );
 
   protected:
-    std::map< std::string, void* > m_Plugins;
-    TFilters m_Filters;
+    static void* _DLOpen( const std::string& fname );
+    static TFilters _DLGetFilters( void* hnd );
+    static TCreator _DLGetCreator(
+      void* hnd, const std::string& category, const std::string& name
+      );
+    static void _DLClose( void* hnd );
+
+  protected:
+    TDynLibraries m_DynLibraries;
+    TDynFilters   m_DynFilters;
+    TFilters      m_Filters;
   };
 
 } // ecapseman
index 4418c66aff1d03cfe8cc11103c26f9a4549abbfe..76be57cc68d145378fa1921958afa56589796393 100644 (file)
@@ -66,7 +66,7 @@ _GD1( I* image )
   if( image == NULL )
     return( "IO::ImageWriter: Invalid pixel type." );
   auto f = this->_CreateITK< itk::ImageFileWriter< I > >( );
-  f->SetFileName( this->m_Parameters.GetOpenFileName( "FileName" ) );
+  f->SetFileName( this->m_Parameters.GetSaveFileName( "FileName" ) );
   f->SetInput( image );
   f->Update( );
   return( "" );