diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-10-10 13:52:34 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-12 01:31:11 +0200 |
commit | 0466acb02740b5dbf3254d6445186b4d3ccd0699 (patch) | |
tree | a1b7314c2faae73cf93403afdc7ca92f2106d70d /src/declarative/qml/qdeclarativeengine.cpp | |
parent | 3422d4adda7480a44a063ab86447c2fe2792fe02 (diff) |
Optimize signal handling
Bindings connect to lots of signals that are never emitted. By managing
signal connection lists ourselves, we can do a much better job than Qt's
generic signal/slot connection logic.
Also, by connecting to QDeclarativeNotifierEndpoint's rather than QObject
slots, we can eliminate the need to instantiate a QObject for the V4 and
V8 binding managers.
Change-Id: I598667deaefdbd2860227bd74378a1b196761686
Reviewed-on: http://codereview.qt-project.org/6278
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Sanity-Review: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative/qml/qdeclarativeengine.cpp')
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 5231704da9..383d37a3ed 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -410,6 +410,15 @@ void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o static_cast<QDeclarativeData *>(d)->objectNameChanged(o); } +void QDeclarativeData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int index, void **) +{ + QDeclarativeData *ddata = QDeclarativeData::get(object, false); + if (!ddata) return; // Probably being deleted + + QDeclarativeNotifierEndpoint *ep = ddata->notify(index); + if (ep) QDeclarativeNotifier::emitNotify(ep); +} + void QDeclarativeEnginePrivate::init() { Q_Q(QDeclarativeEngine); @@ -1047,6 +1056,80 @@ QDeclarativeDataExtended::~QDeclarativeDataExtended() { } +void QDeclarativeData::NotifyList::layout(QDeclarativeNotifierEndpoint *endpoint) +{ + if (endpoint->next) + layout(endpoint->next); + + int index = endpoint->sourceSignal; + index = qMin(index, 0xFFFF - 1); + + endpoint->next = notifies[index]; + if (endpoint->next) endpoint->next->prev = &endpoint->next; + endpoint->prev = ¬ifies[index]; + notifies[index] = endpoint; +} + +void QDeclarativeData::NotifyList::layout() +{ + Q_ASSERT(maximumTodoIndex >= notifiesSize); + + if (todo) { + QDeclarativeNotifierEndpoint **old = notifies; + const int reallocSize = (maximumTodoIndex + 1) * sizeof(QDeclarativeNotifierEndpoint*); + notifies = (QDeclarativeNotifierEndpoint**)realloc(notifies, reallocSize); + const int memsetSize = (maximumTodoIndex - notifiesSize + 1) * + sizeof(QDeclarativeNotifierEndpoint*); + memset(notifies + notifiesSize, 0, memsetSize); + + if (notifies != old) { + for (int ii = 0; ii < notifiesSize; ++ii) + if (notifies[ii]) + notifies[ii]->prev = ¬ifies[ii]; + } + + notifiesSize = maximumTodoIndex + 1; + + layout(todo); + } + + maximumTodoIndex = 0; + todo = 0; +} + +void QDeclarativeData::addNotify(int index, QDeclarativeNotifierEndpoint *endpoint) +{ + if (!notifyList) { + notifyList = (NotifyList *)malloc(sizeof(NotifyList)); + notifyList->connectionMask = 0; + notifyList->maximumTodoIndex = 0; + notifyList->notifiesSize = 0; + notifyList->todo = 0; + notifyList->notifies = 0; + } + + Q_ASSERT(!endpoint->isConnected()); + + index = qMin(index, 0xFFFF - 1); + notifyList->connectionMask |= (1 << (index % 64)); + + if (index < notifyList->notifiesSize) { + + endpoint->next = notifyList->notifies[index]; + if (endpoint->next) endpoint->next->prev = &endpoint->next; + endpoint->prev = ¬ifyList->notifies[index]; + notifyList->notifies[index] = endpoint; + + } else { + notifyList->maximumTodoIndex = qMax(int(notifyList->maximumTodoIndex), index); + + endpoint->next = notifyList->todo; + if (endpoint->next) endpoint->next->prev = &endpoint->next; + endpoint->prev = ¬ifyList->todo; + notifyList->todo = endpoint; + } +} + QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const { if (!extendedData) extendedData = new QDeclarativeDataExtended; @@ -1093,6 +1176,17 @@ void QDeclarativeData::destroyed(QObject *object) guard->objectDestroyed(object); } + if (notifyList) { + while (notifyList->todo) + notifyList->todo->disconnect(); + for (int ii = 0; ii < notifyList->notifiesSize; ++ii) { + while (QDeclarativeNotifierEndpoint *ep = notifyList->notifies[ii]) + ep->disconnect(); + } + free(notifyList->notifies); + free(notifyList); + } + if (extendedData) delete extendedData; |