Merge pull request #10388 from humbletim/21308

CR #21308 Fix Script.print
This commit is contained in:
Chris Collins 2017-05-08 10:46:49 -07:00 committed by GitHub
commit 4bfb23b5d2
14 changed files with 131 additions and 34 deletions

View file

@ -28,11 +28,15 @@ const int MAX_HISTORY_SIZE = 64;
const QString COMMAND_STYLE = "color: #266a9b;";
const QString RESULT_SUCCESS_STYLE = "color: #677373;";
const QString RESULT_INFO_STYLE = "color: #223bd1;";
const QString RESULT_WARNING_STYLE = "color: #d13b22;";
const QString RESULT_ERROR_STYLE = "color: #d13b22;";
const QString GUTTER_PREVIOUS_COMMAND = "<span style=\"color: #57b8bb;\">&lt;</span>";
const QString GUTTER_ERROR = "<span style=\"color: #d13b22;\">X</span>";
const QString JSConsole::_consoleFileName { "about:console" };
JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) :
QWidget(parent),
_ui(new Ui::Console),
@ -77,6 +81,8 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) {
}
if (_scriptEngine != NULL) {
disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &JSConsole::handlePrint);
disconnect(_scriptEngine, &ScriptEngine::infoMessage, this, &JSConsole::handleInfo);
disconnect(_scriptEngine, &ScriptEngine::warningMessage, this, &JSConsole::handleWarning);
disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError);
if (_ownScriptEngine) {
_scriptEngine->deleteLater();
@ -84,10 +90,12 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) {
}
// if scriptEngine is NULL then create one and keep track of it using _ownScriptEngine
_ownScriptEngine = scriptEngine == NULL;
_scriptEngine = _ownScriptEngine ? DependencyManager::get<ScriptEngines>()->loadScript(QString(), false) : scriptEngine;
_ownScriptEngine = (scriptEngine == NULL);
_scriptEngine = _ownScriptEngine ? DependencyManager::get<ScriptEngines>()->loadScript(_consoleFileName, false) : scriptEngine;
connect(_scriptEngine, &ScriptEngine::printedMessage, this, &JSConsole::handlePrint);
connect(_scriptEngine, &ScriptEngine::infoMessage, this, &JSConsole::handleInfo);
connect(_scriptEngine, &ScriptEngine::warningMessage, this, &JSConsole::handleWarning);
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError);
}
@ -107,11 +115,10 @@ void JSConsole::executeCommand(const QString& command) {
QScriptValue JSConsole::executeCommandInWatcher(const QString& command) {
QScriptValue result;
static const QString filename = "JSConcole";
QMetaObject::invokeMethod(_scriptEngine, "evaluate", Qt::ConnectionType::BlockingQueuedConnection,
Q_RETURN_ARG(QScriptValue, result),
Q_ARG(const QString&, command),
Q_ARG(const QString&, filename));
Q_ARG(const QString&, _consoleFileName));
return result;
}
@ -134,16 +141,26 @@ void JSConsole::commandFinished() {
resetCurrentCommandHistory();
}
void JSConsole::handleError(const QString& scriptName, const QString& message) {
void JSConsole::handleError(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName);
appendMessage(GUTTER_ERROR, "<span style='" + RESULT_ERROR_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
}
void JSConsole::handlePrint(const QString& scriptName, const QString& message) {
void JSConsole::handlePrint(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName);
appendMessage("", message);
}
void JSConsole::handleInfo(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName);
appendMessage("", "<span style='" + RESULT_INFO_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
}
void JSConsole::handleWarning(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName);
appendMessage("", "<span style='" + RESULT_WARNING_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
}
void JSConsole::mouseReleaseEvent(QMouseEvent* event) {
_ui->promptTextEdit->setFocus();
}

View file

@ -47,8 +47,10 @@ protected:
protected slots:
void scrollToBottom();
void resizeTextInput();
void handlePrint(const QString& scriptName, const QString& message);
void handleError(const QString& scriptName, const QString& message);
void handlePrint(const QString& message, const QString& scriptName);
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();
private:
@ -66,6 +68,7 @@ private:
bool _ownScriptEngine;
QString _rootCommand;
ScriptEngine* _scriptEngine;
static const QString _consoleFileName;
};

View file

