]> Creatis software - cpPlugins.git/blob - lib/third_party/Pluma/PluginManager.cpp
...
[cpPlugins.git] / lib / third_party / Pluma / PluginManager.cpp
1 ////////////////////////////////////////////////////////////\r
2 //\r
3 // Pluma - Plug-in Management Framework\r
4 // Copyright (C) 2010-2012 Gil Costa (gsaurus@gmail.com)\r
5 //\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
8 //\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
12 //\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
17 //\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
20 //\r
21 // 3. This notice may not be removed or altered from any source distribution.\r
22 //\r
23 ////////////////////////////////////////////////////////////\r
24 \r
25 ////////////////////////////////////////////////////////////\r
26 // Headers\r
27 ////////////////////////////////////////////////////////////\r
28 #include <Pluma/PluginManager.hpp>\r
29 #include <Pluma/DLibrary.hpp>\r
30 #include <Pluma/Dir.hpp>\r
31 #include <cstdio>\r
32 #include <stdexcept>\r
33 \r
34 namespace pluma{\r
35 \r
36 ////////////////////////////////////////////////////////////\r
37 PluginManager::PluginManager(){\r
38     // Nothing to do\r
39 }\r
40 \r
41 \r
42 ////////////////////////////////////////////////////////////\r
43 PluginManager::~PluginManager(){\r
44     unloadAll();\r
45 }\r
46 \r
47 \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
54 \r
55     fnRegisterPlugin* registerFunction;\r
56     registerFunction = reinterpret_cast<fnRegisterPlugin*>(lib->getSymbol("connect"));\r
57 \r
58     if(!registerFunction){\r
59       //fprintf(stderr, "Failed to initialize plugin \"%s\": connect function not found\n", plugName.c_str());\r
60         delete lib;\r
61         throw std::runtime_error(\r
62           std::string( "Failed to initialize plugin \"" ) +\r
63           plugName +\r
64           std::string( "\": connect function not found" )\r
65           );\r
66         return false;\r
67     }\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
73         delete lib;\r
74         throw std::runtime_error(\r
75           std::string( "Self registry failed on plugin \"" ) +\r
76           plugName +\r
77           std::string( "\"" )\r
78           );\r
79         return false;\r
80     }\r
81     // Store the library if addictions are confirmed\r
82     if (host.confirmAddictions())\r
83         libraries[plugName] = lib;\r
84     else{\r
85         // otherwise nothing was registered\r
86       // fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());\r
87         delete lib;\r
88         throw std::runtime_error(\r
89           std::string( "Nothing registered by plugin \"" ) +\r
90           plugName +\r
91           std::string( "\"." )\r
92           );\r
93         return false;\r
94     }\r
95     return true;\r
96 }\r
97 \r
98 \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
106 }\r
107 \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
115       // *** LFV ***\r
116       try\r
117       {\r
118         if ( load(*it) ) loaded_files.push_back( *it );\r
119       }\r
120       catch( ... )\r
121       {\r
122       } // yrt\r
123       // *** LFV ***\r
124     }\r
125     return loaded_files;\r
126 }\r
127 \r
128 \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
134         delete it->second;\r
135         libraries.erase(it);\r
136         return true;\r
137     }\r
138     return false;\r
139 }\r
140 \r
141 ////////////////////////////////////////////////////////////\r
142 void PluginManager::unloadAll(){\r
143 \r
144     host.clearProviders();\r
145     LibMap::iterator it;\r
146     for (it = libraries.begin() ; it != libraries.end() ; ++it){\r
147         delete it->second;\r
148     }\r
149     libraries.clear();\r
150 }\r
151 \r
152 \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
158     else ++lastDash;\r
159     if (lastDot < lastDash || lastDot == std::string::npos){\r
160         // path without extension\r
161         lastDot = path.length();\r
162     }\r
163     return path.substr(lastDash, lastDot-lastDash);\r
164 }\r
165 \r
166 \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
172     else ++lastDash;\r
173     if (lastDot < lastDash || lastDot == std::string::npos){\r
174         // path without extension, add it\r
175         return path + "." + PLUMA_LIB_EXTENSION;\r
176     }\r
177     return path;\r
178 }\r
179 \r
180 \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
184 }\r
185 \r
186 \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
192         return false;\r
193     }\r
194     return host.registerProvider(provider);\r
195 }\r
196 \r
197 \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
204     }\r
205 }\r
206 \r
207 \r
208 ////////////////////////////////////////////////////////////\r
209 bool PluginManager::isLoaded(const std::string& pluginName) const{\r
210     return libraries.find(getPluginName(pluginName)) != libraries.end();\r
211 }\r
212 \r
213 \r
214 ////////////////////////////////////////////////////////////\r
215 const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const{\r
216     return host.getProviders(type);\r
217 }\r
218 \r
219 \r
220 \r
221 }   // namespace pluma\r
222 \r