Merge branch 'master' of https://github.com/highfidelity/hifi into event-installer-interface-options

This commit is contained in:
howard-stearns 2017-06-20 13:25:38 -07:00
commit 41003bd307
20 changed files with 492 additions and 116 deletions

View file

@ -1,70 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 50 50"
style="enable-background:new 0 0 50 50;"
xml:space="preserve"
id="svg2"
inkscape:version="0.91 r13725"
sodipodi:docname="mic-mute-a.svg"><metadata
id="metadata22"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs20" /><sodipodi:namedview
pagecolor="#ff0000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="852"
inkscape:window-height="480"
id="namedview18"
showgrid="false"
inkscape:zoom="4.72"
inkscape:cx="25"
inkscape:cy="25"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" /><style
type="text/css"
id="style4">
.st0{fill:#FFFFFF;}
</style><g
id="Layer_2" /><g
id="Layer_1"
style="fill:#000000;fill-opacity:1"><path
class="st0"
d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6h0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"
id="path8"
style="fill:#000000;fill-opacity:1" /><path
class="st0"
d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6h0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"
id="path10"
style="fill:#000000;fill-opacity:1" /><path
class="st0"
d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2l-0.2-0.2c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4 c0.7-0.6,1.8-0.5,2.4,0.2l0.2,0.2C39.8,15.1,39.7,16.1,39.1,16.8z"
id="path12"
style="fill:#000000;fill-opacity:1" /><path
class="st0"
d="M23.4,40.2l0,3.4h-4.3c-1,0-1.8,0.8-1.8,1.8c0,1,0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8 c0-1-0.8-1.8-1.8-1.8h-4.4l0-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8 c0,0.3,0,4.8,0,5.2c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"
id="path14"
style="fill:#000000;fill-opacity:1" /><path
class="st0"
d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1 C17.7,25.9,17.7,25,17.7,24.9z"
id="path16"
style="fill:#000000;fill-opacity:1" /></g></svg>
<svg version="1.1"
id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="mic-mute-a.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50"
style="enable-background:new 0 0 50 50;" xml:space="preserve">
<style type="text/css">
.st0{fill:#EA4C5F;}
</style>
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview18" inkscape:current-layer="svg2" inkscape:cx="25" inkscape:cy="25" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="480" inkscape:window-maximized="0" inkscape:window-width="852" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="4.72" objecttolerance="10" pagecolor="#ff0000" showgrid="false">
</sodipodi:namedview>
<g id="Layer_2">
</g>
<g id="Layer_1">
<path id="path8" class="st0" d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6l0,0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"/>
<path id="path10" class="st0" d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6l0,0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"/>
<path id="path12" class="st0" d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2L11,38.7c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4
c0.7-0.6,1.8-0.5,2.4,0.2l0.2,0.2C39.8,15.1,39.7,16.1,39.1,16.8z"/>
<path id="path14" class="st0" d="M23.4,40.2v3.4h-4.3c-1,0-1.8,0.8-1.8,1.8s0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8
s-0.8-1.8-1.8-1.8H27v-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8c0,0.3,0,4.8,0,5.2
c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"/>
<path id="path16" class="st0" d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1
C17.7,25.9,17.7,25,17.7,24.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -1,21 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<svg version="1.1"
id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="mic-mute-a.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50"
style="enable-background:new 0 0 50 50;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st0{fill:#EA4C5F;}
</style>
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview18" inkscape:current-layer="svg2" inkscape:cx="25" inkscape:cy="25" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="480" inkscape:window-maximized="0" inkscape:window-width="852" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="4.72" objecttolerance="10" pagecolor="#ff0000" showgrid="false">
</sodipodi:namedview>
<g id="Layer_2">
</g>
<g id="Layer_1">
<path class="st0" d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6h0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"/>
<path class="st0" d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6h0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"/>
<path class="st0" d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2l-0.2-0.2c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4
<path id="path8" class="st0" d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6l0,0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"/>
<path id="path10" class="st0" d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6l0,0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"/>
<path id="path12" class="st0" d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2L11,38.7c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4
c0.7-0.6,1.8-0.5,2.4,0.2l0.2,0.2C39.8,15.1,39.7,16.1,39.1,16.8z"/>
<path class="st0" d="M23.4,40.2l0,3.4h-4.3c-1,0-1.8,0.8-1.8,1.8c0,1,0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8
c0-1-0.8-1.8-1.8-1.8h-4.4l0-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8
c0,0.3,0,4.8,0,5.2c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"/>
<path class="st0" d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1
<path id="path14" class="st0" d="M23.4,40.2v3.4h-4.3c-1,0-1.8,0.8-1.8,1.8s0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8
s-0.8-1.8-1.8-1.8H27v-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8c0,0.3,0,4.8,0,5.2
c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"/>
<path id="path16" class="st0" d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1
C17.7,25.9,17.7,25,17.7,24.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -65,6 +65,12 @@ Windows.Window {
root.dynamicContent.fromScript(message);
}
}
function clearDebugWindow() {
if (root.dynamicContent && root.dynamicContent.clearWindow) {
root.dynamicContent.clearWindow();
}
}
// Handle message traffic from our loaded QML to the script that launched us
signal sendToScript(var message);

View file

@ -59,6 +59,7 @@ Rectangle {
AudioControls.CheckBox {
text: qsTr("Mute microphone");
isRedCheck: true;
checked: Audio.muted;
onClicked: {
Audio.muted = checked;

View file

@ -5593,6 +5593,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
connect(scriptEngine, &ScriptEngine::errorMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
connect(scriptEngine, &ScriptEngine::warningMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onWarningMessage);
connect(scriptEngine, &ScriptEngine::infoMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onInfoMessage);
connect(scriptEngine, &ScriptEngine::clearDebugWindow, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onClearDebugWindow);
}
bool Application::canAcceptURL(const QString& urlString) const {

View file

@ -386,7 +386,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
return 0;
}
qint64 clockSkew = args.sourceNode ? args.sourceNode->getClockSkewUsec() : 0;
int64_t clockSkew = 0;
uint64_t maxPingRoundTrip = 33333; // two frames periods at 60 fps
if (args.sourceNode) {
clockSkew = args.sourceNode->getClockSkewUsec();
const float MSECS_PER_USEC = 1000;
maxPingRoundTrip += args.sourceNode->getPingMs() * MSECS_PER_USEC;
}
BufferParser parser(data, bytesLeftToRead);
@ -653,7 +659,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
const QUuid& myNodeID = nodeList->getSessionUUID();
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
// pack SimulationOwner and terse update properties near each other
// NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data
// even when we would otherwise ignore the rest of the packet.
@ -678,7 +683,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
if (newSimOwner.getID().isNull() && !_simulationOwner.pendingRelease(lastEditedFromBufferAdjusted)) {
// entity-server is trying to clear our ownership (probably at our own request)
// but we actually want to own it, therefore we ignore this clear event
// and pretend that we own it (we assume we'll recover it soon)
// and pretend that we own it (e.g. we assume we'll receive ownership soon)
// However, for now, when the server uses a newer time than what we sent, listen to what we're told.
if (overwriteLocalData) {
@ -690,16 +695,19 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// recompute weOwnSimulation for later
weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
}
} else if (newSimOwner.getID().isNull() && _simulationOwner.pendingTake(lastEditedFromBufferAdjusted)) {
// entity-server is trying to clear someone else's ownership
// but we want to own it, therefore we ignore this clear event
// and pretend that we own it (we assume we'll get it soon)
} else if (_simulationOwner.pendingTake(now - maxPingRoundTrip)) {
// we sent a bid before this packet could have been sent from the server
// so we ignore it and pretend we own the object's simulation
weOwnSimulation = true;
if (!_simulationOwner.isNull()) {
// someone else really did own it
markDirtyFlags(Simulation::DIRTY_SIMULATOR_ID);
somethingChanged = true;
_simulationOwner.clearCurrentOwner();
if (newSimOwner.getID().isNull()) {
// entity-server is trying to clear someone else's ownership
// but we want to own it, therefore we ignore this clear event
if (!_simulationOwner.isNull()) {
// someone else really did own it
markDirtyFlags(Simulation::DIRTY_SIMULATOR_ID);
somethingChanged = true;
_simulationOwner.clearCurrentOwner();
}
}
} else if (newSimOwner.matchesValidID(myNodeID) && !_hasBidOnSimulation) {
// entity-server tells us that we have simulation ownership while we never requested this for this EntityItem,

View file

@ -23,14 +23,16 @@ const uint16_t ObjectActionTractor::tractorVersion = 1;
ObjectActionTractor::ObjectActionTractor(const QUuid& id, EntityItemPointer ownerEntity) :
ObjectAction(DYNAMIC_TYPE_TRACTOR, id, ownerEntity),
_positionalTarget(glm::vec3(0.0f)),
_desiredPositionalTarget(glm::vec3(0.0f)),
_positionalTarget(0.0f),
_desiredPositionalTarget(0.0f),
_linearTimeScale(FLT_MAX),
_positionalTargetSet(true),
_rotationalTarget(glm::quat()),
_desiredRotationalTarget(glm::quat()),
_positionalTargetSet(false),
_rotationalTarget(),
_desiredRotationalTarget(),
_angularTimeScale(FLT_MAX),
_rotationalTargetSet(true) {
_rotationalTargetSet(true),
_linearVelocityTarget(0.0f)
{
#if WANT_DEBUG
qCDebug(physics) << "ObjectActionTractor::ObjectActionTractor";
#endif
@ -77,7 +79,6 @@ bool ObjectActionTractor::prepareForTractorUpdate(btScalar deltaTimeStep) {
glm::quat rotation;
glm::vec3 position;
glm::vec3 linearVelocity;
glm::vec3 angularVelocity;
bool linearValid = false;
@ -117,7 +118,6 @@ bool ObjectActionTractor::prepareForTractorUpdate(btScalar deltaTimeStep) {
linearValid = true;
linearTractorCount++;
position += positionForAction;
linearVelocity += linearVelocityForAction;
}
}
}
@ -126,9 +126,18 @@ bool ObjectActionTractor::prepareForTractorUpdate(btScalar deltaTimeStep) {
withWriteLock([&]{
if (linearValid && linearTractorCount > 0) {
position /= linearTractorCount;
linearVelocity /= linearTractorCount;
if (_positionalTargetSet) {
_lastPositionTarget = _positionalTarget;
} else {
_lastPositionTarget = position;
}
_positionalTarget = position;
_linearVelocityTarget = linearVelocity;
if (deltaTimeStep > EPSILON) {
// blend the new velocity with the old (low-pass filter)
glm::vec3 newVelocity = (1.0f / deltaTimeStep) * (position - _lastPositionTarget);
const float blend = 0.25f;
_linearVelocityTarget = (1.0f - blend) * _linearVelocityTarget + blend * newVelocity;
}
_positionalTargetSet = true;
_active = true;
}
@ -169,19 +178,19 @@ void ObjectActionTractor::updateActionWorker(btScalar deltaTimeStep) {
}
if (_linearTimeScale < MAX_TRACTOR_TIMESCALE) {
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
btVector3 offsetVelocity(0.0f, 0.0f, 0.0f);
btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
float offsetLength = offset.length();
if (offsetLength > FLT_EPSILON) {
float speed = glm::min(offsetLength / _linearTimeScale, TRACTOR_MAX_SPEED);
targetVelocity = (-speed / offsetLength) * offset;
offsetVelocity = (-speed / offsetLength) * offset;
if (speed > rigidBody->getLinearSleepingThreshold()) {
forceBodyNonStatic();
rigidBody->activate();
}
}
// this action is aggresively critically damped and defeats the current velocity
rigidBody->setLinearVelocity(targetVelocity);
rigidBody->setLinearVelocity(glmToBullet(_linearVelocityTarget) + offsetVelocity);
}
if (_angularTimeScale < MAX_TRACTOR_TIMESCALE) {

View file

@ -36,6 +36,7 @@ protected:
glm::vec3 _positionalTarget;
glm::vec3 _desiredPositionalTarget;
glm::vec3 _lastPositionTarget;
float _linearTimeScale;
bool _positionalTargetSet;

View file

@ -0,0 +1,182 @@
//
// ConsoleScriptingInterface.cpp
// libraries/script-engine/src
//
// Created by NeetBhagat on 6/1/17.
// Copyright 2014 High Fidelity, Inc.
//
// ConsoleScriptingInterface is responsible for following functionality
// Printing logs with various tags and grouping on debug Window and Logs/log file.
// Debugging functionalities like Timer start-end, assertion, trace.
// To use these functionalities, use "console" object in Javascript files.
// For examples please refer "scripts/developer/tests/consoleObjectTest.js"
//
// 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"
#define INDENTATION 4 // 1 Tab - 4 spaces
const QString LINE_SEPARATOR = "\n ";
const QString SPACE_SEPARATOR = " ";
const QString STACK_TRACE_FORMAT = "\n[Stacktrace]%1%2";
QList<QString> ConsoleScriptingInterface::_groupDetails = QList<QString>();
QScriptValue ConsoleScriptingInterface::info(QScriptContext* context, QScriptEngine* engine) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptInfoMessage(appendArguments(context));
}
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::log(QScriptContext* context, QScriptEngine* engine) {
QString message = appendArguments(context);
if (_groupDetails.count() == 0) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptPrintedMessage(message);
}
} else {
logGroupMessage(message, engine);
}
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::debug(QScriptContext* context, QScriptEngine* engine) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptPrintedMessage(appendArguments(context));
}
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::warn(QScriptContext* context, QScriptEngine* engine) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptWarningMessage(appendArguments(context));
}
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::error(QScriptContext* context, QScriptEngine* engine) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptErrorMessage(appendArguments(context));
}
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::exception(QScriptContext* context, QScriptEngine* engine) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptErrorMessage(appendArguments(context));
}
return QScriptValue::NullValue;
}
void ConsoleScriptingInterface::time(QString labelName) {
_timerDetails.insert(labelName, QDateTime::currentDateTime().toUTC());
QString message = QString("%1: Timer started").arg(labelName);
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->scriptPrintedMessage(message);
}
}
void ConsoleScriptingInterface::timeEnd(QString labelName) {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
if (!_timerDetails.contains(labelName)) {
scriptEngine->scriptErrorMessage("No such label found " + labelName);
return;
}
if (_timerDetails.value(labelName).isNull()) {
_timerDetails.remove(labelName);
scriptEngine->scriptErrorMessage("Invalid start time for " + labelName);
return;
}
QDateTime _startTime = _timerDetails.value(labelName);
QDateTime _endTime = QDateTime::currentDateTime().toUTC();
qint64 diffInMS = _startTime.msecsTo(_endTime);
QString message = QString("%1: %2ms").arg(labelName).arg(QString::number(diffInMS));
_timerDetails.remove(labelName);
scriptEngine->scriptPrintedMessage(message);
}
}
QScriptValue ConsoleScriptingInterface::assertion(QScriptContext* context, QScriptEngine* engine) {
QString message;
bool condition = false;
for (int i = 0; i < context->argumentCount(); i++) {
if (i == 0) {
condition = context->argument(i).toBool(); // accept first value as condition
} else {
message += SPACE_SEPARATOR + context->argument(i).toString(); // accept other parameters as message
}
}
QString assertionResult;
if (!condition) {
if (message.isEmpty()) {
assertionResult = "Assertion failed";
} else {
assertionResult = QString("Assertion failed : %1").arg(message);
}
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptErrorMessage(assertionResult);
}
}
return QScriptValue::NullValue;
}
void ConsoleScriptingInterface::trace() {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->scriptPrintedMessage
(QString(STACK_TRACE_FORMAT).arg(LINE_SEPARATOR,
scriptEngine->currentContext()->backtrace().join(LINE_SEPARATOR)));
}
}
void ConsoleScriptingInterface::clear() {
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine())) {
scriptEngine->clearDebugLogWindow();
}
}
QScriptValue ConsoleScriptingInterface::group(QScriptContext* context, QScriptEngine* engine) {
logGroupMessage(context->argument(0).toString(), engine); // accept first parameter as label
_groupDetails.push_back(context->argument(0).toString());
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::groupCollapsed(QScriptContext* context, QScriptEngine* engine) {
logGroupMessage(context->argument(0).toString(), engine); // accept first parameter as label
_groupDetails.push_back(context->argument(0).toString());
return QScriptValue::NullValue;
}
QScriptValue ConsoleScriptingInterface::groupEnd(QScriptContext* context, QScriptEngine* engine) {
ConsoleScriptingInterface::_groupDetails.removeLast();
return QScriptValue::NullValue;
}
QString ConsoleScriptingInterface::appendArguments(QScriptContext* context) {
QString message;
for (int i = 0; i < context->argumentCount(); i++) {
if (i > 0) {
message += SPACE_SEPARATOR;
}
message += context->argument(i).toString();
}
return message;
}
void ConsoleScriptingInterface::logGroupMessage(QString message, QScriptEngine* engine) {
int _addSpaces = _groupDetails.count() * INDENTATION;
QString logMessage;
for (int i = 0; i < _addSpaces; i++) {
logMessage.append(SPACE_SEPARATOR);
}
logMessage.append(message);
if (ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(engine)) {
scriptEngine->scriptPrintedMessage(logMessage);
}
}

View file

@ -0,0 +1,56 @@
//
// ConsoleScriptingInterface.h
// libraries/script-engine/src
//
// Created by NeetBhagat on 6/1/17.
// Copyright 2014 High Fidelity, Inc.
//
// ConsoleScriptingInterface is responsible for following functionality
// Printing logs with various tags and grouping on debug Window and Logs/log file.
// Debugging functionalities like Timer start-end, assertion, trace.
// To use these functionalities, use "console" object in Javascript files.
// For examples please refer "scripts/developer/tests/consoleObjectTest.js"
//
// 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 <QtCore/QObject>
#include <QtCore/QString>
#include <QtScript/QScriptable>
#include <QList>
#include <QHash>
// Scriptable interface of "console" object. Used exclusively in the JavaScript API
class ConsoleScriptingInterface : public QObject, protected QScriptable {
Q_OBJECT
public:
static QScriptValue info(QScriptContext* context, QScriptEngine* engine);
static QScriptValue log(QScriptContext* context, QScriptEngine* engine);
static QScriptValue debug(QScriptContext* context, QScriptEngine* engine);
static QScriptValue warn(QScriptContext* context, QScriptEngine* engine);
static QScriptValue error(QScriptContext* context, QScriptEngine* engine);
static QScriptValue exception(QScriptContext* context, QScriptEngine* engine);
static QScriptValue assertion(QScriptContext* context, QScriptEngine* engine);
static QScriptValue group(QScriptContext* context, QScriptEngine* engine);
static QScriptValue groupCollapsed(QScriptContext* context, QScriptEngine* engine);
static QScriptValue groupEnd(QScriptContext* context, QScriptEngine* engine);
public slots:
void time(QString labelName);
void timeEnd(QString labelName);
void trace();
void clear();
private:
QHash<QString, QDateTime> _timerDetails;
static QList<QString> _groupDetails;
static void logGroupMessage(QString message, QScriptEngine* engine);
static QString appendArguments(QScriptContext* context);
};
#endif // hifi_ConsoleScriptingInterface_h

View file

@ -472,20 +472,24 @@ void ScriptEngine::scriptErrorMessage(const QString& message) {
}
void ScriptEngine::scriptWarningMessage(const QString& message) {
qCWarning(scriptengine) << message;
qCWarning(scriptengine) << qPrintable(message);
emit warningMessage(message, getFilename());
}
void ScriptEngine::scriptInfoMessage(const QString& message) {
qCInfo(scriptengine) << message;
qCInfo(scriptengine) << qPrintable(message);
emit infoMessage(message, getFilename());
}
void ScriptEngine::scriptPrintedMessage(const QString& message) {
qCDebug(scriptengine) << message;
qCDebug(scriptengine) << qPrintable(message);
emit printedMessage(message, getFilename());
}
void ScriptEngine::clearDebugLogWindow() {
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...
@ -668,8 +672,18 @@ void ScriptEngine::init() {
registerGlobalObject("Mat4", &_mat4Library);
registerGlobalObject("Uuid", &_uuidLibrary);
registerGlobalObject("Messages", DependencyManager::get<MessagesClient>().data());
registerGlobalObject("File", new FileScriptingInterface(this));
registerGlobalObject("console", &_consoleScriptingInterface);
registerFunction("console", "info", ConsoleScriptingInterface::info, currentContext()->argumentCount());
registerFunction("console", "log", ConsoleScriptingInterface::log, currentContext()->argumentCount());
registerFunction("console", "debug", ConsoleScriptingInterface::debug, currentContext()->argumentCount());
registerFunction("console", "warn", ConsoleScriptingInterface::warn, currentContext()->argumentCount());
registerFunction("console", "error", ConsoleScriptingInterface::error, currentContext()->argumentCount());
registerFunction("console", "exception", ConsoleScriptingInterface::exception, currentContext()->argumentCount());
registerFunction("console", "assert", ConsoleScriptingInterface::assertion, currentContext()->argumentCount());
registerFunction("console", "group", ConsoleScriptingInterface::group, 1);
registerFunction("console", "groupCollapsed", ConsoleScriptingInterface::groupCollapsed, 1);
registerFunction("console", "groupEnd", ConsoleScriptingInterface::groupEnd, 0);
qScriptRegisterMetaType(this, animVarMapToScriptValue, animVarMapFromScriptValue);
qScriptRegisterMetaType(this, resultHandlerToScriptValue, resultHandlerFromScriptValue);

View file

@ -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 clearDebugLogWindow();
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<bool> _isUserLoaded { false };
bool _isReloading { false };

View file

@ -54,6 +54,10 @@ void ScriptEngines::onInfoMessage(const QString& message, const QString& scriptN
emit infoMessage(message, scriptName);
}
void ScriptEngines::onClearDebugWindow() {
emit clearDebugWindow();
}
void ScriptEngines::onErrorLoadingScript(const QString& url) {
emit errorLoadingScript(url);
}

View file

@ -79,6 +79,7 @@ signals:
void warningMessage(const QString& message, const QString& engineName);
void infoMessage(const QString& message, const QString& engineName);
void errorLoadingScript(const QString& url);
void clearDebugWindow();
public slots:
void onPrintedMessage(const QString& message, const QString& scriptName);
@ -86,6 +87,7 @@ public slots:
void onWarningMessage(const QString& message, const QString& scriptName);
void onInfoMessage(const QString& message, const QString& scriptName);
void onErrorLoadingScript(const QString& url);
void onClearDebugWindow();
protected slots:
void onScriptFinished(const QString& fileNameString, ScriptEngine* engine);

View file

@ -153,6 +153,9 @@ void QmlWindowClass::sendToQml(const QVariant& message) {
QMetaObject::invokeMethod(asQuickItem(), "fromScript", Qt::QueuedConnection, Q_ARG(QVariant, message));
}
void QmlWindowClass::clearDebugWindow() {
QMetaObject::invokeMethod(asQuickItem(), "clearDebugWindow", Qt::QueuedConnection);
}
void QmlWindowClass::emitScriptEvent(const QVariant& scriptMessage) {
if (QThread::currentThread() != thread()) {

View file

@ -53,6 +53,7 @@ public slots:
// Scripts can use this to send a message to the QML object
void sendToQml(const QVariant& message);
void clearDebugWindow();
// QmlWindow content may include WebView requiring EventBridge.
void emitScriptEvent(const QVariant& scriptMessage);

View file

@ -49,4 +49,8 @@ ScriptDiscoveryService.infoMessage.connect(function(message, scriptFileName) {
sendToLogWindow("INFO", message, scriptFileName);
});
}()); // END LOCAL_SCOPE
ScriptDiscoveryService.clearDebugWindow.connect(function() {
window.clearDebugWindow();
});
}());

View file

@ -40,6 +40,10 @@ Rectangle {
}
textArea.append(message);
}
function clearWindow() {
textArea.remove(0,textArea.length);
}
}

