From: Vitaliy Cherepanov/AI Tools Lab/Engineer/삼성전자 Date: Mon, 4 Jun 2018 09:50:08 +0000 (+0300) Subject: nnc: Implement PluginManager class (#273) X-Git-Tag: nncc_backup~2628 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cd21e41aba7948303fb928a355e94fe9639df75f;p=platform%2Fcore%2Fml%2Fnnfw.git nnc: Implement PluginManager class (#273) nnc: Implement PluginsManager class This class will search, load, initialize plugins and delegate plugins to modules by plugin type Signed-off-by: Vitaliy Cherepanov --- diff --git a/contrib/nnc/include/module/plugin/PluginManager.h b/contrib/nnc/include/module/plugin/PluginManager.h new file mode 100644 index 0000000..9b2eeb4 --- /dev/null +++ b/contrib/nnc/include/module/plugin/PluginManager.h @@ -0,0 +1,63 @@ +#ifndef __PLUGIN_MANAGER_H__ +#define __PLUGIN_MANAGER_H__ + +#include + +#include "PluginData.h" +#include "PluginProxy.h" +#include "module/AbstractModule.h" + +namespace nncc +{ +namespace contrib +{ +namespace module +{ +namespace plugin +{ + +class PluginManagerException : public foundation::Exception +{ +public: + PluginManagerException() = delete; + explicit PluginManagerException(const std::string &info); + PluginManagerException(Exception &e, const std::string &info); +}; + +class PluginManager +{ +public: + static const std::string paramPluginPath; + static const std::string paramVerboseLoading; + static const std::string paramPluginHelp; + + PluginManager(); + + void setConfig(std::shared_ptr conf); + void loadPlugins(std::vector &modules); + static PluginManager &getInstance(); + void help() const; + + friend std::ostream &operator<<(std::ostream &st, const PluginManager &mod); + +private: + std::vector getPluginPathList(); + + void applyParam(const std::string &name); + void applyParam(const std::string &name, const std::string &value); + + std::vector _modules; + + std::vector> _plugins; + std::shared_ptr _config; + std::string _pluginsPath; + std::vector _supportedParams; + bool _showPluginInfo; +}; + +} // namespace plugin +} // namespace module +} // namespace contrib +} // namespace nncc + +#endif // __PLUGIN_MANAGER_H__ diff --git a/contrib/nnc/src/module/plugin/PluginManager.cpp b/contrib/nnc/src/module/plugin/PluginManager.cpp new file mode 100644 index 0000000..2729cc3 --- /dev/null +++ b/contrib/nnc/src/module/plugin/PluginManager.cpp @@ -0,0 +1,197 @@ +#include +#include +#include +#include + +#include "module/plugin/PluginProxy.h" +#include "module/plugin/PluginSession.h" +#include "module/plugin/PluginManager.h" + +#include "PluginException.h" +#include "ConfigException.h" + +namespace nncc +{ +namespace contrib +{ +namespace module +{ +namespace plugin +{ + +const std::string PluginManager::paramPluginPath = "plugins-path"; +const std::string PluginManager::paramVerboseLoading = "plugins-verbose"; +const std::string PluginManager::paramPluginHelp = "plugins-help"; + +std::vector PluginManager::getPluginPathList() { + std::vector pluginPathList; + std::vector dirList; + + // Push first path + dirList.clear(); + dirList.push_back(_pluginsPath); + + while (!dirList.empty()) { + const auto curPluginsPath = dirList.back(); + dirList.pop_back(); + + DIR *dir; + struct dirent *ent; + if ((dir = opendir(curPluginsPath.c_str())) != nullptr) { + while ((ent = readdir(dir)) != nullptr) { + if ((ent->d_type == DT_DIR) && (std::string(ent->d_name) != ".") && + (std::string(ent->d_name) != "..")) { + std::string f = curPluginsPath + std::string("/") + std::string(ent->d_name); + dirList.push_back(f); + } else if (strstr(ent->d_name, ".so") != nullptr) { + std::string f = curPluginsPath + std::string("/") + std::string(ent->d_name); + pluginPathList.push_back(f); + } + } + closedir(dir); + } else { + // could not open directory + // TODO add some log + } + } + return pluginPathList; +} + +void PluginManager::loadPlugins(std::vector &modules) { + std::cout << "Current plugin path is <" << _pluginsPath << ">" << std::endl; + auto plugins = getPluginPathList(); + + for (const auto &pluginPath : plugins) { + try { + auto pl = PluginProxy::create(pluginPath); + auto plInst = pl->getPluginInstance(); + std::shared_ptr session = std::make_shared(); + plInst->setSession(session); + plInst->fillSession(); + + if (_showPluginInfo) + std::cout << "plugin <" + pluginPath + ">: {" << std::endl + << "name <" + pl->getPluginName() + "> " << std::endl + << dynamic_cast(*session) << std::endl + << "}" << std::endl; + + _plugins.push_back(pl); + } + catch (PluginException &e) { + if (_showPluginInfo) + std::cout << "plugin <" + pluginPath << ">: {" << std::endl + << "bad plugin :" << e.what() << std::endl + << "}" << std::endl; + } + catch (config::DataException &eOp) { + std::cout << "bad plugin info <" + pluginPath << ">:" << eOp.what() << std::endl; + } + } + + if (_plugins.empty()) + throw PluginManagerException("No plugins found"); + + // Fill modules by plugins + for (auto &pl : _plugins) { + for (auto m : modules) { + auto session = + dynamic_cast(pl->getPluginInstance()->getSession().get()); + if (m->getModuleType() == session->getPluginType()) { + m->registerPlugin(pl); + break; + } + } + } + + for (auto m : modules) { + std::cout << *m; + } +} + +std::ostream &operator<<(std::ostream &st, const PluginManager &mod) { + for (const auto &pl : mod._plugins) + st << pl << std::endl; + return st; +} + +PluginManager &PluginManager::getInstance() { + static PluginManager instance; + return instance; +} + +void PluginManager::setConfig(std::shared_ptr conf) { + try { + _config = conf; + auto plist = config::DataList::intersection(*conf, _supportedParams); + + for (auto &p : plist->getElements()) { + if (p.second.hasValue()) + applyParam(p.second.getName(), p.second.getValue()); + else + applyParam(p.second.getName()); + } + } + catch (ConfigException &e) { + throw PluginManagerException(e, "config error"); + } + catch (PluginException &e) { + throw PluginManagerException(e, "plugin error"); + } +} + +void PluginManager::applyParam(const std::string &name) { + if (name == paramPluginHelp) { + help(); + } else if (name == paramVerboseLoading) { + _showPluginInfo = true; + } else { + std::string info = + "[ERR]" + std::string(__func__) + " <" + name + ">" + " WRONG SINGLE PARAMETER"; + throw ConfigException(info); + } +} + +void PluginManager::applyParam(const std::string &name, const std::string &value) { + std::cout << __func__ << " <" + name + "> = " + value << std::endl; + if (name == paramPluginPath) { + _pluginsPath = value; + } else { + help(); + std::string info = + "[ERR]" + std::string(__func__) + " <" + name + "> = " + value + " WRONG PARAMETER"; + throw ConfigException(info); + } +} + +void PluginManager::help() const { + std::cout << "HELP" << std::endl; + + for (auto &p : _supportedParams) + if (!p.isOptional()) + std::cout << "--" << p.getName() << " "; + + for (auto &p : _supportedParams) + if (p.isOptional()) + std::cout << "[--" << p.getName() << "] "; + std::cout << std::endl; + + for (auto &p : _supportedParams) + std::cout << p << std::endl; +} + +PluginManager::PluginManager() : _config(nullptr), _showPluginInfo(false) { + _supportedParams = {{paramPluginPath, "[path]", true}, + {paramVerboseLoading, "[show found plugins info]", true}, + {paramPluginHelp, "[help]", true}}; +} + +PluginManagerException::PluginManagerException(const std::string &info) : Exception(info) {} + +PluginManagerException::PluginManagerException(Exception &e, const std::string &info) + : Exception(e, info) { +} + +} // namespace plugin +} // namespace module +} // namespace contrib +} // namespace nncc