1613 lines · 71.6 KB · C++
RawDownload
     // untangle the arguments    V8ScriptValue callback(_engine, v8::Null(isolate));    V8ScriptValue callbackThis(_engine, v8::Null(isolate));    if (arg1.isFunction()) {        auto unwrappedArg0 = ScriptValueV8Wrapper::unwrap(arg0);        auto unwrappedArg1 = ScriptValueV8Wrapper::unwrap(arg1);        if (!unwrappedArg0 || !unwrappedArg1) {            Q_ASSERT(false);            return;        }        callbackThis = unwrappedArg0->toV8Value();        callback = unwrappedArg1->toV8Value();    } else {        auto unwrappedArg0 = ScriptValueV8Wrapper::unwrap(arg0);        if (!unwrappedArg0) {            Q_ASSERT(false);            return;        }        callback = unwrappedArg0->toV8Value();    }    if (!callback.get()->IsFunction()) {        isolate->ThrowError("Function expected as argument to 'disconnect'");        return;    }     // locate this connection in our list of connections    {        ConnectionList::iterator lookup = findConnection(callbackThis, callback);        if (lookup == _connections.end()) {            return;  // not here        }         // remove it from our internal list of connections        withWriteLock([&]{            _connections.erase(lookup);        });    }     // remove a reference to ourselves from the destination callback    v8::Local<v8::Function> destFunction = v8::Local<v8::Function>::Cast(callback.get());    v8::Local<v8::String> destDataName = v8::String::NewFromUtf8(isolate, "__data__").ToLocalChecked();    v8::Local<v8::Value> destData;     auto destFunctionContext = context;    ScriptEngine::QObjectWrapOptions options = ScriptEngine::ExcludeSuperClassContents |                                               ScriptEngine::PreferExistingWrapperObject;    // It's not necessarily new, newQObject looks for it first in object wrapper map, and for already existing signal it should be found there    V8ScriptValue v8ThisObject = ScriptObjectV8Proxy::newQObject(_engine, this, ScriptEngine::ScriptOwnership, options);    if (!destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData)) {        Q_ASSERT(false);    }    if (destData->IsArray()) {        v8::Local<v8::Array> destArray = v8::Local<v8::Array>::Cast(destData);        int length = destArray->Length();        v8::Local<v8::Array> newArray = v8::Array::New(isolate, length - 1);        int findCounter = 0;        int newIndex = 0;        for (int idx = 0; idx < length; ++idx) {            v8::Local<v8::Value> entry = destArray->Get(destFunctionContext, idx).ToLocalChecked();            // For debugging:            {                Q_ASSERT(entry->IsObject());                V8ScriptValue v8EntryObject(_engine, entry);                Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8EntryObject));            }            if (entry->StrictEquals(v8ThisObject.get())) {                findCounter++;            } else {                if (!newArray->Set(destFunctionContext, newIndex, entry).FromMaybe(false)) {                    Q_ASSERT(false);                }                newIndex++;            }        }        Q_ASSERT(findCounter == 1);        if (!destFunction->Set(destFunctionContext, destDataName, newArray).FromMaybe(false)) {            Q_ASSERT(false);        }    } else {        Q_ASSERT(false);    }     // inform Qt that we're no longer connected to this signal    if (_connections.empty()) {        Q_ASSERT(_isConnected);        // During cleanup qobject might be null since it might have been already deleted        if (!_cleanup || (_cleanup && qobject)) {            Q_ASSERT(qobject);            bool result = QMetaObject::disconnect(qobject, _meta.methodIndex(), this, _metaCallId);            Q_ASSERT(result);        }        _isConnected = false;    }} void ScriptSignalV8Proxy::disconnectAllScriptSignalProxies() {    _cleanup = true;    QList<Connection> connections;    withReadLock([&]{        connections = _connections;    });     for (auto &connection : connections) {        ScriptValue thisValue(new ScriptValueV8Wrapper(_engine, connection.thisValue));        ScriptValue callback(new ScriptValueV8Wrapper(_engine, connection.callback));        disconnect(thisValue, callback);    }} void ScriptSignalV8Proxy::disconnectAll() {    QObject::disconnect(this, nullptr, nullptr, nullptr);}

Lines 1501–1613 of 1613. Previous lines