| 1 | // Copyright (C) 2017 Ford Motor Company |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
| 3 | |
| 4 | #ifndef QREMOTEOBJECTSOURCE_H |
| 5 | #define QREMOTEOBJECTSOURCE_H |
| 6 | |
| 7 | #include <QtCore/qscopedpointer.h> |
| 8 | #include <QtRemoteObjects/qtremoteobjectglobal.h> |
| 9 | #include <QtCore/qmetaobject.h> |
| 10 | |
| 11 | QT_BEGIN_NAMESPACE |
| 12 | |
| 13 | namespace QtPrivate { |
| 14 | |
| 15 | //Based on compile time checks for static connect() from qobjectdefs_impl.h |
| 16 | template <class ObjectType, typename Func1, typename Func2> |
| 17 | static inline int qtro_property_index(Func1, Func2, const char *propName) |
| 18 | { |
| 19 | typedef QtPrivate::FunctionPointer<Func1> Type1; |
| 20 | typedef QtPrivate::FunctionPointer<Func2> Type2; |
| 21 | |
| 22 | //compilation error if the arguments do not match. |
| 23 | Q_STATIC_ASSERT_X(int(Type1::ArgumentCount) >= int(Type2::ArgumentCount), |
| 24 | "Argument counts are not compatible." ); |
| 25 | Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename Type1::Arguments, typename Type2::Arguments>::value), |
| 26 | "Arguments are not compatible." ); |
| 27 | Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename Type1::ReturnType, typename Type2::ReturnType>::value), |
| 28 | "Return types are not compatible." ); |
| 29 | return ObjectType::staticMetaObject.indexOfProperty(propName); |
| 30 | } |
| 31 | |
| 32 | template <class ObjectType, typename Func1, typename Func2> |
| 33 | static inline int qtro_signal_index(Func1 func, Func2, int *count, int const **types) |
| 34 | { |
| 35 | typedef QtPrivate::FunctionPointer<Func1> Type1; |
| 36 | typedef QtPrivate::FunctionPointer<Func2> Type2; |
| 37 | |
| 38 | //compilation error if the arguments do not match. |
| 39 | Q_STATIC_ASSERT_X(int(Type1::ArgumentCount) >= int(Type2::ArgumentCount), |
| 40 | "Argument counts are not compatible." ); |
| 41 | Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename Type1::Arguments, typename Type2::Arguments>::value), |
| 42 | "Arguments are not compatible." ); |
| 43 | Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename Type1::ReturnType, typename Type2::ReturnType>::value), |
| 44 | "Return types are not compatible." ); |
| 45 | const QMetaMethod sig = QMetaMethod::fromSignal(func); |
| 46 | *count = Type2::ArgumentCount; |
| 47 | *types = QtPrivate::ConnectionTypes<typename Type2::Arguments>::types(); |
| 48 | return sig.methodIndex(); |
| 49 | } |
| 50 | |
| 51 | template <class ObjectType, typename Func1, typename Func2> |
| 52 | static inline void qtro_method_test(Func1, Func2) |
| 53 | { |
| 54 | typedef QtPrivate::FunctionPointer<Func1> Type1; |
| 55 | typedef QtPrivate::FunctionPointer<Func2> Type2; |
| 56 | |
| 57 | //compilation error if the arguments do not match. |
| 58 | Q_STATIC_ASSERT_X(int(Type1::ArgumentCount) >= int(Type2::ArgumentCount), |
| 59 | "Argument counts are not compatible." ); |
| 60 | Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename Type1::Arguments, typename Type2::Arguments>::value), |
| 61 | "Arguments are not compatible." ); |
| 62 | Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename Type1::ReturnType, typename Type2::ReturnType>::value), |
| 63 | "Return types are not compatible." ); |
| 64 | } |
| 65 | |
| 66 | Q_REMOTEOBJECTS_EXPORT |
| 67 | int qtro_method_index_impl(const QMetaObject *staticMetaObj, const char *className, |
| 68 | const char *methodName, int *count, const int **types); |
| 69 | |
| 70 | template <class ObjectType, typename Func1, typename Func2> |
| 71 | static inline int qtro_method_index(Func1, Func2, const char *methodName, int *count, int const **types) |
| 72 | { |
| 73 | typedef QtPrivate::FunctionPointer<Func1> Type1; |
| 74 | typedef QtPrivate::FunctionPointer<Func2> Type2; |
| 75 | |
| 76 | //compilation error if the arguments do not match. |
| 77 | Q_STATIC_ASSERT_X(int(Type1::ArgumentCount) >= int(Type2::ArgumentCount), |
| 78 | "Argument counts are not compatible." ); |
| 79 | Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename Type1::Arguments, typename Type2::Arguments>::value), |
| 80 | "Arguments are not compatible." ); |
| 81 | Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename Type1::ReturnType, typename Type2::ReturnType>::value), |
| 82 | "Return types are not compatible." ); |
| 83 | *count = Type2::ArgumentCount; |
| 84 | *types = QtPrivate::ConnectionTypes<typename Type2::Arguments>::types(); |
| 85 | |
| 86 | return qtro_method_index_impl(&ObjectType::staticMetaObject, |
| 87 | ObjectType::staticMetaObject.className(), methodName, count, |
| 88 | types); |
| 89 | } |
| 90 | |
| 91 | template <class ObjectType> |
| 92 | static inline QByteArray qtro_enum_signature(const char *enumName) |
| 93 | { |
| 94 | const auto qme = ObjectType::staticMetaObject.enumerator(ObjectType::staticMetaObject.indexOfEnumerator(enumName)); |
| 95 | return QByteArrayLiteral("1::2" ).replace("1" , qme.scope()).replace("2" , qme.name()); |
| 96 | } |
| 97 | |
| 98 | QByteArray qtro_classinfo_signature(const QMetaObject *metaObject); |
| 99 | |
| 100 | } |
| 101 | |
| 102 | // TODO ModelInfo just needs roles, and no need for SubclassInfo |
| 103 | class QAbstractItemModel; |
| 104 | |
| 105 | struct ModelInfo |
| 106 | { |
| 107 | QAbstractItemModel *ptr; |
| 108 | QString name; |
| 109 | QByteArray roles; |
| 110 | }; |
| 111 | |
| 112 | class Q_REMOTEOBJECTS_EXPORT SourceApiMap |
| 113 | { |
| 114 | protected: |
| 115 | SourceApiMap() {} |
| 116 | public: |
| 117 | virtual ~SourceApiMap(); |
| 118 | virtual QString name() const = 0; |
| 119 | virtual QString typeName() const = 0; |
| 120 | virtual QByteArray className() const { return typeName().toLatin1().append(s: "Source" ); } |
| 121 | virtual int enumCount() const = 0; |
| 122 | virtual int propertyCount() const = 0; |
| 123 | virtual int signalCount() const = 0; |
| 124 | virtual int methodCount() const = 0; |
| 125 | virtual int sourceEnumIndex(int index) const = 0; |
| 126 | virtual int sourcePropertyIndex(int index) const = 0; |
| 127 | virtual int sourceSignalIndex(int index) const = 0; |
| 128 | virtual int sourceMethodIndex(int index) const = 0; |
| 129 | virtual int signalParameterCount(int index) const = 0; |
| 130 | virtual int signalParameterType(int sigIndex, int paramIndex) const = 0; |
| 131 | virtual const QByteArray signalSignature(int index) const = 0; |
| 132 | virtual QByteArrayList signalParameterNames(int index) const = 0; |
| 133 | virtual int methodParameterCount(int index) const = 0; |
| 134 | virtual int methodParameterType(int methodIndex, int paramIndex) const = 0; |
| 135 | virtual const QByteArray methodSignature(int index) const = 0; |
| 136 | virtual QMetaMethod::MethodType methodType(int index) const = 0; |
| 137 | virtual const QByteArray typeName(int index) const = 0; |
| 138 | virtual QByteArrayList methodParameterNames(int index) const = 0; |
| 139 | virtual int propertyIndexFromSignal(int index) const = 0; |
| 140 | virtual int propertyRawIndexFromSignal(int index) const = 0; |
| 141 | virtual QByteArray objectSignature() const = 0; |
| 142 | virtual bool isDynamic() const { return false; } |
| 143 | virtual bool isAdapterSignal(int) const { return false; } |
| 144 | virtual bool isAdapterMethod(int) const { return false; } |
| 145 | virtual bool isAdapterProperty(int) const { return false; } |
| 146 | QList<ModelInfo> m_models; |
| 147 | QList<SourceApiMap *> m_subclasses; |
| 148 | }; |
| 149 | |
| 150 | QT_END_NAMESPACE |
| 151 | |
| 152 | #endif |
| 153 | |