1 #include <cpPlugins/Interface/Interface.h>
2 #include <cpPlugins/Interface/ProcessObjectProvider.h>
7 #include <Pluma/Pluma.hpp>
10 # define PLUGIN_PREFIX ""
11 # define PLUGIN_EXT ".dll"
13 # define PLUGIN_PREFIX "lib"
14 # define PLUGIN_EXT ".so"
16 #define PLUGIN_CONFIG_FILE "plugins.cfg"
24 bool operator()( char c ) const
27 return( c == '\\' || c == '/' );
38 // -------------------------------------------------------------------------
39 std::string cpPlugins_Interface_CanonicalPath( const std::string& path )
42 TCHAR buffer[ 4096 ] = TEXT( "" );
43 TCHAR** lppPart = { NULL };
44 GetFullPathName( path.c_str( ), 4096, buffer, lppPart );
45 return( std::string( buffer ) );
47 return( std::string( realpath( path.c_str( ), NULL ) ) );
51 // -------------------------------------------------------------------------
52 cpPlugins::Interface::Interface::
55 this->m_Pluma = new pluma::Pluma( );
56 this->m_Pluma->acceptProviderType< ProcessObjectProvider >( );
59 // -------------------------------------------------------------------------
60 cpPlugins::Interface::Interface::
67 // -------------------------------------------------------------------------
68 bool cpPlugins::Interface::Interface::
69 LoadDefaultConfiguration( const std::string& path )
71 std::ifstream file( PLUGIN_CONFIG_FILE );
75 while( file.getline( buffer, 1000 ) )
77 // std::string line( buffer );
78 std::istringstream line( buffer );
79 std::string name, folder;
80 std::getline( line, name, '@' );
81 std::getline( line, folder, '@' );
82 std::stringstream path;
83 path << folder << "/" << PLUGIN_PREFIX << name << PLUGIN_EXT;
84 this->Load( path.str( ) );
95 // -------------------------------------------------------------------------
96 bool cpPlugins::Interface::Interface::
97 SaveDefaultConfiguration( const std::string& path )
99 std::ofstream file( PLUGIN_CONFIG_FILE );
102 auto pIt = this->m_LoadedPlugins.begin( );
103 for( ; pIt != this->m_LoadedPlugins.end( ); ++pIt )
105 auto fIt = pIt->second.begin( );
106 for( ; fIt != pIt->second.end( ); ++fIt )
107 file << *fIt << "@" << pIt->first << std::endl;
117 // -------------------------------------------------------------------------
118 cpPlugins::Interface::Interface::
119 TClasses& cpPlugins::Interface::Interface::
122 return( this->m_Classes );
125 // -------------------------------------------------------------------------
126 const cpPlugins::Interface::Interface::
127 TClasses& cpPlugins::Interface::Interface::
130 return( this->m_Classes );
133 // -------------------------------------------------------------------------
134 cpPlugins::Interface::Interface::
135 TLoadedPlugins& cpPlugins::Interface::Interface::
138 return( this->m_LoadedPlugins );
141 // -------------------------------------------------------------------------
142 const cpPlugins::Interface::Interface::
143 TLoadedPlugins& cpPlugins::Interface::Interface::
144 GetLoadedPlugins( ) const
146 return( this->m_LoadedPlugins );
149 // -------------------------------------------------------------------------
150 cpPlugins::Interface::ProcessObject::Pointer
151 cpPlugins::Interface::Interface::
152 CreateObject( const std::string& name ) const
154 cpPlugins::Interface::ProcessObject::Pointer po = NULL;
155 auto catIt = this->m_Classes.begin( );
156 while( catIt != this->m_Classes.end( ) )
158 auto classIt = catIt->second.find( name );
159 if( classIt != catIt->second.end( ) )
161 ProcessObjectProvider* provider =
162 dynamic_cast< ProcessObjectProvider* >(
163 this->m_Providers[ classIt->second ]
165 if( provider != NULL )
166 po = provider->create( );
167 catIt = this->m_Classes.end( );
177 // -------------------------------------------------------------------------
178 bool cpPlugins::Interface::Interface::
179 Load( const std::string& path )
184 ret = this->m_Pluma->load( path );
187 std::string folder, name;
188 Self::_SepFName( path, folder, name );
189 this->m_LoadedPlugins[ folder ].push_back( name );
190 this->_LoadClasses( );
202 // -------------------------------------------------------------------------
203 bool cpPlugins::Interface::Interface::
204 Load( const std::string& folder, const std::string& name )
206 std::string real_folder = folder;
208 if( sep( folder[ folder.size( ) - 1 ] ) )
209 real_folder = folder.substr( 0, folder.size( ) - 1 );
210 real_folder = cpPlugins_Interface_CanonicalPath( real_folder );
215 ret = this->m_Pluma->load( real_folder, name );
218 // Update loaded plugins
219 std::string prefix( PLUGIN_PREFIX );
220 std::string ext( PLUGIN_EXT );
221 std::string real_name = name;
223 real_name.replace( real_name.find( prefix ), prefix.size( ), "" );
224 real_name.replace( real_name.find( ext ), ext.size( ), "" );
225 this->m_LoadedPlugins[ real_folder ].push_back( real_name );
226 this->_LoadClasses( );
238 // -------------------------------------------------------------------------
239 bool cpPlugins::Interface::Interface::
240 LoadFromFolder( const std::string& folder, bool r )
244 std::list< std::string > f = this->m_Pluma->loadFromFolder( folder, r );
247 // Update loaded plugins
248 for( auto i = f.begin( ); i != f.end( ); ++i )
250 std::string folder, name;
251 Self::_SepFName( *i, folder, name );
252 this->m_LoadedPlugins[ folder ].push_back( name );
257 this->_LoadClasses( );
270 // -------------------------------------------------------------------------
271 bool cpPlugins::Interface::Interface::
272 Unload( const std::string& name )
277 ret = this->m_Pluma->unload( name );
280 this->m_Providers.clear( );
281 this->m_Classes.clear( );
283 // TODO: this->m_LoadedPlugins
285 this->_LoadClasses( );
297 // -------------------------------------------------------------------------
298 void cpPlugins::Interface::Interface::
303 this->m_Pluma->unloadAll( );
310 this->m_Providers.clear( );
311 this->m_Classes.clear( );
312 this->m_LoadedPlugins.clear( );
315 // -------------------------------------------------------------------------
316 bool cpPlugins::Interface::Interface::
317 IsLoaded( const std::string& name ) const
319 return( this->m_Pluma->isLoaded( name ) );
322 // -------------------------------------------------------------------------
323 void cpPlugins::Interface::Interface::
326 this->m_Providers.clear( );
327 this->m_Classes.clear( );
328 this->m_Pluma->getProviders( this->m_Providers );
330 // Get reader provider
331 for( unsigned int i = 0; i < this->m_Providers.size( ); ++i )
333 ProcessObject::Pointer d = this->m_Providers[ i ]->create( );
334 this->m_Classes[ d->GetClassCategory( ) ][ d->GetClassName( ) ] = i;
339 // -------------------------------------------------------------------------
340 void cpPlugins::Interface::Interface::
341 _SepFName( const std::string& path, std::string& folder, std::string& name )
346 std::string real_path = cpPlugins_Interface_CanonicalPath( path );
350 std::find_if( real_path.rbegin( ), real_path.rend( ), sep ).base( ),
354 // Get containing folder
356 folder.replace( folder.find( name ), name.size( ), "" );
357 if( sep( folder[ folder.size( ) - 1 ] ) )
358 folder = folder.substr( 0, folder.size( ) - 1 );
360 // Erase prefix and extension from filename
361 std::string prefix( PLUGIN_PREFIX );
362 std::string ext( PLUGIN_EXT );
364 name.replace( name.find( prefix ), prefix.size( ), "" );
365 name.replace( name.find( ext ), ext.size( ), "" );