View file

@ -0,0 +1,114 @@
// Examples and understanding of console object. Include console methods like
// info, log, debug, warn, error, exception, trace, clear, asserts, group, groupCollapsed, groupEnd, time, timeEnd.
// Useful in debugging and exclusively made for JavaScript files.
// To view the logs click on Developer -> script logs [logs on debug window] and for text file logs go to Logs/log file.
main();
function main() {
var someObject = { str: "Some text", id: 5 };
var someValue = 5;
// console.info examples
console.info("[console.info] Hello World.");
console.info(5 + 6);
console.info(someObject.str);
console.info(a = 2 * 6);
console.info(someValue);
console.info('someObject id ' + someObject.id);
console.info('Hello World ', 'someObject.id = ', someObject.id, "a = 2 * 6 = ", a = 2 * 6);
// console.log examples
console.log("[console.log] Hello World");
console.log(5 + 6);
console.log(someObject.str);
console.log(a = 2 * 6);
console.log(someValue);
console.log('someObject id ' + someObject.id);
console.log('Hello World ', 'someObject.id = ', someObject.id, "a = 2 * 6 = ", a = 2 * 6);
// console.debug examples
console.debug("[console.debug] Hello World.");
console.debug(5 + 6);
console.debug(someObject.str);
console.debug(a = 2 * 6);
console.debug(someValue);
console.debug('someObject id ' + someObject.id);
console.debug('Hello World ', 'someObject.id = ', someObject.id, "a = 2 * 6 = ", a = 2 * 6);
// console.warn examples
console.warn("[console.warn] This is warning message.");
console.warn(5 + 6);
console.warn(someObject.str);
console.warn(a = 2 * 6);
console.warn(someValue);
console.warn('someObject id ' + someObject.id);
console.warn('Hello World ', 'someObject.id = ', someObject.id, "a = 2 * 6 = ", a = 2 * 6);
// console.error examples
console.error('An error occurred!');
console.error('An error occurred! ', 'Value = ', someValue);
console.error('An error occurred! ' + 'Value = ' + someValue);
// console.exception examples
console.exception('An exception occurred!');
console.exception('An exception occurred! ', 'Value = ', someValue);
console.exception('An exception occurred! ' + 'Value = ' + someValue);
// console.trace examples
function fooA() {
function fooB() {
function fooC() {
console.trace();
}
fooC();
}
fooB();
}
fooA();
// console.assert() examples
var valA = 1, valB = "1";
console.assert(valA === valB, "Value A doesn't equal to B");
console.assert(valA === valB);
console.assert(5 === 5, "5 equals to 5");
console.assert(5 === 5);
console.assert(5 > 6, "5 is not greater than 6");
console.assert(5 > 6, "5 is not greater than 6", "This assertion will fail");
// console.group() examples.
console.group("Group 1");
console.log("Sentence 1");
console.log("Sentence 2");
console.group("Group 2");
console.log("Sentence 3");
console.log("Sentence 4");
console.groupCollapsed("Group 3");
console.log("Sentence 5");
console.log("Sentence 6");
console.groupEnd();
console.log("Sentence 7");
console.groupEnd();
console.log("Sentence 8");
console.groupEnd();
console.log("Sentence 9");
// console.time(),console.timeEnd() examples
console.time('MyTimer');
// Do some process
sleep(1000);
console.timeEnd('MyTimer');
// use console.clear() to clean Debug Window logs
// console.clear();
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}

