plugins_manager.cpp 6.87 KB
Newer Older
1
#include "plugins_manager.h"
2 3
#include "rational_function.h"
#include "vertical_segment.h"
4 5 6 7

#include <QCoreApplication>
#include <QPluginLoader>
#include <QtPlugin>
8
#include <QLibrary>
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
#include <QDir>

// 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 << "<<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
		}
	}
}

82 83 84 85 86 87
#ifdef USING_STATIC
typedef function* (*FunctionPrototype)();
typedef fitter*   (*FitterPrototype)();
typedef data*     (*DataPrototype)();
#endif

88 89 90
// Get instances of the function, the data and the
// fitter
//
91
function* plugins_manager::get_function()
92
{
93 94 95 96
#ifdef USING_STATIC
    return new rational_function() ;
#else
    if(_functions.empty())
97
	{
98
		return new rational_function() ;
99 100 101 102 103
	}
	else
	{
		return _functions.begin()->second ;
	}
104 105
#endif

106
}
107
data* plugins_manager::get_data()
108
{
Laurent Belcour's avatar
Laurent Belcour committed
109
	//if(_datas.empty())
110
	{
111 112 113
#ifdef DEBUG
        std::cout << "<<DEBUG>>  using vertical segment data loader" << std::endl ;
#endif
114
		return new vertical_segment() ;
Laurent Belcour's avatar
Laurent Belcour committed
115
	}/*
116 117
	else
	{
118
#ifdef DEBUG
119
		std::cout << "<<DEBUG>>  using \"" << _datas.begin()->first << "\" data loader" << std::endl ;
120
#endif
121
		return _datas.begin()->second ;
Laurent Belcour's avatar
Laurent Belcour committed
122
	}*/
123
}
124
fitter* plugins_manager::get_fitter()
125
{
126 127 128
#ifdef USING_STATIC
    return NULL;
#else
129 130 131 132 133 134
	if(_fitters.empty())
	{
		return NULL ;
	}
	else
	{
135
#ifdef DEBUG
136
		std::cout << "<<DEBUG>>  using \"" <<  _fitters.begin()->first << "\"" << std::endl ;
137
#endif
138 139
		return _fitters.begin()->second ;
	}
140
#endif
141 142
}

143

144 145 146 147
// Get instances of the function, the data and the
// fitter, select one based on the name. Return null
// if no one exist.
//
148
function* plugins_manager::get_function(const std::string& n)
149
{
150 151 152 153 154 155 156 157
    if(n.empty())
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> no function plugin specified, returning a rational function" << std::endl;
#endif
        return new rational_function();
    }

158
#ifdef USING_STATIC
159 160 161 162 163 164 165 166 167
    QString path = QDir::currentPath() + QString(n.c_str()) ;
    QLibrary function_lib(path);
    if(!function_lib.isLoaded())
    {
        std::cerr << "<<ERROR>> unable to load file \"" << path.toStdString() << "\"" << std::endl;
        return NULL;
    }

    FunctionPrototype myFunction = (FunctionPrototype) function_lib.resolve("_Z16provide_functionv");
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182

    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

183
	if(_functions.count(n) == 0)
184
	{
185
		return new rational_function() ;
186 187 188
	}
	else
	{
Laurent Belcour's avatar
Laurent Belcour committed
189
		return _functions.find(n)->second ;
190
	}
191
#endif
192
}
193
data* plugins_manager::get_data(const std::string& n)
194
{
195 196
    if(n.empty())
    {
197
#ifdef DEBUG
198
        std::cout << "<<DEBUG>> no data plugin specified, returning a vertial_segment loader" << std::endl;
199
#endif
200 201 202 203
        return new vertical_segment();
    }

#ifdef USING_STATIC
204 205 206 207 208 209 210 211
    QString path = QDir::currentPath() + QString(n.c_str()) ;
    QLibrary data_lib(path);
    if(!data_lib.isLoaded())
    {
        std::cerr << "<<ERROR>> unable to load file \"" << path.toStdString() << "\"" << std::endl;
        return NULL;
    }

212
    DataPrototype myData = (DataPrototype) data_lib.resolve("_Z12provide_datav");
213 214 215

    if(myData != NULL)
    {
216
#ifdef DEBUG
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
        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 ;
    }
236
#endif
237
}
238
fitter* plugins_manager::get_fitter(const std::string& n)
239
{
Laurent Belcour's avatar
Laurent Belcour committed
240 241 242 243 244 245 246 247
    if(n.empty())
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> no fitter plugin specified, returning null" << std::endl;
#endif
        return NULL;
    }

248 249 250 251 252 253 254 255 256 257
#ifdef USING_STATIC
    QString path = QDir::currentPath() + QString(n.c_str()) ;
    QLibrary fitting_lib(path);
    if(!fitting_lib.isLoaded())
    {
        std::cerr << "<<ERROR>> unable to load file \"" << path.toStdString() << "\"" << std::endl;
        return NULL;
    }

    FitterPrototype myFitter = (FitterPrototype) fitting_lib.resolve("_Z14provide_fitterv");
Laurent Belcour's avatar
Laurent Belcour committed
258 259 260 261 262 263 264 265 266 267

    if(myFitter != NULL)
    {
#ifdef DEBUG
        std::cout << "<<DEBUG>> using function provider in file \"" << n << "\"" << std::endl;
#endif
        return myFitter();
    }
    else
    {
268 269
        std::cerr << "<<ERROR>> no fitter provider found in file \"" << n << "\"" << std::endl;
        return NULL ;
Laurent Belcour's avatar
Laurent Belcour committed
270 271
    }
#else
272
	if(_fitters.count(n) == 0)
273 274 275 276 277
	{
		return NULL ;
	}
	else
	{
278
#ifdef DEBUG
279
		std::cout << "<<DEBUG>>  using \"" <<  n << "\"" << std::endl ;
280
#endif
Laurent Belcour's avatar
Laurent Belcour committed
281
		return _fitters.find(n)->second ;
282
	}
Laurent Belcour's avatar
Laurent Belcour committed
283
#endif
284
}
285 286 287 288
		
// \todo implement the Darwin (MACOS) version.
#ifdef WIN32
#include <windows.h>
289
size_t plugins_manager::get_system_memory()
290 291 292 293 294 295 296 297
{
	MEMORYSTATUSEX status;
	status.dwLength = sizeof(status);
	GlobalMemoryStatusEx(&status);
	return status.ullTotalPhys;
}
#else
#include <unistd.h>
298
size_t plugins_manager::get_system_memory()
299 300 301 302 303 304
{
	long pages = sysconf(_SC_PHYS_PAGES);
	long page_size = sysconf(_SC_PAGE_SIZE);
	return pages * page_size;
}
#endif