1 ////////////////////////////////////////////////////////////
\r
3 // Pluma - Plug-in Management Framework
\r
4 // Copyright (C) 2010-2012 Gil Costa (gsaurus@gmail.com)
\r
6 // This software is provided 'as-is', without any express or implied warranty.
\r
7 // In no event will the authors be held liable for any damages arising from the use of this software.
\r
9 // Permission is granted to anyone to use this software for any purpose,
\r
10 // including commercial applications, and to alter it and redistribute it freely,
\r
11 // subject to the following restrictions:
\r
13 // 1. The origin of this software must not be misrepresented;
\r
14 // you must not claim that you wrote the original software.
\r
15 // If you use this software in a product, an acknowledgment
\r
16 // in the product documentation would be appreciated but is not required.
\r
18 // 2. Altered source versions must be plainly marked as such,
\r
19 // and must not be misrepresented as being the original software.
\r
21 // 3. This notice may not be removed or altered from any source distribution.
\r
23 ////////////////////////////////////////////////////////////
\r
25 ////////////////////////////////////////////////////////////
\r
27 ////////////////////////////////////////////////////////////
\r
28 #include <Pluma/PluginManager.hpp>
\r
29 #include <Pluma/DLibrary.hpp>
\r
30 #include <Pluma/Dir.hpp>
\r
32 #include <stdexcept>
\r
36 ////////////////////////////////////////////////////////////
\r
37 PluginManager::PluginManager(){
\r
42 ////////////////////////////////////////////////////////////
\r
43 PluginManager::~PluginManager(){
\r
48 ////////////////////////////////////////////////////////////
\r
49 bool PluginManager::load(const std::string& path){
\r
50 std::string plugName = getPluginName(path);
\r
51 std::string realPath = resolvePathExtension(path);
\r
52 DLibrary* lib = DLibrary::load(realPath);
\r
53 if (!lib) return false;
\r
55 fnRegisterPlugin* registerFunction;
\r
56 registerFunction = reinterpret_cast<fnRegisterPlugin*>(lib->getSymbol("connect"));
\r
58 if(!registerFunction){
\r
59 //fprintf(stderr, "Failed to initialize plugin \"%s\": connect function not found\n", plugName.c_str());
\r
61 throw std::runtime_error(
\r
62 std::string( "Failed to initialize plugin \"" ) +
\r
64 std::string( "\": connect function not found" )
\r
68 // try to initialize plugin:
\r
69 if (!registerFunction(host)){
\r
70 // plugin decided to fail
\r
71 // fprintf(stderr, "Self registry failed on plugin \"%s\".\n", plugName.c_str());
\r
72 host.cancelAddictions();
\r
74 throw std::runtime_error(
\r
75 std::string( "Self registry failed on plugin \"" ) +
\r
81 // Store the library if addictions are confirmed
\r
82 if (host.confirmAddictions())
\r
83 libraries[plugName] = lib;
\r
85 // otherwise nothing was registered
\r
86 // fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());
\r
88 throw std::runtime_error(
\r
89 std::string( "Nothing registered by plugin \"" ) +
\r
91 std::string( "\"." )
\r
99 ////////////////////////////////////////////////////////////
\r
100 bool PluginManager::load(const std::string& folder, const std::string& pluginName){
\r
101 if (folder.empty())
\r
102 return load(pluginName);
\r
103 else if (folder[folder.size()-1] == '/' || folder[folder.size()-1] == '\\')
\r
104 return load(folder + pluginName);
\r
105 return load(folder + '/' + pluginName);
\r
108 ////////////////////////////////////////////////////////////
\r
109 std::list< std::string > PluginManager::loadFromFolder(const std::string& folder, bool recursive){
\r
110 std::list<std::string> files, loaded_files;
\r
111 dir::listFiles(files, folder, PLUMA_LIB_EXTENSION, recursive);
\r
112 // try to load every library
\r
113 std::list<std::string>::const_iterator it;
\r
114 for (it = files.begin() ; it != files.end() ; ++it){
\r
118 if ( load(*it) ) loaded_files.push_back( *it );
\r
125 return loaded_files;
\r
129 ////////////////////////////////////////////////////////////
\r
130 bool PluginManager::unload(const std::string& pluginName){
\r
131 std::string plugName = getPluginName(pluginName);
\r
132 LibMap::iterator it = libraries.find(plugName);
\r
133 if( it != libraries.end() ) {
\r
135 libraries.erase(it);
\r
141 ////////////////////////////////////////////////////////////
\r
142 void PluginManager::unloadAll(){
\r
144 host.clearProviders();
\r
145 LibMap::iterator it;
\r
146 for (it = libraries.begin() ; it != libraries.end() ; ++it){
\r
153 ////////////////////////////////////////////////////////////
\r
154 std::string PluginManager::getPluginName(const std::string& path){
\r
155 size_t lastDash = path.find_last_of("/\\");
\r
156 size_t lastDot = path.find_last_of('.');
\r
157 if (lastDash == std::string::npos) lastDash = 0;
\r
159 if (lastDot < lastDash || lastDot == std::string::npos){
\r
160 // path without extension
\r
161 lastDot = path.length();
\r
163 return path.substr(lastDash, lastDot-lastDash);
\r
167 ////////////////////////////////////////////////////////////
\r
168 std::string PluginManager::resolvePathExtension(const std::string& path){
\r
169 size_t lastDash = path.find_last_of("/\\");
\r
170 size_t lastDot = path.find_last_of('.');
\r
171 if (lastDash == std::string::npos) lastDash = 0;
\r
173 if (lastDot < lastDash || lastDot == std::string::npos){
\r
174 // path without extension, add it
\r
175 return path + "." + PLUMA_LIB_EXTENSION;
\r
181 ////////////////////////////////////////////////////////////
\r
182 void PluginManager::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion){
\r
183 host.registerType(type, version, lowestVersion);
\r
187 ////////////////////////////////////////////////////////////
\r
188 bool PluginManager::addProvider(Provider* provider){
\r
189 if (provider == NULL){
\r
190 // fprintf(stderr, "Trying to add null provider\n");
\r
191 throw std::runtime_error( "Trying to add null provider." );
\r
194 return host.registerProvider(provider);
\r
198 ////////////////////////////////////////////////////////////
\r
199 void PluginManager::getLoadedPlugins(std::vector<const std::string*>& pluginNames) const{
\r
200 pluginNames.reserve(pluginNames.size()+libraries.size());
\r
201 LibMap::const_iterator it;
\r
202 for(it = libraries.begin() ; it != libraries.end() ; ++it){
\r
203 pluginNames.push_back(&(it->first));
\r
208 ////////////////////////////////////////////////////////////
\r
209 bool PluginManager::isLoaded(const std::string& pluginName) const{
\r
210 return libraries.find(getPluginName(pluginName)) != libraries.end();
\r
214 ////////////////////////////////////////////////////////////
\r
215 const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const{
\r
216 return host.getProviders(type);
\r
221 } // namespace pluma
\r