#include "plugins_manager.h" #include "rational_function.h" #include "vertical_segment.h" /* #include #include */ #ifdef WIN32 #include #else #include #endif #include //! \brief Open a dynamic library file (.so or .dll) and extract the associated //! provide function. The template argument is used to cast the library to a //! specific type. template T open_library(const std::string& filename, const char* function) { #ifdef WIN32 HINSTANCE handle = LoadLibrary((LPCTSTR)filename.c_str()); if(handle != NULL) { T res = (T)GetProcAddress(handle, function); if(res == NULL) { std::cerr << "<> unable to load the symbol \"" << function << "\" from " << filename << std::endl; return NULL; } #ifdef DEBUG_CORE std::cout << "<> will provide a " << function << " for library \"" << filename << "\"" << std::endl; #endif return res; } else { std::cerr << "<> unable to load the dynamic library file \"" << filename << "\"" << std::endl; std::cerr << " cause: \"" << GetLastError() << "\"" << std::endl; return NULL; } #else void* handle = dlopen(filename.c_str(), RTLD_LAZY); if(handle != NULL) { void* res = dlsym(handle, function); if(dlerror() != NULL) { std::cerr << "<> unable to load the symbol \"" << function << "\" from " << filename << std::endl; return NULL; } #ifdef DEBUG_CORE std::cout << "<> will provide a " << function << " for library \"" << filename << "\"" << std::endl; #endif return (T)res; } else { std::cerr << "<> unable to load the dynamic library file \"" << filename << "\"" << std::endl; std::cerr << " cause: \"" << dlerror() << "\"" << std::endl; return NULL; } #endif } // Create the object, parse the argument and load all the plugins plugins_manager::plugins_manager(const arguments& args) { /* QDir pluginsDir; if(args.is_defined("plugins")) { pluginsDir = QDir(args["plugins"].c_str()) ; } else if(QCoreApplication::instance() != NULL) { pluginsDir = QDir(QCoreApplication::instance()->applicationDirPath()); } */ /* foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { QPluginLoader loader ; loader.setLoadHints(QLibrary::ExportExternalSymbolsHint) ; loader.setFileName(pluginsDir.absoluteFilePath(fileName)); // Convert filename for outputing std::string filename(fileName.toStdString()) ; if(!loader.load()) { #ifdef DEBUG std::cout << "<> " << loader.errorString().toStdString() << std::endl ; #endif continue ; } QObject *plugin = loader.instance(); if (plugin != NULL) { #ifdef DEBUG std::cout << "<> loading plugin " << filename << std::endl ; #endif if(dynamic_cast(plugin) != NULL) { #ifdef DEBUG std::cout << "<> -> it is a function" << std::endl ; #endif _functions.insert(std::pair(filename, dynamic_cast(plugin))) ; } if(dynamic_cast(plugin) != NULL) { #ifdef DEBUG std::cout << "<> -> it is a data loader" << std::endl ; #endif _datas.insert(std::pair(filename, dynamic_cast(plugin))) ; } if(dynamic_cast(plugin) != NULL) { #ifdef DEBUG std::cout << "<> -> it is a fitter" << std::endl ; #endif _fitters.insert(std::pair(filename, dynamic_cast(plugin))) ; } } else { #ifdef DEBUG std::cout << "<> " << loader.errorString().toStdString() << std::endl ; #endif } } */ } // Get instances of the function, the data and the // fitter // function* plugins_manager::get_function() { #ifdef USING_STATIC return new rational_function() ; #else if(_functions.empty()) { return new rational_function() ; } else { return _functions.begin()->second ; } #endif } data* plugins_manager::get_data() { //if(_datas.empty()) { #ifdef DEBUG std::cout << "<> using vertical segment data loader" << std::endl ; #endif return new vertical_segment() ; }/* else { #ifdef DEBUG std::cout << "<> using \"" << _datas.begin()->first << "\" data loader" << std::endl ; #endif return _datas.begin()->second ; }*/ } fitter* plugins_manager::get_fitter() { #ifdef USING_STATIC return NULL; #else if(_fitters.empty()) { return NULL ; } else { #ifdef DEBUG std::cout << "<> using \"" << _fitters.begin()->first << "\"" << std::endl ; #endif return _fitters.begin()->second ; } #endif } //! Get an instance of the function selected based on the name n. //! Return NULL if no one exist. function* plugins_manager::get_function(const arguments& args) { if(!args.is_defined("func")) { #ifdef DEBUG std::cout << "<> no function plugin specified, returning a rational function" << std::endl; #endif return new rational_function(); } if(args.is_vec("func")) { std::vector args_vec = args.get_vec("func"); // Treating the case [] if(args_vec.size() == 0) { return NULL; } //! \todo create a compound class to store multiple //! functions in it. //! For each args_vec element, create a function object and add //! it to the compound one. std::string n = args_vec[0]; std::vector cmd_vec; cmd_vec.push_back("--func"); std::stringstream stream(n); while(stream.good()) { std::string temp; stream >> temp; cmd_vec.push_back(temp); } int argc = cmd_vec.size(); char* argv[argc]; for(int i=0; i(filename, "provide_function"); if(myFunction != NULL) { #ifdef DEBUG std::cout << "<> using function provider in file \"" << filename << "\"" << std::endl; #endif return myFunction(); } else { std::cerr << "<> no function provider found in file \"" << filename << "\"" << std::endl; return new rational_function() ; } } } data* plugins_manager::get_data(const std::string& n) { if(n.empty()) { #ifdef DEBUG std::cout << "<> no data plugin specified, returning a vertial_segment loader" << std::endl; #endif return new vertical_segment(); } DataPrototype myData = open_library(n, "provide_data"); if(myData != NULL) { #ifdef DEBUG std::cout << "<> using function provider in file \"" << n << "\"" << std::endl; #endif return myData(); } else { std::cerr << "<> no data provider found in file \"" << n << "\"" << std::endl; return new vertical_segment() ; } } fitter* plugins_manager::get_fitter(const std::string& n) { if(n.empty()) { #ifdef DEBUG std::cout << "<> no fitter plugin specified, returning null" << std::endl; #endif return NULL; } FitterPrototype myFitter = open_library(n, "provide_fitter"); if(myFitter != NULL) { #ifdef DEBUG std::cout << "<> using function provider in file \"" << n << "\"" << std::endl; #endif return myFitter(); } else { std::cerr << "<> no fitter provider found in file \"" << n << "\"" << std::endl; return NULL ; } } void plugins_manager::check_compatibility(data*& d, function*& f, const arguments& args) { if(d->parametrization() == params::UNKNOWN_INPUT) { std::cout << "<> unknown parametrization for data" << std::endl; } if(f->parametrization() == params::UNKNOWN_INPUT) { std::cout << "<> function will take the parametrization of the data" << std::endl; f->setParametrization(d->parametrization()); } else if(d->parametrization() != f->parametrization()) { std::cout << "<> has to change the parametrization of the input data" << std::endl; data_params* dd = new data_params(d, f->parametrization()); d = dd ; } else { std::cout << "<> no change was made to the parametrization" << std::endl; } if(f->dimY() != d->dimY()) { std::cout << "<> the data and the function have different Y dimensions" << std::endl; } /* // Check is the data has to be clusterized if(args.is_defined("cluster-dim")) { clustering* cluster = new clustering(d, args); d = cluster; } */ } // \todo implement the Darwin (MACOS) version. #ifdef WIN32 #include size_t plugins_manager::get_system_memory() { MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx(&status); return status.ullTotalPhys; } #else #include size_t plugins_manager::get_system_memory() { long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); return pages * page_size; } #endif