Le 04/02/2011 11:43, Sylvain Meunier a écrit :
Le 03/02/2011 19:44, Hugo Parente Lima a écrit :
On Thursday 03 February 2011 16:29:59 Anderson Lizardo wrote:
On Thu, Feb 3, 2011 at 12:13 PM, Hugo Parente Lima

<hugo.l...@openbossa.org>  wrote:
On Thursday 03 February 2011 12:54:50 Sylvain Meunier wrote:
Hello,

What is the usual way for binding method templates ?
There's no simple way, sometimes it's possible some times not because we
can't instantiate those template methods at runtime. So you need to
analyze the semantics of the method and write some kind of code
injection to do the hard task of connect the world of compile time stuff
(C++ templates) to the world of run time stuff (Python).

As an example you could see our implementation of qmlRegisterType<T>[1]
or QObject::findChildren to have an idea.
I wonder if this could be made automatic by extending apiextractor to
parse templates as well? or does it already parse templates and one
could extend the generator?

Of course, it would not work in 100% cases, but it would be nice if we
could have some typesystem support for simple templates which would
not require manual inject code.
It isn't a parser problem, it's a "can't generate C++ code at runtime problem"
:-P

C++ knows everything at compile time, but when we are generating the bindings
we don't know what types the python user will use to call Foo::bar<T>  method.

For some cases we can do workarounds like creating a C++ type and using it in
the function call every time the python user calls the bar function with a
Python type, for other cases it is a bit harder, btw you can take as hard
example the qRegisterMetaType function that isn't binded yet in PySide because
it requires a non trivial workaround.

My two BRL cents :)


_______________________________________________
PySide mailing list
PySide@lists.openbossa.org
http://lists.openbossa.org/listinfo/pyside

I follow Anderson Lizardo on this point. Instantiating some templates adding one line in a type system could be really helpful.



_______________________________________________
PySide mailing list
PySide@lists.openbossa.org
http://lists.openbossa.org/listinfo/pyside

For illustrating my previous point, a very mechanical code injection for binding this method template :

class QtAbstractPropertyBrowser : public QWidget
{
    ...

    template <class PropertyManager>
    void setFactoryForManager(PropertyManager *manager,
                    QtAbstractEditorFactory<PropertyManager> *factory) {
        QtAbstractPropertyManager *abstractManager = manager;
        QtAbstractEditorFactoryBase *abstractFactory = factory;

        if (addFactory(abstractManager, abstractFactory))
            factory->addPropertyManager(manager);
    }

    ...
};



I just want to use the available factories in Python, so I add this glue (some template instantiations and "tricky" memory managements) :

#include "qtintpropertymanager_wrapper.h"
#include "qtspinboxfactory_wrapper.h"

namespace
{
void setFactoryForManager_glue( QtAbstractPropertyBrowserWrapper* self, PyObject* pyManager, PyObject* pyFactory )
    {
        // QtIntPropertyManager
        // QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory
        //
if( Shiboken::Converter< QtIntPropertyManager* >::isConvertible( pyManager ) )
        {
QtIntPropertyManager* cppManager = Shiboken::Converter< QtIntPropertyManager* >::toCpp( pyManager ); QtAbstractEditorFactory< QtIntPropertyManager >* cppFactory = Shiboken::ObjectTypeConverter< QtAbstractEditorFactory<QtIntPropertyManager> >::toCpp( pyFactory );

            self->setFactoryForManager( cppManager, cppFactory );
        }

        // QtColorPropertyManager
        // QtColorEditorFactory
        //
else if( Shiboken::Converter< QtColorPropertyManager* >::isConvertible( pyManager ) )
        {
QtColorPropertyManager* cppManager = Shiboken::Converter< QtColorPropertyManager* >::toCpp( pyManager ); QtAbstractEditorFactory< QtColorPropertyManager >* cppFactory = Shiboken::ObjectTypeConverter< QtAbstractEditorFactory<QtColorPropertyManager> >::toCpp( pyFactory );

            self->setFactoryForManager( cppManager, cppFactory );
        }

        // QtBoolPropertyManager
        // QtCheckBoxFactory
        //
else if( Shiboken::Converter< QtBoolPropertyManager* >::isConvertible( pyManager ) )
        {
QtBoolPropertyManager* cppManager = Shiboken::Converter< QtBoolPropertyManager* >::toCpp( pyManager ); QtAbstractEditorFactory< QtBoolPropertyManager >* cppFactory = Shiboken::ObjectTypeConverter< QtAbstractEditorFactory< QtBoolPropertyManager > >::toCpp( pyFactory );

            self->setFactoryForManager( cppManager, cppFactory );
        }
    }
}



And define my code injection :

...

<object-type name="QtAbstractPropertyBrowser" >
<inject-code class="native" file="QtAbstractPropertyBrowser_glue.cpp" />
<add-function signature="setFactoryForManager( PyObject*, PyObject* )" return-type="void">
<inject-code class="target" position="beginning">
            setFactoryForManager_glue( %CPPSELF, %PYARG_1, %PYARG_2 );
</inject-code>
</add-function>
</object-type>

...



There is no runtime problem in this case, all the required types are available at compilation time.





_______________________________________________
PySide mailing list
PySide@lists.openbossa.org
http://lists.openbossa.org/listinfo/pyside

Reply via email to