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; }
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; }