Commit 827abdab authored by Laurent Belcour's avatar Laurent Belcour

On the way to remove Qt library loading from the core

parent c571d4f3
......@@ -5,8 +5,6 @@
#include "args.h"
#include "common.h"
#include <QtPlugin>
/*! \brief Fitting interface for generic fitting algorithms
* \ingroup core
*
......@@ -14,15 +12,16 @@
class fitter
{
public:
//! \brief static function to fit a data set d with the underling
//! function class. Return the best fit (along with fitting
//! information ?)
virtual bool fit_data(const data* d, function* f, const arguments& args) = 0 ;
//! \brief static function to fit a data set d with the underling
//! function class. Return the best fit (along with fitting
//! information ?)
virtual bool fit_data(const data* d, function* f, const arguments& args) = 0 ;
//! \brief parse the command line arguments to setup some general
//! options before any fit. Those options should be resilient to
//! multiple call to the fit_data procedure
virtual void set_parameters(const arguments& args) = 0 ;
} ;
Q_DECLARE_INTERFACE(fitter, "Fitter.Fitter")
......@@ -3,14 +3,53 @@
#include "vertical_segment.h"
#include <QCoreApplication>
/*
#include <QPluginLoader>
#include <QtPlugin>
#include <QLibrary>
*/
#include <QDir>
// Create the object, parse the argument and load
// all the plugins
//
#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;
return NULL;
}
#endif
}
// Create the object, parse the argument and load all the plugins
plugins_manager::plugins_manager(const arguments& args)
{
......@@ -24,6 +63,7 @@ plugins_manager::plugins_manager(const arguments& args)
pluginsDir = QDir(QCoreApplication::instance()->applicationDirPath());
}
/*
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
QPluginLoader loader ;
......@@ -77,14 +117,9 @@ plugins_manager::plugins_manager(const arguments& args)
#endif
}
}
*/
}
#ifdef USING_STATIC
typedef function* (*FunctionPrototype)();
typedef fitter* (*FitterPrototype)();
typedef data* (*DataPrototype)();
#endif
// Get instances of the function, the data and the
// fitter
//
......@@ -140,40 +175,6 @@ fitter* plugins_manager::get_fitter()
#endif
}
#ifdef WIN32
#else
#include <stdio.h>
#include <dlfcn.h>
#endif
void* 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 res;
}
else
{
std::cerr << "<<ERROR>> unable to load the dynamic library file \"" << filename << "\"" << std::endl;
return NULL;
}
#endif
}
// Get instances of the function, the data and the
// fitter, select one based on the name. Return null
// if no one exist.
......@@ -200,15 +201,8 @@ function* plugins_manager::get_function(const std::string& n)
}
QString path = QDir::currentPath() + QString(file.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("provide_function");
FunctionPrototype myFunction = open_library<FunctionPrototype>(path.toStdString(), "provide_function");
if(myFunction != NULL)
{
#ifdef DEBUG
......@@ -255,15 +249,8 @@ data* plugins_manager::get_data(const std::string& n)
}
QString path = QDir::currentPath() + QString(file.c_str()) ;
QLibrary data_lib(path);
if(!data_lib.isLoaded())
{
std::cerr << "<<ERROR>> unable to load file \"" << path.toStdString() << "\"" << std::endl;
return NULL;
}
DataPrototype myData = (DataPrototype) data_lib.resolve("provide_data");
DataPrototype myData = open_library<DataPrototype>(path.toStdString(), "provide_data");
if(myData != NULL)
{
#ifdef DEBUG
......@@ -310,18 +297,8 @@ fitter* plugins_manager::get_fitter(const std::string& n)
}
QString path = QDir::currentPath() + QString(file.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("provide_fitter");
*/
void* link = open_library(path.toStdString(), "provide_fitter");
FitterPrototype myFitter = (FitterPrototype)link;
FitterPrototype myFitter = open_library<FitterPrototype>(path.toStdString(), "provide_fitter");
if(myFitter != NULL)
{
......
......@@ -106,6 +106,13 @@ class plugins_manager
private: //data
// Object provider prototypes
typedef function* (*FunctionPrototype)();
typedef fitter* (*FitterPrototype)();
typedef data* (*DataPrototype)();
// Map associating a filename to a provider. This is used to store a list of
// accessible provider to make automatic type testing.
std::map<std::string, function*> _functions ;
std::map<std::string, data*> _datas ;
std::map<std::string, fitter*> _fitters ;
......
......@@ -109,7 +109,7 @@ struct EigenFunctor: Eigen::DenseFunctor<double>
const data* _d;
};
nonlinear_fitter_eigen::nonlinear_fitter_eigen() : QObject()
nonlinear_fitter_eigen::nonlinear_fitter_eigen()
{
}
nonlinear_fitter_eigen::~nonlinear_fitter_eigen()
......@@ -182,4 +182,3 @@ void nonlinear_fitter_eigen::set_parameters(const arguments& args)
data* nonlinear_fitter_eigen::provide_data() const { return NULL; }
function* nonlinear_fitter_eigen::provide_function() const { return NULL; }
Q_EXPORT_PLUGIN2(nonlinear_fitter_eigen, nonlinear_fitter_eigen)
......@@ -5,7 +5,6 @@
#include <string>
// Interface
#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
......@@ -16,11 +15,8 @@
* Levenberg-Marquardt solver.
* \ingroup plugins
*/
class nonlinear_fitter_eigen: public QObject, public fitter
class nonlinear_fitter_eigen: public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
nonlinear_fitter_eigen() ;
......
......@@ -2,7 +2,7 @@ TEMPLATE = subdirs
SUBDIRS = \
rational_fitter_cgal \
rational_fitter_quadprog \
rational_fitter_quadprog \
# rational_fitter_parallel \
rational_fitter_eigen \
rational_fitter_leastsquare \
......
......@@ -16,9 +16,6 @@
class rational_fitter_cgal : public QObject, public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
rational_fitter_cgal() ;
......
......@@ -29,7 +29,7 @@ function* rational_fitter_eigen::provide_function() const
return new rational_function() ;
}
rational_fitter_eigen::rational_fitter_eigen() : QObject()
rational_fitter_eigen::rational_fitter_eigen()
{
}
rational_fitter_eigen::~rational_fitter_eigen()
......@@ -193,5 +193,3 @@ bool rational_fitter_eigen::fit_data(const vertical_segment* d, int np, int nq,
}
}
Q_EXPORT_PLUGIN2(rational_fitter_eigen, rational_fitter_eigen)
......@@ -5,7 +5,6 @@
#include <string>
// Interface
#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
......@@ -13,10 +12,8 @@
#include <core/rational_function.h>
#include <core/vertical_segment.h>
class rational_fitter_eigen : public QObject, public fitter
class rational_fitter_eigen : public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
......
......@@ -13,5 +13,5 @@ INCLUDEPATH += ../rational_function \
HEADERS = rational_fitter.h
SOURCES = rational_fitter.cpp
LIBS += -L../../build \
LIBS += -L../../build \
-lcore
......@@ -29,7 +29,7 @@ function* rational_fitter_leastsquare::provide_function() const
return new rational_function() ;
}
rational_fitter_leastsquare::rational_fitter_leastsquare() : QObject()
rational_fitter_leastsquare::rational_fitter_leastsquare()
{
}
rational_fitter_leastsquare::~rational_fitter_leastsquare()
......@@ -229,5 +229,3 @@ bool rational_fitter_leastsquare::fit_data(const vertical_segment* d, int np, in
return true;
}
Q_EXPORT_PLUGIN2(rational_fitter_leastsquare, rational_fitter_leastsquare)
......@@ -5,7 +5,6 @@
#include <string>
// Interface
#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
......@@ -13,19 +12,16 @@
#include <core/rational_function.h>
#include <core/vertical_segment.h>
class rational_fitter_leastsquare : public QObject, public fitter
class rational_fitter_leastsquare : public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
rational_fitter_leastsquare() ;
virtual ~rational_fitter_leastsquare() ;
// Fitting a data object
//
virtual bool fit_data(const data* d, function* fit, const arguments& args) ;
virtual bool fit_data(const data* d, function* fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......@@ -41,11 +37,11 @@ class rational_fitter_leastsquare : public QObject, public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const vertical_segment* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
protected: // data
int _np, _nq ;
int _max_iter;
int _max_iter;
} ;
......@@ -14,22 +14,12 @@
#define BUFFER_SIZE 10000
data* rational_fitter_matlab::provide_data() const
{
return new vertical_segment() ;
}
function* rational_fitter_matlab::provide_function() const
{
return new rational_function() ;
}
ALTA_DLL_EXPORT fitter* provide_fitter()
{
return new rational_fitter_matlab();
}
rational_fitter_matlab::rational_fitter_matlab() : QObject()
rational_fitter_matlab::rational_fitter_matlab()
{
}
rational_fitter_matlab::~rational_fitter_matlab()
......@@ -360,5 +350,3 @@ bool rational_fitter_matlab::fit_data(const vertical_segment* d, int np, int nq,
return false ;
}
}
Q_EXPORT_PLUGIN2(rational_fitter_matlab, rational_fitter_matlab)
......@@ -6,7 +6,6 @@
#include <engine.h>
// Interface
#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
......@@ -14,19 +13,16 @@
#include <core/rational_function.h>
#include <core/vertical_segment.h>
class rational_fitter_matlab : public QObject, public fitter
class rational_fitter_matlab : public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
rational_fitter_matlab() ;
virtual ~rational_fitter_matlab() ;
// Fitting a data object
//
virtual bool fit_data(const data* d, function* fit, const arguments& args) ;
virtual bool fit_data(const data* d, function* fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......@@ -42,7 +38,7 @@ class rational_fitter_matlab : public QObject, public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const vertical_segment* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
protected: // data
......
......@@ -14,6 +14,6 @@ INCLUDEPATH += ../rational_function \
HEADERS = rational_fitter.h
SOURCES = rational_fitter.cpp
LIBS += -L../../build \
LIBS += -L../../build \
-lcore
......@@ -34,7 +34,7 @@ function* rational_fitter_quadprog::provide_function() const
return new rational_function() ;
}
rational_fitter_quadprog::rational_fitter_quadprog() : QObject(), _boundary(1.0)
rational_fitter_quadprog::rational_fitter_quadprog() : _boundary(1.0)
{
}
rational_fitter_quadprog::~rational_fitter_quadprog()
......@@ -337,5 +337,3 @@ bool rational_fitter_quadprog::fit_data(const vertical_segment* dat, int np, int
return false;
}
}
//Q_EXPORT_PLUGIN2(rational_fitter_quadprog, rational_fitter_quadprog)
......@@ -16,11 +16,8 @@
/*! \brief A rational fitter using the library QuadProg++
* You can find the library here: http://quadprog.sourceforge.net/
*/
class rational_fitter_quadprog : public QObject, public fitter
class rational_fitter_quadprog : public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
rational_fitter_quadprog() ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment