diff options
12 files changed, 231 insertions, 14 deletions
diff --git a/demos/declarative/samegame/SamegameCore/samegame.js b/demos/declarative/samegame/SamegameCore/samegame.js index bb587bc..d7b827a 100755 --- a/demos/declarative/samegame/SamegameCore/samegame.js +++ b/demos/declarative/samegame/SamegameCore/samegame.js @@ -8,6 +8,7 @@ var blockSrc = "SamegameCore/BoomBlock.qml"; var scoresURL = ""; var gameDuration; var component = Qt.createComponent(blockSrc); +var highScoreBar = 0; // Index function used instead of a 2D array function index(column, row) @@ -152,11 +153,15 @@ function victoryCheck() // Checks for game over if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) { gameDuration = new Date() - gameDuration; - nameInputDialog.show("You won! Please enter your name: "); - nameInputDialog.initialWidth = nameInputDialog.text.width + 20; - if (nameInputDialog.name == "") - nameInputDialog.width = nameInputDialog.initialWidth; - nameInputDialog.text.opacity = 0; // Just a spacer + if(gameCanvas.score > highScoreBar){ + nameInputDialog.show("You won! Please enter your name: "); + nameInputDialog.initialWidth = nameInputDialog.text.width + 20; + if (nameInputDialog.name == "") + nameInputDialog.width = nameInputDialog.initialWidth; + nameInputDialog.text.opacity = 0; // Just a spacer + }else{ + dialog.show("You won!"); + } } } @@ -203,6 +208,30 @@ function createBlock(column,row) return true; } +function initHighScoreBar() +{ + if(scoresURL != "") + return true;//don't query remote scores + var db = openDatabaseSync( + "SameGameScores", + "1.0", + "Local SameGame High Scores", + 100 + ); + db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)'); + // Only show results for the current grid size + var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "' + + maxColumn + "x" + maxRow + '" ORDER BY score desc LIMIT 10'); + if(rs.rows.length < 10) + highScoreBar = 0; + else + highScoreBar = rs.rows.item(rs.rows.length - 1).score; + } + ); +} + function saveHighScore(name) { if (scoresURL != "") @@ -235,6 +264,8 @@ function saveHighScore(name) + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n'; } + if(rs.rows.length == 10) + highScoreBar = rs.rows.item(9).score; dialog.show(r); } ); diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 2d5cfab..0a1f5d7 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -167,7 +167,7 @@ Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer) QUnifiedTimer::QUnifiedTimer() : QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), - currentAnimationIdx(0), consistentTiming(false), slowMode(false), + currentAnimationIdx(0), insideTick(false), consistentTiming(false), slowMode(false), slowdownFactor(5.0f), isPauseTimerActive(false), runningLeafAnimations(0) { time.invalidate(); @@ -206,6 +206,10 @@ void QUnifiedTimer::ensureTimerUpdate() void QUnifiedTimer::updateAnimationsTime() { + //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations + if(insideTick) + return; + qint64 totalElapsed = time.elapsed(); // ignore consistentTiming in case the pause timer is active int delta = (consistentTiming && !isPauseTimerActive) ? @@ -223,12 +227,14 @@ void QUnifiedTimer::updateAnimationsTime() //it might happen in some cases that the time doesn't change because events are delayed //when the CPU load is high if (delta) { + insideTick = true; for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) { QAbstractAnimation *animation = animations.at(currentAnimationIdx); int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta); animation->setCurrentTime(elapsed); } + insideTick = false; currentAnimationIdx = 0; } } @@ -254,7 +260,8 @@ void QUnifiedTimer::restartAnimationTimer() } else if (!driver->isRunning() || isPauseTimerActive) { driver->start(); isPauseTimerActive = false; - } + } else if (runningLeafAnimations == 0) + driver->stop(); } void QUnifiedTimer::setTimingInterval(int interval) diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 1ab05cd..0ccc502 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -184,6 +184,9 @@ public: void restartAnimationTimer(); void updateAnimationsTime(); + //useful for profiling/debugging + int runningAnimationCount() { return animations.count(); } + protected: void timerEvent(QTimerEvent *); @@ -202,6 +205,7 @@ private: qint64 lastTick; int timingInterval; int currentAnimationIdx; + bool insideTick; bool consistentTiming; bool slowMode; diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 2cb1c94..c15426d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -273,7 +273,6 @@ void QDeclarativeTextEdit::setText(const QString &text) \o TextEdit.AutoText \o TextEdit.PlainText \o TextEdit.RichText - \o TextEdit.StyledText \endlist The default is TextEdit.AutoText. If the text format is TextEdit.AutoText the text edit diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index dc3ecca..e7ab9cd 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -395,6 +395,33 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, } else if (value.isFunction() && !value.isRegExp()) { // this is handled by the binding creation above } else { + //### expand optimization for other known types + if (lastData->propType == QMetaType::Int && value.isNumber()) { + int rawValue = qRound(value.toNumber()); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } else if (lastData->propType == QMetaType::QReal && value.isNumber()) { + qreal rawValue = qreal(value.toNumber()); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } else if (lastData->propType == QMetaType::QString && value.isString()) { + const QString &rawValue = value.toString(); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } + QVariant v; if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >()); diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp index 6a0226f..448797b 100644 --- a/src/declarative/qml/qmetaobjectbuilder.cpp +++ b/src/declarative/qml/qmetaobjectbuilder.cpp @@ -101,7 +101,7 @@ bool isVariantType(const char* type) return qvariant_nameToType(type) != 0; } -// copied from qmetaobject.cpp +// copied from qmetaobject_p.h // do not touch without touching the moc as well enum PropertyFlags { Invalid = 0x00000000, @@ -111,6 +111,8 @@ enum PropertyFlags { EnumOrFlag = 0x00000008, StdCppSet = 0x00000100, // Override = 0x00000200, + Constant = 0x00000400, + Final = 0x00000800, Designable = 0x00001000, ResolveDesignable = 0x00002000, Scriptable = 0x00004000, @@ -618,6 +620,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot property.setUser(prototype.isUser()); property.setStdCppSet(prototype.hasStdCppSet()); property.setEnumOrFlag(prototype.isEnumType()); + property.setConstant(prototype.isConstant()); + property.setFinal(prototype.isFinal()); if (prototype.hasNotifySignal()) { // Find an existing method for the notify signal, or add a new one. QMetaMethod method = prototype.notifySignal(); @@ -2278,6 +2282,32 @@ bool QMetaPropertyBuilder::isEnumOrFlag() const } /*! + Returns true if the property is constant; otherwise returns false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isConstant() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Constant); + else + return false; +} + +/*! + Returns true if the property is final; otherwise returns false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isFinal() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Final); + else + return false; +} + +/*! Sets this property to readable if \a value is true. \sa isReadable(), setWritable() @@ -2401,6 +2431,31 @@ void QMetaPropertyBuilder::setEnumOrFlag(bool value) } /*! + Sets the \c CONSTANT flag on this property to \a value. + + \sa isConstant() +*/ +void QMetaPropertyBuilder::setConstant(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Constant, value); +} + +/*! + Sets the \c FINAL flag on this property to \a value. + + \sa isFinal() +*/ +void QMetaPropertyBuilder::setFinal(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Final, value); +} + + +/*! \class QMetaEnumBuilder \internal \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder. diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/qmetaobjectbuilder_p.h index 2678bff..392e13b 100644 --- a/src/declarative/qml/qmetaobjectbuilder_p.h +++ b/src/declarative/qml/qmetaobjectbuilder_p.h @@ -258,6 +258,8 @@ public: bool isUser() const; bool hasStdCppSet() const; bool isEnumOrFlag() const; + bool isConstant() const; + bool isFinal() const; void setReadable(bool value); void setWritable(bool value); @@ -269,6 +271,8 @@ public: void setUser(bool value); void setStdCppSet(bool value); void setEnumOrFlag(bool value); + void setConstant(bool value); + void setFinal(bool value); private: const QMetaObjectBuilder *_mobj; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml new file mode 100644 index 0000000..cbbbbf9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + function test1() { + value = 4.2 + } + function test2() { + value = 7.9 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 48466d5..f913ab8 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -176,6 +176,7 @@ private slots: void aliasBindingsOverrideTarget(); void aliasWritesOverrideBindings(); void pushCleanContext(); + void realToInt(); void include(); @@ -3069,6 +3070,18 @@ void tst_qdeclarativeecmascript::pushCleanContext() QCOMPARE(func2.call().toInt32(), 6); } +void tst_qdeclarativeecmascript::realToInt() +{ + QDeclarativeComponent component(&engine, TEST_FILE("realToInt.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QVERIFY(object != 0); + + QMetaObject::invokeMethod(object, "test1"); + QCOMPARE(object->value(), int(4)); + QMetaObject::invokeMethod(object, "test2"); + QCOMPARE(object->value(), int(8)); +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 06baed8..ff72654 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -546,6 +546,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!nullProp.isUser()); QVERIFY(!nullProp.hasStdCppSet()); QVERIFY(!nullProp.isEnumOrFlag()); + QVERIFY(!nullProp.isConstant()); + QVERIFY(!nullProp.isFinal()); QCOMPARE(nullProp.index(), 0); // Add a property and check its attributes. @@ -563,6 +565,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop1.isUser()); QVERIFY(!prop1.hasStdCppSet()); QVERIFY(!prop1.isEnumOrFlag()); + QVERIFY(!prop1.isConstant()); + QVERIFY(!prop1.isFinal()); QCOMPARE(prop1.index(), 0); QCOMPARE(builder.propertyCount(), 1); @@ -581,6 +585,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 1); QCOMPARE(builder.propertyCount(), 2); @@ -602,6 +608,8 @@ void tst_QMetaObjectBuilder::property() prop1.setUser(true); prop1.setStdCppSet(true); prop1.setEnumOrFlag(true); + prop1.setConstant(true); + prop1.setFinal(true); // Check that prop1 is changed, but prop2 is not. QCOMPARE(prop1.name(), QByteArray("foo")); @@ -616,6 +624,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop1.isUser()); QVERIFY(prop1.hasStdCppSet()); QVERIFY(prop1.isEnumOrFlag()); + QVERIFY(prop1.isConstant()); + QVERIFY(prop1.isFinal()); QVERIFY(prop2.isReadable()); QVERIFY(prop2.isWritable()); QCOMPARE(prop2.name(), QByteArray("bar")); @@ -628,6 +638,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); // Remove prop1 and check that prop2 becomes index 0. builder.removeProperty(0); @@ -643,6 +655,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 0); // Perform index-based lookup again. @@ -666,6 +680,8 @@ void tst_QMetaObjectBuilder::property() prop2.setUser(false); \ prop2.setStdCppSet(false); \ prop2.setEnumOrFlag(false); \ + prop2.setConstant(false); \ + prop2.setFinal(false); \ } while (0) #define COUNT_FLAGS() \ ((prop2.isReadable() ? 1 : 0) + \ @@ -677,7 +693,9 @@ void tst_QMetaObjectBuilder::property() (prop2.isEditable() ? 1 : 0) + \ (prop2.isUser() ? 1 : 0) + \ (prop2.hasStdCppSet() ? 1 : 0) + \ - (prop2.isEnumOrFlag() ? 1 : 0)) + (prop2.isEnumOrFlag() ? 1 : 0) + \ + (prop2.isConstant() ? 1 : 0) + \ + (prop2.isFinal() ? 1 : 0)) #define CHECK_FLAG(setFunc,isFunc) \ do { \ CLEAR_FLAGS(); \ @@ -696,6 +714,8 @@ void tst_QMetaObjectBuilder::property() CHECK_FLAG(setUser, isUser); CHECK_FLAG(setStdCppSet, hasStdCppSet); CHECK_FLAG(setEnumOrFlag, isEnumOrFlag); + CHECK_FLAG(setConstant, isConstant); + CHECK_FLAG(setFinal, isFinal); // Check that nothing else changed. QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties)); diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp index 2020a18..b07ffa1 100644 --- a/tests/benchmarks/declarative/script/tst_script.cpp +++ b/tests/benchmarks/declarative/script/tst_script.cpp @@ -70,6 +70,9 @@ private slots: void property_qobject(); void property_qmlobject(); + void setproperty_js(); + void setproperty_qmlobject(); + void function_js(); void function_cpp(); void function_qobject(); @@ -108,12 +111,13 @@ inline QUrl TEST_FILE(const QString &filename) class TestObject : public QObject { Q_OBJECT - Q_PROPERTY(int x READ x) + Q_PROPERTY(int x READ x WRITE setX) public: TestObject(QObject *parent = 0); int x(); + void setX(int x) { m_x = x; } void emitMySignal() { emit mySignal(); } void emitMySignalWithArgs(int n) { emit mySignalWithArgs(n); } @@ -323,6 +327,49 @@ void tst_script::property_qmlobject() } } +#define SETPROPERTY_PROGRAM \ + "(function(testObject) { return (function() { " \ + " for (var ii = 0; ii < 10000; ++ii) { " \ + " testObject.x = ii; " \ + " } " \ + "}); })" + +void tst_script::setproperty_js() +{ + QScriptEngine engine; + + QScriptValue v = engine.newObject(); + v.setProperty(QLatin1String("x"), 0); + + QScriptValueList args; + args << v; + QScriptValue prog = engine.evaluate(SETPROPERTY_PROGRAM).call(engine.globalObject(), args); + prog.call(); + + QBENCHMARK { + prog.call(); + } +} + +void tst_script::setproperty_qmlobject() +{ + QDeclarativeEngine qmlengine; + + QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine); + TestObject to; + + QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to); + + QScriptValueList args; + args << v; + QScriptValue prog = engine->evaluate(SETPROPERTY_PROGRAM).call(engine->globalObject(), args); + prog.call(); + + QBENCHMARK { + prog.call(); + } +} + #define FUNCTION_PROGRAM \ "(function(testObject) { return (function() { " \ " var test = 0; " \ diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 6ca6bfb..ce0a1bd 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -155,7 +155,9 @@ void usage() qWarning(" -P <directory> ........................... prepend to the plugin search path"); #if defined(Q_WS_MAC) qWarning(" -no-opengl ............................... don't use a QGLWidget for the viewport"); + qWarning(" -opengl .................................. use a QGLWidget for the viewport (default)"); #else + qWarning(" -no-opengl ............................... don't use a QGLWidget for the viewport (default)"); qWarning(" -opengl .................................. use a QGLWidget for the viewport"); #endif qWarning(" -script <path> ........................... set the script to use"); @@ -374,13 +376,10 @@ static void parseCommandLineOptions(const QStringList &arguments) } else if (arg == "-translation") { if (lastArg) usage(); opts.translationFile = arguments.at(++i); -#if defined(Q_WS_MAC) } else if (arg == "-no-opengl") { opts.useGL = false; -#else } else if (arg == "-opengl") { opts.useGL = true; -#endif } else if (arg == "-qmlbrowser") { opts.useNativeFileBrowser = false; } else if (arg == "-warnings") { |