itom 1.0.14
D:/git-itom/sources/itom/Qitom/python/pythonQtSignalMapper.h
00001 /* ********************************************************************
00002     itom software
00003     URL: http://www.uni-stuttgart.de/ito
00004     Copyright (C) 2013, Institut für Technische Optik (ITO),
00005     Universität Stuttgart, Germany
00006 
00007     This file is part of itom.
00008   
00009     itom is free software; you can redistribute it and/or modify it
00010     under the terms of the GNU Library General Public Licence as published by
00011     the Free Software Foundation; either version 2 of the Licence, or (at
00012     your option) any later version.
00013 
00014     itom is distributed in the hope that it will be useful, but
00015     WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library
00017     General Public Licence for more details.
00018 
00019     You should have received a copy of the GNU Library General Public License
00020     along with itom. If not, see <http://www.gnu.org/licenses/>.
00021 *********************************************************************** */
00022 
00023 #ifndef PYTHONQTSIGNALMAPPER_H
00024 #define PYTHONQTSIGNALMAPPER_H
00025 
00026 #ifndef Q_MOC_RUN
00027     #define PY_ARRAY_UNIQUE_SYMBOL itom_ARRAY_API
00028 #endif
00029 
00030 
00031 //python
00032 // see http://vtk.org/gitweb?p=VTK.git;a=commitdiff;h=7f3f750596a105d48ea84ebfe1b1c4ca03e0bab3
00033 #ifdef _DEBUG
00034     #undef _DEBUG
00035     #if (defined linux) | (defined CMAKE)
00036         #include "Python.h"
00037     #else
00038         #include "Python.h"
00039     #endif
00040     #define _DEBUG
00041 #else
00042 #ifdef linux
00043     #include "Python.h"
00044 #else
00045     #include "Python.h"
00046 #endif
00047 #endif
00048 
00049 #include "../global.h"
00050 
00051 #include <qvariant.h>
00052 #include <qobject.h>
00053 
00054 class PythonQtSignalTarget
00055 {
00056 public:
00057 
00059     PythonQtSignalTarget() :
00060         m_slotId(-1),
00061         m_signalId(-1),
00062         m_function(NULL),
00063         m_boundedInstance(NULL),
00064         m_boundedMethod(false)
00065 
00066     {
00067     };
00068 
00070 
00082     PythonQtSignalTarget(IntList &argTypeList, int slotId, int signalId, PyObject* callable, const char *signal) :
00083             m_slotId(slotId),
00084             m_signalId(signalId),
00085             m_function(NULL),
00086             m_boundedInstance(NULL),
00087             m_boundedMethod(false),
00088             m_signalName(signal)
00089     {
00090         m_argTypeList = argTypeList;
00091         PyObject *temp = NULL;
00092 
00093         if(PyMethod_Check(callable))
00094         {
00095             m_boundedMethod = true;
00096             Py_XDECREF(m_boundedInstance);
00097             Py_XDECREF(m_function);
00098             temp = PyMethod_Self(callable); //borrowed
00099             m_boundedInstance = PyWeakref_NewRef(temp, NULL); //new ref (weak reference used to avoid cyclic garbage collection)
00100             temp = PyMethod_Function(callable); //borrowed
00101             m_function = PyWeakref_NewRef(temp, NULL); //new ref
00102         }
00103         else if(PyFunction_Check(callable))
00104         {
00105             m_boundedMethod = false;
00106             Py_XDECREF(m_boundedInstance);
00107             Py_XDECREF(m_function);
00108             m_function = PyWeakref_NewRef(callable, NULL); //new ref
00109         }
00110     };
00111         
00113     PythonQtSignalTarget(const PythonQtSignalTarget &copy) :
00114         m_slotId(-1),
00115         m_signalId(-1),
00116         m_function(NULL),
00117         m_boundedInstance(NULL),
00118         m_boundedMethod(false),
00119         m_signalName(copy.m_signalName)
00120     {
00121         Py_XDECREF(m_boundedInstance);
00122         Py_XDECREF(m_function);
00123         m_slotId = copy.slotId();
00124         m_signalId = copy.signalId();
00125         m_argTypeList = copy.argTypeList();
00126 
00127         m_boundedMethod = copy.m_boundedMethod;
00128         m_function = copy.m_function;
00129         Py_XINCREF(m_function);
00130         m_boundedInstance = copy.m_boundedInstance;
00131         Py_XINCREF(m_boundedInstance);
00132     }
00133         
00135     ~PythonQtSignalTarget()
00136     {
00137         Py_XDECREF(m_boundedInstance);
00138         Py_XDECREF(m_function);
00139         m_argTypeList.clear();
00140     }
00141 
00143     inline int signalId() const { return m_signalId; }
00144 
00146     inline int slotId()  const { return m_slotId; }
00147 
00148     // call the python callable with the given arguments (docs see source file)
00149     void call(void ** arguments) const;
00150 
00152     inline IntList argTypeList() const { return m_argTypeList; };
00153 
00155 
00162     bool isSame(int signalId, PyObject* callable) const 
00163     { 
00164         if(signalId == m_signalId)
00165         {
00166             if(PyMethod_Check(callable))
00167             {
00168                 return PyMethod_Self(callable) == PyWeakref_GetObject(m_boundedInstance) && PyMethod_Function(callable) == PyWeakref_GetObject(m_function);
00169             }
00170             return callable == PyWeakref_GetObject(m_function);
00171         }
00172         return false;
00173     }
00174 
00175 private:
00176     int m_slotId;                               
00177     int m_signalId;                             
00178     IntList m_argTypeList;              
00179     PyObject *m_function;               
00180     PyObject *m_boundedInstance; 
00181     bool m_boundedMethod;               
00182     QString m_signalName;               
00183 };
00184 
00201 class PythonQtSignalMapperBase : public QObject 
00202 {
00203         Q_OBJECT
00204 public:
00205         PythonQtSignalMapperBase() {}; 
00206 };
00207 
00208 
00209 class PythonQtSignalMapper : public PythonQtSignalMapperBase
00210 {
00211 
00212 public:
00213     PythonQtSignalMapper(unsigned int initSlotCount); 
00214     ~PythonQtSignalMapper();
00215 
00216     bool addSignalHandler(QObject *obj, const char* signal, int sigId, PyObject* callable, IntList &argTypeList);
00217     bool removeSignalHandler(QObject *obj, const char* signal, int sigId, PyObject* callable);
00218     void removeSignalHandlers();
00219     virtual int qt_metacall(QMetaObject::Call c, int id, void **arguments);
00220    
00221 private:
00222     QList<PythonQtSignalTarget> m_targets;      
00223     int m_slotCount;                                            
00224 };
00225 
00226 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends