QMetaObject::activate(源码C++)

// SIGNAL 0,ageChanged信号的实现
void Object::ageChanged(int _t1)
{
    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 0, _a);
}

// SIGNAL 1  scoreChanged信号的实现
void Object::scoreChanged(int _t1)
{
    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 1, _a);
}
void QMetaObject::activate(QObject *sender, const QMetaObject *m,
                           int local_signal_index,void **argv)
{
    int signalOffset;
    int methodOffset;
    computeOffsets(m, &signalOffset, &methodOffset);

    int signal_index = signalOffset + local_signal_index;

    if (!sender->d_func()->isSignalConnected(signal_index))
        return; // 如果发送的信号没有槽连接,直接返回

    if (sender->d_func()->blockSig)
        return;//如果阻塞,直接返回

    int signal_absolute_index = methodOffset + local_signal_index;

    void *empty_argv[] = { 0 };
    if (qt_signal_spy_callback_set.signal_begin_callback != 0)
    {
        qt_signal_spy_callback_set.signal_begin_callback(sender, signal_absolute_index,
                                                         argv ? argv : empty_argv);
    }

    Qt::HANDLE currentThreadId = QThread::currentThreadId();

    QMutexLocker locker(signalSlotLock(sender));
    //获取发送者的连接链表容器
    QObjectConnectionListVector *connectionLists = sender->d_func()->connectionLists;
    if (!connectionLists)
    {
        locker.unlock();
        if (qt_signal_spy_callback_set.signal_end_callback != 0)
            qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
        return;
    }
    ++connectionLists->inUse;

    //从发送者的连接链表容器中使用信号索引作为索引,获取相应的连接链表
    const QObjectPrivate::ConnectionList *list;
    if (signal_index < connectionLists->count())
        list = &connectionLists->at(signal_index);
    else
        list = &connectionLists->allsignals;

    do {
        //索取发送的信号的连接链表的第一个连接
        QObjectPrivate::Connection *c = list->first;
        if (!c) continue;//如果连接为空,继续
        // We need to check against last here to ensure that signals added
        // during the signal emission are not emitted in this emission.
        QObjectPrivate::Connection *last = list->last;

        do
        {
            if (!c->receiver)
                continue;//如果连接的接收者为空,继续

            QObject * const receiver = c->receiver;
            const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;

            // determine if this connection should be sent immediately or
            // put into the event queue
            if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
                    || (c->connectionType == Qt::QueuedConnection))
            {
                queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
#ifndef QT_NO_THREAD
            }
            //阻塞队列连接类型
            else if (c->connectionType == Qt::BlockingQueuedConnection)
            {
                locker.unlock();
                if (receiverInSameThread)
                {
                    qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
                             "Sender is %s(%p), receiver is %s(%p)",
                             sender->metaObject()->className(), sender,
                             receiver->metaObject()->className(), receiver);
                }
                QSemaphore semaphore;
                QCoreApplication::postEvent(receiver, new QMetaCallEvent(c->method_offset, c->method_relative,
                                                                         c->callFunction,
                                                                         sender, signal_absolute_index,
                                                                         0, 0,
                                                                         argv ? argv : empty_argv,
                                                                         &semaphore));
                semaphore.acquire();
                locker.relock();
                continue;
#endif
            }

            QObjectPrivate::Sender currentSender;
            QObjectPrivate::Sender *previousSender = 0;
            if (receiverInSameThread)
            {
                currentSender.sender = sender;
                currentSender.signal = signal_absolute_index;
                currentSender.ref = 1;
                previousSender = QObjectPrivate::setCurrentSender(receiver, ¤tSender);
            }
            //获取连接的回调函数指针
            const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
            const int method_relative = c->method_relative;
            //如果连接的方法的偏移小于接收者的元对象的方法的偏移
            if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset())
            {
                //we compare the vtable to make sure we are not in the destructor of the object.
                locker.unlock();
                if (qt_signal_spy_callback_set.slot_begin_callback != 0)
                    qt_signal_spy_callback_set.slot_begin_callback(receiver, c->method(), argv ? argv : empty_argv);
                //根据接收者的方法偏移,接收者等参数调用qt_static_metacall回调函数
                callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);

                if (qt_signal_spy_callback_set.slot_end_callback != 0)
                    qt_signal_spy_callback_set.slot_end_callback(receiver, c->method());
                locker.relock();
            }
            else
            {
                const int method = method_relative + c->method_offset;
                locker.unlock();

                if (qt_signal_spy_callback_set.slot_begin_callback != 0)
                {
                    qt_signal_spy_callback_set.slot_begin_callback(receiver,
                                                                   method,
                                                                   argv ? argv : empty_argv);
                }
                //根据接收者、接收者的方法索引等参数调用发送元对象的metacall
                metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);

                if (qt_signal_spy_callback_set.slot_end_callback != 0)
                    qt_signal_spy_callback_set.slot_end_callback(receiver, method);

                locker.relock();
            }

            if (receiverInSameThread)
                QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender);

            if (connectionLists->orphaned)
                break;
        } while (c != last && (c = c->nextConnectionList) != 0);

        if (connectionLists->orphaned)
            break;
    } while (list != &connectionLists->allsignals &&
             //start over for all signals;
             ((list = &connectionLists->allsignals), true));

    --connectionLists->inUse;
    Q_ASSERT(connectionLists->inUse >= 0);
    if (connectionLists->orphaned)
    {
        if (!connectionLists->inUse)
            delete connectionLists;
    }
    else if (connectionLists->dirty)
    {
        sender->d_func()->cleanConnectionLists();
    }

    locker.unlock();

    if (qt_signal_spy_callback_set.signal_end_callback != 0)
        qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);

}
metacall函数内部调用了qt_metacall函数。
int QMetaObject::metacall(QObject *object, Call cl, int idx, void **argv)
{
    if (QMetaObject *mo = object->d_ptr->metaObject)
        return static_cast<QAbstractDynamicMetaObject*>(mo)->metaCall(cl, idx, argv);
    else
        return object->qt_metacall(cl, idx, argv);
}
int Object::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) 
    {
        if (_id < 4)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 4;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) 
    {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< int*>(_v) = age(); break;
        case 1: *reinterpret_cast< int*>(_v) = score(); break;
        case 2: *reinterpret_cast< Level*>(_v) = level(); break;
        }
        _id -= 3;
    } 
    else if (_c == QMetaObject::WriteProperty) 
    {
        void *_v = _a[0];
        switch (_id) {
        case 0: setAge(*reinterpret_cast< int*>(_v)); break;
        case 1: setScore(*reinterpret_cast< int*>(_v)); break;
        case 2: setLevel(*reinterpret_cast< Level*>(_v)); break;
        }
        _id -= 3;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 3;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 3;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 3;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 3;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 3;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 3;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值