@ -11,7 +11,9 @@
#include <QDebug>
#include <GLMHelpers.h>
#include <glm/gtx/string_cast.hpp>
#include "ScriptEngineLogging.h"
#include "ScriptEngine.h"
#include "Mat4.h"
glm::mat4 Mat4::multiply(const glm::mat4& m1, const glm::mat4& m2) const {
@ -66,10 +68,12 @@ glm::vec3 Mat4::getUp(const glm::mat4& m) const {
return glm::vec3(m[0][1], m[1][1], m[2][1]);
}
void Mat4::print(const QString& label, const glm::mat4& m) const {
qCDebug(scriptengine) << qPrintable(label) <<
"row0 =" << m[0][0] << "," << m[1][0] << "," << m[2][0] << "," << m[3][0] <<
"row1 =" << m[0][1] << "," << m[1][1] << "," << m[2][1] << "," << m[3][1] <<
"row2 =" << m[0][2] << "," << m[1][2] << "," << m[2][2] << "," << m[3][2] <<
"row3 =" << m[0][3] << "," << m[1][3] << "," << m[2][3] << "," << m[3][3];
void Mat4::print(const QString& label, const glm::mat4& m, bool transpose) const {
glm::dmat4 out = transpose ? glm::transpose(m) : m;
QString message = QString("%1 %2").arg(qPrintable(label));
message = message.arg(glm::to_string(out).c_str());
qCDebug(scriptengine) << message;
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->print(message);
}
}

View file

@ -16,9 +16,10 @@
#include <QObject>
#include <QString>
#include <QtScript/QScriptable>
/// Scriptable Mat4 object. Used exclusively in the JavaScript API
class Mat4 : public QObject {
class Mat4 : public QObject, protected QScriptable {
Q_OBJECT
public slots:
@ -43,7 +44,7 @@ public slots:
glm::vec3 getRight(const glm::mat4& m) const;
glm::vec3 getUp(const glm::mat4& m) const;
void print(const QString& label, const glm::mat4& m) const;
void print(const QString& label, const glm::mat4& m, bool transpose = false) const;
};
#endif // hifi_Mat4_h

View file

@ -15,7 +15,9 @@
#include <OctreeConstants.h>
#include <GLMHelpers.h>
#include <glm/gtx/string_cast.hpp>
#include "ScriptEngineLogging.h"
#include "ScriptEngine.h"
#include "Quat.h"
quat Quat::normalize(const glm::quat& q) {
@ -114,8 +116,17 @@ float Quat::dot(const glm::quat& q1, const glm::quat& q2) {
return glm::dot(q1, q2);
}
void Quat::print(const QString& label, const glm::quat& q) {
qCDebug(scriptengine) << qPrintable(label) << q.x << "," << q.y << "," << q.z << "," << q.w;
void Quat::print(const QString& label, const glm::quat& q, bool asDegrees) {
QString message = QString("%1 %2").arg(qPrintable(label));
if (asDegrees) {
message = message.arg(glm::to_string(glm::dvec3(safeEulerAngles(q))).c_str());
} else {
message = message.arg(glm::to_string(glm::dquat(q)).c_str());
}
qCDebug(scriptengine) << message;
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->print(message);
}
}
bool Quat::equal(const glm::quat& q1, const glm::quat& q2) {

View file

@ -18,6 +18,7 @@
#include <QObject>
#include <QString>
#include <QtScript/QScriptable>
/**jsdoc
* A Quaternion
@ -30,7 +31,7 @@
*/
/// Scriptable interface a Quaternion helper class object. Used exclusively in the JavaScript API
class Quat : public QObject {
class Quat : public QObject, protected QScriptable {
Q_OBJECT
public slots:
@ -58,7 +59,7 @@ public slots:
glm::quat slerp(const glm::quat& q1, const glm::quat& q2, float alpha);
glm::quat squad(const glm::quat& q1, const glm::quat& q2, const glm::quat& s1, const glm::quat& s2, float h);
float dot(const glm::quat& q1, const glm::quat& q2);
void print(const QString& label, const glm::quat& q);
void print(const QString& label, const glm::quat& q, bool asDegrees = false);
bool equal(const glm::quat& q1, const glm::quat& q2);
glm::quat cancelOutRollAndPitch(const glm::quat& q);
glm::quat cancelOutRoll(const glm::quat& q);

View file

@ -105,11 +105,11 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) {
}
message += context->argument(i).toString();
}
qCDebug(scriptengineScript).noquote() << "script:print()<<" << message; // noquote() so that \n is treated as newline
qCDebug(scriptengineScript).noquote() << message; // noquote() so that \n is treated as newline
// FIXME - this approach neeeds revisiting. print() comes here, which ends up calling Script.print?
engine->globalObject().property("Script").property("print")
.call(engine->nullValue(), QScriptValueList({ message }));
if (ScriptEngine *scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->print(message);
}
return QScriptValue();
}
@ -472,6 +472,11 @@ void ScriptEngine::scriptInfoMessage(const QString& message) {
emit infoMessage(message, getFilename());
}
void ScriptEngine::scriptPrintedMessage(const QString& message) {
qCDebug(scriptengine) << message;
emit printedMessage(message, getFilename());
}
// 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...

View file

@ -221,6 +221,7 @@ public:
void scriptErrorMessage(const QString& message);
void scriptWarningMessage(const QString& message);
void scriptInfoMessage(const QString& message);
void scriptPrintedMessage(const QString& message);
int getNumRunningEntityScripts() const;
bool getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const;

View file

@ -453,7 +453,8 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL
(scriptFilename.scheme() != "http" &&
scriptFilename.scheme() != "https" &&
scriptFilename.scheme() != "atp" &&
scriptFilename.scheme() != "file")) {
scriptFilename.scheme() != "file" &&
scriptFilename.scheme() != "about")) {
// deal with a "url" like c:/something
scriptUrl = normalizeScriptURL(QUrl::fromLocalFile(scriptFilename.toString()));
} else {
@ -472,7 +473,7 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL
}, Qt::QueuedConnection);
if (scriptFilename.isEmpty()) {
if (scriptFilename.isEmpty() || !scriptUrl.isValid()) {
launchScriptEngine(scriptEngine);
} else {
// connect to the appropriate signals of this script engine

View file

@ -14,6 +14,7 @@
#include <QDebug>
#include "ScriptEngineLogging.h"
#include "ScriptEngine.h"
#include "ScriptUUID.h"
QUuid ScriptUUID::fromString(const QString& s) {
@ -36,6 +37,11 @@ bool ScriptUUID::isNull(const QUuid& id) {
return id.isNull();
}
void ScriptUUID::print(const QString& lable, const QUuid& id) {
qCDebug(scriptengine) << qPrintable(lable) << id.toString();
void ScriptUUID::print(const QString& label, const QUuid& id) {
QString message = QString("%1 %2").arg(qPrintable(label));
message = message.arg(id.toString());
qCDebug(scriptengine) << message;
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->print(message);
}
}

View file

@ -15,9 +15,10 @@
#define hifi_ScriptUUID_h
#include <QUuid>
#include <QtScript/QScriptable>
/// Scriptable interface for a UUID helper class object. Used exclusively in the JavaScript API
class ScriptUUID : public QObject {
class ScriptUUID : public QObject, protected QScriptable {
Q_OBJECT
public slots:
@ -26,7 +27,7 @@ public slots:
QUuid generate();
bool isEqual(const QUuid& idA, const QUuid& idB);
bool isNull(const QUuid& id);
void print(const QString& lable, const QUuid& id);
void print(const QString& label, const QUuid& id);
};
#endif // hifi_ScriptUUID_h

View file

@ -14,20 +14,26 @@
#include <QDebug>
#include <GLMHelpers.h>
#include <glm/gtx/string_cast.hpp>
#include "ScriptEngineLogging.h"
#include "NumericalConstants.h"
#include "Vec3.h"
#include "ScriptEngine.h"
float Vec3::orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3) {
float radians = glm::orientedAngle(glm::normalize(v1), glm::normalize(v2), glm::normalize(v3));
return glm::degrees(radians);
}
void Vec3::print(const QString& lable, const glm::vec3& v) {
qCDebug(scriptengine) << qPrintable(lable) << v.x << "," << v.y << "," << v.z;
void Vec3::print(const QString& label, const glm::vec3& v) {
QString message = QString("%1 %2").arg(qPrintable(label));
message = message.arg(glm::to_string(glm::dvec3(v)).c_str());
qCDebug(scriptengine) << message;
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->print(message);
}
}
bool Vec3::withinEpsilon(const glm::vec3& v1, const glm::vec3& v2, float epsilon) {

View file

@ -17,6 +17,7 @@
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtScript/QScriptable>
#include "GLMHelpers.h"
@ -48,7 +49,7 @@
*/
/// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API
class Vec3 : public QObject {
class Vec3 : public QObject, protected QScriptable {
Q_OBJECT
Q_PROPERTY(glm::vec3 UNIT_X READ UNIT_X CONSTANT)
Q_PROPERTY(glm::vec3 UNIT_Y READ UNIT_Y CONSTANT)

View file

@ -0,0 +1,39 @@
/* eslint-env jasmine */
// this test generates sample print, Script.print, etc. output
main();
function main() {
// to match with historical behavior, Script.print(message) output only triggers
// the printedMessage signal (and therefore doesn't show up in the application log)
Script.print('[Script.print] hello world');
// the rest of these should show up in both the application log and signaled print handlers
print('[print]', 'hello', 'world');
// note: these trigger the equivalent of an emit
Script.printedMessage('[Script.printedMessage] hello world', '{filename}');
Script.infoMessage('[Script.infoMessage] hello world', '{filename}');
Script.warningMessage('[Script.warningMessage] hello world', '{filename}');
Script.errorMessage('[Script.errorMessage] hello world', '{filename}');
{
Vec3.print('[Vec3.print]', Vec3.HALF);
var q = Quat.fromPitchYawRollDegrees(45, 45, 45);
Quat.print('[Quat.print]', q);
Quat.print('[Quat.print (euler)]', q, true);
function vec4(x,y,z,w) {
return { x: x, y: y, z: z, w: w };
}
var m = Mat4.createFromColumns(
vec4(1,2,3,4), vec4(5,6,7,8), vec4(9,10,11,12), vec4(13,14,15,16)
);
Mat4.print('[Mat4.print (col major)]', m);
Mat4.print('[Mat4.print (row major)]', m, true);
Uuid.print('[Uuid.print]', Uuid.fromString(Uuid.toString(0)));
}
}