View file

@ -622,7 +622,7 @@ var toolBar = (function () {
}));
isActive = active;
activeButton.editProperties({isActive: isActive});
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
if (!isActive) {
@ -1519,6 +1519,8 @@ function importSVO(importURL) {
// entities after they're imported so that they're all the correct distance in front of and with geometric mean
// centered on the avatar/camera direction.
var deltaPosition = Vec3.ZERO;
var entityPositions = [];
var entityParentIDs = [];
var properties = Entities.getEntityProperties(pastedEntityIDs[0], ["type"]);
var NO_ADJUST_ENTITY_TYPES = ["Zone", "Light", "ParticleEffect"];
@ -1534,10 +1536,9 @@ function importSVO(importURL) {
var targetPosition = getPositionToCreateEntity();
var deltaParallel = HALF_TREE_SCALE; // Distance to move entities parallel to targetDirection.
var deltaPerpendicular = Vec3.ZERO; // Distance to move entities perpendicular to targetDirection.
var entityPositions = [];
for (var i = 0, length = pastedEntityIDs.length; i < length; i++) {
var properties = Entities.getEntityProperties(pastedEntityIDs[i], ["position", "dimensions",
"registrationPoint", "rotation"]);
"registrationPoint", "rotation", "parentID"]);
var adjustedPosition = adjustPositionPerBoundingBox(targetPosition, targetDirection,
properties.registrationPoint, properties.dimensions, properties.rotation);
var delta = Vec3.subtract(adjustedPosition, properties.position);
@ -1546,6 +1547,7 @@ function importSVO(importURL) {
deltaPerpendicular = Vec3.sum(Vec3.subtract(delta, Vec3.multiply(distance, targetDirection)),
deltaPerpendicular);
entityPositions[i] = properties.position;
entityParentIDs[i] = properties.parentID;
}
deltaPerpendicular = Vec3.multiply(1 / pastedEntityIDs.length, deltaPerpendicular);
deltaPosition = Vec3.sum(Vec3.multiply(deltaParallel, targetDirection), deltaPerpendicular);
@ -1562,9 +1564,11 @@ function importSVO(importURL) {
if (!Vec3.equal(deltaPosition, Vec3.ZERO)) {
for (var i = 0, length = pastedEntityIDs.length; i < length; i++) {
Entities.editEntity(pastedEntityIDs[i], {
position: Vec3.sum(deltaPosition, entityPositions[i])
});
if (Uuid.isNull(entityParentIDs[i])) {
Entities.editEntity(pastedEntityIDs[i], {
position: Vec3.sum(deltaPosition, entityPositions[i])
});
}
}
}
}