From 0f9cd5d0c7a9c58f0627d43e4a147d70b1e9f16a Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Thu, 1 Jun 2017 12:18:32 +0530 Subject: [PATCH] intial commit hifi: #21369 Implement parts of the JS "console" object --- interface/src/ui/JSConsole.cpp | 11 +- interface/src/ui/JSConsole.h | 6 +- interface/src/ui/TestingDialog.cpp | 3 +- .../src/ConsoleScriptingInterface.cpp | 137 ++++++++++++++++++ .../src/ConsoleScriptingInterface.h | 51 +++++++ libraries/script-engine/src/ScriptEngine.cpp | 6 +- libraries/script-engine/src/ScriptEngine.h | 5 +- scripts/developer/tests/printTest.js | 6 + 8 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 libraries/script-engine/src/ConsoleScriptingInterface.cpp create mode 100644 libraries/script-engine/src/ConsoleScriptingInterface.h diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index 79314ce49a..3c1787ab2e 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -21,6 +21,7 @@ #include "Application.h" #include "JSConsole.h" #include "ScriptHighlighting.h" +//#include "D:\Dhruvesh\Project\Hifi\github\hifi\libraries\script-engine\src\ScriptEngineLogging.h" const int NO_CURRENT_HISTORY_COMMAND = -1; const int MAX_HISTORY_SIZE = 64; @@ -84,6 +85,7 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) { disconnect(_scriptEngine, &ScriptEngine::infoMessage, this, &JSConsole::handleInfo); disconnect(_scriptEngine, &ScriptEngine::warningMessage, this, &JSConsole::handleWarning); disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError); + disconnect(_scriptEngine, &ScriptEngine::clearDebugWindow, this, &JSConsole::clear); if (_ownScriptEngine) { _scriptEngine->deleteLater(); } @@ -97,6 +99,7 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) { connect(_scriptEngine, &ScriptEngine::infoMessage, this, &JSConsole::handleInfo); connect(_scriptEngine, &ScriptEngine::warningMessage, this, &JSConsole::handleWarning); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError); + connect(_scriptEngine, &ScriptEngine::clearDebugWindow, this, &JSConsole::clear); } void JSConsole::executeCommand(const QString& command) { @@ -144,6 +147,7 @@ void JSConsole::commandFinished() { void JSConsole::handleError(const QString& message, const QString& scriptName) { Q_UNUSED(scriptName); appendMessage(GUTTER_ERROR, "" + message.toHtmlEscaped() + ""); + } void JSConsole::handlePrint(const QString& message, const QString& scriptName) { @@ -291,11 +295,14 @@ void JSConsole::appendMessage(const QString& gutter, const QString& message) { } void JSConsole::clear() { + /* qCDebug(scriptengine) << "============================="; + qCDebug(scriptengine) << "Clear fUNCTION";*/ QLayoutItem* item; while ((item = _ui->logArea->layout()->takeAt(0)) != NULL) { + // qCDebug(scriptengine) << "While loop called"; delete item->widget(); delete item; } - _ui->logArea->updateGeometry(); - scrollToBottom(); + // _ui->logArea->updateGeometry(); + // scrollToBottom(); } diff --git a/interface/src/ui/JSConsole.h b/interface/src/ui/JSConsole.h index 864f847071..1e33414183 100644 --- a/interface/src/ui/JSConsole.h +++ b/interface/src/ui/JSConsole.h @@ -32,8 +32,7 @@ public: JSConsole(QWidget* parent, ScriptEngine* scriptEngine = NULL); ~JSConsole(); - void setScriptEngine(ScriptEngine* scriptEngine = NULL); - void clear(); + void setScriptEngine(ScriptEngine* scriptEngine = NULL); public slots: void executeCommand(const QString& command); @@ -51,7 +50,8 @@ protected slots: void handleInfo(const QString& message, const QString& scriptName); void handleWarning(const QString& message, const QString& scriptName); void handleError(const QString& message, const QString& scriptName); - void commandFinished(); + void commandFinished(); + void clear(); private: void appendMessage(const QString& gutter, const QString& message); diff --git a/interface/src/ui/TestingDialog.cpp b/interface/src/ui/TestingDialog.cpp index f55eb63a5b..10e66e05a1 100644 --- a/interface/src/ui/TestingDialog.cpp +++ b/interface/src/ui/TestingDialog.cpp @@ -26,10 +26,11 @@ TestingDialog::TestingDialog(QWidget* parent) : auto _engines = DependencyManager::get(); _engine = _engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath); _console->setScriptEngine(_engine); - connect(_engine, &ScriptEngine::finished, this, &TestingDialog::onTestingFinished); + connect(_engine, &ScriptEngine::finished, this, &TestingDialog::onTestingFinished); } void TestingDialog::onTestingFinished(const QString& scriptPath) { _engine = nullptr; _console->setScriptEngine(nullptr); + } diff --git a/libraries/script-engine/src/ConsoleScriptingInterface.cpp b/libraries/script-engine/src/ConsoleScriptingInterface.cpp new file mode 100644 index 0000000000..4131f81320 --- /dev/null +++ b/libraries/script-engine/src/ConsoleScriptingInterface.cpp @@ -0,0 +1,137 @@ +// +// ConsoleScriptingInterface.cpp +// libraries/script-engine/src +// +// Created by volansystech on 6/1/17. +// Copyright 2014 High Fidelity, Inc. +// +// ConsoleScriptingInterface is responsible to print logs +// using "console" object on debug Window and Logs/log file with proper tags. +// Used in Javascripts file. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ConsoleScriptingInterface.h" +#include "ScriptEngine.h" + +void ConsoleScriptingInterface::info(QString message) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptInfoMessage(message); + } +} + +void ConsoleScriptingInterface::log(QString message) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptPrintedMessage(message); + } +} + +void ConsoleScriptingInterface::debug(QString message) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptPrintedMessage(message); + } +} + +void ConsoleScriptingInterface::warn(QString message) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptWarningMessage(message); + } +} + +void ConsoleScriptingInterface::error(QString message) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptErrorMessage(message); + } +} + +void ConsoleScriptingInterface::exception(QString message) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptErrorMessage(message); + } +} + +void ConsoleScriptingInterface::time(QString labelName) { + QDateTime date; + std::string val_string = "2017-06-06 11:15:00.000"; + QString d = QString::fromStdString(val_string.substr(0, 19)); + date = QDateTime::fromString(d, "yyyy-MM-dd HH:mm:ss"); + qDebug() << d; + qDebug() << d.length() << date.toUTC(); + + QDateTime _currentTime = QDateTime::currentDateTime().toUTC(); + _listOfTimeValues.insert(labelName, date.toUTC()); +} + +void ConsoleScriptingInterface::timeEnd(QString labelName) { + QDateTime _dateTimeOfLabel; + QString message; + qint64 millisecondsDiff = 0; + + bool _labelInList = _listOfTimeValues.contains(labelName); + + //Check if not exist items in list + if (!_labelInList) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + message = "No such label found " + labelName; + scriptEngine->scriptErrorMessage(message); + } + return; + } + QDateTime _currentDateTimeValue = QDateTime::currentDateTime().toUTC(); + _dateTimeOfLabel = _listOfTimeValues.value(labelName); + + if (!_dateTimeOfLabel.isNull()) { + _listOfTimeValues.remove(labelName); + } + + if (_dateTimeOfLabel.toString(TIME_FORMAT) == _currentDateTimeValue.toString(TIME_FORMAT)) { + millisecondsDiff = _dateTimeOfLabel.msecsTo(_currentDateTimeValue); + message = QString::number(millisecondsDiff) + " ms"; + } else { + message = secondsToString(_dateTimeOfLabel.secsTo(_currentDateTimeValue)); + } + + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptPrintedMessage("Time : " + message); + } +} + +QString ConsoleScriptingInterface::secondsToString(qint64 seconds) +{ + qint64 days = seconds / DAY; + QTime timeDuration = QTime(0, 0).addSecs(seconds % DAY); + + return QString("%1 days, %2 hours, %3 minutes, %4 seconds") + .arg(QString::number(days)).arg(QString::number(timeDuration.hour())).arg(QString::number(timeDuration.minute())).arg(QString::number(timeDuration.second())); +} + +void ConsoleScriptingInterface::asserts(bool condition, QString message) { + if (!condition) { + QString assertFailed = "Assertion failed"; + if (message.isEmpty()) { + message = assertFailed; + } else { + if (typeid(message) != typeid(QString)) { + message = assertFailed; + } else { + message = assertFailed + " " + message; + } + } + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptErrorMessage(message); + } + } +} + +void ConsoleScriptingInterface::trace(QString labelName) { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->scriptErrorMessage(labelName); + } +} +void ConsoleScriptingInterface::clear() { + if (ScriptEngine* scriptEngine = qobject_cast(engine())) { + scriptEngine->clearConsole(); + } +} \ No newline at end of file diff --git a/libraries/script-engine/src/ConsoleScriptingInterface.h b/libraries/script-engine/src/ConsoleScriptingInterface.h new file mode 100644 index 0000000000..70969a11fb --- /dev/null +++ b/libraries/script-engine/src/ConsoleScriptingInterface.h @@ -0,0 +1,51 @@ +// +// ConsoleScriptingInterface.h +// libraries/script-engine/src +// +// Created by volansystech on 6/1/17. +// Copyright 2014 High Fidelity, Inc. +// +// ConsoleScriptingInterface is responsible to print log. +// using "console" object on debug Window and Logs/log file with proper tags. +// Used in Javascripts file. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_ConsoleScriptingInterface_h +#define hifi_ConsoleScriptingInterface_h + + +#include +#include +#include +#include + + +/// Scriptable interface of console object. Used exclusively in the JavaScript API +class ConsoleScriptingInterface : public QObject, protected QScriptable { + Q_OBJECT +public slots: + void info(QString message); + void log(QString message); + void debug(QString message); + void warn(QString message); + void error(QString message); + void exception(QString message); + void time(QString labelName); + void timeEnd(QString labelName); + void asserts(bool condition, QString data=""); + void trace(QString labelName); + void clear(); +public: + QString secondsToString(qint64 seconds); + bool isInteger(const std::string & s); +private: + QMap _listOfTimeValues; + const qint64 DAY = 86400; + const QString TIME_FORMAT = "yyyy-MM-dd HH:mm"; +}; + +#endif // hifi_ConsoleScriptingInterface_h diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 61bf601019..add7ab411d 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -485,7 +485,10 @@ void ScriptEngine::scriptPrintedMessage(const QString& message) { qCDebug(scriptengine) << message; emit printedMessage(message, getFilename()); } - +void ScriptEngine::clearConsole() { + qCDebug(scriptengine) << "Clearing debug window"; + emit clearDebugWindow(); +} // Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of // callAnimationStateHandler requires that the type be registered. // These two are meaningful, if we ever do want to use them... @@ -665,6 +668,7 @@ void ScriptEngine::init() { registerGlobalObject("Entities", entityScriptingInterface.data()); registerGlobalObject("Quat", &_quatLibrary); registerGlobalObject("Vec3", &_vec3Library); + registerGlobalObject("console", &_consoleScriptingInterface); registerGlobalObject("Mat4", &_mat4Library); registerGlobalObject("Uuid", &_uuidLibrary); registerGlobalObject("Messages", DependencyManager::get().data()); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 010cdfbc75..a12a399b84 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -41,6 +41,7 @@ #include "ScriptCache.h" #include "ScriptUUID.h" #include "Vec3.h" +#include "ConsoleScriptingInterface.h" #include "SettingHandle.h" class QScriptEngineDebugger; @@ -225,7 +226,7 @@ public: void scriptWarningMessage(const QString& message); void scriptInfoMessage(const QString& message); void scriptPrintedMessage(const QString& message); - + void clearConsole(); int getNumRunningEntityScripts() const; bool getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const; @@ -245,6 +246,7 @@ signals: void warningMessage(const QString& message, const QString& scriptName); void infoMessage(const QString& message, const QString& scriptName); void runningStateChanged(); + void clearDebugWindow(); void loadScript(const QString& scriptName, bool isUserLoaded); void reloadScript(const QString& scriptName, bool isUserLoaded); void doneRunning(); @@ -305,6 +307,7 @@ protected: Vec3 _vec3Library; Mat4 _mat4Library; ScriptUUID _uuidLibrary; + ConsoleScriptingInterface _consoleScriptingInterface; std::atomic _isUserLoaded { false }; bool _isReloading { false }; diff --git a/scripts/developer/tests/printTest.js b/scripts/developer/tests/printTest.js index c1fe6ec745..4e6d68e170 100644 --- a/scripts/developer/tests/printTest.js +++ b/scripts/developer/tests/printTest.js @@ -36,4 +36,10 @@ function main() { Uuid.print('[Uuid.print]', Uuid.fromString(Uuid.toString(0))); } + console.info('[console.info] hello world'); + console.log('[console.log] hello world'); + console.debug('[console.Debug] hello world'); + console.warn('[console.Warn] hello world'); + console.error('[console.error] hello world'); + console.exception('[console.exception] hello world'); }