From 8870d7173fce840277d15cab9daf75aa1b587a87 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 8 Mar 2010 13:35:41 +0100 Subject: Add a benchmark comparing single shot timer with invokeMethod Reviewed-by: joao --- .../qtimer_vs_qmetaobject.pro | 11 +++ .../tst_qtimer_vs_qmetaobject.cpp | 96 ++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro create mode 100644 tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/tst_qtimer_vs_qmetaobject.cpp diff --git a/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro new file mode 100644 index 0000000..9c6b16b --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = qtimer_vs_qmetaobject +DEPENDPATH += . +INCLUDEPATH += . + +CONFIG += release +#CONFIG += debug + + +SOURCES += tst_qtimer_vs_qmetaobject.cpp diff --git a/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/tst_qtimer_vs_qmetaobject.cpp b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/tst_qtimer_vs_qmetaobject.cpp new file mode 100644 index 0000000..2f265bf --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/tst_qtimer_vs_qmetaobject.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#define INVOKE_COUNT 10000 + +class qtimer_vs_qmetaobject : public QObject +{ + Q_OBJECT +private slots: + void testZeroTimerSingleShot(); + void testQueuedInvokeMethod(); +}; + +class InvokeCounter : public QObject { + Q_OBJECT +public: + InvokeCounter() : count(0) { }; +public slots: + void invokeSlot() { + count++; + if (count == INVOKE_COUNT) + QTestEventLoop::instance().exitLoop(); + } +protected: + int count; +}; + +void qtimer_vs_qmetaobject::testZeroTimerSingleShot() +{ + QBENCHMARK { + InvokeCounter invokeCounter; + for(int i = 0; i < INVOKE_COUNT; ++i) { + QTimer::singleShot(0, &invokeCounter, SLOT(invokeSlot())); + } + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + } +} + +void qtimer_vs_qmetaobject::testQueuedInvokeMethod() +{ + QBENCHMARK { + InvokeCounter invokeCounter; + for(int i = 0; i < INVOKE_COUNT; ++i) { + QMetaObject::invokeMethod(&invokeCounter, "invokeSlot", Qt::QueuedConnection); + } + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + } +} + + +QTEST_MAIN(qtimer_vs_qmetaobject) + +#include "tst_qtimer_vs_qmetaobject.moc" -- cgit v0.12 From 7a52e5948c0305ca41a9b66d591a12d171fd2bae Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 8 Mar 2010 15:21:38 +0100 Subject: Improve performance of QTimer::singleShot Avoid allocation of QObject and OS timer. Reviewed-by: Olivier Goffart --- src/corelib/kernel/qtimer.cpp | 14 +++++++++++++- tests/auto/qtimer/tst_qtimer.cpp | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index e17c995..7650f6a 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -339,8 +339,20 @@ QT_END_INCLUDE_NAMESPACE void QTimer::singleShot(int msec, QObject *receiver, const char *member) { - if (receiver && member) + if (receiver && member) { + if (msec == 0) { + // special code shortpath for 0-timers + const char* bracketPosition = strchr(member, '('); + if (!bracketPosition || !(member[0] >= '0' && member[0] <= '3')) { + qWarning("QTimer::singleShot: Invalid slot specification"); + return; + } + QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name + QMetaObject::invokeMethod(receiver, methodName.constData(), Qt::QueuedConnection); + return; + } (void) new QSingleShotTimer(msec, receiver, member); + } } /*! diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index cc97e4e..a0408ef 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -85,6 +85,7 @@ private slots: void timerFiresOnlyOncePerProcessEvents(); void timerIdPersistsAfterThreadExit(); void cancelLongTimer(); + void singleShotStaticFunctionZeroTimeout(); }; class TimerHelper : public QObject @@ -611,5 +612,16 @@ void tst_QTimer::cancelLongTimer() QVERIFY(!timer.isActive()); } +void tst_QTimer::singleShotStaticFunctionZeroTimeout() +{ + TimerHelper helper; + + QTimer::singleShot(0, &helper, SLOT(timeout())); + QTest::qWait(500); + QCOMPARE(helper.count, 1); + QTest::qWait(500); + QCOMPARE(helper.count, 1); +} + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" -- cgit v0.12 From d0794c43f21aab3d1ce926f38c315ba2ac999c41 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 9 Mar 2010 11:06:30 +0100 Subject: Cocoa: Native filedialog does not apply filters on app-bundles The native file dialog (and finder) handles bundles (like .app) like normal files rather than directories, unless specified otherwise. But since they are directories at the same time, we skip sending them through the name filters. This patch makes sure that we are more consistent on this matter for the cocoa port. Task-number: QTBUG-834 Reviewed-by: msorvig --- src/gui/dialogs/qfiledialog_mac.mm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index 67daced..da8cab5 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -295,10 +295,14 @@ QT_USE_NAMESPACE if (!mQDirFilterEntryList->contains(info.fileName())) return NO; - // Always accept directories regardless of their names: + // Always accept directories regardless of their names (unless it is a bundle): BOOL isDir; - if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) - return YES; + if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) { + if ([mSavePanel treatsFilePackagesAsDirectories] == NO) { + if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO) + return YES; + } + } // No filter means accept everything if (mSelectedNameFilter->isEmpty()) -- cgit v0.12 From 382cbd618fe4f5093bb1ca3f4fca3bb35614a18d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 9 Mar 2010 11:33:58 +0100 Subject: Carbon: Native filedialog does not apply filters on app-bundles The native file dialog (and finder) handles bundles (like .app) like normal files rather than directories, unless specified otherwise. But since they are directories at the same time, we skip sending them through the name filters. This patch makes sure that we are more consistent on this matter for the carbon port. Task-number: QTBUG-834 Reviewed-by: msorvig --- src/gui/dialogs/qfiledialog_mac.mm | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index da8cab5..14a5f15 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -729,6 +729,7 @@ Boolean QFileDialogPrivate::qt_mac_filedialog_filter_proc(AEDesc *theItem, void NavFileOrFolderInfo *theInfo = static_cast(info); QString file; + QString path; const QtMacFilterName &fn = fileDialogPrivate->filterInfo.filters.at(fileDialogPrivate->filterInfo.currentSelection); if (theItem->descriptorType == typeFSRef) { @@ -736,10 +737,12 @@ Boolean QFileDialogPrivate::qt_mac_filedialog_filter_proc(AEDesc *theItem, void AEGetDescData(theItem, &ref, sizeof(ref)); UInt8 str_buffer[1024]; FSRefMakePath(&ref, str_buffer, 1024); - file = QString::fromUtf8(reinterpret_cast(str_buffer)); - int slsh = file.lastIndexOf(QLatin1Char('/')); + path = QString::fromUtf8(reinterpret_cast(str_buffer)); + int slsh = path.lastIndexOf(QLatin1Char('/')); if (slsh != -1) - file = file.right(file.length() - slsh - 1); + file = path.right(path.length() - slsh - 1); + else + file = path; } QStringList reg = fn.regexp.split(QLatin1String(";")); for (QStringList::const_iterator it = reg.constBegin(); it != reg.constEnd(); ++it) { @@ -751,7 +754,13 @@ Boolean QFileDialogPrivate::qt_mac_filedialog_filter_proc(AEDesc *theItem, void if (rg.exactMatch(file)) return true; } - return (theInfo->isFolder && !file.endsWith(QLatin1String(".app"))); + + if (theInfo->isFolder) { + if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:qt_mac_QStringToNSString(path)]) + return false; + return true; + } + return false; } void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMessage msg, -- cgit v0.12