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
26 ////////////////////////////////////////////////////////////
\r
28 ////////////////////////////////////////////////////////////
\r
29 #include <Pluma/PluginManager.hpp>
\r
30 #include <Pluma/DLibrary.hpp>
\r
31 #include <Pluma/Dir.hpp>
\r
33 #include <stdexcept>
\r
37 ////////////////////////////////////////////////////////////
\r
38 PluginManager::PluginManager(){
\r
43 ////////////////////////////////////////////////////////////
\r
44 PluginManager::~PluginManager(){
\r
49 ////////////////////////////////////////////////////////////
\r
50 bool PluginManager::load(const std::string& path){
\r
51 std::string plugName = getPluginName(path);
\r
52 std::string realPath = resolvePathExtension(path);
\r
53 DLibrary* lib = DLibrary::load(realPath);
\r
54 if (!lib) return false;
\r
56 fnRegisterPlugin* registerFunction;
\r
57 registerFunction = reinterpret_cast<fnRegisterPlugin*>(lib->getSymbol("connect"));
\r
59 if(!registerFunction){
\r
60 //fprintf(stderr, "Failed to initialize plugin \"%s\": connect function not found\n", plugName.c_str());
\r
62 throw std::runtime_error(
\r
63 std::string( "Failed to initialize plugin \"" ) +
\r
65 std::string( "\": connect function not found" )
\r
69 // try to initialize plugin:
\r
70 if (!registerFunction(host)){
\r
71 // plugin decided to fail
\r
72 // fprintf(stderr, "Self registry failed on plugin \"%s\".\n", plugName.c_str());
\r
73 host.cancelAddictions();
\r
75 throw std::runtime_error(
\r
76 std::string( "Self registry failed on plugin \"" ) +
\r
82 // Store the library if addictions are confirmed
\r
83 if (host.confirmAddictions())
\r
84 libraries[plugName] = lib;
\r
86 // otherwise nothing was registered
\r
87 // fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());
\r
89 throw std::runtime_error(
\r
90 std::string( "Nothing registered by plugin \"" ) +
\r
92 std::string( "\"." )
\r
100 ////////////////////////////////////////////////////////////
\r
101 bool PluginManager::load(const std::string& folder, const std::string& pluginName){
\r
102 if (folder.empty())
\r
103 return load(pluginName);
\r
104 else if (folder[folder.size()-1] == '/' || folder[folder.size()-1] == '\\')
\r
105 return load(folder + pluginName);
\r
106 return load(folder + '/' + pluginName);
\r
110 ////////////////////////////////////////////////////////////
\r
111 int PluginManager::loadFromFolder(const std::string& folder, bool recursive){
\r
112 std::list<std::string> files;
\r
113 dir::listFiles(files, folder, PLUMA_LIB_EXTENSION, recursive);
\r
114 // try to load every library
\r
116 std::list<std::string>::const_iterator it;
\r
117 for (it = files.begin() ; it != files.end() ; ++it){
\r
118 if ( load(*it) ) ++res;
\r
124 ////////////////////////////////////////////////////////////
\r
125 bool PluginManager::unload(const std::string& pluginName){
\r
126 std::string plugName = getPluginName(pluginName);
\r
127 LibMap::iterator it = libraries.find(plugName);
\r
128 if( it != libraries.end() ) {
\r
130 libraries.erase(it);
\r
136 ////////////////////////////////////////////////////////////
\r
137 void PluginManager::unloadAll(){
\r
139 host.clearProviders();
\r
140 LibMap::iterator it;
\r
141 for (it = libraries.begin() ; it != libraries.end() ; ++it){
\r
148 ////////////////////////////////////////////////////////////
\r
149 std::string PluginManager::getPluginName(const std::string& path){
\r
150 size_t lastDash = path.find_last_of("/\\");
\r
151 size_t lastDot = path.find_last_of('.');
\r
152 if (lastDash == std::string::npos) lastDash = 0;
\r
154 if (lastDot < lastDash || lastDot == std::string::npos){
\r
155 // path without extension
\r
156 lastDot = path.length();
\r
158 return path.substr(lastDash, lastDot-lastDash);
\r
162 ////////////////////////////////////////////////////////////
\r
163 std::string PluginManager::resolvePathExtension(const std::string& path){
\r
164 size_t lastDash = path.find_last_of("/\\");
\r
165 size_t lastDot = path.find_last_of('.');
\r
166 if (lastDash == std::string::npos) lastDash = 0;
\r
168 if (lastDot < lastDash || lastDot == std::string::npos){
\r
169 // path without extension, add it
\r
170 return path + "." + PLUMA_LIB_EXTENSION;
\r
176 ////////////////////////////////////////////////////////////
\r
177 void PluginManager::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion){
\r
178 host.registerType(type, version, lowestVersion);
\r
182 ////////////////////////////////////////////////////////////
\r
183 bool PluginManager::addProvider(Provider* provider){
\r
184 if (provider == NULL){
\r
185 // fprintf(stderr, "Trying to add null provider\n");
\r
186 throw std::runtime_error( "Trying to add null provider." );
\r
189 return host.registerProvider(provider);
\r
193 ////////////////////////////////////////////////////////////
\r
194 void PluginManager::getLoadedPlugins(std::vector<const std::string*>& pluginNames) const{
\r
195 pluginNames.reserve(pluginNames.size()+libraries.size());
\r
196 LibMap::const_iterator it;
\r
197 for(it = libraries.begin() ; it != libraries.end() ; ++it){
\r
198 pluginNames.push_back(&(it->first));
\r
203 ////////////////////////////////////////////////////////////
\r
204 bool PluginManager::isLoaded(const std::string& pluginName) const{
\r
205 return libraries.find(getPluginName(pluginName)) != libraries.end();
\r
209 ////////////////////////////////////////////////////////////
\r
210 const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const{
\r
211 return host.getProviders(type);
\r
216 } // namespace pluma
\r