📄 qscriptextqobject.cpp
字号:
case METHOD_ID: { QScript::Member m; bool maybeOverloaded = (member.flags() & MAYBE_OVERLOADED) != 0; *result = eng->createFunction(new QtFunction(qobject, member.id(), maybeOverloaded)); // make it persist (otherwise Function.prototype.disconnect() would fail) QScriptObject *instance = obj.objectValue(); if (!instance->findMember(member.nameId(), &m)) { instance->createMember(member.nameId(), &m, QScriptValue::QObjectMember); } instance->put(m, *result); } break; case CHILD_ID: { QObject *child = qobject->children().at(member.id()); *result = eng->newQObject(child); } break; } // switch return true; } virtual bool put(QScriptValueImpl *object, const QScript::Member &member, const QScriptValueImpl &value) { if (! member.isNativeProperty() || ! member.isWritable()) return false; ExtQObject::Instance *inst = ExtQObject::Instance::get(*object, m_classInfo); QObject *qobject = inst->value; if (!qobject) { QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object->engine()); QScriptContextPrivate *ctx = QScriptContextPrivate::get(eng->currentContext()); ctx->throwError(QString::fromLatin1("cannot access member `%0' of deleted QObject") .arg(member.nameId()->s)); return true; } switch (member.flags() & ID_MASK) { case CHILD_ID: return false; case METHOD_ID: { QScript::Member m; QScriptObject *instance = object->objectValue(); if (!instance->findMember(member.nameId(), &m)) { instance->createMember(member.nameId(), &m, /*flags=*/0); } instance->put(m, value); return true; } case PROPERTY_ID: if (GeneratePropertyFunctions) { // we shouldn't get here, QScriptValueImpl::setProperty() messed up Q_ASSERT_X(0, "put", "Q_PROPERTY access cannot be overridden"); return false; } else { const QMetaObject *meta = qobject->metaObject(); QMetaProperty prop = meta->property(member.id()); Q_ASSERT(prop.isScriptable()); QVariant v = variantFromValue(prop.userType(), value); bool ok = prop.write(qobject, v); return ok; } case DYNAPROPERTY_ID: { QVariant v = value.toVariant(); return ! qobject->setProperty(member.nameId()->s.toLatin1(), v); } } // switch return false; } virtual int extraMemberCount(const QScriptValueImpl &object) { ExtQObject::Instance *inst = ExtQObject::Instance::get(object, m_classInfo); QObject *qobject = inst->value; if (! qobject) return 0; const QScriptEngine::QObjectWrapOptions &opt = inst->options; const QMetaObject *meta = qobject->metaObject(); int count = 0; // meta-object-defined properties int offset = (opt & QScriptEngine::ExcludeSuperClassProperties) ? meta->propertyOffset() : 0; for (int i = offset; i < meta->propertyCount(); ++i) { QMetaProperty prop = meta->property(i); if (prop.isScriptable() && !isObjectProperty(object, prop.name())) { ++count; } } // dynamic properties QList<QByteArray> dpNames = qobject->dynamicPropertyNames(); for (int i = 0; i < dpNames.count(); ++i) { if (!isObjectProperty(object, dpNames.at(i))) { ++count; } } // meta-object-defined methods offset = (opt & QScriptEngine::ExcludeSuperClassMethods) ? meta->methodOffset() : 0; for (int i = offset; i < meta->methodCount(); ++i) { QMetaMethod method = meta->method(i); if (hasMethodAccess(method) && !isObjectProperty(object, method.signature())) { ++count; } } return count; } virtual bool extraMember(const QScriptValueImpl &object, int index, QScript::Member *member) { ExtQObject::Instance *inst = ExtQObject::Instance::get(object, m_classInfo); QObject *qobject = inst->value; const QScriptEngine::QObjectWrapOptions &opt = inst->options; const QMetaObject *meta = qobject->metaObject(); QScriptEnginePrivate *eng = QScriptEnginePrivate::get(object.engine()); int logicalIndex = 0; // meta-object-defined properties int physicalIndex = (opt & QScriptEngine::ExcludeSuperClassProperties) ? meta->propertyOffset() : 0; for ( ; physicalIndex < meta->propertyCount(); ++physicalIndex) { QMetaProperty prop = meta->property(physicalIndex); if (prop.isScriptable() && !isObjectProperty(object, prop.name())) { if (logicalIndex == index) break; ++logicalIndex; } } if (physicalIndex < meta->propertyCount()) { QMetaProperty prop = meta->property(physicalIndex); QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(prop.name())); member->native(nameId, physicalIndex, QScriptValue::Undeletable | (!prop.isWritable() ? QScriptValue::ReadOnly : QScriptValue::PropertyFlag(0)) | QScriptValue::QObjectMember | PROPERTY_ID); return true; } // dynamic properties physicalIndex = 0; QList<QByteArray> dpNames = qobject->dynamicPropertyNames(); for ( ; physicalIndex < dpNames.count(); ++physicalIndex) { if (!isObjectProperty(object, dpNames.at(physicalIndex))) { if (logicalIndex == index) break; ++logicalIndex; } } if (physicalIndex < dpNames.count()) { QByteArray name = dpNames.at(physicalIndex); QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(name)); member->native(nameId, physicalIndex, QScriptValue::QObjectMember | DYNAPROPERTY_ID); return true; } // meta-object-defined methods physicalIndex = (opt & QScriptEngine::ExcludeSuperClassMethods) ? meta->methodOffset() : 0; for ( ; physicalIndex < meta->methodCount(); ++physicalIndex) { QMetaMethod method = meta->method(physicalIndex); if (hasMethodAccess(method) && !isObjectProperty(object, method.signature())) { if (logicalIndex == index) break; ++logicalIndex; } } if (physicalIndex < meta->methodCount()) { QMetaMethod method = meta->method(physicalIndex); QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(method.signature())); member->native(nameId, index, QScriptValue::QObjectMember | METHOD_ID); return true; } return false; } virtual bool removeMember(const QScriptValueImpl &object, const QScript::Member &member) { QObject *qobject = object.toQObject(); if (!qobject || !member.isNativeProperty() || !member.isDeletable()) return false; if ((member.flags() & ID_MASK) == DYNAPROPERTY_ID) { qobject->setProperty(member.nameId()->s.toLatin1(), QVariant()); return true; } return false; } virtual void mark(const QScriptValueImpl &object, int generation) { ExtQObject::Instance *inst = ExtQObject::Instance::get(object, m_classInfo); if (inst->isConnection) { ConnectionQObject *connection = static_cast<ConnectionQObject*>((QObject*)inst->value); Q_ASSERT(connection != 0); connection->mark(generation); } }private: QScriptClassInfo *m_classInfo;};} // ::QScriptQScript::ExtQObject::ExtQObject(QScriptEnginePrivate *eng, QScriptClassInfo *classInfo): Ecma::Core(eng), m_classInfo(classInfo){ newQObject(&publicPrototype, new QScript::QObjectPrototype(), QScriptEngine::AutoOwnership, QScriptEngine::ExcludeSuperClassMethods | QScriptEngine::ExcludeSuperClassProperties | QScriptEngine::ExcludeChildObjects); eng->newConstructor(&ctor, this, publicPrototype); const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration; publicPrototype.setProperty(QLatin1String("toString"), eng->createFunction(method_toString, 0, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("findChild"), eng->createFunction(method_findChild, 1, m_classInfo), flags); publicPrototype.setProperty(QLatin1String("findChildren"), eng->createFunction(method_findChildren, 1, m_classInfo), flags); QExplicitlySharedDataPointer<QScriptClassData> data(new QScript::ExtQObjectData(eng, classInfo)); m_classInfo->setData(data);}QScript::ExtQObject::~ExtQObject(){}void QScript::ExtQObject::execute(QScriptContextPrivate *context){ QScriptValueImpl tmp; newQObject(&tmp, 0); context->setReturnValue(tmp);}void QScript::ExtQObject::newQObject(QScriptValueImpl *result, QObject *value, QScriptEngine::ValueOwnership ownership, const QScriptEngine::QObjectWrapOptions &options, bool isConnection){ Instance *instance = new Instance(); instance->value = value; instance->isConnection = isConnection; instance->ownership = ownership; instance->options = options; engine()->newObject(result, publicPrototype, classInfo()); result->setObjectData(QExplicitlySharedDataPointer<QScriptObjectData>(instance));}QScriptValueImpl QScript::ExtQObject::method_findChild(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { QObject *obj = instance->value; QString name = context->argument(0).toString(); return eng->newQObject(qFindChild<QObject*>(obj, name)); } return eng->undefinedValue();}QScriptValueImpl QScript::ExtQObject::method_findChildren(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { QObject *obj = instance->value; QList<QObject*> found; QScriptValueImpl arg = context->argument(0);#ifndef QT_NO_REGEXP if (arg.isRegExp()) { QRegExp re = arg.toRegExp(); found = qFindChildren<QObject*>(obj, re); } else#endif { QString name = arg.toString(); found = qFindChildren<QObject*>(obj, name); } QScriptValueImpl result = eng->newArray(found.size()); for (int i = 0; i < found.size(); ++i) { QScriptValueImpl value = eng->newQObject(found.at(i)); result.setProperty(i, value); } return result; } return eng->undefinedValue();}QScriptValueImpl QScript::ExtQObject::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo){ if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { QObject *obj = instance->value; const QMetaObject *meta = obj ? obj->metaObject() : &QObject::staticMetaObject; QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed"); QString str = QString::fromUtf8("%0(name = \"%1\")") .arg(QLatin1String(meta->className())).arg(name); return QScriptValueImpl(eng, str); } return eng->undefinedValue();}QScript::ConnectionQObject::ConnectionQObject(const QMetaMethod &method, const QScriptValueImpl &sender, const QScriptValueImpl &receiver, const QScriptValueImpl &slot) : m_method(method), m_sender(sender), m_receiver(receiver){ m_slot = slot; QScriptEngine *eng = m_slot.engine(); QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(eng); QScriptValueImpl me; eng_p->qobjectConstructor->newQObject(&me, this, QScriptEngine::QtOwnership, /*options=*/0, /*isConnection=*/true); QScriptValuePrivate::init(m_self, eng_p->registerValue(me)); QObject *qobject = static_cast<QtFunction*>(sender.toFunction())->object(); Q_ASSERT(qobject); connect(qobject, SIGNAL(destroyed()), this, SLOT(deleteLater()));}QScript::ConnectionQObject::~ConnectionQObject(){}static const uint qt_meta_data_ConnectionQObject[] = { // content: 1, // revision 0, // classname 0, 0, // classinfo 1, 10, // methods 0, 0, // properties 0, 0, // enums/sets // slots: signature, parameters, type, tag, flags 19, 18, 18, 18, 0x0a, 0 // eod};static const char qt_meta_stringdata_ConnectionQObject[] = { "ConnectionQObject\0\0execute()\0"};const QMetaObject QScript::ConnectionQObject::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_ConnectionQObject, qt_meta_data_ConnectionQObject, 0 }};const QMetaObject *QScript::ConnectionQObject::metaObject() const{ return &staticMetaObject;}void *QScript::ConnectionQObject::qt_metacast(const char *_clname){ if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_ConnectionQObject)) return static_cast<void*>(const_cast<ConnectionQObject*>(this)); return QObject::qt_metacast(_clname);}int QScript::ConnectionQObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -