示例#1
0
    //service side
    void setupSignalIntercepters(QObject * service)
    {
        Q_ASSERT(endPointType == ObjectEndPoint::Service);

        //create a signal intercepter for each signal
        //offered by service 
        //exclude QObject signals
        const QMetaObject* mo = service->metaObject();
        while (mo && strcmp(mo->className(), "QObject"))
        {
            for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
                const QMetaMethod method = mo->method(i);
                if (method.methodType() == QMetaMethod::Signal) {
                    QByteArray signal = method.signature();
                    //add '2' for signal - see QSIGNAL_CODE
                    ServiceSignalIntercepter* intercept = 
                        new ServiceSignalIntercepter(service, "2"+signal, parent );
                    intercept->setMetaIndex(i);
                }
            }
            mo = mo->superClass();
        }
    }
/*!
    Client requests proxy object. The proxy is owned by calling
    code and this object must clean itself up upon destruction of
    proxy.
*/
QObject* ObjectEndPoint::constructProxy(const QRemoteServiceRegister::Entry& entry)
{
    // Client side
    Q_ASSERT(d->endPointType == ObjectEndPoint::Client);

    // Request a serialized meta object
    QServicePackage p;
    p.d = new QServicePackagePrivate();
    p.d->messageId = QUuid::createUuid();
    p.d->entry = entry;

    Response* response = new Response();
    openRequests()->insert(p.d->messageId, response);

    dispatch->writePackage(p);
    waitForResponse(p.d->messageId);

    // Get the proxy based on the meta object
    if (response->isFinished) {
        if (response->result == 0)
            qWarning() << "Request for remote service failed";
        else
            service = reinterpret_cast<QServiceProxy* >(response->result);
    } else {
        qDebug() << "response passed but not finished";
    }

    openRequests()->take(p.d->messageId);
    delete response;

    if (!service)
        return 0;

    // Connect all DBus interface signals to the proxy slots
    const QMetaObject *mo = service->metaObject();
    while (mo && strcmp(mo->className(), "QObject")) {
        for (int i = mo->methodOffset(); i < mo->methodCount(); i++) {
            const QMetaMethod mm = mo->method(i);
            if (mm.methodType() == QMetaMethod::Signal) {
                QByteArray sig(mm.methodSignature());

                bool customType = false;

                QList<QByteArray> params = mm.parameterTypes();
                for (int arg = 0; arg < params.size(); arg++) {
                    const QByteArray& type = params[arg];
                    int variantType = QMetaType::type(type);
                    if (variantType >= QMetaType::User || variantType == QMetaType::QVariant) {
                        sig.replace(QByteArray(type), QByteArray("QDBusVariant"));
                        customType = true;
                    }
                }

                int serviceIndex = iface->metaObject()->indexOfSignal(sig);
                QByteArray signal = QByteArray("2").append(sig);

                if (serviceIndex > 0) {
                    if (customType) {
                        QObject::connect(iface, signal.constData(), signalsObject, signal.constData());

                        ServiceSignalIntercepter *intercept =
                            new ServiceSignalIntercepter((QObject*)signalsObject, signal, this);
                        intercept->setMetaIndex(localToRemote[i]);
                    } else {
                        QObject::connect(iface, signal.constData(), service, signal.constData());
                    }
                }
            }
        }
        mo = mo->superClass();
    }

    return service;
}