PythonQt
PythonQtMethodInfo.h
Go to the documentation of this file.
1 #ifndef _PYTHONQTMETHODINFO_H
2 #define _PYTHONQTMETHODINFO_H
3 
4 /*
5  *
6  * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * Further, this software is distributed without any warranty that it is
19  * free of the rightful claim of any third person regarding infringement
20  * or the like. Any license provided herein, whether implied or
21  * otherwise, applies only to this software file. Patent licenses, if
22  * any, provided herein do not apply to combinations of this program with
23  * other software, or any other product whatsoever.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28  *
29  * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
30  * 28359 Bremen, Germany or:
31  *
32  * http://www.mevis.de
33  *
34  */
35 
36 //----------------------------------------------------------------------------------
43 //----------------------------------------------------------------------------------
44 
45 #include "PythonQtPythonInclude.h"
46 #include "PythonQtSystem.h"
47 
48 #include <QByteArray>
49 #include <QHash>
50 #include <QList>
51 #include <QMetaMethod>
52 
53 class PythonQtClassInfo;
54 struct _object;
55 typedef struct _object PyObject;
56 
59 {
60 public:
62  Unknown = -1,
63  Variant = -2
64  };
65 
67  struct ParameterInfo {
68  QByteArray name;
69  QByteArray innerName; // if the type is a template, this stores the inner name
70  PyObject* enumWrapper; // if it is an enum, a pointer to the enum wrapper
71  int typeId; // a mixture from QMetaType and ParameterType
72  char pointerCount; // the number of pointer indirections
73  char innerNamePointerCount; // the number of pointer indirections in the inner name
74  bool isConst;
76  bool isQList;
80  };
81 
83  _shouldAllowThreads = true;
84  };
86  PythonQtMethodInfo(const QMetaMethod& meta, PythonQtClassInfo* classInfo);
87  PythonQtMethodInfo(const QByteArray& typeName, const QList<QByteArray>& args);
89  _parameters = other._parameters;
90  _shouldAllowThreads = other._shouldAllowThreads;
91  }
92 
95  static const PythonQtMethodInfo* getCachedMethodInfo(const QMetaMethod& method, PythonQtClassInfo* classInfo);
96 
98  static const PythonQtMethodInfo* getCachedMethodInfoFromArgumentList(int numArgs, const char** args);
99 
102 
104  int parameterCount() const { return _parameters.size(); };
105 
107  static int nameToType(const char* name);
108 
110  const QList<ParameterInfo>& parameters() const { return _parameters; }
111 
113  static void addParameterTypeAlias(const QByteArray& alias, const QByteArray& name);
114 
116  static void fillParameterInfo(ParameterInfo& type, const QByteArray& name, PythonQtClassInfo* classInfo = nullptr);
117 
120 
122  static int getInnerTemplateMetaType(const QByteArray& typeName);
123 
125  static QByteArray getInnerTemplateTypeName(const QByteArray& typeName);
126 
128  static QByteArray getInnerListTypeName(const QByteArray& typeName);
129 
133  bool shouldAllowThreads() const { return _shouldAllowThreads; }
134 
135 protected:
137 
138  static QHash<QByteArray, int> _parameterTypeDict;
139  static QHash<QByteArray, QByteArray> _parameterNameAliases;
140 
142  static QHash<QByteArray, PythonQtMethodInfo*> _cachedSignatures;
143 
144  static QHash<int, ParameterInfo> _cachedParameterInfos;
145 
146  QList<ParameterInfo> _parameters;
148 
149 };
150 
153 {
154 public:
155  enum Type {
156  MemberSlot, InstanceDecorator, ClassDecorator
157  };
158 
160  _meta = info._meta;
161  _parameters = info._parameters;
162  _shouldAllowThreads = info._shouldAllowThreads;
163  _slotIndex = info._slotIndex;
164  _next = nullptr;
165  _decorator = info._decorator;
166  _type = info._type;
167  _upcastingOffset = 0;
168  }
169 
170  PythonQtSlotInfo(PythonQtClassInfo* classInfo, const QMetaMethod& meta, int slotIndex, QObject* decorator = nullptr, Type type = MemberSlot ):PythonQtMethodInfo()
171  {
172  const PythonQtMethodInfo* info = getCachedMethodInfo(meta, classInfo);
173  _meta = meta;
174  _parameters = info->parameters();
175  _shouldAllowThreads = info->shouldAllowThreads();
176  _slotIndex = slotIndex;
177  _next = nullptr;
178  _decorator = decorator;
179  _type = type;
180  _upcastingOffset = 0;
181  }
182 
183 
184 public:
186  QList<ParameterInfo> arguments() const;
187 
189 
190  const QMetaMethod* metaMethod() const { return &_meta; }
191 
192  void setUpcastingOffset(int upcastingOffset) { _upcastingOffset = upcastingOffset; }
193 
194  int upcastingOffset() const { return _upcastingOffset; }
195 
197  int slotIndex() const { return _slotIndex; }
198 
200  PythonQtSlotInfo* nextInfo() const { return _next; }
201 
203  void setNextInfo(PythonQtSlotInfo* next) { _next = next; }
204 
206  bool isInstanceDecorator() const { return _decorator!=nullptr && _type == InstanceDecorator; }
207 
209  bool isClassDecorator() const { return _decorator!=nullptr && _type == ClassDecorator; }
210 
211  QObject* decorator() const { return _decorator; }
212 
214  QString fullSignature(bool skipReturnValue = false, int optionalArgsIndex = -1) const;
215 
217  QByteArray signature() const;
218 
220  QByteArray slotName(bool removeDecorators = false) const;
221 
225  QStringList overloads(bool skipReturnValue = false) const;
226 
229  QByteArray getImplementingClassName() const;
230 
232  static void invokeQtMethod(QObject* obj, PythonQtSlotInfo* slot, void** argList);
233 
235  static void setGlobalShouldAllowThreads(bool flag);
236 
239 
240 private:
241  int _slotIndex;
242  PythonQtSlotInfo* _next;
243  QObject* _decorator;
244  Type _type;
245  QMetaMethod _meta;
246  int _upcastingOffset;
247 
248  static bool _globalShouldAllowThreads;
249 };
250 
251 
252 #endif
struct _object PyObject
#define PYTHONQT_EXPORT
a class that stores all required information about a Qt object (and an optional associated C++ class ...
stores information about a specific signal/slot/method
static const ParameterInfo & getParameterInfoForMetaType(int type)
returns a parameter info for the given metatype (and creates and caches one if it is not yet present)
static QByteArray getInnerTemplateTypeName(const QByteArray &typeName)
returns the inner type name of a simple template of the form SomeObject<InnerType>
static void addParameterTypeAlias(const QByteArray &alias, const QByteArray &name)
add an alias for a typename, e.g. QObjectList and QList<QObject*>.
static QHash< QByteArray, QByteArray > _parameterNameAliases
static int getInnerTemplateMetaType(const QByteArray &typeName)
returns the inner type id of a simple template of the form SomeObject<InnerType>
static QHash< QByteArray, int > _parameterTypeDict
static QByteArray getInnerListTypeName(const QByteArray &typeName)
returns the inner type name of a simple template or the typename without appended "List".
const QList< ParameterInfo > & parameters() const
get the parameter infos
static void cleanupCachedMethodInfos()
cleanup the cache
PythonQtMethodInfo(const QByteArray &typeName, const QList< QByteArray > &args)
PythonQtMethodInfo(const PythonQtMethodInfo &other)
QList< ParameterInfo > _parameters
static const PythonQtMethodInfo * getCachedMethodInfoFromArgumentList(int numArgs, const char **args)
get the cached method info using the passed in list of return value and arguments,...
static QHash< int, ParameterInfo > _cachedParameterInfos
int parameterCount() const
returns the number of parameters including the return value
static int nameToType(const char *name)
returns the id for the given type (using an internal dictionary)
static void fillParameterInfo(ParameterInfo &type, const QByteArray &name, PythonQtClassInfo *classInfo=nullptr)
fill the parameter info for the given type name
static QHash< QByteArray, PythonQtMethodInfo * > _cachedSignatures
stores the cached signatures of methods to speedup mapping from Qt to Python types
static const PythonQtMethodInfo * getCachedMethodInfo(const QMetaMethod &method, PythonQtClassInfo *classInfo)
bool shouldAllowThreads() const
PythonQtMethodInfo(const QMetaMethod &meta, PythonQtClassInfo *classInfo)
stores information about a slot, including a next pointer to overloaded slots
PythonQtSlotInfo(PythonQtClassInfo *classInfo, const QMetaMethod &meta, int slotIndex, QObject *decorator=nullptr, Type type=MemberSlot)
QByteArray getImplementingClassName() const
QStringList overloads(bool skipReturnValue=false) const
int slotIndex() const
get the index of the slot (needed for qt_metacall)
QList< ParameterInfo > arguments() const
get the parameter infos for the arguments, without return type and instance decorator.
QString fullSignature(bool skipReturnValue=false, int optionalArgsIndex=-1) const
get the full signature including return type
static bool getGlobalShouldAllowThreads()
Returns if calling slots should release the GIL to allow Python threads while being inside of C++.
QByteArray slotName(bool removeDecorators=false) const
get the short slot name
static void invokeQtMethod(QObject *obj, PythonQtSlotInfo *slot, void **argList)
Invoke the given slot on obj, save/restore thread state if needed.
bool isInstanceDecorator() const
returns if the slot is a decorator slot
void setNextInfo(PythonQtSlotInfo *next)
set the next overloaded slot
QByteArray signature() const
get the Qt signature of the slot
bool isClassDecorator() const
returns if the slot is a constructor slot
static void setGlobalShouldAllowThreads(bool flag)
Sets if calling slots should release the GIL to allow other Python threads while being inside of C++.
void setUpcastingOffset(int upcastingOffset)
void deleteOverloadsAndThis()
PythonQtSlotInfo(const PythonQtSlotInfo &info)
const QMetaMethod * metaMethod() const
QObject * decorator() const
PythonQtSlotInfo * nextInfo() const
get next overloaded slot (which has the same name)
int upcastingOffset() const
QByteArray typeName(const QMetaMethod &method)
Definition: PythonQtUtils.h:72
stores various informations about a parameter/type name