plugins_manager.cpp 7.79 KB
Newer Older
1
#include "plugins_manager.h"
2 3
#include "rational_function.h"
#include "vertical_segment.h"
4

5
/*
6
#include <QCoreApplication>
7
#include <QDir>
8
*/
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

#ifdef WIN32
#else
    #include <stdio.h>
    #include <dlfcn.h>
#endif

//! \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<typename T> T open_library(const std::string& filename, const char* function)
{
#ifdef WIN32
    return NULL;
#else
    void* handle = dlopen(filename.c_str(), RTLD_LAZY);
    if(handle != NULL)
    {
        void* res = dlsym(handle, function);

        if(dlerror() != NULL)
        {
            std::cerr << "<<ERROR>> unable to load the symbol \"" << function << "\" from " << filename << std::endl;
            return NULL;
        }
#ifdef DEBUG_CORE
        std::cout << "<<DEBUG>> will provide a " << function << " for library \"" << filename << "\"" << std::endl;
#endif
        return (T)res;
    }
    else
    {
        std::cerr << "<<ERROR>> unable to load the dynamic library file \"" << filename << "\"" << std::endl;
42
		  std::cerr << "          cause: \"" << dlerror() << "\"" << std::endl;
43 44 45 46 47 48 49
        return NULL;
    }
#endif
}


// Create the object, parse the argument and load all the plugins
50 51
plugins_manager::plugins_manager(const arguments& args) 
{
52
/*
53 54 55 56 57 58 59 60 61
	QDir pluginsDir;
	if(args.is_defined("plugins"))
	{
		pluginsDir = QDir(args["plugins"].c_str()) ;
	}
	else if(QCoreApplication::instance() != NULL)
	{
		pluginsDir = QDir(QCoreApplication::instance()->applicationDirPath());
	}
62
	*/
63

64
	/*
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	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 << "<<DEBUG>> " << loader.errorString().toStdString() << std::endl ;
#endif
			continue ;
		}

		QObject *plugin = loader.instance();
		if (plugin != NULL) 
		{
#ifdef DEBUG
			std::cout << "<<DEBUG>> loading plugin " << filename << std::endl ;
#endif
			if(dynamic_cast<function*>(plugin) != NULL)
			{
#ifdef DEBUG
				std::cout << "<<DEBUG>>  -> it is a function" << std::endl ;
#endif
				_functions.insert(std::pair<std::string, function*>(filename, dynamic_cast<function*>(plugin))) ;
			}
			
			if(dynamic_cast<data*>(plugin) != NULL)
			{
#ifdef DEBUG
				std::cout << "<<DEBUG>>  -> it is a data loader" << std::endl ;
#endif
				_datas.insert(std::pair<std::string, data*>(filename, dynamic_cast<data*>(plugin))) ;
			}
			if(dynamic_cast<fitter*>(plugin) != NULL)
			{
#ifdef DEBUG
				std::cout << "<<DEBUG>>  -> it is a fitter" << std::endl ;
#endif
				_fitters.insert(std::pair<std::string, fitter*>(filename, dynamic_cast<fitter*>(plugin))) ;
			}
		}
		else
		{
#ifdef DEBUG
			std::cout << "<<DEBUG>> " << loader.errorString().toStdString() << std::endl ;
#endif
		}
	}
118
	*/
119 120 121 122 123
}

// Get instances of the function, the data and the
// fitter
//
124
function* plugins_manager::get_function()
125
{
126 127 128 129
#ifdef USING_STATIC
    return new rational_function() ;
#else
    if(_functions.empty())
130
	{
131
		return new rational_function() ;
132 133 134 135 136
	}
	else
	{
		return _functions.begin()->second ;
	}
137 138
#endif

139
}
140
data* plugins_manager::get_data()
141
{
Laurent Belcour's avatar
Laurent Belcour committed
142
	//if(_datas.empty())
143
	{
144 145 146
#ifdef DEBUG
        std::cout << "<<DEBUG>>  using vertical segment data loader" << std::endl ;
#endif
147
		return new vertical_segment() ;
Laurent Belcour's avatar
Laurent Belcour committed
148
	}/*
149 150
	else
	{
151
#ifdef DEBUG
152
		std::cout << "<<DEBUG>>  using \"" << _datas.begin()->first << "\" data loader" << std::endl ;
153
#endif
154
		return _datas.begin()->second ;
Laurent Belcour's avatar
Laurent Belcour committed
155
	}*/
156
}
157
fitter* plugins_manager::get_fitter()
158
{
159 160 161
#ifdef USING_STATIC
    return NULL;
#else
162 163 164 165 166 167
	if(_fitters.empty())
	{
		return NULL ;
	}
	else
	{
168
#ifdef DEBUG
169
		std::cout << "<<DEBUG>>  using \"" <<  _fitters.begin()->first << "\"" << std::endl ;
170
#endif
171 172
		return _fitters.begin()->second ;
	}
173
#endif
174 175 176 177 178 179
}

// Get instances of the function, the data and the
// fitter, select one based on the name. Return null
// if no one exist.
//
180
function* plugins_manager::get_function(const std::string& n)
181
{
182 183 184 185 186 187 188 189
    if(n.empty())
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> no function plugin specified, returning a rational function" << std::endl;
#endif
        return new rational_function();
    }

