diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qml/main.cpp | 37 | ||||
-rw-r--r-- | tools/qmlimportscanner/main.cpp | 2 | ||||
-rw-r--r-- | tools/qmljs/qmljs.cpp | 14 | ||||
-rw-r--r-- | tools/qmllint/main.cpp | 2 | ||||
-rw-r--r-- | tools/qmlprofiler/main.cpp | 26 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerapplication.cpp | 254 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerapplication.h | 8 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerclient.cpp | 52 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerclient.h | 12 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerdata.cpp | 10 |
10 files changed, 192 insertions, 225 deletions
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 7e59810cd8..ea601ba946 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -51,6 +51,7 @@ #include <QFileInfo> #include <QRegularExpression> #include <QStringList> +#include <QScopedPointer> #include <QDebug> #include <QStandardPaths> #include <QTranslator> @@ -64,8 +65,8 @@ #include <cstdlib> #define VERSION_MAJ 1 -#define VERSION_MIN 0 -#define VERSION_STR "1.0" +#define VERSION_MIN 1 +#define VERSION_STR "1.1" #define FILE_OPEN_EVENT_WAIT_TIME 3000 // ms @@ -172,13 +173,20 @@ class LoadWatcher : public QObject public: LoadWatcher(QQmlApplicationEngine *e, int expected) : QObject(e) + , earlyExit(false) , expect(expected) , haveOne(false) { connect(e, SIGNAL(objectCreated(QObject*,QUrl)), this, SLOT(checkFinished(QObject*))); + // QQmlApplicationEngine also connects quit() to QCoreApplication::quit + // but if called before exec() then QCoreApplication::quit does nothing + connect(e, SIGNAL(quit()), + this, SLOT(quit())); } + bool earlyExit; + private: int expect; bool haveOne; @@ -201,6 +209,11 @@ public Q_SLOTS: exit(2);//Different return code from qFatal } } + + void quit() { + //Will be checked before calling exec() + earlyExit = true; + } }; void quietMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg) @@ -251,11 +264,10 @@ void printVersion() void printUsage() { - printf("Usage: qml [options] [files]\n"); + printf("Usage: qml [options] [files] [-- args]\n"); printf("\n"); - printf("Any argument ending in .qml will be treated as a QML file to be loaded.\n"); + printf("Any unknown argument before '--' will be treated as a QML file to be loaded.\n"); printf("Any number of QML files can be loaded. They will share the same engine.\n"); - printf("Any argument which is not a recognized option and which does not end in .qml will be ignored.\n"); printf("'gui' application type is only available if the QtGui module is available.\n"); printf("'widget' application type is only available if the QtWidgets module is available.\n"); printf("\n"); @@ -388,8 +400,8 @@ int main(int argc, char *argv[]) app->setOrganizationName("QtProject"); app->setOrganizationDomain("qt-project.org"); - qmlRegisterType<Config>("QmlRuntime.Config", VERSION_MAJ, VERSION_MIN, "Configuration"); - qmlRegisterType<PartialScene>("QmlRuntime.Config", VERSION_MAJ, VERSION_MIN, "PartialScene"); + qmlRegisterType<Config>("QmlRuntime.Config", 1, 0, "Configuration"); + qmlRegisterType<PartialScene>("QmlRuntime.Config", 1, 0, "PartialScene"); QQmlApplicationEngine e; QStringList files; QString confFile; @@ -398,7 +410,7 @@ int main(int argc, char *argv[]) //Handle main arguments QStringList argList = app->arguments(); - for (int i = 0; i < argList.count(); i++) { + for (int i = 1; i < argList.count(); i++) { const QString &arg = argList[i]; if (arg == QLatin1String("-quiet")) quietMode = true; @@ -440,9 +452,7 @@ int main(int argc, char *argv[]) dummyDir = argList[i+1]; i++; } else { - //If it ends in .qml, treat it as a file. Else ignore it - if (arg.endsWith(".qml")) - files << arg; + files << arg; } } @@ -486,7 +496,7 @@ int main(int argc, char *argv[]) loadConf(confFile, !verboseMode); //Load files - LoadWatcher lw(&e, files.count()); + QScopedPointer<LoadWatcher> lw(new LoadWatcher(&e, files.count())); // Load dummy data before loading QML-files if (!dummyDir.isEmpty() && QFileInfo (dummyDir).isDir()) @@ -518,6 +528,9 @@ int main(int argc, char *argv[]) } } + if (lw->earlyExit) + return 0; + return app->exec(); } diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index 37f2962a14..beb47e43c1 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -35,7 +35,7 @@ #include <private/qqmljsparser_p.h> #include <private/qqmljsast_p.h> #include <private/qv4codegen_p.h> -#include <private/qv4value_inl_p.h> +#include <private/qv4value_p.h> #include <private/qqmlpool_p.h> #include <private/qqmlirbuilder_p.h> diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp index db9d1b9cda..53e520cd1f 100644 --- a/tools/qmljs/qmljs.cpp +++ b/tools/qmljs/qmljs.cpp @@ -44,6 +44,7 @@ #include "private/qv4mm_p.h" #include "private/qv4context_p.h" #include "private/qv4script_p.h" +#include "private/qv4string_p.h" #ifdef V4_ENABLE_JIT # include "private/qv4isel_masm_p.h" @@ -72,7 +73,7 @@ struct Print: FunctionObject }; V4_OBJECT(FunctionObject) - static ReturnedValue call(Managed *, CallData *callData) + static ReturnedValue call(const Managed *, CallData *callData) { for (int i = 0; i < callData->argc; ++i) { QString s = callData->args[i].toQStringNoThrow(); @@ -98,9 +99,9 @@ struct GC: public FunctionObject }; V4_OBJECT(FunctionObject) - static ReturnedValue call(Managed *m, CallData *) + static ReturnedValue call(const Managed *m, CallData *) { - static_cast<GC *>(m)->engine()->memoryManager->runGC(); + static_cast<const GC *>(m)->engine()->memoryManager->runGC(); return Encode::undefined(); } }; @@ -113,7 +114,7 @@ static void showException(QV4::ExecutionContext *ctx, const QV4::Value &exceptio { QV4::Scope scope(ctx); QV4::ScopedValue ex(scope, exception); - QV4::ErrorObject *e = ex->asErrorObject(); + QV4::ErrorObject *e = ex->as<QV4::ErrorObject>(); if (!e) { std::cerr << "Uncaught exception: " << qPrintable(ex->toQString()) << std::endl; } else { @@ -187,11 +188,10 @@ int main(int argc, char *argv[]) QV4::Scope scope(&vm); QV4::ScopedContext ctx(scope, vm.rootContext()); - QV4::ScopedObject globalObject(scope, vm.globalObject()); QV4::ScopedObject print(scope, vm.memoryManager->alloc<builtins::Print>(ctx)); - globalObject->put(QV4::ScopedString(scope, vm.newIdentifier(QStringLiteral("print"))).getPointer(), print); + vm.globalObject->put(QV4::ScopedString(scope, vm.newIdentifier(QStringLiteral("print"))).getPointer(), print); QV4::ScopedObject gc(scope, vm.memoryManager->alloc<builtins::GC>(ctx)); - globalObject->put(QV4::ScopedString(scope, vm.newIdentifier(QStringLiteral("gc"))).getPointer(), gc); + vm.globalObject->put(QV4::ScopedString(scope, vm.newIdentifier(QStringLiteral("gc"))).getPointer(), gc); foreach (const QString &fn, args) { QFile file(fn); diff --git a/tools/qmllint/main.cpp b/tools/qmllint/main.cpp index cd81a5bad6..a1161c635a 100644 --- a/tools/qmllint/main.cpp +++ b/tools/qmllint/main.cpp @@ -37,7 +37,7 @@ #include <QCommandLineParser> #include <QCoreApplication> -#include <private/qv4value_inl_p.h> +#include <private/qv4value_p.h> #include <private/qqmljslexer_p.h> #include <private/qqmljsparser_p.h> #include <private/qqmljsengine_p.h> diff --git a/tools/qmlprofiler/main.cpp b/tools/qmlprofiler/main.cpp index a1bd1b38b4..2a85b72f1e 100644 --- a/tools/qmlprofiler/main.cpp +++ b/tools/qmlprofiler/main.cpp @@ -38,19 +38,17 @@ int main(int argc, char *argv[]) { QmlProfilerApplication app(argc, argv); - if (!app.parseArguments()) { - app.printUsage(); - return 1; - } - - CommandListener listener; - QObject::connect(&listener, SIGNAL(command(QString)), &app, SLOT(userCommand(QString))); - listener.start(); - - int exitValue = app.exec(); - // wait for listener to exit - listener.wait(); + app.parseArguments(); - - return exitValue; + if (app.isInteractive()) { + CommandListener listener; + QObject::connect(&listener, SIGNAL(command(QString)), &app, SLOT(userCommand(QString))); + listener.start(); + int exitValue = app.exec(); + // wait for listener to exit + listener.wait(); + return exitValue; + } else { + return app.exec(); + } } diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index a51f67164f..c2d3375d10 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -40,35 +40,12 @@ #include <QtCore/QDateTime> #include <QtCore/QFileInfo> #include <QtCore/QDebug> - -static const char usageTextC[] = -"Usage:\n" -" qmlprofiler [options] [program] [program-options]\n" -" qmlprofiler [options] -attach [hostname]\n" -"\n" -"QML Profiler retrieves QML tracing data from a running application.\n" -"The data collected can then be visualized in Qt Creator.\n" -"\n" -"The application to be profiled has to enable QML debugging. See the Qt Creator\n" -"documentation on how to do this for different Qt versions.\n" -"\n" -"Options:\n" -" -help Show this information and exit.\n" -" -fromStart\n" -" Record as soon as the engine is started, default is false.\n" -" -p <number>, -port <number>\n" -" TCP/IP port to use, default is 3768.\n" -" -v, -verbose\n" -" Print debugging output.\n" -" -version\n" -" Show the version of qmlprofiler and exit.\n"; +#include <QtCore/QCommandLineParser> static const char commandTextC[] = -"Commands:\n" -" r, record\n" -" Switch recording on or off.\n" -" q, quit\n" -" Terminate program."; + "The following commands are available:\n" + "\"r\", \"record\" Switch recording on or off.\n" + "\"q\", \"quit\" Terminate program."; static const char TraceFileExtension[] = ".qtd"; @@ -81,6 +58,8 @@ QmlProfilerApplication::QmlProfilerApplication(int &argc, char **argv) : m_port(3768), m_verbose(false), m_quitAfterSave(false), + m_recording(true), + m_interactive(false), m_qmlProfilerClient(&m_connection), m_v8profilerClient(&m_connection), m_connectionAttempts(0), @@ -95,11 +74,11 @@ QmlProfilerApplication::QmlProfilerApplication(int &argc, char **argv) : connect(&m_connection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError))); connect(&m_qmlProfilerClient, SIGNAL(enabledChanged()), this, SLOT(traceClientEnabled())); - connect(&m_qmlProfilerClient, SIGNAL(recordingChanged(bool)), this, SLOT(recordingChanged())); connect(&m_qmlProfilerClient, SIGNAL(range(QQmlProfilerService::RangeType,QQmlProfilerService::BindingType,qint64,qint64,QStringList,QmlEventLocation)), &m_profilerData, SLOT(addQmlEvent(QQmlProfilerService::RangeType,QQmlProfilerService::BindingType,qint64,qint64,QStringList,QmlEventLocation))); connect(&m_qmlProfilerClient, SIGNAL(traceFinished(qint64)), &m_profilerData, SLOT(setTraceEndTime(qint64))); connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), &m_profilerData, SLOT(setTraceStartTime(qint64))); + connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), this, SLOT(notifyTraceStarted())); connect(&m_qmlProfilerClient, SIGNAL(frame(qint64,int,int,int)), &m_profilerData, SLOT(addFrameEvent(qint64,int,int,int))); connect(&m_qmlProfilerClient, SIGNAL(sceneGraphFrame(QQmlProfilerService::SceneGraphFrameType, qint64,qint64,qint64,qint64,qint64,qint64)), @@ -140,63 +119,97 @@ QmlProfilerApplication::~QmlProfilerApplication() delete m_process; } -bool QmlProfilerApplication::parseArguments() +void QmlProfilerApplication::parseArguments() { - for (int argPos = 1; argPos < arguments().size(); ++argPos) { - const QString arg = arguments().at(argPos); - if (arg == QLatin1String("-attach") || arg == QLatin1String("-a")) { - if (argPos + 1 == arguments().size()) { - return false; - } - m_hostName = arguments().at(++argPos); - m_runMode = AttachMode; - } else if (arg == QLatin1String("-port") || arg == QLatin1String("-p")) { - if (argPos + 1 == arguments().size()) { - return false; - } - const QString portStr = arguments().at(++argPos); - bool isNumber; - m_port = portStr.toUShort(&isNumber); - if (!isNumber) { - logError(QString("'%1' is not a valid port").arg(portStr)); - return false; - } - } else if (arg == QLatin1String("-fromStart")) { - m_qmlProfilerClient.setRecording(true); - m_v8profilerClient.setRecording(true); - } else if (arg == QLatin1String("-help") || arg == QLatin1String("-h") || arg == QLatin1String("/h") || arg == QLatin1String("/?")) { - return false; - } else if (arg == QLatin1String("-verbose") || arg == QLatin1String("-v")) { - m_verbose = true; - } else if (arg == QLatin1String("-version")) { - print(QString("QML Profiler based on Qt %1.").arg(qVersion())); - ::exit(1); - return false; - } else { - if (m_programPath.isEmpty()) { - m_programPath = arg; - m_tracePrefix = QFileInfo(m_programPath).fileName(); - } else { - m_programArguments << arg; - } + setApplicationName(QLatin1String("qmlprofiler")); + setApplicationVersion(QLatin1String(qVersion())); + + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); + + parser.setApplicationDescription(QChar::LineFeed + tr( + "The QML Profiler retrieves QML tracing data from an application. The data\n" + "collected can then be visualized in Qt Creator. The application to be profiled\n" + "has to enable QML debugging. See the Qt Creator documentation on how to do\n" + "this for different Qt versions.")); + + QCommandLineOption attach(QStringList() << QLatin1String("a") << QLatin1String("attach"), + tr("Attach to an application already running on <hostname>, " + "instead of starting it locally."), + QLatin1String("hostname")); + parser.addOption(attach); + + QCommandLineOption port(QStringList() << QLatin1String("p") << QLatin1String("port"), + tr("Connect to the TCP port <port>. The default is 3768."), + QLatin1String("port"), QLatin1String("3768")); + parser.addOption(port); + + QCommandLineOption record(QLatin1String("record"), + tr("If set to 'off', don't immediately start recording data when the " + "QML engine starts, but instead either start the recording " + "interactively or with the JavaScript console.profile() function. " + "By default the recording starts immediately."), + QLatin1String("on|off"), QLatin1String("on")); + parser.addOption(record); + + QCommandLineOption interactive(QLatin1String("interactive"), + tr("Manually control the recording from the command line. The " + "profiler will not terminate itself when the application " + "does so in this case.") + QChar::Space + tr(commandTextC)); + parser.addOption(interactive); + + QCommandLineOption verbose(QStringList() << QLatin1String("verbose"), + tr("Print debugging output.")); + parser.addOption(verbose); + + parser.addHelpOption(); + parser.addVersionOption(); + + parser.addPositionalArgument(QLatin1String("program"), + tr("The program to be started and profiled."), + QLatin1String("[program]")); + parser.addPositionalArgument(QLatin1String("parameters"), + tr("Parameters for the program to be started."), + QLatin1String("[parameters...]")); + + parser.process(*this); + + if (parser.isSet(attach)) { + m_hostName = parser.value(attach); + m_runMode = AttachMode; + } + + if (parser.isSet(port)) { + bool isNumber; + m_port = parser.value(port).toUShort(&isNumber); + if (!isNumber) { + logError(tr("'%1' is not a valid port.").arg(parser.value(port))); + parser.showHelp(1); } } - if (m_runMode == LaunchMode - && m_programPath.isEmpty()) - return false; + m_recording = (parser.value(record) == QLatin1String("on")); + m_interactive = parser.isSet(interactive); - if (m_runMode == AttachMode - && !m_programPath.isEmpty()) - return false; + if (parser.isSet(verbose)) + m_verbose = true; - return true; -} + m_programArguments = parser.positionalArguments(); + if (!m_programArguments.isEmpty()) { + m_programPath = m_programArguments.takeFirst(); + m_tracePrefix = QFileInfo(m_programPath).fileName(); + } -void QmlProfilerApplication::printUsage() -{ - print(QLatin1String(usageTextC)); - print(QLatin1String(commandTextC)); + if (m_runMode == LaunchMode && m_programPath.isEmpty()) { + logError(tr("You have to specify either --attach or a program to start.")); + parser.showHelp(2); + } + + if (m_runMode == AttachMode && !m_programPath.isEmpty()) { + logError(tr("--attach cannot be used when starting a program.")); + parser.showHelp(3); + } } int QmlProfilerApplication::exec() @@ -205,9 +218,14 @@ int QmlProfilerApplication::exec() return QCoreApplication::exec(); } +bool QmlProfilerApplication::isInteractive() const +{ + return m_interactive; +} + void QmlProfilerApplication::printCommands() { - print(QLatin1String(commandTextC)); + print(tr(commandTextC)); } QString QmlProfilerApplication::traceFileName() const @@ -237,26 +255,28 @@ void QmlProfilerApplication::userCommand(const QString &command) printCommands(); } else if (cmd == Constants::CMD_RECORD || cmd == Constants::CMD_RECORD2) { - m_qmlProfilerClient.setRecording( - !m_qmlProfilerClient.isRecording()); - m_v8profilerClient.setRecording(!m_v8profilerClient.isRecording()); - m_qmlDataReady = false; - m_v8DataReady = false; + m_qmlProfilerClient.sendRecordingStatus(!m_recording); + m_v8profilerClient.sendRecordingStatus(!m_recording); } else if (cmd == Constants::CMD_QUIT || cmd == Constants::CMD_QUIT2) { print(QLatin1String("Quit")); - if (m_qmlProfilerClient.isRecording()) { + if (m_recording) { m_quitAfterSave = true; - m_qmlDataReady = false; - m_v8DataReady = false; - m_qmlProfilerClient.setRecording(false); - m_v8profilerClient.setRecording(false); + m_qmlProfilerClient.sendRecordingStatus(false); + m_v8profilerClient.sendRecordingStatus(false); } else { quit(); } } } +void QmlProfilerApplication::notifyTraceStarted() +{ + // Synchronize to server state. It doesn't hurt to do this multiple times in a row for + // different traces. There is no symmetric event to "Complete" after all. + m_recording = true; +} + void QmlProfilerApplication::run() { if (m_runMode == LaunchMode) { @@ -304,17 +324,9 @@ void QmlProfilerApplication::tryToConnect() void QmlProfilerApplication::connected() { m_connectTimer.stop(); - print(QString(QLatin1String("Connected to host:port %1:%2." - "Wait for profile data or type a command" - "(type 'help'' to show list of commands).") - ).arg(m_hostName).arg((m_port))); - QString recordingStatus(QLatin1String("Recording Status: %1")); - if (!m_qmlProfilerClient.isRecording() && - !m_v8profilerClient.isRecording()) - recordingStatus = recordingStatus.arg(QLatin1String("Off")); - else - recordingStatus = recordingStatus.arg(QLatin1String("On")); - print(recordingStatus); + print(tr("Connected to host:port %1:%2. Wait for profile data or type a command (type 'help' " + "to show list of commands).").arg(m_hostName).arg((m_port))); + print(tr("Recording Status: %1").arg(m_recording ? tr("on") : tr("off"))); } void QmlProfilerApplication::connectionStateChanged( @@ -342,19 +354,19 @@ void QmlProfilerApplication::processHasOutput() void QmlProfilerApplication::processFinished() { Q_ASSERT(m_process); + int exitCode = 0; if (m_process->exitStatus() == QProcess::NormalExit) { logStatus(QString("Process exited (%1).").arg(m_process->exitCode())); - - if (m_qmlProfilerClient.isRecording()) { - logError("Process exited while recording, last trace is lost!"); - exit(2); - } else { - exit(0); + if (m_recording) { + logError("Process exited while recording, last trace is damaged!"); + exitCode = 2; } } else { - logError("Process crashed! Exiting ..."); - exit(3); + logError("Process crashed!"); + exitCode = 3; } + if (!m_interactive) + exit(exitCode); } void QmlProfilerApplication::traceClientEnabled() @@ -362,8 +374,8 @@ void QmlProfilerApplication::traceClientEnabled() logStatus("Trace client is attached."); // blocked server is waiting for recording message from both clients // once the last one is connected, both messages should be sent - m_qmlProfilerClient.sendRecordingStatus(); - m_v8profilerClient.sendRecordingStatus(); + m_qmlProfilerClient.sendRecordingStatus(m_recording); + m_v8profilerClient.sendRecordingStatus(m_recording); } void QmlProfilerApplication::profilerClientEnabled() @@ -372,30 +384,26 @@ void QmlProfilerApplication::profilerClientEnabled() // blocked server is waiting for recording message from both clients // once the last one is connected, both messages should be sent - m_qmlProfilerClient.sendRecordingStatus(); - m_v8profilerClient.sendRecordingStatus(); + m_qmlProfilerClient.sendRecordingStatus(m_recording); + m_v8profilerClient.sendRecordingStatus(m_recording); } void QmlProfilerApplication::traceFinished() { + m_recording = false; // only on "Complete" we know that the trace is really finished. const QString fileName = traceFileName(); if (m_profilerData.save(fileName)) print(QString("Saving trace to %1.").arg(fileName)); + // after saving, reset the flags + m_qmlDataReady = false; + m_v8DataReady = false; + if (m_quitAfterSave) quit(); } -void QmlProfilerApplication::recordingChanged() -{ - if (m_qmlProfilerClient.isRecording()) { - print(QLatin1String("Recording is on.")); - } else { - print(QLatin1String("Recording is off.")); - } -} - void QmlProfilerApplication::print(const QString &line) { QTextStream err(stderr); @@ -422,8 +430,6 @@ void QmlProfilerApplication::qmlComplete() if (m_v8profilerClient.state() != QQmlDebugClient::Enabled || m_v8DataReady) { m_profilerData.complete(); - // once complete is sent, reset the flag - m_qmlDataReady = false; } } @@ -433,7 +439,5 @@ void QmlProfilerApplication::v8Complete() if (m_qmlProfilerClient.state() != QQmlDebugClient::Enabled || m_qmlDataReady) { m_profilerData.complete(); - // once complete is sent, reset the flag - m_v8DataReady = false; } } diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h index 7e7cebfcf1..d4af3b0c37 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.h +++ b/tools/qmlprofiler/qmlprofilerapplication.h @@ -48,12 +48,13 @@ public: QmlProfilerApplication(int &argc, char **argv); ~QmlProfilerApplication(); - bool parseArguments(); - void printUsage(); + void parseArguments(); int exec(); + bool isInteractive() const; public slots: void userCommand(const QString &command); + void notifyTraceStarted(); private slots: void run(); @@ -67,7 +68,6 @@ private slots: void traceClientEnabled(); void profilerClientEnabled(); void traceFinished(); - void recordingChanged(); void print(const QString &line); void logError(const QString &error); @@ -95,6 +95,8 @@ private: quint16 m_port; bool m_verbose; bool m_quitAfterSave; + bool m_recording; + bool m_interactive; QQmlDebugConnection m_connection; QmlProfilerClient m_qmlProfilerClient; diff --git a/tools/qmlprofiler/qmlprofilerclient.cpp b/tools/qmlprofiler/qmlprofilerclient.cpp index 711ddbd862..f6ac846668 100644 --- a/tools/qmlprofiler/qmlprofilerclient.cpp +++ b/tools/qmlprofiler/qmlprofilerclient.cpp @@ -39,17 +39,12 @@ ProfilerClient::ProfilerClient(const QString &clientName, QQmlDebugConnection *client) : QQmlDebugClient(clientName, client), - m_recording(false), m_enabled(false) { } ProfilerClient::~ProfilerClient() { - //Disable profiling if started by client - //Profiling data will be lost!! - if (isRecording()) - setRecording(false); } void ProfilerClient::clearData() @@ -62,29 +57,6 @@ bool ProfilerClient::isEnabled() const return m_enabled; } -void ProfilerClient::sendRecordingStatus() -{ -} - -bool ProfilerClient::isRecording() const -{ - return m_recording; -} - -void ProfilerClient::setRecording(bool v) -{ - if (v == m_recording) - return; - - m_recording = v; - - if (state() == Enabled) { - sendRecordingStatus(); - } - - emit recordingChanged(v); -} - void ProfilerClient::stateChanged(State status) { if ((m_enabled && status != Enabled) || @@ -100,7 +72,6 @@ class QmlProfilerClientPrivate public: QmlProfilerClientPrivate() : inProgressRanges(0) - , maximumTime(0) { ::memset(rangeCount, 0, QQmlProfilerService::MaximumRangeType * sizeof(int)); @@ -112,7 +83,6 @@ public: QStack<QmlEventLocation> rangeLocations[QQmlProfilerService::MaximumRangeType]; QStack<QQmlProfilerService::BindingType> bindingTypes; int rangeCount[QQmlProfilerService::MaximumRangeType]; - qint64 maximumTime; }; QmlProfilerClient::QmlProfilerClient( @@ -135,11 +105,11 @@ void QmlProfilerClient::clearData() ProfilerClient::clearData(); } -void QmlProfilerClient::sendRecordingStatus() +void QmlProfilerClient::sendRecordingStatus(bool record) { QByteArray ba; QDataStream stream(&ba, QIODevice::WriteOnly); - stream << isRecording(); + stream << record; sendMessage(ba); } @@ -162,8 +132,6 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) if (event == QQmlProfilerService::EndTrace) { emit this->traceFinished(time); - d->maximumTime = time; - d->maximumTime = qMax(time, d->maximumTime); } else if (event == QQmlProfilerService::AnimationFrame) { int frameRate, animationCount; int threadId = 0; @@ -171,12 +139,9 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) if (!stream.atEnd()) stream >> threadId; emit this->frame(time, frameRate, animationCount, threadId); - d->maximumTime = qMax(time, d->maximumTime); } else if (event == QQmlProfilerService::StartTrace) { emit this->traceStarted(time); - d->maximumTime = time; } else if (event < QQmlProfilerService::MaximumEventType) { - d->maximumTime = qMax(time, d->maximumTime); } } else if (messageType == QQmlProfilerService::Complete) { emit complete(); @@ -193,7 +158,6 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) params[count++] = 0; emit sceneGraphFrame((QQmlProfilerService::SceneGraphFrameType)sgEventType, time, params[0], params[1], params[2], params[3], params[4]); - d->maximumTime = qMax(time, d->maximumTime); } else if (messageType == QQmlProfilerService::PixmapCacheEvent) { int pixEvTy, width = 0, height = 0, refcount = 0; QString pixUrl; @@ -207,13 +171,11 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) } emit pixmapCache((QQmlProfilerService::PixmapEventType)pixEvTy, time, QmlEventLocation(pixUrl,0,0), width, height, refcount); - d->maximumTime = qMax(time, d->maximumTime); } else if (messageType == QQmlProfilerService::MemoryAllocation) { int type; qint64 delta; stream >> type >> delta; emit memoryAllocation((QQmlProfilerService::MemoryType)type, time, delta); - d->maximumTime = qMax(time, d->maximumTime); } else { int range; stream >> range; @@ -263,7 +225,6 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) if (d->inProgressRanges & (static_cast<qint64>(1) << range)) d->inProgressRanges &= ~(static_cast<qint64>(1) << range); - d->maximumTime = qMax(time, d->maximumTime); QStringList data = d->rangeDatas[range].count() ? d->rangeDatas[range].pop() : QStringList(); QmlEventLocation location = d->rangeLocations[range].count() ? @@ -296,19 +257,14 @@ V8ProfilerClient::~V8ProfilerClient() { } -void V8ProfilerClient::sendRecordingStatus() +void V8ProfilerClient::sendRecordingStatus(bool record) { QByteArray ba; QDataStream stream(&ba, QIODevice::WriteOnly); QByteArray cmd("V8PROFILER"); - QByteArray option(""); + QByteArray option(record ? "start" : "stop"); QByteArray title(""); - if (m_recording) { - option = "start"; - } else { - option = "stop"; - } stream << cmd << option << title; sendMessage(ba); } diff --git a/tools/qmlprofiler/qmlprofilerclient.h b/tools/qmlprofiler/qmlprofilerclient.h index 2d9c382ff6..84da96197b 100644 --- a/tools/qmlprofiler/qmlprofilerclient.h +++ b/tools/qmlprofiler/qmlprofilerclient.h @@ -44,25 +44,18 @@ class ProfilerClient : public QQmlDebugClient Q_OBJECT Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged) - Q_PROPERTY(bool recording READ isRecording WRITE setRecording - NOTIFY recordingChanged) - public: ProfilerClient(const QString &clientName, QQmlDebugConnection *client); ~ProfilerClient(); bool isEnabled() const; - bool isRecording() const; public slots: - void setRecording(bool); virtual void clearData(); - virtual void sendRecordingStatus(); signals: void complete(); - void recordingChanged(bool arg); void enabledChanged(); void cleared(); @@ -70,7 +63,6 @@ protected: virtual void stateChanged(State); protected: - bool m_recording; bool m_enabled; }; @@ -84,7 +76,7 @@ public: public slots: void clearData(); - void sendRecordingStatus(); + void sendRecordingStatus(bool record); signals: void traceFinished( qint64 time ); @@ -125,7 +117,7 @@ public: ~V8ProfilerClient(); public slots: - void sendRecordingStatus(); + void sendRecordingStatus(bool record); signals: void range(int depth, const QString &function, const QString &filename, diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp index c5992652f8..eaa7cc0e7e 100644 --- a/tools/qmlprofiler/qmlprofilerdata.cpp +++ b/tools/qmlprofiler/qmlprofilerdata.cpp @@ -187,8 +187,8 @@ void QmlProfilerData::clear() d->clearV8RootEvent(); d->v8MeasuredTime = 0; - d->traceEndTime = 0; - d->traceStartTime = -1; + d->traceEndTime = std::numeric_limits<qint64>::min(); + d->traceStartTime = std::numeric_limits<qint64>::max(); d->qmlMeasuredTime = 0; setState(Empty); @@ -226,12 +226,14 @@ QString QmlProfilerData::qmlMessageAsString(QQmlProfilerService::Message type) void QmlProfilerData::setTraceStartTime(qint64 time) { - d->traceStartTime = time; + if (time < d->traceStartTime) + d->traceStartTime = time; } void QmlProfilerData::setTraceEndTime(qint64 time) { - d->traceEndTime = time; + if (time > d->traceEndTime) + d->traceEndTime = time; } qint64 QmlProfilerData::traceStartTime() const |