]> Creatis software - cpPlugins.git/blob - lib/third_party/Pluma/PluginManager.cpp
Parameters are now part of the pipeline update process
[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 ////////////////////////////////////////////////////////////\r
27 // Headers\r
28 ////////////////////////////////////////////////////////////\r
29 #include <Pluma/PluginManager.hpp>\r
30 #include <Pluma/DLibrary.hpp>\r
31 #include <Pluma/Dir.hpp>\r
32 #include <cstdio>\r
33 #include <stdexcept>\r
34 \r
35 namespace pluma{\r
36 \r
37 ////////////////////////////////////////////////////////////\r
38 PluginManager::PluginManager(){\r
39     // Nothing to do\r
40 }\r
41 \r
42 \r
43 ////////////////////////////////////////////////////////////\r
44 PluginManager::~PluginManager(){\r
45     unloadAll();\r
46 }\r
47 \r
48 \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
55 \r
56     fnRegisterPlugin* registerFunction;\r
57     registerFunction = reinterpret_cast<fnRegisterPlugin*>(lib->getSymbol("connect"));\r
58 \r
59     if(!registerFunction){\r
60       //fprintf(stderr, "Failed to initialize plugin \"%s\": connect function not found\n", plugName.c_str());\r
61         delete lib;\r
62         throw std::runtime_error(\r
63           std::string( "Failed to initialize plugin \"" ) +\r
64           plugName +\r
65           std::string( "\": connect function not found" )\r
66           );\r
67         return false;\r
68     }\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
74         delete lib;\r
75         throw std::runtime_error(\r
76           std::string( "Self registry failed on plugin \"" ) +\r
77           plugName +\r
78           std::string( "\"" )\r
79           );\r
80         return false;\r
81     }\r
82     // Store the library if addictions are confirmed\r
83     if (host.confirmAddictions())\r
84         libraries[plugName] = lib;\r
85     else{\r
86         // otherwise nothing was registered\r
87       // fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());\r
88         delete lib;\r
89         throw std::runtime_error(\r
90           std::string( "Nothing registered by plugin \"" ) +\r
91           plugName +\r
92           std::string( "\"." )\r
93           );\r
94         return false;\r
95     }\r
96     return true;\r
97 }\r
98 \r
99 \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
107 }\r
108 \r
109 \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
115     int res = 0;\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
119     }\r
120     return res;\r
121 }\r
122 \r
123 \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
129         delete it->second;\r
130         libraries.erase(it);\r
131         return true;\r
132     }\r
133     return false;\r
134 }\r
135 \r
136 ////////////////////////////////////////////////////////////\r
137 void PluginManager::unloadAll(){\r
138 \r
139     host.clearProviders();\r
140     LibMap::iterator it;\r
141     for (it = libraries.begin() ; it != libraries.end() ; ++it){\r
142         delete it->second;\r
143     }\r
144     libraries.clear();\r
145 }\r
146 \r
147 \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
153     else ++lastDash;\r
154     if (lastDot < lastDash || lastDot == std::string::npos){\r
155         // path without extension\r
156         lastDot = path.length();\r
157     }\r
158     return path.substr(lastDash, lastDot-lastDash);\r
159 }\r
160 \r
161 \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
167     else ++lastDash;\r
168     if (lastDot < lastDash || lastDot == std::string::npos){\r
169         // path without extension, add it\r
170         return path + "." + PLUMA_LIB_EXTENSION;\r
171     }\r
172     return path;\r
173 }\r
174 \r
175 \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
179 }\r
180 \r
181 \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
187         return false;\r
188     }\r
189     return host.registerProvider(provider);\r
190 }\r
191 \r
192 \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
199     }\r
200 }\r
201 \r
202 \r
203 ////////////////////////////////////////////////////////////\r
204 bool PluginManager::isLoaded(const std::string& pluginName) const{\r
205     return libraries.find(getPluginName(pluginName)) != libraries.end();\r
206 }\r
207 \r
208 \r
209 ////////////////////////////////////////////////////////////\r
210 const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const{\r
211     return host.getProviders(type);\r
212 }\r
213 \r
214 \r
215 \r
216 }   // namespace pluma\r
217 \r