/*! * Creates a binding to the provided signal, slot, or Q_INVOKABLE method using the * provided parameter list. The type of each argument is deduced from the type of * the QVariant. This function cannot bind positional arguments; see the * overload using QGenericArgument. * * If the provided QObject does not implement the requested method, or if the * argument list is incompatible with the method's function signature, this * function returns NULL. * * The returned QxtBoundFunction is created as a child of the receiver. * Changing the parent will result in undefined behavior. * * \sa QxtMetaObject::connect, QxtBoundFunction */ QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QVariant)) { if (!recv) { qWarning() << "QxtMetaObject::bind: cannot connect to null QObject"; return 0; } QVariant* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 }; QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable)); const QMetaObject* meta = recv->metaObject(); int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData())); if (methodID == -1) { qWarning() << "QxtMetaObject::bind: no such method " << recvSlot; return 0; } QMetaMethod method = meta->method(methodID); int argCount = method.parameterTypes().count(); const QList<QByteArray> paramTypes = method.parameterTypes(); for (int i = 0; i < argCount; i++) { if (paramTypes[i] == "QxtBoundArgument") continue; int type = QMetaType::type(paramTypes[i].constData()); if (!args[i]->canConvert((QVariant::Type)type)) { qWarning() << "QxtMetaObject::bind: incompatible parameter list for " << recvSlot; return 0; } } return QxtMetaObject::bind(recv, invokable, QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7), QXT_ARG(8), QXT_ARG(9), QXT_ARG(10)); }
void QxtRPCServicePrivate::dispatchFromClient(quint64 id, const QString& fn, const QVariant& p0, const QVariant& p1, const QVariant& p2, const QVariant& p3, const QVariant& p4, const QVariant& p5, const QVariant& p6, const QVariant& p7) const { // If the received message is not connected to any slots, ignore it. if(!connectedSlots.contains(fn)) return; foreach(const SlotDef& slot, connectedSlots.value(fn)) { // Look up the parameters for each slot based on its metamethod definition. MetaMethodDef method = qMakePair(slot.recv->metaObject(), slot.slot); const QList<QByteArray>& params = slotParameters.value(method); int numParams = params.count(); // Invoke the specified slot on the receiver object using the arguments passed to the function. // See dispatchFromServer() for a discussion of the safety of QXT_ARG here. if(!QMetaObject::invokeMethod(slot.recv, slot.slot.constData(), slot.type, Q_ARG(quint64, id), QXT_ARG(0), QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7))) { qWarning() << "QxtRPCService: invokeMethod for " << slot.recv << "::" << slot.slot << " failed"; } } }
void QxtRPCServicePrivate::dispatchFromServer(const QString& fn, const QVariant& p0, const QVariant& p1, const QVariant& p2, const QVariant& p3, const QVariant& p4, const QVariant& p5, const QVariant& p6, const QVariant& p7) const { // If the received message is not connected to any slots, ignore it. if(!connectedSlots.contains(fn)) return; foreach(const SlotDef& slot, connectedSlots.value(fn)) { // Look up the parameters for each slot based on its metamethod definition. MetaMethodDef method = qMakePair(slot.recv->metaObject(), slot.slot); const QList<QByteArray>& params = slotParameters.value(method); int numParams = params.count(); // Invoke the specified slot on the receiver object using the arguments passed to the function. The // QGenericArgument stuff is done here for safety, as it's not inconceivable (but it IS dangerous) for // different slots to have different parameter lists. if(!QMetaObject::invokeMethod(slot.recv, slot.slot.constData(), slot.type, QXT_ARG(0), QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7))) { qWarning() << "QxtRPCService: invokeMethod for " << slot.recv << "::" << slot.slot << " failed"; } } }