itom 1.0.14
|
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 ©) : 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