]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/Interface.cxx
...
[cpPlugins.git] / lib / cpPlugins / Interface.cxx
index 53b7b118174179807139737986a54f5e9a1ed93b..1f0a0159148e2159abbb31a75e7e39587beb0adf 100644 (file)
@@ -12,6 +12,7 @@
 cpPlugins::Interface::
 Interface( )
 {
+  this->UpdatePaths( );
 }
 
 // -------------------------------------------------------------------------
@@ -31,74 +32,101 @@ GetFilters( )
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::
-GuessAccesiblePlugins( )
+UpdatePaths( )
 {
   // Load environment configuration
-  char* path = std::getenv( "cpPlugins_PATHS" );
-  if( path != NULL )
-  {
-    std::vector< std::string > tokens;
-    cpPlugins::TokenizeString( tokens, path, "#" );
-    for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
-      try { this->LoadPluginDir( *tIt ); } catch( ... ) { }
-
-  } // fi
+  this->m_Paths.clear( );
+  char* p = std::getenv( "cpPlugins_PATHS" );
+  if( p != NULL )
+    cpPlugins::TokenizeString( this->m_Paths, p, cpPlugins_SEPARATOR );
+  this->m_Paths.push_back( "." );
+}
 
-  // Load local path
-  auto lpath = cpPlugins::CanonicalPath( "." );
-  try { this->LoadPluginDir( lpath ); } catch( ... ) { }
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::
+GuessAccesiblePlugins( )
+{
+  for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
+    try { this->LoadPluginDir( *i ); } catch( ... ) { }
 }
 
 // -------------------------------------------------------------------------
-bool cpPlugins::Interface::
-LoadConfiguration( const std::string& filename )
+void cpPlugins::Interface::
+LoadPlugin( const std::string& name )
 {
-  std::ifstream in( filename.c_str( ) );
-  if( !in )
-    return( false );
+  std::stringstream str;
+  str << cpPlugins_LIB_PREFIX << name << "." << cpPlugins_LIB_EXT;
+  std::string base_name = str.str( );
+  bool found = false;
+  for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
+  {
+    std::string filename = *i;
+    if( i->back( ) != '/' )
+      filename += std::string( "/" );
+    filename += base_name;
+    try
+    {
+      this->LoadPluginFile( filename );
+      found = true;
+    }
+    catch( ... )
+    {
+    } // yrt
 
-  this->UnloadAll( );
-  std::string line;
-  while( std::getline( in, line ) )
-    try { this->LoadPluginFile( line ); } catch( ... ) { }
-  return( true );
+  } // rof
+  if( !found )
+    throw std::runtime_error(
+      std::string( "cpPlugins::Interface: Plugins library \"" ) +
+      name +
+      std::string( "\" not found." )
+      );
 }
 
 // -------------------------------------------------------------------------
