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 )
167 po = provider->create( );
171 catIt = this->m_Classes.end( );
181 // -------------------------------------------------------------------------
182 bool cpPlugins::Interface::Interface::
183 Load( const std::string& path )
188 ret = this->m_Pluma->load( path );
191 std::string folder, name;
192 Self::_SepFName( path, folder, name );
193 this->m_LoadedPlugins[ folder ].push_back( name );
194 this->_LoadClasses( );
206 // -------------------------------------------------------------------------
207 bool cpPlugins::Interface::Interface::
208 Load( const std::string& folder, const std::string& name )
210 std::string real_folder = folder;
212 if( sep( folder[ folder.size( ) - 1 ] ) )
213 real_folder = folder.substr( 0, folder.size( ) - 1 );
214 real_folder = cpPlugins_Interface_CanonicalPath( real_folder );
219 ret = this->m_Pluma->load( real_folder, name );
222 // Update loaded plugins
223 std::string prefix( PLUGIN_PREFIX );
224 std::string ext( PLUGIN_EXT );
225 std::string real_name = name;
227 real_name.replace( real_name.find( prefix ), prefix.size( ), "" );
228 real_name.replace( real_name.find( ext ), ext.size( ), "" );
229 this->m_LoadedPlugins[ real_folder ].push_back( real_name );
230 this->_LoadClasses( );
242 // -------------------------------------------------------------------------
243 bool cpPlugins::Interface::Interface::
244 LoadFromFolder( const std::string& folder, bool r )
248 std::list< std::string > f = this->m_Pluma->loadFromFolder( folder, r );
251 // Update loaded plugins
252 for( auto i = f.begin( ); i != f.end( ); ++i )
254 std::string folder, name;
255 Self::_SepFName( *i, folder, name );
256 this->m_LoadedPlugins[ folder ].push_back( name );
261 this->_LoadClasses( );
274 // -------------------------------------------------------------------------
275 bool cpPlugins::Interface::Interface::
276 Unload( const std::string& name )
281 ret = this->m_Pluma->unload( name );
284 this->m_Providers.clear( );
285 this->m_Classes.clear( );
287 // TODO: this->m_LoadedPlugins
289 this->_LoadClasses( );
301 // -------------------------------------------------------------------------
302 void cpPlugins::Interface::Interface::
307 this->m_Pluma->unloadAll( );
314 this->m_Providers.clear( );
315 this->m_Classes.clear( );
316 this->m_LoadedPlugins.clear( );
319 // -------------------------------------------------------------------------
320 bool cpPlugins::Interface::Interface::
321 IsLoaded( const std::string& name ) const
323 return( this->m_Pluma->isLoaded( name ) );
326 // -------------------------------------------------------------------------
327 void cpPlugins::Interface::Interface::
330 this->m_Providers.clear( );
331 this->m_Classes.clear( );
332 this->m_Pluma->getProviders( this->m_Providers );
334 // Get reader provider
335 for( unsigned int i = 0; i < this->m_Providers.size( ); ++i )
337 ProcessObject::Pointer d = this->m_Providers[ i ]->create( );
338 this->m_Classes[ d->GetClassCategory( ) ][ d->GetClassName( ) ] = i;
343 // -------------------------------------------------------------------------
344 void cpPlugins::Interface::Interface::
345 _SepFName( const std::string& path, std::string& folder, std::string& name )
350 std::string real_path = cpPlugins_Interface_CanonicalPath( path );
354 std::find_if( real_path.rbegin( ), real_path.rend( ), sep ).base( ),
358 // Get containing folder
360 folder.replace( folder.find( name ), name.size( ), "" );
361 if( sep( folder[ folder.size( ) - 1 ] ) )
362 folder = folder.substr( 0, folder.size( ) - 1 );
364 // Erase prefix and extension from filename
365 std::string prefix( PLUGIN_PREFIX );
366 std::string ext( PLUGIN_EXT );
368 name.replace( name.find( prefix ), prefix.size( ), "" );
369 name.replace( name.find( ext ), ext.size( ), "" );