Commit 2bcf16e3 authored by NICLAUSSE Nicolas's avatar NICLAUSSE Nicolas
Browse files

add sip wrapping dtkArray and dtkCoreLayerManager; add recordPlugin in

factory API
parent b5001d0d
// SIP support for dtkArray.h
// by Giovanni Bajo <rasky <at> develer.com>
// Public domain
// ****************************************************
// SIP generic implementation for dtkArray.h
// ****************************************************
// ALas, this template-based generic implementation is valid only
// if the element type is a SIP-wrapped type. For basic types (int, double, etc.)
// we are forced to cut & paste to provide a specialization.
template<TYPE>
%MappedType dtkArray<TYPE>
{
%TypeHeaderCode
#include <dtkCore/dtkArray.h>
%End
%ConvertFromTypeCode
PyObject *l = PyList_New(sipCpp -> size());
// Create the Python list of the correct length.
if (!l)
return NULL;
// Go through each element in the C++ instance and convert it to a
// wrapped P2d.
for (int i = 0; i < (int)sipCpp->size(); ++i) {
TYPE *cpp = new TYPE(sipCpp->at(i));
PyObject *pobj = sipConvertFromInstance(cpp, sipClass_TYPE, sipTransferObj);
// Get the Python wrapper for the Type instance, creating a new
// one if necessary, and handle any ownership transfer.
if (!pobj) {
// There was an error so garbage collect the Python list.
Py_DECREF(l);
return NULL;
}
// Add the wrapper to the list.
PyList_SET_ITEM(l, i, pobj);
}
// Return the Python list.
return l;
%End
%ConvertToTypeCode
// Check if type is compatible
if (!sipIsErr) {
// Must be any iterable
PyObject *i = PyObject_GetIter(sipPy);
bool iterable = (i != NULL);
Py_XDECREF(i);
return iterable;
}
// Iterate over the object
PyObject *iterator = PyObject_GetIter(sipPy);
PyObject *item;
dtkArray<TYPE> *V = new dtkArray<TYPE>();
while ((item = PyIter_Next(iterator)))
{
if (!sipCanConvertToInstance(item, sipClass_TYPE, SIP_NOT_NONE)) {
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to TYPE");
*sipIsErr = 1;
break;
}
int state;
TYPE* p = reinterpret_cast<TYPE*>(
sipConvertToInstance(item, sipClass_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
if (!*sipIsErr)
V->push_back(*p);
sipReleaseInstance(p, sipClass_TYPE, state);
Py_DECREF(item);
}
Py_DECREF(iterator);
if (*sipIsErr) {
delete V;
return 0;
}
*sipCppPtr = V;
return sipGetState(sipTransferObj);
%End
};
// ****************************************************
// Specialization for dtkArray<double>
// ****************************************************
%MappedType dtkArray<double>
{
%TypeHeaderCode
#include <dtkCore/dtkArray.h>
%End
%ConvertFromTypeCode
PyObject *l;
// Create the Python list of the correct length.
if ((l = PyList_New(sipCpp -> size())) == NULL)
return NULL;
// Go through each element in the C++ instance and convert it to a
// wrapped object.
for (int i = 0; i < (int)sipCpp -> size(); ++i)
{
// Add the wrapper to the list.
PyList_SET_ITEM(l, i, PyFloat_FromDouble(sipCpp -> at(i)));
}
// Return the Python list.
return l;
%End
%ConvertToTypeCode
// Check if type is compatible
if (sipIsErr == NULL)
{
// Must be any iterable
PyObject *i = PyObject_GetIter(sipPy);
bool iterable = (i != NULL);
Py_XDECREF(i);
return iterable;
}
// Iterate over the object
PyObject *iterator = PyObject_GetIter(sipPy);
PyObject *item;
// Maximum number of elements
int len = PyObject_Size(sipPy);
dtkArray<double> *V = new dtkArray<double>();
V->reserve(len);
if (len)
{
while ((item = PyIter_Next(iterator)))
{
if (!PyNumber_Check(item))
{
PyErr_Format(PyExc_TypeError, "object in iterable is not a number");
*sipIsErr = 1;
break;
}
PyObject *f = PyNumber_Float(item);
V->push_back(PyFloat_AsDouble(f));
Py_DECREF(f);
Py_DECREF(item);
}
Py_DECREF(iterator);
if (*sipIsErr)
{
delete V;
return 0;
}
}
*sipCppPtr = V;
return sipGetState(sipTransferObj);
%End
};
// ****************************************************
// Specialization for dtkArray<int>
// ****************************************************
%MappedType dtkArray<int>
{
%TypeHeaderCode
#include <dtkCore/dtkArray.h>
%End
%ConvertFromTypeCode
PyObject *l;
// Create the Python list of the correct length.
if ((l = PyList_New((SIP_SSIZE_T)sipCpp -> size())) == NULL)
return NULL;
// Go through each element in the C++ instance and convert it to a
// wrapped object.
for (int i = 0; i < (int)sipCpp -> size(); ++i)
{
// Add the wrapper to the list.
PyList_SET_ITEM(l, i, PyInt_FromLong(sipCpp -> at(i)));
}
// Return the Python list.
return l;
%End
%ConvertToTypeCode
// Check if type is compatible
if (sipIsErr == NULL)
{
// Must be any iterable
PyObject *i = PyObject_GetIter(sipPy);
bool iterable = (i != NULL);
Py_XDECREF(i);
return iterable;
}
// Iterate over the object
PyObject *iterator = PyObject_GetIter(sipPy);
PyObject *item;
// Maximum number of elements
int len = PyObject_Size(sipPy);
dtkArray<int> *V = new dtkArray<int>();
V->reserve(len);
if (len)
{
while ((item = PyIter_Next(iterator)))
{
if (!PyInt_Check(item))
{
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to float");
*sipIsErr = 1;
break;
}
int val = PyInt_AsLong(item);
V->push_back(val);
Py_DECREF(item);
}
Py_DECREF(iterator);
if (*sipIsErr)
{
delete V;
return 0;
}
}
*sipCppPtr = V;
return sipGetState(sipTransferObj);
%End
};
// ****************************************************
// Specialization for dtkArray<long long>
// ****************************************************
%MappedType dtkArray<long long>
{
%TypeHeaderCode
#include <dtkCore/dtkArray.h>
%End
%ConvertFromTypeCode
PyObject *l;
// Create the Python list of the correct length.
if ((l = PyList_New(sipCpp -> size())) == NULL)
return NULL;
// Go through each element in the C++ instance and convert it to a
// wrapped object.
for (int i = 0; i < (int)sipCpp -> size(); ++i)
{
// Add the wrapper to the list.
PyList_SET_ITEM(l, i, PyInt_FromLong(sipCpp -> at(i)));
}
// Return the Python list.
return l;
%End
%ConvertToTypeCode
// Check if type is compatible
if (sipIsErr == NULL)
{
// Must be any iterable
PyObject *i = PyObject_GetIter(sipPy);
bool iterable = (i != NULL);
Py_XDECREF(i);
return iterable;
}
// Iterate over the object
PyObject *iterator = PyObject_GetIter(sipPy);
PyObject *item;
// Maximum number of elements
Py_ssize_t size = PyObject_Size(sipPy);
if (size == -1) {
Py_DECREF(iterator);
return 0;
}
unsigned int len = size;
dtkArray<long long> *V = new dtkArray<long long>();
V->reserve(len);
if (len)
{
while ((item = PyIter_Next(iterator)))
{
if (!PyInt_Check(item))
{
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to float");
*sipIsErr = 1;
break;
}
long long val = PyInt_AsLong(item);
V->push_back(val);
Py_DECREF(item);
}
Py_DECREF(iterator);
if (*sipIsErr)
{
delete V;
return 0;
}
}
*sipCppPtr = V;
return sipGetState(sipTransferObj);
%End
};
class dtkCoreLayerManager
{
%TypeHeaderCode
#include <dtkCore/dtkCoreLayerManager.h>
%End
public:
dtkCoreLayerManager();
~dtkCoreLayerManager();
public:
void record(const QString& plugin_manager_name, dtkCorePluginManagerBase *plugin_manager);
void initialize();
void initialize(const QString& path);
void uninitialize();
void setVerboseLoading(bool value);
bool verboseLoading() const;
void setAutoLoading(bool value);
bool autoLoading() const;
};
......@@ -11,4 +11,5 @@ public:
public:
virtual void initialize() = 0;
virtual void uninitialize() = 0;
virtual void *create() /Factory/;
};
......@@ -11,17 +11,14 @@ public:
// https://www.riverbankcomputing.com/pipermail/pyqt/2009-June/023375.html
// public:
// typedef TYPE *(*creator) ();
// typedef dtkCorePluginTuner<TYPE> *(*tunerCreator) ();
public:
// typedef TYPE *(*creator) ();
public:
void record(const QString& key, creator func);
void recordTuner(const QString& key, tunerCreator func);
void recordPlugin(const QString& key, dtkCorePluginBase *plugin);
public:
TYPE *create(const QString& key) const;
dtkCorePluginTuner<TYPE> *createTuner(const QString& key) const;
TYPE *create(const QString& key) const /Factory/ ;
public:
QStringList keys() const;
......
......@@ -5,3 +5,5 @@
%Include dtkCorePluginBase.sip
%Include dtkCorePluginFactory.sip
%Include dtkCorePluginManager.sip
%Include dtkCoreLayerManager.sip
%Include dtkArray.sip
......@@ -100,6 +100,10 @@ if(DTK_BUILD_WRAPPERS)
if(SIP_FOUND)
set(${PROJECT_NAME}_SIP_WRAPPERS
sip${PROJECT_NAME}dtkCorePluginBase.cpp
sip${PROJECT_NAME}dtkArray1800.cpp
sip${PROJECT_NAME}dtkArray2400.cpp
sip${PROJECT_NAME}dtkArray3800.cpp
sip${PROJECT_NAME}dtkCoreLayerManager.cpp
sip${PROJECT_NAME}dtkCorePluginManagerBase.cpp)
dtk_wrap_sip(${PROJECT_NAME} ${PROJECT_NAME}_SOURCES_WRAP dtkCore ${CMAKE_SOURCE_DIR}/sip/dtkCore/dtkCoremod.sip "${${PROJECT_NAME}_SIP_WRAPPERS}" ${${PROJECT_NAME}_WRAP_DEPENDS})
......
......@@ -14,4 +14,5 @@ public:
public:
virtual void initialize(void) = 0;
virtual void uninitialize(void) = 0;
virtual void *create(void) {return nullptr;};
};
......@@ -39,6 +39,8 @@ public:
void connect(dtkObjectManager *manager) const;
};
#include "dtkCorePluginBase.h"
// ///////////////////////////////////////////////////////////////////
// dtkCorePluginFactory
// ///////////////////////////////////////////////////////////////////
......@@ -57,6 +59,7 @@ public:
public:
void record(const QString& key, creator func);
void recordPlugin(const QString& key, dtkCorePluginBase *plugin);
void recordTuner(const QString& key, tunerCreator func);
public:
......@@ -71,6 +74,7 @@ public:
private:
QHash<QString, creator> creators;
QHash<QString, dtkCorePluginBase*> creators_plugins;
QHash<QString, tunerCreator> tuner_creators;
private:
......
......@@ -42,6 +42,16 @@ template <typename T> void dtkCorePluginFactory<T>::record(const QString& key, c
this->creators.insert(key, func);
}
template <typename T> void dtkCorePluginFactory<T>::recordPlugin(const QString& key, dtkCorePluginBase *plugin)
{
if (this->creators_plugins.contains(key)) {
qDebug() << Q_FUNC_INFO << "Factory already contains key" << key << ". Nothing is done";
return;
}
this->creators_plugins.insert(key, plugin);
}
template <typename T> void dtkCorePluginFactory<T>::recordTuner(const QString& key, tunerCreator func)
{
if (this->tuner_creators.contains(key)) {
......@@ -61,9 +71,15 @@ template <typename T> T *dtkCorePluginFactory<T>::create(const QString& key) con
T *obj = nullptr;
if (this->creators.contains(key)) {
obj = this->creators.value(key)();
if (obj) {
m_d->touch(qMetaTypeId<T *>(), obj);
}
} else if (this->creators_plugins.contains(key)) {
qDebug() << "will call create from " << this->creators_plugins.value(key);
void *o = this->creators_plugins.value(key)->create();
qDebug() << "got void * " << o;
obj = static_cast<T*>(o);
}
if (obj) {
m_d->touch(qMetaTypeId<T *>(), obj);
}
return obj;
......@@ -84,7 +100,9 @@ template <typename T> dtkCorePluginTuner<T> *dtkCorePluginFactory<T>::createTune
template <typename T> QStringList dtkCorePluginFactory<T>::keys(void) const
{
return this->creators.keys();
QStringList lkeys = this->creators.keys() ;
lkeys << this->creators_plugins.keys();
return lkeys;
}
// ///////////////////////////////////////////////////////////////////
......
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