// 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;
}
QMetaObject::activate(源码C++)
于 2024-09-08 17:41:25 首次发布