-bool cpPlugins::Interface::
-SaveConfiguration( const std::string& filename ) const
+void cpPlugins::Interface::
+LoadPluginDir( const std::string& dirname )
 {
-  std::ofstream out( filename.c_str( ) );
-  if( !out )
-    return( false );
-  auto dIt = this->m_DynLibraries.begin( );
-  for( ; dIt != this->m_DynLibraries.end( ); ++dIt )
-    out << dIt->first << std::endl;
-  out.close( );
-  return( true );
+  DIR* dir;
+  struct dirent* ent;
+  if( ( dir = opendir( dirname.c_str( ) ) ) != NULL )
+  {
+    while( ( ent = readdir( dir ) ) != NULL )
+    {
+      try
+      {
+        this->LoadPluginFile(
+          dirname +
+          std::string( "/" ) +
+          ent->d_name
+          );
+      }
+      catch( ... ) { }
+
+    } // elihw
+    closedir( dir );
+  }
+  else
+    throw std::runtime_error(
+      std::string( "cpPlugins::Interface: Could not load directory " ) +
+      std::string( "\"" ) +  dirname + std::string( "\"" )
+      );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::
 LoadPluginFile( const std::string& filename )
 {
-  // Open library with its canonical path name
-  auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
-  if( canonical_fn == "" )
+  // Canonical filename
+  auto canonical = cpPlugins::PathHelper::CanonicalPath( filename );
+  if( canonical == "" )
     throw std::runtime_error(
       std::string( "cpPlugins::Interface: Library \"" ) +
       filename +
       std::string( "\" does not exist." )
       );
 
-  // Check if it was already loaded
-  if(
-    this->m_DynLibraries.find( canonical_fn ) != this->m_DynLibraries.end( )
-    )
-    return;
-
-  // Ok, try to load the library
-  void* hnd = Self::_DLOpen( canonical_fn );
+  // Try to load the library
+  void* hnd = Self::_DLOpen( canonical );
   if( hnd == NULL )
     throw std::runtime_error(
       std::string( "cpPlugins::Interface: Could not load library \"" ) +
@@ -106,6 +134,13 @@ LoadPluginFile( const std::string& filename )
       std::string( "\"" )
       );
 
+  // Get plugin name
+  std::string pl_name = Self::_DLGetName( hnd );
+
+  // Check if it was already loaded
+  if( this->m_DynLibraries.find( pl_name ) != this->m_DynLibraries.end( ) )
+    return;
+
   // Load filters
   TFilters filters = Self::_DLGetFilters( hnd );
 
@@ -134,7 +169,7 @@ LoadPluginFile( const std::string& filename )
         if( creator != NULL )
         {
           this->m_DynFilters[ catIt->first][ *clsIt ] =
-            TDynFunc( canonical_fn, creator );
+            TDynFunc( pl_name, creator );
           this->m_Filters[ catIt->first ].insert( *clsIt );
           save_handler = true;
 
@@ -148,44 +183,11 @@ LoadPluginFile( const std::string& filename )
 
   // Keep dynlib handler, if needed
   if( save_handler )
-    this->m_DynLibraries[ canonical_fn ] = hnd;
+    this->m_DynLibraries[ pl_name ] = TDynFileInfo( canonical, hnd );
   else
     Self::_DLClose( hnd );
 }
 
-// -------------------------------------------------------------------------
-unsigned int cpPlugins::Interface::
-LoadPluginDir( const std::string& dirname )
-{
-  DIR* dir;
-  struct dirent* ent;
-  unsigned int count = 0;
-  if( ( dir = opendir( dirname.c_str( ) ) ) != NULL )
-  {
-    while( ( ent = readdir( dir ) ) != NULL )
-    {
-      try
-      {
-        this->LoadPluginFile(
-          dirname +
-          std::string( "/" ) +
-          ent->d_name
-          );
-        count++;
-      }
-      catch( ... ) { }
-
-    } // elihw
-    closedir( dir );
-  }
-  else
-    throw std::runtime_error(
-      std::string( "cpPlugins::Interface: Could not load directory " ) +
-      std::string( "\"" ) +  dirname + std::string( "\"" )
-      );
-  return( count );
-}
-
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::
 UnloadAll( )
@@ -195,7 +197,7 @@ UnloadAll( )
     d != this->m_DynLibraries.end( );
     ++d
     )
-    Self::_DLClose( d->second );
+    Self::_DLClose( d->second.second );
   this->m_DynLibraries.clear( );
   this->m_DynFilters.clear( );
   this->m_Filters.clear( );
@@ -220,6 +222,33 @@ Create( const std::string& category, const std::string& name )
   return( filter );
 }
 
+// -------------------------------------------------------------------------
+std::string cpPlugins::Interface::
+GetPluginName( const std::string& category, const std::string& name ) const
+{
+  std::string plugin = "";
+  auto catIt = this->m_DynFilters.find( category );
+  if( catIt != this->m_DynFilters.end( ) )
+  {
+    auto clsIt = catIt->second.find( name );
+    if( clsIt != catIt->second.end( ) )
+      plugin = clsIt->second.first;
+
+  } // fi
+  return( plugin );
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string > cpPlugins::Interface::
+GetPlugins( ) const
+{
+  std::vector< std::string > res;
+  auto i = this->m_DynLibraries.begin( );
+  for( ; i != this->m_DynLibraries.end( ); ++i )
+    res.push_back( i->first );
+  return( res );
+}
+
 // -------------------------------------------------------------------------
 void* cpPlugins::Interface::
 _DLOpen( const std::string& fname )
@@ -234,6 +263,29 @@ _DLOpen( const std::string& fname )
   return( hnd );
 }
 
+// -------------------------------------------------------------------------
+const char* cpPlugins::Interface::
+_DLGetName( void* hnd )
+{
+  // Get descriptors
+  typedef const char* ( *f_t )( );
+  f_t f = NULL;
+#ifdef cpPlugins_SYS_WINDOWS
+  f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_Name" ) );
+#else // cpPlugins_SYS_WINDOWS
+  f = ( f_t )( dlsym( hnd, "cpPlugins_Name" ) );
+#endif // cpPlugins_SYS_WINDOWS
+  if( f == NULL )
+  {
+    Self::_DLClose( hnd );
+    throw std::runtime_error(
+      "cpPlugins::Interface: Library not recognized as a cpPlugins library."
+      );
+
+  } // fi
+  return( f( ) );
+}
+
 // -------------------------------------------------------------------------
 cpPlugins::Interface::
 TFilters cpPlugins::Interface::
@@ -251,7 +303,7 @@ _DLGetFilters( void* hnd )
   {
     Self::_DLClose( hnd );
     throw std::runtime_error(
-      "cpPlugins::Interface: Library not recognized as a cpPlugins library"
+      "cpPlugins::Interface: Library not recognized as a cpPlugins library."
       );
 
   } // fi