QPy
Python-Qt dynamic bindings
PyCallbackDispatcher.h
Go to the documentation of this file.
00001 #pragma once
00002 // QPy - Copyright (c) 2012,2013 Ugo Varetto
00003 // All rights reserved.
00004 //
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the author and copyright holder nor the
00013 //       names of contributors to the project may be used to endorse or promote products
00014 //       derived from this software without specific prior written permission.
00015 //
00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 // DISCLAIMED. IN NO EVENT SHALL UGO VARETTO BE LIABLE FOR ANY
00020 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00029 #include <Python.h>
00030 #include <QObject>
00031 #include <QMap>
00032 #include <QList>
00033 
00034 namespace qpy {
00035 
00036 class PyContext;
00037 
00038 typedef QList< PyArgWrapper > CBackParameterTypes;
00039 
00040 //------------------------------------------------------------------------------
00047 class PyCBackMethod {
00048 public:
00055     PyCBackMethod( PyContext* pc, PyObject* pm, const CBackParameterTypes& p, PyObject* pyCBack ) 
00056         : pc_( pc ), pyModule_( pm ), paramTypes_( p ), pyCBack_( pyCBack ) {}
00064     void Invoke( void **arguments );
00066     PyObject* CBack() const{ return pyCBack_; }
00070     void DeleteCBack() { 
00071         Py_XDECREF( pyCBack_ );
00072         pyCBack_ = 0;
00073     } 
00074 private:
00076     PyContext* pc_;
00078     CBackParameterTypes paramTypes_;
00080     PyObject* pyCBack_;
00082     PyObject* pyModule_;
00083 };
00084 
00085 
00086 typedef PyObject* PyCBack;
00087 typedef int MethodId;
00088 
00089 //------------------------------------------------------------------------------
00103 class PyCallbackDispatcher : public QObject {
00104 public:
00106     PyCallbackDispatcher( QObject* parent = 0 ) 
00107         : QObject( parent ), pc_( 0 ) {}
00109     PyCallbackDispatcher( PyContext* pc, PyObject* pm, QObject* parent = 0 ) 
00110         : pc_( pc ), QObject( parent ) {}
00113     int qt_metacall( QMetaObject::Call c, int id, void **arguments ); 
00121     bool Connect( QObject *obj, 
00122                   int signalIdx,
00123                   const CBackParameterTypes& paramTypes,
00124                   PyCBack pyCBack,
00125                   PyObject* module );
00130     bool Disconnect( QObject *obj, 
00131                      int signalIdx,
00132                      PyCBack pyCBack );
00134     void SetPyContext( PyContext* pc ) { pc_ = pc; };
00136     virtual ~PyCallbackDispatcher() {
00137         for( QMap< int, PyCBackMethod* >::iterator i = pyCBackMethods_.begin();
00138              i != pyCBackMethods_.end(); ++i ) {
00139             Py_XDECREF( i.value()->CBack() );
00140             delete *i;
00141         }
00142     }
00143 private:
00144     int GetMethodIndex() const {
00145         return methodIdx_++;
00146     }    
00147 private:
00149     PyContext* pc_;
00151     //QList< PyCBackMethod* > pyCBackMethods_;
00152     QMap< int, PyCBackMethod* > pyCBackMethods_;
00154     QMap< PyCBack, MethodId > cbackToMethodIndex_;
00155 
00156     static int methodIdx_; //thread_local
00157    
00158 };
00159 }
 All Classes Namespaces Files Functions