]> Creatis software - cpPlugins.git/blob - lib/third_party/Pluma/PluginManager.cpp
1124505c3bb5c11afd453b4e68e1db0291ed294a
[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 \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         return false;\r
62     }\r
63     // try to initialize plugin:\r
64     if (!registerFunction(host)){\r
65         // plugin decided to fail\r
66         fprintf(stderr, "Self registry failed on plugin \"%s\".\n", plugName.c_str());\r
67         host.cancelAddictions();\r
68         delete lib;\r
69         return false;\r
70     }\r
71     // Store the library if addictions are confirmed\r
72     if (host.confirmAddictions())\r
73         libraries[plugName] = lib;\r
74     else{\r
75         // otherwise nothing was registered\r
76         fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());\r
77         delete lib;\r
78         return false;\r
79     }\r
80     return true;\r
81 }\r
82 \r
83 \r
84 ////////////////////////////////////////////////////////////\r
85 bool PluginManager::load(const std::string& folder, const std::string& pluginName){\r
86     if (folder.empty())\r
87         return load(pluginName);\r
88     else if (folder[folder.size()-1] == '/' || folder[folder.size()-1] == '\\')\r
89         return load(folder + pluginName);\r
90     return load(folder + '/' + pluginName);\r
91 }\r
92 \r
93 \r
94 ////////////////////////////////////////////////////////////\r
95 int PluginManager::loadFromFolder(const std::string& folder, bool recursive){\r
96     std::list<std::string> files;\r
97     dir::listFiles(files, folder, PLUMA_LIB_EXTENSION, recursive);\r
98     // try to load every library\r
99     int res = 0;\r
100     std::list<std::string>::const_iterator it;\r
101     for (it = files.begin() ; it != files.end() ; ++it){\r
102         if ( load(*it) ) ++res;\r
103     }\r
104     return res;\r
105 }\r
106 \r
107 \r
108 ////////////////////////////////////////////////////////////\r
109 bool PluginManager::unload(const std::string& pluginName){\r
110     std::string plugName = getPluginName(pluginName);\r
111     LibMap::iterator it = libraries.find(plugName);\r
112     if( it != libraries.end() ) {\r
113         delete it->second;\r
114         libraries.erase(it);\r
115         return true;\r
116     }\r
117     return false;\r
118 }\r
119 \r
120 \r
121 ////////////////////////////////////////////////////////////\r
122 void PluginManager::unloadAll(){\r
123 \r
124     host.clearProviders();\r
125     LibMap::iterator it;\r
126     for (it = libraries.begin() ; it != libraries.end() ; ++it){\r
127         delete it->second;\r
128     }\r
129     libraries.clear();\r
130 }\r
131 \r
132 \r
133 ////////////////////////////////////////////////////////////\r
134 std::string PluginManager::getPluginName(const std::string& path){\r
135     size_t lastDash = path.find_last_of("/\\");\r
136     size_t lastDot = path.find_last_of('.');\r
137     if (lastDash == std::string::npos) lastDash = 0;\r
138     else ++lastDash;\r
139     if (lastDot < lastDash || lastDot == std::string::npos){\r
140         // path without extension\r
141         lastDot = path.length();\r
142     }\r
143     return path.substr(lastDash, lastDot-lastDash);\r
144 }\r
145 \r
146 \r
147 ////////////////////////////////////////////////////////////\r
148 std::string PluginManager::resolvePathExtension(const std::string& path){\r
149     size_t lastDash = path.find_last_of("/\\");\r
150     size_t lastDot = path.find_last_of('.');\r
151     if (lastDash == std::string::npos) lastDash = 0;\r
152     else ++lastDash;\r
153     if (lastDot < lastDash || lastDot == std::string::npos){\r
154         // path without extension, add it\r
155         return path + "." + PLUMA_LIB_EXTENSION;\r
156     }\r
157     return path;\r
158 }\r
159 \r
160 \r
161 ////////////////////////////////////////////////////////////\r
162 void PluginManager::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion){\r
163     host.registerType(type, version, lowestVersion);\r
164 }\r
165 \r
166 \r
167 ////////////////////////////////////////////////////////////\r
168 bool PluginManager::addProvider(Provider* provider){\r
169     if (provider == NULL){\r
170         fprintf(stderr, "Trying to add null provider\n");\r
171         return false;\r
172     }\r
173     return host.registerProvider(provider);\r
174 }\r
175 \r
176 \r
177 ////////////////////////////////////////////////////////////\r
178 void PluginManager::getLoadedPlugins(std::vector<const std::string*>& pluginNames) const{\r
179     pluginNames.reserve(pluginNames.size()+libraries.size());\r
180     LibMap::const_iterator it;\r
181     for(it = libraries.begin() ; it != libraries.end() ; ++it){\r
182         pluginNames.push_back(&(it->first));\r
183     }\r
184 }\r
185 \r
186 \r
187 ////////////////////////////////////////////////////////////\r
188 bool PluginManager::isLoaded(const std::string& pluginName) const{\r
189     return libraries.find(getPluginName(pluginName)) != libraries.end();\r
190 }\r
191 \r
192 \r
193 ////////////////////////////////////////////////////////////\r
194 const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const{\r
195     return host.getProviders(type);\r
196 }\r
197 \r
198 \r
199 \r
200 }   // namespace pluma\r
201 \r