Example #1
0
int SignalProxy::SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {
  _id = QObject::qt_metacall(_c, _id, _a);
  if(_id < 0)
    return _id;

  if(_c == QMetaObject::InvokeMetaMethod) {
    if(_slots.contains(_id)) {
      QObject *caller = sender();

      SignalProxy::ExtendedMetaObject *eMeta = proxy()->extendedMetaObject(caller->metaObject());
      Q_ASSERT(eMeta);

      const Signal &signal = _slots[_id];

      QVariantList params;
      params << signal.signature;

      const QList<int> &argTypes = eMeta->argTypes(signal.signalId);
      for(int i = 0; i < argTypes.size(); i++) {
	if(argTypes[i] == 0) {
	  qWarning() << "SignalRelay::qt_metacall(): received invalid data for argument number" << i << "of signal" << QString("%1::%2").arg(caller->metaObject()->className()).arg(caller->metaObject()->method(_id).signature());
	  qWarning() << "                            - make sure all your data types are known by the Qt MetaSystem";
	  return _id;
	}
	params << QVariant(argTypes[i], _a[i+1]);
      }

      proxy()->dispatchSignal(SignalProxy::RpcCall, params);
    }
    _id -= _slots.count();
  }
  return _id;
}
Example #2
0
int SignalProxy::SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QObject::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;

    if (_c == QMetaObject::InvokeMetaMethod) {
        if (!proxy()->_peers.empty() && _slots.contains(_id)) {

            QObject *caller = sender();

            SignalProxy::ExtendedMetaObject *eMeta = proxy()->extendedMetaObject(caller->metaObject());
            Q_ASSERT(eMeta);

            const Signal &signal = _slots[_id];

            const QList<int> &argTypes = eMeta->argTypes(signal.signalId);

            Peer *remotePeer = 0; // Non-null if we have a specific remove peer to send to
            QSet<Peer *>::ConstIterator peerIt; // If we don't have a specific peer to send to, the first peer. May later be used to iterate over other peers if needed.

            Quassel::Features peerProtocolVersion;

            if (argTypes.size() >= 1 && argTypes[0] == qMetaTypeId<PeerPtr>() && proxy()->proxyMode() == SignalProxy::Server) {
                remotePeer = QVariant(qMetaTypeId<PeerPtr>(), _a[1]).value<PeerPtr>();
                peerProtocolVersion = remotePeer->features();
            } else {
                peerIt = proxy()->_peers.begin();
                peerProtocolVersion = (*peerIt)->features();
            }


            // Compatability: Are our peers at the same level of compatability with each other wrt the message we need to send?
            bool sameMessage = true;
            for (int i = 0; i < argTypes.size(); i++) {
                if (argTypes[i] == 0) {
#if QT_VERSION >= 0x050000
                    qWarning() << "SignalRelay::qt_metacall(): received invalid data for argument number" << i << "of signal" << QString("%1::%2").arg(caller->metaObject()->className()).arg(caller->metaObject()->method(signal.signalId).methodSignature().constData());
#else
                    qWarning() << "SignalRelay::qt_metacall(): received invalid data for argument number" << i << "of signal" << QString("%1::%2").arg(caller->metaObject()->className()).arg(caller->metaObject()->method(signal.signalId).signature());
#endif
                    qWarning() << "                            - make sure all your data types are known by the Qt MetaSystem";
                    return _id;
                }
                if (!remotePeer && proxy()->peerCompatDifferences() & objectCompat->flagsNeeded(i)) {
                    sameMessage = false;
                }
            }
            if (sameMessage) {
                QVariantList params;
                for (int i = 0; i < argTypes.size(); i++) {
                    params << objectCompat->peerCompatibleQVariant(peerProtocolVersion, argTypes[i], _a[i+1]);
                }
                if (remotePeer) {
                    // FIXME: params still includes remotePeer! Are we really sending a pointer value over the network? O_o
                    proxy()->dispatch(remotePeer, RpcCall(signal.signature, params));
                } else if (sameMessage) {
                    // Multiple peers, but they support the same level of compatability for what we're sending them
                    proxy()->dispatch(RpcCall(signal.signature, params));
                }
            } else {
                do {
                    // We have multiple peers, and at least two of them differ on what needs to be sent to each of them.
                    QVariantList params;
                    peerProtocolVersion = (*peerIt)->features();
                    for (int i = 0; i < argTypes.size(); i++) {
                        params << objectCompat->peerCompatibleQVariant(peerProtocolVersion, argTypes[i], _a[i+1]);
                    }
                    proxy()->dispatch(*peerIt, RpcCall(signal.signature, params));
                } while (++peerIt != proxy()->_peers.end());
            }
        }
        _id -= _slots.count();
    }
    return _id;
}