190
#ifdef USING_STATIC
191
	 /*
Laurent Belcour's avatar
Laurent Belcour committed
192 193 194 195 196 197 198 199 200 201 202
	 std::string file;
	 if(n[0] == '.')
	 {
		 file = n.substr(1, n.size()-1);
	 }
	 else
	 {
		 file = n;
	 }

    QString path = QDir::currentPath() + QString(file.c_str()) ;
203 204
	 
	 FunctionPrototype myFunction = open_library<FunctionPrototype>(path.toStdString(), "provide_function");
205 206
	 */
	 FunctionPrototype myFunction = open_library<FunctionPrototype>(n, "provide_function");
207 208 209 210 211 212 213 214 215 216 217 218 219 220
    if(myFunction != NULL)
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> using function provider in file \"" << n << "\"" << std::endl;
#endif
        return myFunction();
    }
    else
    {
        std::cerr << "<<ERROR>> no function provider found in file \"" << n << "\"" << std::endl;
        return new rational_function() ;
    }
#else

221
	if(_functions.count(n) == 0)
222
	{
223
		return new rational_function() ;
224 225 226
	}
	else
	{
Laurent Belcour's avatar
Laurent Belcour committed
227
		return _functions.find(n)->second ;
228
	}
229
#endif
230
}
231
data* plugins_manager::get_data(const std::string& n)
232
{
233 234
    if(n.empty())
    {
235
#ifdef DEBUG
236
        std::cout << "<<DEBUG>> no data plugin specified, returning a vertial_segment loader" << std::endl;
237
#endif
238 239 240 241
        return new vertical_segment();
    }

#ifdef USING_STATIC
242
	 /*
Laurent Belcour's avatar
Laurent Belcour committed
243 244 245 246 247 248 249 250 251 252 253
	 std::string file;
	 if(n[0] == '.')
	 {
		 file = n.substr(1, n.size()-1);
	 }
	 else
	 {
		 file = n;
	 }

    QString path = QDir::currentPath() + QString(file.c_str()) ;
254 255
	 
	 DataPrototype myData = open_library<DataPrototype>(path.toStdString(), "provide_data");
256 257
	 */
	 DataPrototype myData = open_library<DataPrototype>(n, "provide_data");
258 259
    if(myData != NULL)
    {
260
#ifdef DEBUG
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
        std::cout << "<<DEBUG>> using function provider in file \"" << n << "\"" << std::endl;
#endif
        return myData();
    }
    else
    {
        std::cerr << "<<ERROR>> no data provider found in file \"" << n << "\"" << std::endl;
        return new vertical_segment() ;
    }
#else

    if(_functions.count(n) == 0)
    {
        return new vertical_segment() ;
    }
    else
    {
        return _datas.find(n)->second ;
    }
280
#endif
281
}
282
fitter* plugins_manager::get_fitter(const std::string& n)
283
{
Laurent Belcour's avatar
Laurent Belcour committed
284 285 286 287 288 289 290 291
    if(n.empty())
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> no fitter plugin specified, returning null" << std::endl;
#endif
        return NULL;
    }

292
#ifdef USING_STATIC
293
/*
Laurent Belcour's avatar
Laurent Belcour committed
294 295 296 297 298 299 300 301 302 303 304
	 std::string file;
	 if(n[0] == '.')
	 {
		 file = n.substr(1, n.size()-1);
	 }
	 else
	 {
		 file = n;
	 }

    QString path = QDir::currentPath() + QString(file.c_str()) ;
305 306
    
	 FitterPrototype myFitter = open_library<FitterPrototype>(path.toStdString(), "provide_fitter");
307 308
*/
	 FitterPrototype myFitter = open_library<FitterPrototype>(n, "provide_fitter");
Laurent Belcour's avatar
Laurent Belcour committed
309 310 311 312 313 314 315 316 317
    if(myFitter != NULL)
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> using function provider in file \"" << n << "\"" << std::endl;
#endif
        return myFitter();
    }
    else
    {
318 319
        std::cerr << "<<ERROR>> no fitter provider found in file \"" << n << "\"" << std::endl;
        return NULL ;
Laurent Belcour's avatar
Laurent Belcour committed
320 321
    }
#else
322
	if(_fitters.count(n) == 0)
323 324 325 326 327
	{
		return NULL ;
	}
	else
	{
328
#ifdef DEBUG
329
		std::cout << "<<DEBUG>>  using \"" <<  n << "\"" << std::endl ;
330
#endif
Laurent Belcour's avatar
Laurent Belcour committed
331
		return _fitters.find(n)->second ;
332
	}
Laurent Belcour's avatar
Laurent Belcour committed
333
#endif
334
}
335 336 337 338
		
// \todo implement the Darwin (MACOS) version.
#ifdef WIN32
#include <windows.h>
339
size_t plugins_manager::get_system_memory()
340 341 342 343 344 345 346 347
{
	MEMORYSTATUSEX status;
	status.dwLength = sizeof(status);
	GlobalMemoryStatusEx(&status);
	return status.ullTotalPhys;
}
#else
#include <unistd.h>
348
size_t plugins_manager::get_system_memory()
349 350 351 352 353 354
{
	long pages = sysconf(_SC_PHYS_PAGES);
	long page_size = sysconf(_SC_PAGE_SIZE);
	return pages * page_size;
}
#endif