📄 qt_runtime.cpp
字号:
if (!d->m_connect) d->m_connect = new (exec) QtRuntimeConnectionMethod(exec, ident, true, d->m_instance, d->m_index, d->m_signature); return d->m_connect;}JSValuePtr QtRuntimeMetaMethod::disconnectGetter(ExecState* exec, const Identifier& ident, const PropertySlot& slot){ QtRuntimeMetaMethod* thisObj = static_cast<QtRuntimeMetaMethod*>(asObject(slot.slotBase())); QW_DS(QtRuntimeMetaMethod, thisObj); if (!d->m_disconnect) d->m_disconnect = new (exec) QtRuntimeConnectionMethod(exec, ident, false, d->m_instance, d->m_index, d->m_signature); return d->m_disconnect;}// ===============QMultiMap<QObject*, QtConnectionObject*> QtRuntimeConnectionMethod::connections;QtRuntimeConnectionMethod::QtRuntimeConnectionMethod(ExecState* exec, const Identifier& ident, bool isConnect, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature) : QtRuntimeMethod (new QtRuntimeConnectionMethodData(), exec, ident, inst){ QW_D(QtRuntimeConnectionMethod); d->m_signature = signature; d->m_index = index; d->m_isConnect = isConnect;}JSValuePtr QtRuntimeConnectionMethod::call(ExecState* exec, JSObject* functionObject, JSValuePtr thisValue, const ArgList& args){ QtRuntimeConnectionMethodData* d = static_cast<QtRuntimeConnectionMethod *>(functionObject)->d_func(); JSLock lock(false); QObject* sender = d->m_instance->getObject(); if (sender) { JSObject* thisObject = exec->lexicalGlobalObject(); JSObject* funcObject = 0; // QtScript checks signalness first, arguments second int signalIndex = -1; // Make sure the initial index is a signal QMetaMethod m = sender->metaObject()->method(d->m_index); if (m.methodType() == QMetaMethod::Signal) signalIndex = findSignalIndex(sender->metaObject(), d->m_index, d->m_signature); if (signalIndex != -1) { if (args.size() == 1) { funcObject = args.at(exec, 0).toObject(exec); CallData callData; if (funcObject->getCallData(callData) == CallTypeNone) { if (d->m_isConnect) return throwError(exec, TypeError, "QtMetaMethod.connect: target is not a function"); else return throwError(exec, TypeError, "QtMetaMethod.disconnect: target is not a function"); } } else if (args.size() >= 2) { if (args.at(exec, 0).isObject()) { thisObject = args.at(exec, 0).toObject(exec); // Get the actual function to call JSObject *asObj = args.at(exec, 1).toObject(exec); CallData callData; if (asObj->getCallData(callData) != CallTypeNone) { // Function version funcObject = asObj; } else { // Convert it to a string UString funcName = args.at(exec, 1).toString(exec); Identifier funcIdent(exec, funcName); // ### DropAllLocks // This is resolved at this point in QtScript JSValuePtr val = thisObject->get(exec, funcIdent); JSObject* asFuncObj = val.toObject(exec); if (asFuncObj->getCallData(callData) != CallTypeNone) { funcObject = asFuncObj; } else { if (d->m_isConnect) return throwError(exec, TypeError, "QtMetaMethod.connect: target is not a function"); else return throwError(exec, TypeError, "QtMetaMethod.disconnect: target is not a function"); } } } else { if (d->m_isConnect) return throwError(exec, TypeError, "QtMetaMethod.connect: thisObject is not an object"); else return throwError(exec, TypeError, "QtMetaMethod.disconnect: thisObject is not an object"); } } else { if (d->m_isConnect) return throwError(exec, GeneralError, "QtMetaMethod.connect: no arguments given"); else return throwError(exec, GeneralError, "QtMetaMethod.disconnect: no arguments given"); } if (d->m_isConnect) { // to connect, we need: // target object [from ctor] // target signal index etc. [from ctor] // receiver function [from arguments] // receiver this object [from arguments] QtConnectionObject* conn = new QtConnectionObject(d->m_instance, signalIndex, thisObject, funcObject); bool ok = QMetaObject::connect(sender, signalIndex, conn, conn->metaObject()->methodOffset()); if (!ok) { delete conn; QString msg = QString(QLatin1String("QtMetaMethod.connect: failed to connect to %1::%2()")) .arg(QLatin1String(sender->metaObject()->className())) .arg(QLatin1String(d->m_signature)); return throwError(exec, GeneralError, msg.toLatin1().constData()); } else { // Store connection connections.insert(sender, conn); } } else { // Now to find our previous connection object. Hmm. QList<QtConnectionObject*> conns = connections.values(sender); bool ret = false; foreach(QtConnectionObject* conn, conns) { // Is this the right connection? if (conn->match(sender, signalIndex, thisObject, funcObject)) { // Yep, disconnect it QMetaObject::disconnect(sender, signalIndex, conn, conn->metaObject()->methodOffset()); delete conn; // this will also remove it from the map ret = true; break; } } if (!ret) { QString msg = QString(QLatin1String("QtMetaMethod.disconnect: failed to disconnect from %1::%2()")) .arg(QLatin1String(sender->metaObject()->className())) .arg(QLatin1String(d->m_signature)); return throwError(exec, GeneralError, msg.toLatin1().constData()); } } } else { QString msg = QString(QLatin1String("QtMetaMethod.%1: %2::%3() is not a signal")) .arg(QLatin1String(d->m_isConnect ? "connect": "disconnect")) .arg(QLatin1String(sender->metaObject()->className())) .arg(QLatin1String(d->m_signature)); return throwError(exec, TypeError, msg.toLatin1().constData()); } } else { return throwError(exec, GeneralError, "cannot call function of deleted QObject"); } return jsUndefined();}CallType QtRuntimeConnectionMethod::getCallData(CallData& callData){ callData.native.function = call; return CallTypeHost;}bool QtRuntimeConnectionMethod::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot){ if (propertyName == exec->propertyNames().length) { slot.setCustom(this, lengthGetter); return true; } return QtRuntimeMethod::getOwnPropertySlot(exec, propertyName, slot);}JSValuePtr QtRuntimeConnectionMethod::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot&){ // we have one formal argument, and one optional return jsNumber(exec, 1);}// ===============QtConnectionObject::QtConnectionObject(PassRefPtr<QtInstance> instance, int signalIndex, JSObject* thisObject, JSObject* funcObject) : m_instance(instance) , m_signalIndex(signalIndex) , m_originalObject(m_instance->getObject()) , m_thisObject(thisObject) , m_funcObject(funcObject){ setParent(m_originalObject); ASSERT(JSLock::currentThreadIsHoldingLock()); // so our ProtectedPtrs are safe}QtConnectionObject::~QtConnectionObject(){ // Remove us from the map of active connections QtRuntimeConnectionMethod::connections.remove(m_originalObject, this);}static const uint qt_meta_data_QtConnectionObject[] = { // content: 1, // revision 0, // classname 0, 0, // classinfo 1, 10, // methods 0, 0, // properties 0, 0, // enums/sets // slots: signature, parameters, type, tag, flags 28, 27, 27, 27, 0x0a, 0 // eod};static const char qt_meta_stringdata_QtConnectionObject[] = { "JSC::Bindings::QtConnectionObject\0\0execute()\0"};const QMetaObject QtConnectionObject::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_QtConnectionObject, qt_meta_data_QtConnectionObject, 0 }};const QMetaObject *QtConnectionObject::metaObject() const{ return &staticMetaObject;}void *QtConnectionObject::qt_metacast(const char *_clname){ if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_QtConnectionObject)) return static_cast<void*>(const_cast<QtConnectionObject*>(this)); return QObject::qt_metacast(_clname);}int QtConnectionObject::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) { switch (_id) { case 0: execute(_a); break; } _id -= 1; } return _id;}void QtConnectionObject::execute(void **argv){ QObject* obj = m_instance->getObject(); if (obj) { const QMetaObject* meta = obj->metaObject(); const QMetaMethod method = meta->method(m_signalIndex); QList<QByteArray> parameterTypes = method.parameterTypes(); int argc = parameterTypes.count(); JSLock lock(false); // ### Should the Interpreter/ExecState come from somewhere else? RefPtr<RootObject> ro = m_instance->rootObject(); if (ro) { JSGlobalObject* globalobj = ro->globalObject(); if (globalobj) { ExecState* exec = globalobj->globalExec(); if (exec) { // Build the argument list (up to the formal argument length of the slot) ArgList l; // ### DropAllLocks? int funcArgC = m_funcObject->get(exec, exec->propertyNames().length).toInt32(exec); int argTotal = qMax(funcArgC, argc); for(int i=0; i < argTotal; i++) { if (i < argc) { int argType = QMetaType::type(parameterTypes.at(i)); l.append(convertQVariantToValue(exec, ro, QVariant(argType, argv[i+1]))); } else { l.append(jsUndefined()); } } CallData callData; CallType callType = m_funcObject->getCallData(callData); // Stuff in the __qt_sender property, if we can if (m_funcObject->inherits(&JSFunction::info)) { JSFunction* fimp = static_cast<JSFunction*>(m_funcObject.get()); JSObject* qt_sender = QtInstance::getQtInstance(sender(), ro, QScriptEngine::QtOwnership)->createRuntimeObject(exec); JSObject* wrapper = new (exec) JSObject(JSObject::createStructure(jsNull())); PutPropertySlot slot; wrapper->put(exec, Identifier(exec, "__qt_sender__"), qt_sender, slot); ScopeChain oldsc = fimp->scope(); ScopeChain sc = oldsc; sc.push(wrapper); fimp->setScope(sc); call(exec, fimp, callType, callData, m_thisObject, l); fimp->setScope(oldsc); } else { call(exec, m_funcObject, callType, callData, m_thisObject, l); } } } } } else { // A strange place to be - a deleted object emitted a signal here. qWarning() << "sender deleted, cannot deliver signal"; }}bool QtConnectionObject::match(QObject* sender, int signalIndex, JSObject* thisObject, JSObject *funcObject){ if (m_originalObject == sender && m_signalIndex == signalIndex && thisObject == (JSObject*)m_thisObject && funcObject == (JSObject*)m_funcObject) return true; return false;}// ===============template <typename T> QtArray<T>::QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject> rootObject) : Array(rootObject) , m_list(list) , m_type(type){ m_length = m_list.count();}template <typename T> QtArray<T>::~QtArray (){}template <typename T> RootObject* QtArray<T>::rootObject() const{ return _rootObject && _rootObject->isValid() ? _rootObject.get() : 0;}template <typename T> void QtArray<T>::setValueAt(ExecState* exec, unsigned index, JSValuePtr aValue) const{ // QtScript sets the value, but doesn't forward it to the original source // (e.g. if you do 'object.intList[5] = 6', the object is not updated, but the // copy of the list is). int dist = -1; QVariant val = convertValueToQVar
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -