aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp')
-rw-r--r--sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp148
1 files changed, 53 insertions, 95 deletions
diff --git a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
index a042ac2cc..acb733f73 100644
--- a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
+++ b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
@@ -51,56 +51,19 @@
#include "pyside2_qtquick_python.h"
#include "pyside2_qtqml_python.h"
-#ifndef PYSIDE_MAX_QUICK_TYPES
-// Maximum number of different Qt Quick types the user can export to QML using
-// qmlRegisterType. This limit exists because the QML engine instantiates objects
-// by calling a function with one argument (a void* pointer where the object should
-// be created), and thus does not allow us to choose which object to create. Thus
-// we create a C++ factory function for each new registered type at compile time.
-# define PYSIDE_MAX_QUICK_TYPES 50
-#endif // !PYSIDE_MAX_QUICK_TYPES
-
-// All registered python types and their creation functions.
-static PyObject *pyTypes[PYSIDE_MAX_QUICK_TYPES];
-static void (*createFuncs[PYSIDE_MAX_QUICK_TYPES])(void *);
-
// Mutex used to avoid race condition on PySide::nextQObjectMemoryAddr.
static QMutex nextQmlElementMutex;
-// Python object factory functions.
-template<int N>
-struct ElementFactoryBase
-{
- static void createQuickItem(void *memory)
- {
- QMutexLocker locker(&nextQmlElementMutex);
- PySide::setNextQObjectMemoryAddr(memory);
- Shiboken::GilState state;
- PyObject *obj = PyObject_CallObject(pyTypes[N], 0);
- if (!obj || PyErr_Occurred())
- PyErr_Print();
- PySide::setNextQObjectMemoryAddr(0);
- }
-};
-
-template<int N>
-struct ElementFactory : ElementFactoryBase<N>
-{
- static void init()
- {
- createFuncs[N] = &ElementFactoryBase<N>::createQuickItem;
- ElementFactory<N-1>::init();
- }
-};
-
-template<>
-struct ElementFactory<0> : ElementFactoryBase<0>
+static void createQuickItem(void *memory, void *type)
{
- static void init()
- {
- createFuncs[0] = &ElementFactoryBase<0>::createQuickItem;
- }
-};
+ QMutexLocker locker(&nextQmlElementMutex);
+ PySide::setNextQObjectMemoryAddr(memory);
+ Shiboken::GilState state;
+ PyObject *obj = PyObject_CallObject(reinterpret_cast<PyObject *>(type), 0);
+ if (!obj || PyErr_Occurred())
+ PyErr_Print();
+ PySide::setNextQObjectMemoryAddr(0);
+}
#define PY_REGISTER_IF_INHERITS_FROM(className, typeToRegister,typePointerName, \
typeListName, typeMetaObject, type, registered) \
@@ -117,6 +80,40 @@ bool pyTypeObjectInheritsFromClass(PyTypeObject *pyObjType, QByteArray className
return isDerived;
}
+template <typename T>
+struct QPysideQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface
+{
+ const QByteArray name;
+
+ QPysideQmlMetaTypeInterface(const QByteArray &name, const QMetaObject *metaObject = nullptr)
+ : QMetaTypeInterface {
+ /*.revision=*/ 0,
+ /*.alignment=*/ alignof(T),
+ /*.size=*/ sizeof(T),
+ /*.flags=*/ QtPrivate::QMetaTypeTypeFlags<T>::Flags,
+ /*.typeId=*/ 0,
+ /*.metaObject=*/ metaObject,
+ /*.name=*/ name.constData(),
+ /*.defaultCtr=*/ [](const QMetaTypeInterface *, void *addr) { new (addr) T(); },
+ /*.copyCtr=*/ [](const QMetaTypeInterface *, void *addr, const void *other) {
+ new (addr) T(*reinterpret_cast<const T *>(other));
+ },
+ /*.moveCtr=*/ [](const QMetaTypeInterface *, void *addr, void *other) {
+ new (addr) T(std::move(*reinterpret_cast<T *>(other)));
+ },
+ /*.dtor=*/ [](const QMetaTypeInterface *, void *addr) {
+ reinterpret_cast<T *>(addr)->~T();
+ },
+ /*.equals=*/ nullptr,
+ /*.lessThan=*/ nullptr,
+ /*.debugStream=*/ nullptr,
+ /*.dataStreamOut=*/ nullptr,
+ /*.dataStreamIn=*/ nullptr,
+ /*.legacyRegisterOp=*/ nullptr
+ }
+ , name(name) {}
+};
+
template <class WrapperClass>
void registerTypeIfInheritsFromClass(
QByteArray className,
@@ -129,40 +126,11 @@ void registerTypeIfInheritsFromClass(
{
bool shouldRegister = !registered && pyTypeObjectInheritsFromClass(typeToRegister, className);
if (shouldRegister) {
- int ptrType =
- QMetaType::registerNormalizedType(
- typePointerName.constData(),
- QtMetaTypePrivate::QMetaTypeFunctionHelper<WrapperClass *>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<WrapperClass *>::Construct,
- sizeof(WrapperClass *),
- static_cast< ::QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<
- WrapperClass *>::Flags),
- typeMetaObject);
- if (ptrType == -1) {
- PyErr_Format(PyExc_TypeError, "Meta type registration of \"%s\" for QML usage failed.",
- typePointerName.constData());
- return;
- }
+ QMetaType ptrType(new QPysideQmlMetaTypeInterface<WrapperClass *>(typePointerName, typeMetaObject));
+ QMetaType lstType(new QPysideQmlMetaTypeInterface<QQmlListProperty<WrapperClass>>(typeListName));
- int lstType =
- QMetaType::registerNormalizedType(
- typeListName.constData(),
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<WrapperClass> >
- ::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<WrapperClass> >
- ::Construct,
- sizeof(QQmlListProperty<WrapperClass>),
- static_cast< ::QFlags<QMetaType::TypeFlag> >(
- QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<WrapperClass> >::Flags),
- nullptr);
- if (lstType == -1) {
- PyErr_Format(PyExc_TypeError, "Meta type registration of \"%s\" for QML usage failed.",
- typeListName.constData());
- return;
- }
-
- type->typeId = ptrType;
- type->listId = lstType;
+ type->typeId = std::move(ptrType);
+ type->listId = std::move(lstType);
type->attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc<WrapperClass>();
type->attachedPropertiesMetaObject =
QQmlPrivate::attachedPropertiesMetaObject<WrapperClass>();
@@ -178,16 +146,9 @@ void registerTypeIfInheritsFromClass(
}
bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int versionMinor,
- const char *qmlName, QQmlPrivate::RegisterType *type)
+ const char *qmlName, bool creatable, const char *noCreationReason, QQmlPrivate::RegisterType *type)
{
using namespace Shiboken;
- static int nextType = 0;
-
- if (nextType >= PYSIDE_MAX_QUICK_TYPES) {
- PyErr_Format(PyExc_TypeError,
- "You can only export %d Qt Quick types to QML.", PYSIDE_MAX_QUICK_TYPES);
- return false;
- }
PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
PyTypeObject *qQuickItemPyType =
@@ -208,8 +169,6 @@ bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int v
// there's no way to unregister a QML type.
Py_INCREF(pyObj);
- pyTypes[nextType] = pyObj;
-
// Used in macro registration.
QByteArray pointerName(qmlName);
pointerName.append('*');
@@ -227,11 +186,12 @@ bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int v
if (!registered)
return false;
- type->create = createFuncs[nextType];
- type->version = 0;
+ type->structVersion = 0;
+ type->create = creatable ? createQuickItem : nullptr;
+ type->noCreationReason = noCreationReason;
+ type->userdata = pyObj;
type->uri = uri;
- type->versionMajor = versionMajor;
- type->versionMinor = versionMinor;
+ type->version = QTypeRevision::fromVersion(versionMajor, versionMinor);
type->elementName = qmlName;
type->metaObject = metaObject;
@@ -239,14 +199,12 @@ bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int v
type->extensionMetaObject = 0;
type->customParser = 0;
- ++nextType;
return true;
}
void PySide::initQuickSupport(PyObject *module)
{
Q_UNUSED(module);
- ElementFactory<PYSIDE_MAX_QUICK_TYPES - 1>::init();
#ifdef PYSIDE_QML_SUPPORT
setQuickRegisterItemFunction(quickRegisterType);
#endif