+
+
+// ==================================================
+// ExtendedMetaObject
+// ==================================================
+SignalProxy::ExtendedMetaObject::ExtendedMetaObject(const QMetaObject *meta, bool checkConflicts)
+ : _meta(meta),
+ _updatedRemotelyId(_meta->indexOfSignal("updatedRemotely()"))
+{
+ for(int i = 0; i < _meta->methodCount(); i++) {
+ if(_meta->method(i).methodType() != QMetaMethod::Slot)
+ continue;
+
+ if(QByteArray(_meta->method(i).signature()).contains('*'))
+ continue; // skip methods with ptr params
+
+ QByteArray method = methodName(_meta->method(i));
+ if(method.startsWith("init"))
+ continue; // skip initializers
+
+ if(_methodIds.contains(method)) {
+ /* funny... moc creates for methods containing default parameters multiple metaMethod with separate methodIds.
+ we don't care... we just need the full fledged version
+ */
+ const QMetaMethod ¤t = _meta->method(_methodIds[method]);
+ const QMetaMethod &candidate = _meta->method(i);
+ if(current.parameterTypes().count() > candidate.parameterTypes().count()) {
+ int minCount = candidate.parameterTypes().count();
+ QList<QByteArray> commonParams = current.parameterTypes().mid(0, minCount);
+ if(commonParams == candidate.parameterTypes())
+ continue; // we already got the full featured version
+ } else {
+ int minCount = current.parameterTypes().count();
+ QList<QByteArray> commonParams = candidate.parameterTypes().mid(0, minCount);
+ if(commonParams == current.parameterTypes()) {
+ _methodIds[method] = i; // use the new one
+ continue;
+ }
+ }
+ if(checkConflicts) {
+ qWarning() << "class" << meta->className() << "contains overloaded methods which is currently not supported!";
+ qWarning() << " - " << _meta->method(i).signature() << "conflicts with" << _meta->method(_methodIds[method]).signature();
+ }
+ continue;
+ }
+ _methodIds[method] = i;
+ }
+}
+
+const SignalProxy::ExtendedMetaObject::MethodDescriptor &SignalProxy::ExtendedMetaObject::methodDescriptor(int methodId) {
+ if(!_methods.contains(methodId)) {
+ _methods[methodId] = MethodDescriptor(_meta->method(methodId));
+ }
+ return _methods[methodId];
+}
+
+const QHash<int, int> &SignalProxy::ExtendedMetaObject::receiveMap() {
+ if(_receiveMap.isEmpty()) {
+ QHash<int, int> receiveMap;
+
+ QMetaMethod requestSlot;
+ QByteArray returnTypeName;
+ QByteArray signature;
+ QByteArray methodName;
+ QByteArray params;
+ int paramsPos;
+ int receiverId;
+ const int methodCount = _meta->methodCount();
+ for(int i = 0; i < methodCount; i++) {
+ requestSlot = _meta->method(i);
+ if(requestSlot.methodType() != QMetaMethod::Slot)
+ continue;
+
+ returnTypeName = requestSlot.typeName();
+ if(QMetaType::Void == (QMetaType::Type)returnType(i))
+ continue;
+
+ signature = QByteArray(requestSlot.signature());
+ if(!signature.startsWith("request"))
+ continue;
+
+ paramsPos = signature.indexOf('(');
+ if(paramsPos == -1)
+ continue;
+
+ methodName = signature.left(paramsPos);
+ params = signature.mid(paramsPos);
+
+ methodName = methodName.replace("request", "receive");
+ params = params.left(params.count() - 1) + ", " + returnTypeName + ")";
+
+ signature = QMetaObject::normalizedSignature(methodName + params);
+ receiverId = _meta->indexOfSlot(signature);
+
+ if(receiverId == -1) {
+ signature = QMetaObject::normalizedSignature(methodName + "(" + returnTypeName + ")");
+ receiverId = _meta->indexOfSlot(signature);
+ }
+
+ if(receiverId != -1) {
+ receiveMap[i] = receiverId;
+ }
+ }
+ _receiveMap = receiveMap;
+ }
+ return _receiveMap;
+}
+
+QByteArray SignalProxy::ExtendedMetaObject::methodName(const QMetaMethod &method) {
+ QByteArray sig(method.signature());
+ return sig.left(sig.indexOf("("));
+}
+
+QString SignalProxy::ExtendedMetaObject::methodBaseName(const QMetaMethod &method) {
+ QString methodname = QString(method.signature()).section("(", 0, 0);
+
+ // determine where we have to chop:
+ int upperCharPos;
+ if(method.methodType() == QMetaMethod::Slot) {
+ // we take evertyhing from the first uppercase char if it's slot
+ upperCharPos = methodname.indexOf(QRegExp("[A-Z]"));
+ if(upperCharPos == -1)
+ return QString();
+ methodname = methodname.mid(upperCharPos);
+ } else {
+ // and if it's a signal we discard everything from the last uppercase char
+ upperCharPos = methodname.lastIndexOf(QRegExp("[A-Z]"));
+ if(upperCharPos == -1)
+ return QString();
+ methodname = methodname.left(upperCharPos);
+ }
+
+ methodname[0] = methodname[0].toUpper();
+
+ return methodname;
+}
+
+SignalProxy::ExtendedMetaObject::MethodDescriptor::MethodDescriptor(const QMetaMethod &method)
+ : _methodName(SignalProxy::ExtendedMetaObject::methodName(method)),
+ _returnType(QMetaType::type(method.typeName()))
+{
+ // determine argTypes
+ QList<QByteArray> paramTypes = method.parameterTypes();
+ QList<int> argTypes;
+ for(int i = 0; i < paramTypes.count(); i++) {
+ argTypes.append(QMetaType::type(paramTypes[i]));
+ }
+ _argTypes = argTypes;
+
+ // determine minArgCount
+ QString signature(method.signature());
+ _minArgCount = method.parameterTypes().count() - signature.count("=");
+
+ _receiverMode = (_methodName.startsWith("request"))
+ ? SignalProxy::Server
+ : SignalProxy::Client;
+}
+