itom 1.1.0
|
00001 /* ******************************************************************** 00002 itom software 00003 URL: http://www.uni-stuttgart.de/ito 00004 Copyright (C) 2013, Institut fuer Technische Optik (ITO), 00005 Universitaet 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 #if (defined _DEBUG) && (!defined linux) 00034 #undef _DEBUG 00035 #include "Python.h" 00036 #define _DEBUG 00037 #else 00038 #include "Python.h" 00039 #endif 00040 00041 #include "../global.h" 00042 00043 #include <qvariant.h> 00044 #include <qobject.h> 00045 00046 class PythonQtSignalTarget 00047 { 00048 public: 00049 00051 PythonQtSignalTarget() : 00052 m_slotId(-1), 00053 m_signalId(-1), 00054 m_function(NULL), 00055 m_boundedInstance(NULL), 00056 m_boundedMethod(false) 00057 00058 { 00059 }; 00060 00062 00074 PythonQtSignalTarget(IntList &argTypeList, int slotId, int signalId, PyObject* callable, const char *signal) : 00075 m_slotId(slotId), 00076 m_signalId(signalId), 00077 m_function(NULL), 00078 m_boundedInstance(NULL), 00079 m_boundedMethod(false), 00080 m_signalName(signal) 00081 { 00082 m_argTypeList = argTypeList; 00083 PyObject *temp = NULL; 00084 00085 if(PyMethod_Check(callable)) 00086 { 00087 m_boundedMethod = true; 00088 Py_XDECREF(m_boundedInstance); 00089 Py_XDECREF(m_function); 00090 temp = PyMethod_Self(callable); //borrowed 00091 m_boundedInstance = PyWeakref_NewRef(temp, NULL); //new ref (weak reference used to avoid cyclic garbage collection) 00092 temp = PyMethod_Function(callable); //borrowed 00093 m_function = PyWeakref_NewRef(temp, NULL); //new ref 00094 } 00095 else if(PyFunction_Check(callable)) 00096 { 00097 m_boundedMethod = false; 00098 Py_XDECREF(m_boundedInstance); 00099 Py_XDECREF(m_function); 00100 m_function = PyWeakref_NewRef(callable, NULL); //new ref 00101 } 00102 }; 00103 00105 PythonQtSignalTarget(const PythonQtSignalTarget ©) : 00106 m_slotId(-1), 00107 m_signalId(-1), 00108 m_function(NULL), 00109 m_boundedInstance(NULL), 00110 m_boundedMethod(false), 00111 m_signalName(copy.m_signalName) 00112 { 00113 Py_XDECREF(m_boundedInstance); 00114 Py_XDECREF(m_function); 00115 m_slotId = copy.slotId(); 00116 m_signalId = copy.signalId(); 00117 m_argTypeList = copy.argTypeList(); 00118 00119 m_boundedMethod = copy.m_boundedMethod; 00120 m_function = copy.m_function; 00121 Py_XINCREF(m_function); 00122 m_boundedInstance = copy.m_boundedInstance; 00123 Py_XINCREF(m_boundedInstance); 00124 } 00125 00127 ~PythonQtSignalTarget() 00128 { 00129 Py_XDECREF(m_boundedInstance); 00130 Py_XDECREF(m_function); 00131 m_argTypeList.clear(); 00132 } 00133 00135 inline int signalId() const { return m_signalId; } 00136 00138 inline int slotId() const { return m_slotId; } 00139 00140 // call the python callable with the given arguments (docs see source file) 00141 void call(void ** arguments) const; 00142 00144 inline IntList argTypeList() const { return m_argTypeList; }; 00145 00147 00154 bool isSame(int signalId, PyObject* callable) const 00155 { 00156 if(signalId == m_signalId) 00157 { 00158 if(PyMethod_Check(callable)) 00159 { 00160 return PyMethod_Self(callable) == PyWeakref_GetObject(m_boundedInstance) && PyMethod_Function(callable) == PyWeakref_GetObject(m_function); 00161 } 00162 return callable == PyWeakref_GetObject(m_function); 00163 } 00164 return false; 00165 } 00166 00167 private: 00168 int m_slotId; 00169 int m_signalId; 00170 IntList m_argTypeList; 00171 PyObject *m_function; 00172 PyObject *m_boundedInstance; 00173 bool m_boundedMethod; 00174 QString m_signalName; 00175 }; 00176 00193 class PythonQtSignalMapperBase : public QObject 00194 { 00195 Q_OBJECT 00196 public: 00197 PythonQtSignalMapperBase() {}; 00198 }; 00199 00200 00201 class PythonQtSignalMapper : public PythonQtSignalMapperBase 00202 { 00203 00204 public: 00205 PythonQtSignalMapper(unsigned int initSlotCount); 00206 ~PythonQtSignalMapper(); 00207 00208 bool addSignalHandler(QObject *obj, const char* signal, int sigId, PyObject* callable, IntList &argTypeList); 00209 bool removeSignalHandler(QObject *obj, const char* signal, int sigId, PyObject* callable); 00210 void removeSignalHandlers(); 00211 virtual int qt_metacall(QMetaObject::Call c, int id, void **arguments); 00212 00213 private: 00214 QList<PythonQtSignalTarget> m_targets; 00215 int m_slotCount; 00216 }; 00217 00218 #endif