⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qobject.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qobject.h"#include "qobject_p.h"#include "qabstracteventdispatcher.h"#include "qcoreapplication.h"#include "qcoreapplication_p.h"#include "qvariant.h"#include "qmetaobject.h"#include <qregexp.h>#include <qthread.h>#include <private/qthread_p.h>#include <qdebug.h>#include <qhash.h>#include <qpair.h>#include <qvarlengtharray.h>#include <qset.h>#include <new>#include <ctype.h>#include <limits.h>static int DIRECT_CONNECTION_ONLY = 0;Q_GLOBAL_STATIC(QReadWriteLock, qt_object_read_write_lock)QReadWriteLock *QObjectPrivate::readWriteLock() { return qt_object_read_write_lock(); }static int *queuedConnectionTypes(const QList<QByteArray> &typeNames){    int *types = static_cast<int *>(qMalloc((typeNames.count() + 1) * sizeof(int)));    for (int i = 0; i < typeNames.count(); ++i) {        const QByteArray typeName = typeNames.at(i);        if (typeName.endsWith('*'))            types[i] = QMetaType::VoidStar;        else            types[i] = QMetaType::type(typeName);        if (!types[i]) {            qWarning("QObject::connect: Cannot queue arguments of type '%s'", typeName.constData());            qFree(types);            return 0;        }    }    types[typeNames.count()] = 0;    return types;}struct QConnection {    QObject *sender;    int signal;    QObject *receiver;    int method;    int inUse:1;    int type:31; // 0 == auto, 1 == direct, 2 == queued    int *types;};Q_DECLARE_TYPEINFO(QConnection, Q_MOVABLE_TYPE);class QConnectionList{public:    QReadWriteLock lock;    typedef QMultiHash<const QObject *, int> Hash;    Hash sendersHash, receiversHash;    QList<int> unusedConnections;    typedef QList<QConnection> List;    List connections;    void remove(QObject *object);    void addConnection(QObject *sender, int signal,                       QObject *receiver, int method,                       int type = 0, int *types = 0);    bool removeConnection(QObject *sender, int signal,                          QObject *receiver, int method);};Q_GLOBAL_STATIC(QConnectionList, connectionList)/*! \internal    Removes \a object from the connection list completely, i.e. all    connections containing \a object are removed.*/void QConnectionList::remove(QObject *object){    for (int i = 0; i < 2; ++i) {        Hash &hash1 = i == 0 ? sendersHash : receiversHash;        Hash &hash2 = i == 0 ? receiversHash : sendersHash;        Hash::iterator it = hash1.find(object);        const Hash::iterator end = hash1.end();        while (it != end && it.key() == object) {            const int at = it.value();            QConnection &c = connections[at];            if (c.sender) {                if (c.types && c.types != &DIRECT_CONNECTION_ONLY) {                    qFree(c.types);                    c.types = 0;                }                it = hash1.erase(it);                const QObject * const partner = i == 0 ? c.receiver : c.sender;                Hash::iterator x = hash2.find(partner);                const Hash::iterator xend = hash2.end();                while (x != xend && x.key() == partner) {                    if (x.value() == at) {                        x = hash2.erase(x);                        break;                    } else {                        ++x;                    }                }                int inUse = c.inUse;                memset(&c, 0, sizeof(c));                c.inUse = inUse;                Q_ASSERT(!unusedConnections.contains(at));                unusedConnections.prepend(at);            } else {                ++it;            }        }    }}/*! \internal    Adds the specified connection.*/void QConnectionList::addConnection(QObject *sender, int signal,                                    QObject *receiver, int method,                                    int type, int *types){    QConnection c = { sender, signal, receiver, method, 0, 0, types };    c.type = type; // don't warn on VC++6    int at = -1;    for (int i = 0; i < unusedConnections.size(); ++i) {        if (!connections.at(unusedConnections.at(i)).inUse) {            // reuse an unused connection            at = unusedConnections.takeAt(i);            connections[at] = c;            break;        }    }    if (at == -1) {        // append new connection        at = connections.size();        connections << c;    }    sendersHash.insert(sender, at);    receiversHash.insert(receiver, at);}/*! \internal    Removes the specified connection.  See QObject::disconnect() for    more information about valid arguments. */bool QConnectionList::removeConnection(QObject *sender, int signal,                                       QObject *receiver, int method){    bool success = false;    Hash::iterator it = sendersHash.find(sender);    while (it != sendersHash.end() && it.key() == sender) {        const int at = it.value();        QConnection &c = connections[at];        if (c.receiver            && (signal < 0 || signal == c.signal)            && (receiver == 0                || (c.receiver == receiver && (method < 0 || method == c.method)))) {            if (c.types) {                if (c.types != &DIRECT_CONNECTION_ONLY)                    qFree(c.types);                c.types = 0;            }            it = sendersHash.erase(it);            Hash::iterator x = receiversHash.find(c.receiver);            const Hash::iterator xend = receiversHash.end();            while (x != xend && x.key() == c.receiver) {                if (x.value() == at) {                    x = receiversHash.erase(x);                    break;                } else {                    ++x;                }            }            int inUse = c.inUse;            memset(&c, 0, sizeof(c));            c.inUse = inUse;            unusedConnections << at;            success = true;        } else {            ++it;        }    }    return success;}/*  QObjectSet sets the minimum capacity to 4099 (the first prime number  after 4096), so that we can speed up QObject destruction. */class QObjectSet : public QSet<QObject *>{public:    QObjectSet()    { reserve(4099); }};Q_GLOBAL_STATIC(QObjectSet, allObjects)extern "C" Q_CORE_EXPORT void qt_addObject(QObject *object){    QWriteLocker locker(QObjectPrivate::readWriteLock());    QObjectSet *set = allObjects();    if (set)        set->insert(object);}extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *object){    QObjectSet *set = allObjects();    if (set)        set->remove(object);}bool QObjectPrivate::isValidObject(QObject *object){    QObjectSet *set = allObjects();    return set ? set->contains(object) : false;}QObjectPrivate::QObjectPrivate(int version)    : thread(0), currentSender(0){    if (version != QObjectPrivateVersion)        qFatal("Cannot mix incompatible Qt libraries");    // QObjectData initialization    q_ptr = 0;    parent = 0;                                 // no parent yet. It is set by setParent()    isWidget = false;                           // assume not a widget object    pendTimer = false;                          // no timers yet    blockSig = false;                           // not blocking signals    wasDeleted = false;                         // double-delete catcher    sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent    receiveChildEvents = true;    postedEvents = 0;#ifdef QT3_SUPPORT    postedChildInsertedEvents = 0;#endif}QObjectPrivate::~QObjectPrivate(){#ifndef QT_NO_USERDATA    qDeleteAll(userData);#endif}class ConnectionObject : public QObject{    Q_DECLARE_PRIVATE(QObject)public:    bool isSender(const QObject *receiver, const char *signal) const;    QList<QObject*> receiverList(const char *signal) const;    QList<QObject*> senders() const;};bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const{    Q_Q(const QObject);    int signal_index = q->metaObject()->indexOfSignal(signal);    if (signal_index < 0)        return false;    QConnectionList *list = ::connectionList();    QReadLocker locker(&list->lock);    QConnectionList::Hash::const_iterator it = list->sendersHash.find(q);    while (it != list->sendersHash.end() && it.key() == q) {        const QConnection &c = list->connections.at(it.value());        if (c.signal == signal_index && c.receiver == receiver)            return true;        ++it;    }    return false;}QObjectList QObjectPrivate::receiverList(const char *signal) const{    Q_Q(const QObject);    QObjectList receivers;    int signal_index = q->metaObject()->indexOfSignal(signal);    if (signal_index < 0)        return receivers;    QConnectionList *list = ::connectionList();    QReadLocker locker(&list->lock);    QConnectionList::Hash::const_iterator it = list->sendersHash.constFind(q);    while (it != list->sendersHash.constEnd() && it.key() == q) {        const QConnection &c = list->connections.at(it.value());        if (c.signal == signal_index)            receivers << c.receiver;        ++it;    }    return receivers;}QObjectList QObjectPrivate::senderList() const{    Q_Q(const QObject);    QObjectList senders;    QConnectionList *list = ::connectionList();    QReadLocker locker(&list->lock);    QConnectionList::Hash::const_iterator it = list->receiversHash.constFind(q);    while (it != list->receiversHash.constEnd() && it.key() == q) {        const QConnection &c = list->connections.at(it.value());        senders << c.sender;        ++it;    }    return senders;}typedef QMultiHash<QObject *, QObject **> GuardHash;Q_GLOBAL_STATIC(GuardHash, guardHash)Q_GLOBAL_STATIC(QReadWriteLock, guardHashLock)/*!\internal */void QMetaObject::addGuard(QObject **ptr){    if (!*ptr)        return;    GuardHash *hash = guardHash();    if (!hash) {        *ptr = 0;        return;    }    QWriteLocker locker(guardHashLock());    hash->insert(*ptr, ptr);}/*!\internal */void QMetaObject::removeGuard(QObject **ptr){    if (!*ptr)        return;    GuardHash *hash = guardHash();    if (!hash)        return;    QWriteLocker locker(guardHashLock());    GuardHash::iterator it = hash->find(*ptr);    const GuardHash::iterator end = hash->end();    for (; it.key() == *ptr && it != end; ++it) {        if (it.value() == ptr) {            (void) hash->erase(it);            break;        }    }}/*!\internal */void QMetaObject::changeGuard(QObject **ptr, QObject *o){    GuardHash *hash = guardHash();    if (!hash) {        *ptr = 0;        return;    }    QWriteLocker locker(guardHashLock());    if (*ptr) {        GuardHash::iterator it = hash->find(*ptr);        const GuardHash::iterator end = hash->end();        for (; it.key() == *ptr && it != end; ++it) {            if (it.value() == ptr) {                (void) hash->erase(it);                break;            }        }    }    *ptr = o;    if (*ptr)        hash->insert(*ptr, ptr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -