📄 qscriptextqobject.cpp
字号:
// perfect break; default: matchDistance += 10; break; } } else if (actual.isBoolean()) { switch (tid) { case QMetaType::Bool: // perfect break; default: matchDistance += 10; break; } } else if (actual.isDate()) { switch (tid) { case QMetaType::QDateTime: // perfect break; case QMetaType::QDate: matchDistance += 1; break; case QMetaType::QTime: matchDistance += 2; break; default: matchDistance += 10; break; } } else if (actual.isRegExp()) { switch (tid) { case QMetaType::QRegExp: // perfect break; default: matchDistance += 10; break; } } else if (actual.isVariant()) { if (actual.variantValue().userType() || argType.isVariant()) { // perfect } else { matchDistance += 10; } } else if (actual.isQObject()) { switch (tid) { case QMetaType::QObjectStar: case QMetaType::QWidgetStar: // perfect break; default: matchDistance += 10; break; } } else { matchDistance += 10; } } if (converted) args[i+1] = v; } if (converted) { if ((context->argumentCount() == mtd.argumentCount()) && (matchDistance == 0)) { // perfect match, use this one chosenMethod = mtd; chosenIndex = index; break; } else { candidates.append(QScriptMetaArguments(matchDistance, index, mtd, args)); } } if (!m_maybeOverloaded) break; } if ((chosenIndex == -1) && candidates.isEmpty()) { // conversion failed, or incorrect number of arguments result = context->throwError( QScriptContext::SyntaxError, QString::fromUtf8("incorrect number or type of arguments in call to %0::%1()") .arg(QLatin1String(meta->className())) .arg(QLatin1String(funName))); } else { if (chosenIndex == -1) { // pick the best match int dist = INT_MAX; args.clear(); for (int i = 0; i < candidates.size(); ++i) { QScriptMetaArguments cdt = candidates.at(i); if (cdt.method.fullyResolved() && ((cdt.args.count() > args.count()) || ((cdt.args.count() == args.count()) && (cdt.matchDistance < dist)))) { dist = cdt.matchDistance; chosenMethod = cdt.method; chosenIndex = cdt.index; args = cdt.args; } } } if (chosenIndex != -1) { // call it QVarLengthArray<void*, 9> array(args.count()); void **params = array.data(); for (int i = 0; i < args.count(); ++i) { const QVariant &v = args[i]; switch (chosenMethod.type(i).kind()) { case QScriptMetaType::Variant: params[i] = const_cast<QVariant*>(&v); break; case QScriptMetaType::MetaType: case QScriptMetaType::MetaEnum: params[i] = const_cast<void*>(v.constData()); break; default: Q_ASSERT(0); } } QScriptable *scriptable = scriptableFromQObject(thisQObject); QScriptEngine *oldEngine = 0; if (scriptable) { oldEngine = QScriptablePrivate::get(scriptable)->engine; QScriptablePrivate::get(scriptable)->engine = eng; } thisQObject->qt_metacall(QMetaObject::InvokeMetaMethod, chosenIndex, params); if (scriptable) QScriptablePrivate::get(scriptable)->engine = oldEngine; if (context->state() == QScriptContext::ExceptionState) { result = context->returnValue(); // propagate } else { QScriptMetaType retType = chosenMethod.returnType(); if (retType.typeId() != 0) { result = eng_p->create(retType.typeId(), params[0]); if (!result.isValid()) result = eng_p->newVariant(QVariant(retType.typeId(), params[0])); } else if (retType.isVariant()) { result = eng_p->newVariant(*(QVariant *)params[0]); } else { result = eng_p->undefinedValue(); } } } else { // one or more types are unresolved QScriptMetaArguments argsInstance = candidates.first(); int unresolvedIndex = argsInstance.method.firstUnresolvedIndex(); Q_ASSERT(unresolvedIndex != -1); QScriptMetaType unresolvedType = argsInstance.method.type(unresolvedIndex); result = context->throwError( QScriptContext::TypeError, QString::fromUtf8("cannot call %0::%1(): unknown type `%2'") .arg(QLatin1String(meta->className())) .arg(QString::fromLatin1(funName)) .arg(QLatin1String(unresolvedType.name()))); } } context->m_result = result;}bool QScript::QtFunction::createConnection(const QScriptValueImpl &self, const QScriptValueImpl &receiver, const QScriptValueImpl &slot){ Q_ASSERT(slot.isFunction()); const QMetaObject *meta = m_object->metaObject(); int index = m_initialIndex; QMetaMethod method = meta->method(index); if (maybeOverloaded() && (method.attributes() & QMetaMethod::Cloned)) { // find the most general method do { method = meta->method(--index); } while (method.attributes() & QMetaMethod::Cloned); } QObject *conn = new ConnectionQObject(method, self, receiver, slot); m_connections.append(conn); return QMetaObject::connect(m_object, index, conn, conn->metaObject()->methodOffset());}bool QScript::QtFunction::destroyConnection(const QScriptValueImpl &, const QScriptValueImpl &receiver, const QScriptValueImpl &slot){ Q_ASSERT(slot.isFunction()); // find the connection with the given receiver+slot QObject *conn = 0; for (int i = 0; i < m_connections.count(); ++i) { ConnectionQObject *candidate = static_cast<ConnectionQObject*>((QObject*)m_connections.at(i)); if (candidate->hasTarget(receiver, slot)) { conn = candidate; m_connections.removeAt(i); break; } } if (! conn) return false; const QMetaObject *meta = m_object->metaObject(); int index = m_initialIndex; QMetaMethod method = meta->method(index); if (maybeOverloaded() && (method.attributes() & QMetaMethod::Cloned)) { // find the most general method do { method = meta->method(--index); } while (method.attributes() & QMetaMethod::Cloned); } bool ok = QMetaObject::disconnect(m_object, index, conn, conn->metaObject()->methodOffset()); delete conn; return ok;}QScript::QtFunction::~QtFunction(){ qDeleteAll(m_connections);}/////////////////////////////////////////////////////////namespace QScript{ExtQMetaObject::Instance *ExtQMetaObject::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass){ if (! klass || klass == object.classInfo()) return static_cast<Instance*> (object.objectData().data()); return 0;}void QScript::ExtQMetaObject::Instance::execute(QScriptContextPrivate *context){ if (ctor.isFunction()) { QScriptValueImplList args; for (int i = 0; i < context->argumentCount(); ++i) args << context->argument(i); QScriptValueImpl result = ctor.call(context->thisObject(), args); context->m_thisObject = result; context->m_result = result; } else { context->m_result = context->throwError( QScriptContext::TypeError, QString::fromUtf8("no constructor for %0") .arg(QLatin1String(value->className()))); }}struct StaticQtMetaObject : public QObject{ static const QMetaObject *get() { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }};class ExtQMetaObjectData: public QScriptClassData{public: ExtQMetaObjectData(QScriptEnginePrivate *, QScriptClassInfo *classInfo); virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, QScript::Member *member, QScriptValueImpl *base); virtual bool get(const QScriptValueImpl &obj, const QScript::Member &member, QScriptValueImpl *result); virtual void mark(const QScriptValueImpl &object, int generation);private: QScriptClassInfo *m_classInfo;};ExtQMetaObjectData::ExtQMetaObjectData(QScriptEnginePrivate *, QScriptClassInfo *classInfo) : m_classInfo(classInfo){}bool ExtQMetaObjectData::resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, QScript::Member *member, QScriptValueImpl *base){ const QMetaObject *meta = object.toQMetaObject(); if (!meta) return false; QScriptEngine *eng = object.engine(); QByteArray name = QScriptEnginePrivate::get(eng)->toString(nameId).toLatin1(); for (int i = 0; i < meta->enumeratorCount(); ++i) { QMetaEnum e = meta->enumerator(i); for (int j = 0; j < e.keyCount(); ++j) { const char *key = e.key(j); if (! qstrcmp (key, name.constData())) { member->native(nameId, e.value(j), QScriptValue::ReadOnly); *base = object; return true; } } } return false;}bool ExtQMetaObjectData::get(const QScriptValueImpl &obj, const QScript::Member &member, QScriptValueImpl *result){ if (! member.isNativeProperty()) return false; *result = QScriptValueImpl(QScriptEnginePrivate::get(obj.engine()), member.id()); return true;}void ExtQMetaObjectData::mark(const QScriptValueImpl &object, int generation){ ExtQMetaObject::Instance *inst = ExtQMetaObject::Instance::get(object, m_classInfo); if (inst->ctor.isObject() || inst->ctor.isString()) inst->ctor.mark(generation);}} // namespace QScriptQScript::ExtQMetaObject::ExtQMetaObject(QScriptEnginePrivate *eng, QScriptClassInfo *classInfo): Ecma::Core(eng), m_classInfo(classInfo){ publicPrototype.invalidate(); newQMetaObject(&publicPrototype, QScript::StaticQtMetaObject::get()); eng->newConstructor(&ctor, this, publicPrototype); const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration; publicPrototype.setProperty(QLatin1String("className"), eng->createFunction(method_className, 0, m_classInfo), flags); QExplicitlySharedDataPointer<QScriptClassData> data(new QScript::ExtQMetaObjectData(eng, classInfo)); m_classInfo->setData(data);}QScript::ExtQMetaObject::~ExtQMetaObject(){}void QScript::ExtQMetaObject::execute(QScriptContextPrivate *context){ QScriptValueImpl tmp; newQMetaObject(&tmp, 0); context->setReturnValue(tmp);}void QScript::ExtQMetaObject::newQMetaObject(QScriptValueImpl *result, const QMetaObject *value, const QScriptValueImpl &ctor){ Instance *instance = new Instance(); instance->value = value; instance->ctor = ctor; engine()->newObject(result, publicPrototype, classInfo()); result->setObjectData(QExplicitlySharedDataPointer<QScriptObjectData>(instance));}QScriptValueImpl QScript::ExtQMetaObject::method_className(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { return QScriptValueImpl(eng, QString::fromLatin1(instance->value->className())); } return eng->undefinedValue();}#include "qscriptextqobject.moc"#endif // QT_NO_SCRIPT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -