From d410cb4fda5b90e171e0d882b2b316d1a0228b41 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sat, 24 Aug 2019 11:12:28 -0700 Subject: [PATCH 1/8] Added "shutdown" crash annotation and crash menu option --- interface/src/Application.cpp | 16 ++++++++++++++++ interface/src/Application.h | 5 +++++ interface/src/Menu.cpp | 2 ++ interface/src/Menu.h | 1 + 4 files changed, 24 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 090cdd52b6..b957c7073c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -167,6 +167,7 @@ #include "avatar/MyCharacterController.h" #include "CrashRecoveryHandler.h" #include "CrashHandler.h" +#include #include "devices/DdeFaceTracker.h" #include "DiscoverabilityManager.h" #include "GLCanvas.h" @@ -2675,6 +2676,8 @@ void Application::updateHeartbeat() const { } void Application::onAboutToQuit() { + setCrashAnnotation("shutdown", "1"); + // quickly save AvatarEntityData before the EntityTree is dismantled getMyAvatar()->saveAvatarEntityDataToSettings(); @@ -2713,6 +2716,11 @@ void Application::onAboutToQuit() { cleanupBeforeQuit(); + if (_crashOnShutdown) { + // triggered by crash menu + crash::nullDeref(); + } + getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::SHUTDOWN); } @@ -9522,6 +9530,14 @@ void Application::showUrlHandler(const QUrl& url) { } }); } + +// used to test "shutdown" crash annotation. +void Application::crashOnShutdown() { + qDebug() << "crashOnShutdown(), ON PURPOSE!"; + _crashOnShutdown = true; + quit(); +} + void Application::overrideEntry(){ _overrideEntry = true; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 913671473d..20abbf2baf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -497,6 +497,9 @@ public slots: bool gpuTextureMemSizeStable(); void showUrlHandler(const QUrl& url); + // used to test "shutdown" crash annotation. + void crashOnShutdown(); + private slots: void onDesktopRootItemCreated(QQuickItem* qmlContext); void onDesktopRootContextCreated(QQmlContext* qmlContext); @@ -844,5 +847,7 @@ private: bool _overrideEntry { false }; VisionSqueeze _visionSqueeze; + + bool _crashOnShutdown { false }; }; #endif // hifi_Application_h diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 4cf78c23ee..8c6292681b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -763,6 +763,8 @@ Menu::Menu() { action = addActionToQMenuAndActionHash(crashMenu, MenuOption::CrashNewFaultThreaded); connect(action, &QAction::triggered, qApp, []() { std::thread(crash::newFault).join(); }); + addActionToQMenuAndActionHash(crashMenu, MenuOption::CrashOnShutdown, 0, qApp, SLOT(crashOnShutdown())); + // Developer > Show Statistics addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats, 0, true); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 70687786a9..7dff264adc 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -72,6 +72,7 @@ namespace MenuOption { const QString CrashNullDereferenceThreaded = "Null Dereference (threaded)"; const QString CrashAbort = "Abort"; const QString CrashAbortThreaded = "Abort (threaded)"; + const QString CrashOnShutdown = "Crash During Shutdown"; const QString CrashOutOfBoundsVectorAccess = "Out of Bounds Vector Access"; const QString CrashOutOfBoundsVectorAccessThreaded = "Out of Bounds Vector Access (threaded)"; const QString CrashNewFault = "New Fault"; From e98cdab2946b1d805f9ac838522b6893eaead1f6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 26 Aug 2019 17:05:08 -0700 Subject: [PATCH 2/8] Moved CrashHelper.h include to the appropriate place. --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b957c7073c..0fc273fa35 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -167,7 +168,6 @@ #include "avatar/MyCharacterController.h" #include "CrashRecoveryHandler.h" #include "CrashHandler.h" -#include #include "devices/DdeFaceTracker.h" #include "DiscoverabilityManager.h" #include "GLCanvas.h" From 7f1f6dba311820f839d2fb0be229854cd7f8cb5a Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 27 Aug 2019 10:25:35 -0700 Subject: [PATCH 3/8] Implement activation on nodes and use it to trigger random states --- libraries/animation/src/AnimNode.cpp | 7 +++++++ libraries/animation/src/AnimNode.h | 3 +++ libraries/animation/src/AnimRandomSwitch.cpp | 13 ++++++++----- libraries/animation/src/AnimRandomSwitch.h | 3 ++- libraries/animation/src/AnimStateMachine.cpp | 4 ++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/libraries/animation/src/AnimNode.cpp b/libraries/animation/src/AnimNode.cpp index f055e6b473..930be9769c 100644 --- a/libraries/animation/src/AnimNode.cpp +++ b/libraries/animation/src/AnimNode.cpp @@ -60,6 +60,13 @@ void AnimNode::setCurrentFrame(float frame) { } } +void AnimNode::setActive(bool active) { + setActiveInternal(active); + for (auto&& child : _children) { + child->setActiveInternal(active); + } +} + void AnimNode::processOutputJoints(AnimVariantMap& triggersOut) const { if (!_skeleton) { return; diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index ec5f2b7375..a0fb51e891 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -73,6 +73,7 @@ public: } void setCurrentFrame(float frame); + void setActive(bool active); template bool traverse(F func) { @@ -104,6 +105,7 @@ protected: virtual void setCurrentFrameInternal(float frame) {} virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { _skeleton = skeleton; } + virtual void setActiveInternal(bool active) {} // for AnimDebugDraw rendering virtual const AnimPoseVec& getPosesInternal() const = 0; @@ -116,6 +118,7 @@ protected: AnimSkeleton::ConstPointer _skeleton; std::weak_ptr _parent; std::vector _outputJointNames; + bool _active { false }; // no copies AnimNode(const AnimNode&) = delete; diff --git a/libraries/animation/src/AnimRandomSwitch.cpp b/libraries/animation/src/AnimRandomSwitch.cpp index 68c7031de8..3fbd57dde4 100644 --- a/libraries/animation/src/AnimRandomSwitch.cpp +++ b/libraries/animation/src/AnimRandomSwitch.cpp @@ -21,12 +21,16 @@ AnimRandomSwitch::~AnimRandomSwitch() { } +void AnimRandomSwitch::setActiveInternal(bool active) { + _active = active; + _triggerNewRandomState = active; +} + const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { float parentDebugAlpha = context.getDebugAlpha(_id); AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState; - if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1 || animVars.lookup(_triggerRandomSwitchVar, false)) { - + if (_triggerNewRandomState || animVars.lookup(_triggerRandomSwitchVar, false)) { // filter states different to the last random state and with priorities. bool currentStateHasPriority = false; std::vector randomStatesToConsider; @@ -56,8 +60,9 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co } lowerBound = upperBound; } - if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) { + if (_triggerNewRandomState) { switchRandomState(animVars, context, desiredState, false); + _triggerNewRandomState = false; } else { // firing a random switch, be sure that we aren't completing a previously triggered transition if (currentStateHasPriority) { @@ -70,7 +75,6 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co } _triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax); _randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax); - } else { // here we are checking to see if we want a temporary movement @@ -143,7 +147,6 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co _poses = currentStateNode->evaluate(animVars, context, dt, triggersOut); } - _randomSwitchEvaluationCount = context.getEvaluationCount(); processOutputJoints(triggersOut); context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha); diff --git a/libraries/animation/src/AnimRandomSwitch.h b/libraries/animation/src/AnimRandomSwitch.h index 888ed1f6b5..490e2f86e1 100644 --- a/libraries/animation/src/AnimRandomSwitch.h +++ b/libraries/animation/src/AnimRandomSwitch.h @@ -151,10 +151,11 @@ protected: // for AnimDebugDraw rendering virtual const AnimPoseVec& getPosesInternal() const override; + virtual void setActiveInternal(bool active) override; AnimPoseVec _poses; - int _randomSwitchEvaluationCount { 0 }; + bool _triggerNewRandomState = false; // interpolation state bool _duringInterp = false; InterpType _interpType { InterpType::SnapshotPrev }; diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 658309ce71..51e7a24136 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -128,6 +128,10 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon auto prevStateNode = _children[_currentState->getChildIndex()]; auto nextStateNode = _children[desiredState->getChildIndex()]; + // activate/deactivate states + prevStateNode->setActive(false); + nextStateNode->setActive(true); + bool interpActive = _duringInterp; _duringInterp = true; _alpha = 0.0f; From acbeb326a70fbf4cae30790bcd256656f135dc0c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 27 Aug 2019 10:57:22 -0700 Subject: [PATCH 4/8] Set activation when switching random states --- libraries/animation/src/AnimContext.h | 2 -- libraries/animation/src/AnimRandomSwitch.cpp | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index 5f353fcae4..9ad37b513e 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -45,7 +45,6 @@ public: bool getEnableDebugDrawIKChains() const { return _enableDebugDrawIKChains; } const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; } const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; } - int getEvaluationCount() const { return _evaluationCount; } float getDebugAlpha(const QString& key) const { auto it = _debugAlphaMap.find(key); @@ -87,7 +86,6 @@ protected: bool _enableDebugDrawIKChains { false }; glm::mat4 _geometryToRigMatrix; glm::mat4 _rigToWorldMatrix; - int _evaluationCount{ 0 }; // used for debugging internal state of animation system. mutable DebugAlphaMap _debugAlphaMap; diff --git a/libraries/animation/src/AnimRandomSwitch.cpp b/libraries/animation/src/AnimRandomSwitch.cpp index 3fbd57dde4..4f137f7be4 100644 --- a/libraries/animation/src/AnimRandomSwitch.cpp +++ b/libraries/animation/src/AnimRandomSwitch.cpp @@ -168,8 +168,16 @@ void AnimRandomSwitch::addState(RandomSwitchState::Pointer randomState) { } void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const AnimContext& context, RandomSwitchState::Pointer desiredState, bool shouldInterp) { + + auto prevStateNode = _children[_currentState->getChildIndex()]; auto nextStateNode = _children[desiredState->getChildIndex()]; + + // activate/deactivate states + prevStateNode->setActive(false); + nextStateNode->setActive(true); + _lastPlayedState = nextStateNode->getID(); + if (shouldInterp) { bool interpActive = _duringInterp; From 55b54b02a0a558228c779bd08242f03d14438c1b Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 27 Aug 2019 10:59:03 -0700 Subject: [PATCH 5/8] Restate evaluation count on AnimContext --- libraries/animation/src/AnimContext.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index 9ad37b513e..5f353fcae4 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -45,6 +45,7 @@ public: bool getEnableDebugDrawIKChains() const { return _enableDebugDrawIKChains; } const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; } const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; } + int getEvaluationCount() const { return _evaluationCount; } float getDebugAlpha(const QString& key) const { auto it = _debugAlphaMap.find(key); @@ -86,6 +87,7 @@ protected: bool _enableDebugDrawIKChains { false }; glm::mat4 _geometryToRigMatrix; glm::mat4 _rigToWorldMatrix; + int _evaluationCount{ 0 }; // used for debugging internal state of animation system. mutable DebugAlphaMap _debugAlphaMap; From 4098dd9999fe7b02518de14f14a8d0116cfacba9 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 27 Aug 2019 12:59:57 -0700 Subject: [PATCH 6/8] BUGZ-1342: Add lock icon to Emote tray when it's locked open; Make tray close when unlocking it --- .../ui/qml/SimplifiedEmoteIndicator.qml | 33 +++++++++++++++++-- .../ui/qml/images/lock_Icon.svg | 8 +++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 scripts/simplifiedUI/simplifiedEmote/ui/qml/images/lock_Icon.svg diff --git a/scripts/simplifiedUI/simplifiedEmote/ui/qml/SimplifiedEmoteIndicator.qml b/scripts/simplifiedUI/simplifiedEmote/ui/qml/SimplifiedEmoteIndicator.qml index 9aa7571494..a401feec12 100644 --- a/scripts/simplifiedUI/simplifiedEmote/ui/qml/SimplifiedEmoteIndicator.qml +++ b/scripts/simplifiedUI/simplifiedEmote/ui/qml/SimplifiedEmoteIndicator.qml @@ -139,6 +139,28 @@ Rectangle { opacity: emoteIndicator.source.toString().indexOf("Icon.svg") > -1 ? 1.0 : 0.0 } + Image { + id: lockIcon + width: 12 + height: 12 + anchors.top: parent.top + anchors.topMargin: 2 + anchors.left: parent.left + anchors.leftMargin: 0 + source: "images/lock_Icon.svg" + fillMode: Image.PreserveAspectFit + mipmap: true + visible: false + } + + ColorOverlay { + id: lockIconColorOverlay + anchors.fill: lockIcon + source: lockIcon + color: "#ffffff" + visible: drawerContainer.keepDrawerExpanded + } + MouseArea { id: emoteIndicatorMouseArea anchors.fill: parent @@ -147,14 +169,21 @@ Rectangle { onClicked: { Tablet.playSound(TabletEnums.ButtonClick); drawerContainer.keepDrawerExpanded = !drawerContainer.keepDrawerExpanded; + // If the drawer is no longer expanded, disable this MouseArea (which will close + // the emote tray) until the user's cursor leaves the MouseArea (see `onExited()` below). + if (!drawerContainer.keepDrawerExpanded) { + emoteIndicatorMouseArea.enabled = false; + } } onEntered: { Tablet.playSound(TabletEnums.ButtonHover); } - } - + onExited: { + emoteIndicatorMouseArea.enabled = true; + } + } } Row { diff --git a/scripts/simplifiedUI/simplifiedEmote/ui/qml/images/lock_Icon.svg b/scripts/simplifiedUI/simplifiedEmote/ui/qml/images/lock_Icon.svg new file mode 100644 index 0000000000..2195fa728f --- /dev/null +++ b/scripts/simplifiedUI/simplifiedEmote/ui/qml/images/lock_Icon.svg @@ -0,0 +1,8 @@ + + + + + From 757a4f908b3b0e59bd9a752d9375654e238ae7a9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Aug 2019 16:32:22 +1200 Subject: [PATCH 7/8] Fix ScriptDiscoveryService.scriptsModel.data() crash for invalid row Also fixes unexpected data for invalid column > 1. --- libraries/script-engine/src/ScriptsModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptsModel.cpp b/libraries/script-engine/src/ScriptsModel.cpp index 5f30033bf9..233229f2eb 100644 --- a/libraries/script-engine/src/ScriptsModel.cpp +++ b/libraries/script-engine/src/ScriptsModel.cpp @@ -78,7 +78,7 @@ TreeNodeBase* ScriptsModel::getTreeNodeFromIndex(const QModelIndex& index) const } QModelIndex ScriptsModel::index(int row, int column, const QModelIndex& parent) const { - if (row < 0 || column < 0) { + if (row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount(parent)) { return QModelIndex(); } return createIndex(row, column, getFolderNodes(static_cast(getTreeNodeFromIndex(parent))).at(row)); From 8c735ed6aeac25e06f68905218e94b7999432d0d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Aug 2019 16:32:52 +1200 Subject: [PATCH 8/8] Fix ScriptDiscoveryService.scriptsModel.parent() crash for invalid index --- libraries/script-engine/src/ScriptsModel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/script-engine/src/ScriptsModel.cpp b/libraries/script-engine/src/ScriptsModel.cpp index 233229f2eb..429c7f5518 100644 --- a/libraries/script-engine/src/ScriptsModel.cpp +++ b/libraries/script-engine/src/ScriptsModel.cpp @@ -85,6 +85,9 @@ QModelIndex ScriptsModel::index(int row, int column, const QModelIndex& parent) } QModelIndex ScriptsModel::parent(const QModelIndex& child) const { + if (!child.isValid()) { + return QModelIndex(); + } TreeNodeFolder* parent = (static_cast(child.internalPointer()))->getParent(); if (!parent) { return QModelIndex();