From dc9121433d4ac09e3b783181a5613c93feb96b26 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 13 Jun 2016 16:37:34 -0700 Subject: [PATCH 01/76] trying to fix skeleton switching bug --- interface/src/main.cpp | 4 ++-- libraries/avatars/src/AvatarData.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8fc0384aee..f0c7938b2a 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -90,11 +90,11 @@ int main(int argc, const char* argv[]) { qDebug() << "Interface instance appears to be running, exiting"; - return EXIT_SUCCESS; + //return EXIT_SUCCESS; } #ifdef Q_OS_WIN - return EXIT_SUCCESS; + //return EXIT_SUCCESS; #endif } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ff7438bb17..26bf0fb2a2 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1052,6 +1052,8 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } + sendIdentityPacket(); + networkReply->deleteLater(); } @@ -1094,6 +1096,7 @@ void AvatarData::sendIdentityPacket() { void AvatarData::updateJointMappings() { _jointIndices.clear(); _jointNames.clear(); + _jointData.clear(); if (_skeletonModelURL.fileName().toLower().endsWith(".fst")) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); From 5ac946059258f7418d336d30c6ed95e5521b84b5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 13 Jun 2016 16:43:33 -0700 Subject: [PATCH 02/76] fix branching --- scripts/system/users.js | 92 +++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index c010b7ea24..68d82040e9 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var PopUpMenu = function (properties) { +var PopUpMenu = function(properties) { var value = properties.value, promptOverlay, valueOverlay, @@ -217,7 +217,7 @@ var PopUpMenu = function (properties) { }; }; -var usersWindow = (function () { +var usersWindow = (function() { var baseURL = Script.resolvePath("assets/images/tools/"), WINDOW_WIDTH = 260, @@ -253,7 +253,11 @@ var usersWindow = (function () { WINDOW_BORDER_BOTTOM_MARGIN = WINDOW_BASE_MARGIN, WINDOW_BORDER_LEFT_MARGIN = WINDOW_BASE_MARGIN, WINDOW_BORDER_RADIUS = 4, - WINDOW_BORDER_COLOR = { red: 255, green: 255, blue: 255 }, + WINDOW_BORDER_COLOR = { + red: 255, + green: 255, + blue: 255 + }, WINDOW_BORDER_ALPHA = 0.5, windowBorder, @@ -377,9 +381,12 @@ var usersWindow = (function () { isMirrorDisplay = false, isFullscreenMirror = false, - windowPosition = { }, // Bottom left corner of window pane. + windowPosition = {}, // Bottom left corner of window pane. isMovingWindow = false, - movingClickOffset = { x: 0, y: 0 }, + movingClickOffset = { + x: 0, + y: 0 + }, isUsingScrollbars = false, isMovingScrollbar = false, @@ -401,9 +408,7 @@ var usersWindow = (function () { } // Reserve space for title, friends button, and option controls - nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER - + windowLineHeight + VISIBILITY_SPACER - + windowLineHeight + WINDOW_BASE_MARGIN; + nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER + windowLineHeight + VISIBILITY_SPACER + windowLineHeight + WINDOW_BASE_MARGIN; // Limit window to height of viewport above window position minus VU meter and mirror if displayed windowHeight = linesOfUsers.length * windowLineHeight - windowLineSpacing + nonUsersHeight; @@ -456,17 +461,14 @@ var usersWindow = (function () { x: scrollbarBackgroundPosition.x, y: scrollbarBackgroundPosition.y }); - scrollbarBarPosition.y = scrollbarBackgroundPosition.y + 1 - + scrollbarValue * (scrollbarBackgroundHeight - scrollbarBarHeight - 2); + scrollbarBarPosition.y = scrollbarBackgroundPosition.y + 1 + scrollbarValue * (scrollbarBackgroundHeight - scrollbarBarHeight - 2); Overlays.editOverlay(scrollbarBar, { x: scrollbarBackgroundPosition.x + 1, y: scrollbarBarPosition.y }); x = windowLeft + WINDOW_MARGIN; - y = windowPosition.y - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER - - windowLineHeight - VISIBILITY_SPACER - - windowLineHeight - WINDOW_BASE_MARGIN; + y = windowPosition.y - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER - windowLineHeight - VISIBILITY_SPACER - windowLineHeight - WINDOW_BASE_MARGIN; Overlays.editOverlay(friendsButton, { x: x, y: y @@ -554,9 +556,34 @@ var usersWindow = (function () { usersRequest.ontimeout = pollUsersTimedOut; usersRequest.onreadystatechange = processUsers; usersRequest.send(); + checkLoggedIn(); } - processUsers = function () { + var loggedIn = false; + + function checkLoggedIn() { + loggedIn = Account.isLoggedIn(); + if (loggedIn === false) { + Overlays.editOverlay(friendsButton, { + visible: false + }); + visibilityControl.setVisible(false); + displayControl.setVisible(false); + } else { + + Overlays.editOverlay(friendsButton, { + visible: true + }); + visibilityControl.setVisible(true); + displayControl.setVisible(true); + loggedIn = true; + + + } + } + + + processUsers = function() { var response, myUsername, user, @@ -609,7 +636,7 @@ var usersWindow = (function () { } }; - pollUsersTimedOut = function () { + pollUsersTimedOut = function() { print("Error: Request for users status timed out"); usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay. }; @@ -730,8 +757,7 @@ var usersWindow = (function () { userClicked = firstUserToDisplay + lineClicked; - if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX - && overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) { + if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX && overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) { //print("Go to " + usersOnline[linesOfUsers[userClicked]].username); location.goToUser(usersOnline[linesOfUsers[userClicked]].username); } @@ -800,12 +826,8 @@ var usersWindow = (function () { var isVisible; if (isMovingScrollbar) { - if (scrollbarBackgroundPosition.x - WINDOW_MARGIN <= event.x - && event.x <= scrollbarBackgroundPosition.x + SCROLLBAR_BACKGROUND_WIDTH + WINDOW_MARGIN - && scrollbarBackgroundPosition.y - WINDOW_MARGIN <= event.y - && event.y <= scrollbarBackgroundPosition.y + scrollbarBackgroundHeight + WINDOW_MARGIN) { - scrollbarValue = (event.y - scrollbarBarClickedAt * scrollbarBarHeight - scrollbarBackgroundPosition.y) - / (scrollbarBackgroundHeight - scrollbarBarHeight - 2); + if (scrollbarBackgroundPosition.x - WINDOW_MARGIN <= event.x && event.x <= scrollbarBackgroundPosition.x + SCROLLBAR_BACKGROUND_WIDTH + WINDOW_MARGIN && scrollbarBackgroundPosition.y - WINDOW_MARGIN <= event.y && event.y <= scrollbarBackgroundPosition.y + scrollbarBackgroundHeight + WINDOW_MARGIN) { + scrollbarValue = (event.y - scrollbarBarClickedAt * scrollbarBarHeight - scrollbarBackgroundPosition.y) / (scrollbarBackgroundHeight - scrollbarBarHeight - 2); scrollbarValue = Math.min(Math.max(scrollbarValue, 0.0), 1.0); firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay)); updateOverlayPositions(); @@ -831,13 +853,9 @@ var usersWindow = (function () { isVisible = isBorderVisible; if (isVisible) { - isVisible = windowPosition.x - WINDOW_BORDER_LEFT_MARGIN <= event.x - && event.x <= windowPosition.x - WINDOW_BORDER_LEFT_MARGIN + WINDOW_BORDER_WIDTH - && windowPosition.y - windowHeight - WINDOW_BORDER_TOP_MARGIN <= event.y - && event.y <= windowPosition.y + WINDOW_BORDER_BOTTOM_MARGIN; + isVisible = windowPosition.x - WINDOW_BORDER_LEFT_MARGIN <= event.x && event.x <= windowPosition.x - WINDOW_BORDER_LEFT_MARGIN + WINDOW_BORDER_WIDTH && windowPosition.y - windowHeight - WINDOW_BORDER_TOP_MARGIN <= event.y && event.y <= windowPosition.y + WINDOW_BORDER_BOTTOM_MARGIN; } else { - isVisible = windowPosition.x <= event.x && event.x <= windowPosition.x + WINDOW_WIDTH - && windowPosition.y - windowHeight <= event.y && event.y <= windowPosition.y; + isVisible = windowPosition.x <= event.x && event.x <= windowPosition.x + WINDOW_WIDTH && windowPosition.y - windowHeight <= event.y && event.y <= windowPosition.y; } if (isVisible !== isBorderVisible) { isBorderVisible = isVisible; @@ -878,8 +896,7 @@ var usersWindow = (function () { isMirrorDisplay = Menu.isOptionChecked(MIRROR_MENU_ITEM); isFullscreenMirror = Menu.isOptionChecked(FULLSCREEN_MIRROR_MENU_ITEM); - if (viewport.y !== oldViewport.y || isMirrorDisplay !== oldIsMirrorDisplay - || isFullscreenMirror !== oldIsFullscreenMirror) { + if (viewport.y !== oldViewport.y || isMirrorDisplay !== oldIsMirrorDisplay || isFullscreenMirror !== oldIsFullscreenMirror) { calculateWindowHeight(); updateUsersDisplay(); } @@ -929,8 +946,8 @@ var usersWindow = (function () { } else { hmdViewport = Controller.getRecommendedOverlayRect(); windowPosition = { - x: (viewport.x - hmdViewport.width) / 2, // HMD viewport is narrower than screen. - y: hmdViewport.height // HMD viewport starts at top of screen but only extends down so far. + x: (viewport.x - hmdViewport.width) / 2, // HMD viewport is narrower than screen. + y: hmdViewport.height // HMD viewport starts at top of screen but only extends down so far. }; } @@ -938,7 +955,7 @@ var usersWindow = (function () { windowBorder = Overlays.addOverlay("rectangle", { x: 0, - y: viewport.y, // Start up off-screen + y: viewport.y, // Start up off-screen width: WINDOW_BORDER_WIDTH, height: windowBorderHeight, radius: WINDOW_BORDER_RADIUS, @@ -1101,6 +1118,11 @@ var usersWindow = (function () { visible: isVisible && !isMinimized }); + + Script.setTimeout(function() { + checkLoggedIn() + }, 0); + Controller.mousePressEvent.connect(onMousePressEvent); Controller.mouseMoveEvent.connect(onMouseMoveEvent); Controller.mouseReleaseEvent.connect(onMouseReleaseEvent); @@ -1143,4 +1165,4 @@ var usersWindow = (function () { setUp(); Script.scriptEnding.connect(tearDown); -}()); +}()); \ No newline at end of file From 3b2e0842b04121872976246a34b0d4fb7d7dabfa Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 13 Jun 2016 23:27:08 -0700 Subject: [PATCH 03/76] add face camera to text properties --- scripts/system/html/entityProperties.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 2a82d8fa74..51e0914db1 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -452,6 +452,7 @@ var elTextText = document.getElementById("property-text-text"); var elTextLineHeight = document.getElementById("property-text-line-height"); var elTextTextColor = document.getElementById("property-text-text-color"); + var elTextFaceCamera = document.getElementById("property-text-face-camera"); var elTextTextColorRed = document.getElementById("property-text-text-color-red"); var elTextTextColorGreen = document.getElementById("property-text-text-color-green"); var elTextTextColorBlue = document.getElementById("property-text-text-color-blue"); @@ -735,6 +736,7 @@ elTextText.value = properties.text; elTextLineHeight.value = properties.lineHeight.toFixed(4); + elTextFaceCamera = properties.faceCamera; elTextTextColor.style.backgroundColor = "rgb(" + properties.textColor.red + "," + properties.textColor.green + "," + properties.textColor.blue + ")"; elTextTextColorRed.value = properties.textColor.red; elTextTextColorGreen.value = properties.textColor.green; @@ -996,8 +998,8 @@ elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text')); + elTextFaceCamera.addEventListener('change', createEmitCheckedPropertyUpdateFunction('faceCamera')); elTextLineHeight.addEventListener('change', createEmitNumberPropertyUpdateFunction('lineHeight')); - var textTextColorChangeFunction = createEmitColorPropertyUpdateFunction( 'textColor', elTextTextColorRed, elTextTextColorGreen, elTextTextColorBlue); elTextTextColorRed.addEventListener('change', textTextColorChangeFunction); @@ -1715,6 +1717,10 @@ +
+ + +
From b97dc584ea59c8c69fb5e4d76b2d286488bbf4cb Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 14 Jun 2016 14:14:31 -0700 Subject: [PATCH 04/76] fix bug where buttons would show when minimized --- scripts/system/users.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 68d82040e9..5b0ba42a45 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -570,7 +570,10 @@ var usersWindow = (function() { visibilityControl.setVisible(false); displayControl.setVisible(false); } else { - + if (isMinimized === true) { + loggedIn = true; + return + } Overlays.editOverlay(friendsButton, { visible: true }); @@ -578,7 +581,6 @@ var usersWindow = (function() { displayControl.setVisible(true); loggedIn = true; - } } @@ -660,11 +662,15 @@ var usersWindow = (function() { Overlays.editOverlay(scrollbarBar, { visible: isVisible && isUsingScrollbars && !isMinimized }); - Overlays.editOverlay(friendsButton, { - visible: isVisible && !isMinimized - }); - displayControl.setVisible(isVisible && !isMinimized); - visibilityControl.setVisible(isVisible && !isMinimized); + + if (loggedIn === true) { + Overlays.editOverlay(friendsButton, { + visible: isVisible && !isMinimized + }); + displayControl.setVisible(isVisible && !isMinimized); + visibilityControl.setVisible(isVisible && !isMinimized); + } + } function setVisible(visible) { @@ -758,7 +764,6 @@ var usersWindow = (function() { userClicked = firstUserToDisplay + lineClicked; if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX && overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) { - //print("Go to " + usersOnline[linesOfUsers[userClicked]].username); location.goToUser(usersOnline[linesOfUsers[userClicked]].username); } From 3c2b98b15a4cdd9819bf9db7103938aa88930589 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 15 Jun 2016 11:28:38 +1200 Subject: [PATCH 05/76] Let user choose an existing file in the file save dialog --- interface/resources/qml/dialogs/FileDialog.qml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 56f761e42d..f57d20de51 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -614,12 +614,6 @@ ModalWindow { readOnly: !root.saveDialog activeFocusOnTab: !readOnly onActiveFocusChanged: if (activeFocus) { selectAll(); } - onTextChanged: { - if (root.saveDialog && text !== "") { - fileTableView.selection.clear(); - fileTableView.currentRow = -1; - } - } onAccepted: okAction.trigger(); } From 59b785a33bbfcc818a8597b262dec15749b83847 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 15 Jun 2016 16:55:34 -0700 Subject: [PATCH 06/76] trying to debug --- libraries/animation/src/Rig.cpp | 4 +--- libraries/avatars/src/AvatarData.cpp | 27 ++++++++++++++++++--------- libraries/avatars/src/AvatarData.h | 2 +- libraries/render-utils/src/Model.cpp | 3 +++ 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index b21f5a0e84..8f0bd3fd87 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -163,7 +163,6 @@ void Rig::destroyAnimGraph() { } void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) { - _geometryOffset = AnimPose(geometry.offset); _invGeometryOffset = _geometryOffset.inverse(); setModelOffset(modelOffset); @@ -1224,8 +1223,7 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { } void Rig::copyJointsFromJointData(const QVector& jointDataVec) { - - if (_animSkeleton) { + if (_animSkeleton && jointDataVec.size() == _internalPoseSet._overrideFlags.size()) { // transform all the default poses into rig space. const AnimPose geometryToRigPose(_geometryToRigTransform); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 26bf0fb2a2..0ae58ca1de 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -261,7 +261,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { unsigned char validity = 0; int validityBit = 0; - #ifdef WANT_DEBUG + #if 1 int rotationSentCount = 0; unsigned char* beforeRotations = destinationBuffer; #endif @@ -276,7 +276,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { if (data.rotationSet) { validity |= (1 << validityBit); - #ifdef WANT_DEBUG + #if 1 rotationSentCount++; #endif } @@ -310,7 +310,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validity = 0; validityBit = 0; - #ifdef WANT_DEBUG + #if 1 int translationSentCount = 0; unsigned char* beforeTranslations = destinationBuffer; #endif @@ -324,7 +324,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { if (data.translationSet) { validity |= (1 << validityBit); - #ifdef WANT_DEBUG + #if 1 translationSentCount++; #endif maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); @@ -359,7 +359,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } } - #ifdef WANT_DEBUG + #if 1 if (sendAll) { qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll << "rotations:" << rotationSentCount << "translations:" << translationSentCount @@ -584,6 +584,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackOrientationQuatFromSixBytes(sourceBuffer, data.rotation); _hasNewJointRotations = true; data.rotationSet = true; + } else if (numValidJointRotations == numJoints) { + _hasNewJointRotations = true; + data.rotationSet = false; } } @@ -620,10 +623,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); _hasNewJointTranslations = true; data.translationSet = true; + } else if (numValidJointRotations == numJoints) { + _hasNewJointTranslations = true; + data.translationSet = false; } } - #ifdef WANT_DEBUG + #if 1 if (numValidJointRotations > 15) { qDebug() << "RECEIVING -- rotations:" << numValidJointRotations << "translations:" << numValidJointTranslations @@ -1052,17 +1058,20 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } - sendIdentityPacket(); + //sendIdentityPacket(); + //sendAvatarDataPacket(true); + qDebug() << "set joint mapping froms network reply, num joints: " << _jointIndices.size(); networkReply->deleteLater(); } -void AvatarData::sendAvatarDataPacket() { +void AvatarData::sendAvatarDataPacket(bool sendFull) { auto nodeList = DependencyManager::get(); // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. - bool sendFullUpdate = randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO; + bool sendFullUpdate = sendFull || (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); + if (sendFullUpdate) qDebug() << sendFullUpdate; QByteArray avatarByteArray = toByteArray(true, sendFullUpdate); doneEncoding(true); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 61ee649273..7fe339c2b9 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -352,7 +352,7 @@ public: AvatarEntityIDs getAndClearRecentlyDetachedIDs(); public slots: - void sendAvatarDataPacket(); + void sendAvatarDataPacket(bool sendFull = false); void sendIdentityPacket(); void setJointMappingsFromNetworkReply(); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ded1184c24..2112e64a39 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -254,6 +254,7 @@ bool Model::updateGeometry() { _needsReload = false; if (_rig->jointStatesEmpty() && getFBXGeometry().joints.size() > 0) { + qDebug() << "initJointStates, num joints: " << getFBXGeometry().joints.size(); initJointStates(); const FBXGeometry& fbxGeometry = getFBXGeometry(); @@ -817,7 +818,9 @@ void Model::setURL(const QUrl& url) { invalidCalculatedMeshBoxes(); deleteGeometry(); + if (_geometry && _geometry->getGeometry()) qDebug() << "geometry1: " << _geometry->getGeometry()->getGeometry().joints.size(); _geometry = DependencyManager::get()->getGeometry(url); + if (_geometry && _geometry->getGeometry()) qDebug() << "geometry2: " << _geometry->getGeometry()->getGeometry().joints.size(); onInvalidate(); } From f02ffa92fdb03b8a6afd85e95761c62843b113f9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 15 Jun 2016 18:00:08 -0700 Subject: [PATCH 07/76] undo debugging --- libraries/avatars/src/AvatarData.cpp | 33 ++++++++++++++-------------- libraries/avatars/src/AvatarData.h | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0ae58ca1de..c98fec0d7d 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -261,7 +261,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { unsigned char validity = 0; int validityBit = 0; - #if 1 + #ifdef WANT_DEBUG int rotationSentCount = 0; unsigned char* beforeRotations = destinationBuffer; #endif @@ -276,7 +276,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { if (data.rotationSet) { validity |= (1 << validityBit); - #if 1 + #ifdef WANT_DEBUG rotationSentCount++; #endif } @@ -310,7 +310,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validity = 0; validityBit = 0; - #if 1 + #ifdef WANT_DEBUG int translationSentCount = 0; unsigned char* beforeTranslations = destinationBuffer; #endif @@ -324,7 +324,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { if (data.translationSet) { validity |= (1 << validityBit); - #if 1 + #ifdef WANT_DEBUG translationSentCount++; #endif maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); @@ -359,7 +359,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } } - #if 1 + #ifdef WANT_DEBUG if (sendAll) { qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll << "rotations:" << rotationSentCount << "translations:" << translationSentCount @@ -575,6 +575,14 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } } + // If all the rotations were sent, this is a full packet + bool fullPacket = numValidJointRotations == numJoints; + + if (fullPacket) { + _hasNewJointRotations = true; + _hasNewJointTranslations = true; + } + // each joint rotation is stored in 6 bytes. const int COMPRESSED_QUATERNION_SIZE = 6; PACKET_READ_CHECK(JointRotations, numValidJointRotations * COMPRESSED_QUATERNION_SIZE); @@ -584,9 +592,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackOrientationQuatFromSixBytes(sourceBuffer, data.rotation); _hasNewJointRotations = true; data.rotationSet = true; - } else if (numValidJointRotations == numJoints) { - _hasNewJointRotations = true; - data.rotationSet = false; } } @@ -623,13 +628,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); _hasNewJointTranslations = true; data.translationSet = true; - } else if (numValidJointRotations == numJoints) { - _hasNewJointTranslations = true; - data.translationSet = false; } } - #if 1 + #ifdef WANT_DEBUG if (numValidJointRotations > 15) { qDebug() << "RECEIVING -- rotations:" << numValidJointRotations << "translations:" << numValidJointTranslations @@ -1058,20 +1060,17 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } - //sendIdentityPacket(); - //sendAvatarDataPacket(true); qDebug() << "set joint mapping froms network reply, num joints: " << _jointIndices.size(); networkReply->deleteLater(); } -void AvatarData::sendAvatarDataPacket(bool sendFull) { +void AvatarData::sendAvatarDataPacket() { auto nodeList = DependencyManager::get(); // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. - bool sendFullUpdate = sendFull || (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); - if (sendFullUpdate) qDebug() << sendFullUpdate; + bool sendFullUpdate = randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO; QByteArray avatarByteArray = toByteArray(true, sendFullUpdate); doneEncoding(true); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 7fe339c2b9..61ee649273 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -352,7 +352,7 @@ public: AvatarEntityIDs getAndClearRecentlyDetachedIDs(); public slots: - void sendAvatarDataPacket(bool sendFull = false); + void sendAvatarDataPacket(); void sendIdentityPacket(); void setJointMappingsFromNetworkReply(); From ed88232fb06bc8096d20637dc6abdcd8b52ed31d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 09:19:42 -0700 Subject: [PATCH 08/76] Move session id storage to AccountManager --- interface/src/DiscoverabilityManager.cpp | 14 ++++++-------- interface/src/DiscoverabilityManager.h | 1 - libraries/networking/src/AccountManager.cpp | 7 +++++-- libraries/networking/src/AccountManager.h | 3 ++- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index 24256fdf39..c4d985419e 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -80,7 +80,8 @@ void DiscoverabilityManager::updateLocation() { locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends)); // if we have a session ID add it now, otherwise add a null value - rootObject[SESSION_ID_KEY] = _sessionID.isEmpty() ? QJsonValue() : _sessionID; + auto sessionID = accountManager->getSessionID(); + rootObject[SESSION_ID_KEY] = sessionID.isNull() ? QJsonValue() : sessionID.toString(); JSONCallbackParameters callbackParameters; callbackParameters.jsonCallbackReceiver = this; @@ -110,11 +111,8 @@ void DiscoverabilityManager::updateLocation() { callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse"; QJsonObject heartbeatObject; - if (!_sessionID.isEmpty()) { - heartbeatObject[SESSION_ID_KEY] = _sessionID; - } else { - heartbeatObject[SESSION_ID_KEY] = QJsonValue(); - } + auto sessionID = accountManager->getSessionID(); + heartbeatObject[SESSION_ID_KEY] = sessionID.isNull() ? QJsonValue() : sessionID.toString(); accountManager->sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Optional, QNetworkAccessManager::PutOperation, callbackParameters, @@ -126,11 +124,11 @@ void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply auto dataObject = AccountManager::dataObjectFromResponse(requestReply); if (!dataObject.isEmpty()) { - _sessionID = dataObject[SESSION_ID_KEY].toString(); + auto sessionID = dataObject[SESSION_ID_KEY].toString(); // give that session ID to the account manager auto accountManager = DependencyManager::get(); - accountManager->setSessionID(_sessionID); + accountManager->setSessionID(sessionID); } } diff --git a/interface/src/DiscoverabilityManager.h b/interface/src/DiscoverabilityManager.h index 9a1fa7b39c..196b0cdf81 100644 --- a/interface/src/DiscoverabilityManager.h +++ b/interface/src/DiscoverabilityManager.h @@ -49,7 +49,6 @@ private: DiscoverabilityManager(); Setting::Handle _mode; - QString _sessionID; QJsonObject _lastLocationObject; }; diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index bac031885f..2ee49455b7 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -44,6 +44,7 @@ Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) Q_DECLARE_METATYPE(JSONCallbackParameters) const QString ACCOUNTS_GROUP = "accounts"; +static const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, const QString& jsonCallbackMethod, QObject* errorCallbackReceiver, const QString& errorCallbackMethod, @@ -221,8 +222,7 @@ void AccountManager::sendRequest(const QString& path, // if we're allowed to send usage data, include whatever the current session ID is with this request auto& activityLogger = UserActivityLogger::getInstance(); if (activityLogger.isEnabled()) { - static const QString METAVERSE_SESSION_ID_HEADER = "HFM-SessionID"; - networkRequest.setRawHeader(METAVERSE_SESSION_ID_HEADER.toLocal8Bit(), + networkRequest.setRawHeader(METAVERSE_SESSION_ID_HEADER, uuidStringWithoutCurlyBraces(_sessionID).toLocal8Bit()); } @@ -321,6 +321,9 @@ void AccountManager::processReply() { QNetworkReply* requestReply = reinterpret_cast(sender()); if (requestReply->error() == QNetworkReply::NoError) { + if (requestReply->hasRawHeader(METAVERSE_SESSION_ID_HEADER)) { + _sessionID = requestReply->rawHeader(METAVERSE_SESSION_ID_HEADER); + } passSuccessToCallback(requestReply); } else { passErrorToCallback(requestReply); diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 4803d2625f..6e26a56739 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -86,6 +86,7 @@ public: static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply); + QUuid getSessionID() const { return _sessionID; } void setSessionID(const QUuid& sessionID) { _sessionID = sessionID; } public slots: @@ -139,7 +140,7 @@ private: bool _isWaitingForKeypairResponse { false }; QByteArray _pendingPrivateKey; - QUuid _sessionID; + QUuid _sessionID { QUuid::createUuid() }; }; #endif // hifi_AccountManager_h From 8b3b62aad7ac3861f044fdaebf8ecdc5f6388de5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 10:25:38 -0700 Subject: [PATCH 09/76] Add UserActivityLogger scripting interface --- interface/src/Application.cpp | 3 +++ .../UserActivityLoggerScriptingInterface.cpp | 19 ++++++++++++++ .../UserActivityLoggerScriptingInterface.h | 26 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 libraries/networking/src/UserActivityLoggerScriptingInterface.cpp create mode 100644 libraries/networking/src/UserActivityLoggerScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e789b7c508..e8effefd6e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -4558,6 +4559,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("ScriptDiscoveryService", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Reticle", getApplicationCompositor().getReticleInterface()); + + scriptEngine->registerGlobalObject("UserActivityLogger", new UserActivityLoggerScriptingInterface()); } bool Application::canAcceptURL(const QString& urlString) const { diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp new file mode 100644 index 0000000000..c0ed4fce19 --- /dev/null +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -0,0 +1,19 @@ +// +// UserActivityLoggerScriptingInterface.h +// libraries/networking/src +// +// Created by Ryan Huffman on 6/06/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "UserActivityLoggerScriptingInterface.h" +#include "UserActivityLogger.h" + +void UserActivityLoggerScriptingInterface::logAction(QString action, QVariantMap details) const { + QMetaObject::invokeMethod(&UserActivityLogger::getInstance(), "logAction", + Q_ARG(QString, action), + Q_ARG(QJsonObject, QJsonObject::fromVariantMap(details))); +} diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h new file mode 100644 index 0000000000..1e6043491e --- /dev/null +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -0,0 +1,26 @@ +// +// UserActivityLoggerScriptingInterface.h +// libraries/networking/src +// +// Created by Ryan Huffman on 6/06/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_UserActivityLoggerScriptingInterface_h +#define hifi_UserActivityLoggerScriptingInterface_h + +#include +#include + +class QScriptValue; + +class UserActivityLoggerScriptingInterface : public QObject { + Q_OBJECT +public: + Q_INVOKABLE void logAction(QString action, QVariantMap details) const; +}; + +#endif // hifi_UserActivityLoggerScriptingInterface_h \ No newline at end of file From 1ce9e96cba6427ed98d8ff0235004752fe56a43b Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 16 Jun 2016 01:20:28 -0700 Subject: [PATCH 10/76] Send domain metadata for authed domains --- domain-server/src/DomainServer.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 7c596bb187..1f666455c6 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -108,6 +108,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : connect(&_settingsManager, &DomainServerSettingsManager::updateNodePermissions, &_gatekeeper, &DomainGatekeeper::updateNodePermissions); + // update the metadata with current descriptors + _metadata.setDescriptors(_settingsManager.getSettingsMap()); + if (optionallyReadX509KeyAndCertificate() && optionallySetupOAuth()) { // we either read a certificate and private key or were not passed one // and completed login or did not need to @@ -122,10 +125,17 @@ DomainServer::DomainServer(int argc, char* argv[]) : _gatekeeper.preloadAllowedUserPublicKeys(); optionallyGetTemporaryName(args); - } - // update the metadata with current descriptors - _metadata.setDescriptors(_settingsManager.getSettingsMap()); + // send metadata descriptors + QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(_metadata.getDescriptors()).toJson(QJsonDocument::Compact))); + const QUuid& domainID = DependencyManager::get()->getSessionUUID(); + static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; + DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + AccountManagerAuth::Required, + QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), + domainUpdateJSON.toUtf8()); + } } DomainServer::~DomainServer() { From c7955900ab9c35a4f3da1dc5eaa35b77b495e8ad Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 13:17:18 -0700 Subject: [PATCH 11/76] Add new user activity events --- interface/src/Application.cpp | 42 +++++++++++++++++++++++-- interface/src/Application.h | 2 ++ libraries/avatars/src/AvatarHashMap.cpp | 14 +++++++++ libraries/avatars/src/AvatarHashMap.h | 1 + 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e8effefd6e..f2f265aae0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -435,7 +435,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - + DependencyManager::set(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) DependencyManager::set(); @@ -1057,6 +1057,44 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : } }); + // Add periodic checks to send user activity data + static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000; + static int SEND_FPS_INTERVAL_MS = 10000; + + // Periodically send fps as a user activity event + QTimer* sendFPSTimer = new QTimer(this); + sendFPSTimer->setInterval(SEND_FPS_INTERVAL_MS); + connect(sendFPSTimer, &QTimer::timeout, this, [this]() { + UserActivityLogger::getInstance().logAction("fps", { { "rate", _frameCounter.rate() } }); + }); + sendFPSTimer->start(); + + + // Periodically check for count of nearby avatars + static int lastCountOfNearbyAvatars = -1; + QTimer* checkNearbyAvatarsTimer = new QTimer(this); + checkNearbyAvatarsTimer->setInterval(CHECK_NEARBY_AVATARS_INTERVAL_MS); + connect(checkNearbyAvatarsTimer, &QTimer::timeout, this, [this]() { + auto avatarManager = DependencyManager::get(); + int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(), 10) - 1; + if (nearbyAvatars != lastCountOfNearbyAvatars) { + UserActivityLogger::getInstance().logAction("nearby_avatars", { { "count", nearbyAvatars } }); + } + }); + + // Track user activity event when we receive a mute packet + auto onMutedByMixer = []() { + UserActivityLogger::getInstance().logAction("received_mute_packet"); + }; + connect(DependencyManager::get().data(), &AudioClient::mutedByMixer, this, onMutedByMixer); + + // Track when the address bar is opened + auto onAddressBarToggled = [this]() { + // Record time + UserActivityLogger::getInstance().logAction("opened_address_bar", { { "uptime_ms", _sessionRunTimer.elapsed() } }); + }; + connect(DependencyManager::get().data(), &DialogsManager::addressBarToggled, this, onAddressBarToggled); + // Make sure we don't time out during slow operations at startup updateHeartbeat(); @@ -4560,7 +4598,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("ScriptDiscoveryService", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Reticle", getApplicationCompositor().getReticleInterface()); - scriptEngine->registerGlobalObject("UserActivityLogger", new UserActivityLoggerScriptingInterface()); + scriptEngine->registerGlobalObject("UserActivityLogger", DependencyManager::get().data()); } bool Application::canAcceptURL(const QString& urlString) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index a17250a58e..d728359ed1 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -195,6 +195,8 @@ public: float getRenderResolutionScale() const; + qint64 getCurrentSessionRuntime() const { return _sessionRunTimer.elapsed(); } + bool isAboutToQuit() const { return _aboutToQuit; } // the isHMDMode is true whenever we use the interface from an HMD and not a standard flat display diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 9084fd837b..d153cfd977 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -44,6 +44,20 @@ bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range return false; } +int AvatarHashMap::numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters) { + auto hashCopy = getHashCopy(); + auto rangeMeters2 = rangeMeters * rangeMeters; + int count = 0; + for (const AvatarSharedPointer& sharedAvatar : hashCopy) { + glm::vec3 avatarPosition = sharedAvatar->getPosition(); + auto distance2 = glm::distance2(avatarPosition, position); + if (distance2 < rangeMeters2) { + ++count; + } + } + return count; +} + AvatarSharedPointer AvatarHashMap::newSharedAvatar() { return std::make_shared(); } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 5f58074427..9d3ebb60f5 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -39,6 +39,7 @@ public: Q_INVOKABLE AvatarData* getAvatar(QUuid avatarID); virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) { return findAvatar(sessionID); } + int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); signals: void avatarAddedEvent(const QUuid& sessionUUID); From 365037774570a28b1dd2f8883ac1290ad4a670e8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 13:17:31 -0700 Subject: [PATCH 12/76] Clean up NULL => nullptr --- libraries/networking/src/AccountManager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 6e26a56739..d30a05fb2c 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -26,9 +26,9 @@ class JSONCallbackParameters { public: - JSONCallbackParameters(QObject* jsonCallbackReceiver = NULL, const QString& jsonCallbackMethod = QString(), - QObject* errorCallbackReceiver = NULL, const QString& errorCallbackMethod = QString(), - QObject* updateReceiver = NULL, const QString& updateSlot = QString()); + JSONCallbackParameters(QObject* jsonCallbackReceiver = nullptr, const QString& jsonCallbackMethod = QString(), + QObject* errorCallbackReceiver = nullptr, const QString& errorCallbackMethod = QString(), + QObject* updateReceiver = nullptr, const QString& updateSlot = QString()); bool isEmpty() const { return !jsonCallbackReceiver && !errorCallbackReceiver; } From 56c84bbc27cf34cf1a173d67b28e1c0fdc8cc871 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 13:18:08 -0700 Subject: [PATCH 13/76] Add opened_marketplace and enabled_edit to edit.js --- scripts/system/edit.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index afbc679ec4..4c5d9bf4f0 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -150,6 +150,8 @@ function showMarketplace(marketplaceID) { marketplaceWindow.setURL(url); marketplaceWindow.setVisible(true); marketplaceWindow.raise(); + + UserActivityLogger.logAction("opened_marketplace"); } function hideMarketplace() { @@ -358,6 +360,9 @@ var toolBar = (function() { } that.showTools(isActive); } + if (active) { + UserActivityLogger.logAction("enabled_edit"); + } } toolBar.selectTool(activeButton, isActive); lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE)); From bce05df56b5718cc1f21a1238d8c77effe667800 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 13:25:14 -0700 Subject: [PATCH 14/76] Update enabled_edit to only get sent when you have permission --- scripts/system/edit.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 4c5d9bf4f0..f20676efc2 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -340,6 +340,7 @@ var toolBar = (function() { Messages.sendLocalMessage("edit-events", JSON.stringify({ enabled: active })); + UserActivityLogger.logAction("enabled_edit"); isActive = active; if (!isActive) { entityListTool.setVisible(false); @@ -360,9 +361,6 @@ var toolBar = (function() { } that.showTools(isActive); } - if (active) { - UserActivityLogger.logAction("enabled_edit"); - } } toolBar.selectTool(activeButton, isActive); lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE)); From 0f9c637c5a490dd43da16ca74dbfde34e80fd843 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 16 Jun 2016 01:32:38 -0700 Subject: [PATCH 15/76] Wireframe a metadata overlay tutorial --- scripts/tutorials/getDomainMetadata.js | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 scripts/tutorials/getDomainMetadata.js diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js new file mode 100644 index 0000000000..1c78d640e8 --- /dev/null +++ b/scripts/tutorials/getDomainMetadata.js @@ -0,0 +1,28 @@ +// +// Created by Zach Pomerantz on June 16, 2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// Avoid polluting the namespace +// !function() { + var MetadataNotification = null; + + // Every time you enter a domain, display the domain's metadata + SomeEvent.connect(function() { + // Fetch the domain metadata from the directory + + // Display the fetched metadata in an overlay + + }); + + // Remove the overlay if the script is stopped + Script.scriptEnding.connect(teardown); + + function teardown() { + // Close the overlay, if it exists + + } +// }(); From c2ebcd1f77234350a974a03b30c1aac1223e7f8a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jun 2016 13:49:25 -0700 Subject: [PATCH 16/76] Make activity logging from scripts only available for certain events --- .../src/UserActivityLoggerScriptingInterface.cpp | 12 ++++++++++-- .../src/UserActivityLoggerScriptingInterface.h | 14 +++++++++----- scripts/system/edit.js | 2 +- scripts/system/examples.js | 2 ++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index c0ed4fce19..012a569639 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -12,8 +12,16 @@ #include "UserActivityLoggerScriptingInterface.h" #include "UserActivityLogger.h" -void UserActivityLoggerScriptingInterface::logAction(QString action, QVariantMap details) const { +void UserActivityLoggerScriptingInterface::enabledEdit() { + logAction("enabled_edit"); +} + +void UserActivityLoggerScriptingInterface::openedMarketplace() { + logAction("opened_marketplace"); +} + +void UserActivityLoggerScriptingInterface::logAction(QString action, QJsonObject details) { QMetaObject::invokeMethod(&UserActivityLogger::getInstance(), "logAction", Q_ARG(QString, action), - Q_ARG(QJsonObject, QJsonObject::fromVariantMap(details))); + Q_ARG(QJsonObject, details)); } diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index 1e6043491e..cad24b1967 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -13,14 +13,18 @@ #define hifi_UserActivityLoggerScriptingInterface_h #include -#include +#include -class QScriptValue; +#include -class UserActivityLoggerScriptingInterface : public QObject { +class UserActivityLoggerScriptingInterface : public QObject, public Dependency { Q_OBJECT public: - Q_INVOKABLE void logAction(QString action, QVariantMap details) const; + Q_INVOKABLE void enabledEdit(); + Q_INVOKABLE void openedMarketplace(); + +private: + void logAction(QString action, QJsonObject details = {}); }; -#endif // hifi_UserActivityLoggerScriptingInterface_h \ No newline at end of file +#endif // hifi_UserActivityLoggerScriptingInterface_h diff --git a/scripts/system/edit.js b/scripts/system/edit.js index f20676efc2..64c6a06c58 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -340,7 +340,7 @@ var toolBar = (function() { Messages.sendLocalMessage("edit-events", JSON.stringify({ enabled: active })); - UserActivityLogger.logAction("enabled_edit"); + UserActivityLogger.enabledEdit(); isActive = active; if (!isActive) { entityListTool.setVisible(false); diff --git a/scripts/system/examples.js b/scripts/system/examples.js index 9d33e473af..fb5ba02441 100644 --- a/scripts/system/examples.js +++ b/scripts/system/examples.js @@ -37,6 +37,8 @@ function showExamples(marketplaceID) { print("setting examples URL to " + url); examplesWindow.setURL(url); examplesWindow.setVisible(true); + + UserActivityLogger.openedMarketplace(); } function hideExamples() { From aca3d4d90b0acd3522eeabad214152a48406ac0b Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 16 Jun 2016 15:22:34 -0700 Subject: [PATCH 17/76] add example script for metadata from metaverse --- scripts/tutorials/getDomainMetadata.js | 118 ++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 13 deletions(-) diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 1c78d640e8..0a6f742823 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -6,23 +6,115 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// Avoid polluting the namespace -// !function() { - var MetadataNotification = null; +var SERVER = 'https://metaverse.highfidelity.com/api/v1'; - // Every time you enter a domain, display the domain's metadata - SomeEvent.connect(function() { - // Fetch the domain metadata from the directory +var OVERLAY = null; - // Display the fetched metadata in an overlay +// Every time you enter a domain, display the domain's metadata +location.hostChanged.connect(function(host) { + print('Detected host change:', host); - }); + // Fetch the domain ID from the metaverse + var placeData = request(SERVER + '/places/' + host); + if (!placeData) { return; } + var domainID = placeData.data.place.domain.id; + print('Domain ID:', domainID); - // Remove the overlay if the script is stopped - Script.scriptEnding.connect(teardown); + // Fetch the domain metadata from the metaverse + var domainData = request(SERVER + '/domains/' + domainID); + print(SERVER + '/domains/' + domainID); + if (!domainData) { return; } + var metadata = domainData.domain; + print('Domain metadata:', JSON.stringify(metadata)); - function teardown() { - // Close the overlay, if it exists + // Display the fetched metadata in an overlay + displayMetadata(host, metadata); +}); +Script.scriptEnding.connect(clearMetadata); + +function displayMetadata(place, metadata) { + clearMetadata(); + + var COLOR_TEXT = { red: 255, green: 255, blue: 255 }; + var COLOR_BACKGROUND = { red: 0, green: 0, blue: 0 }; + var MARGIN = 200; + var STARTING_OPACITY = 0.8; + var FADE_AFTER_SEC = 2; + var FADE_FOR_SEC = 4; + + var fade_per_sec = STARTING_OPACITY / FADE_FOR_SEC; + var properties = { + color: COLOR_TEXT, + alpha: STARTING_OPACITY, + backgroundColor: COLOR_BACKGROUND, + backgroundAlpha: STARTING_OPACITY, + font: { size: 24 }, + x: MARGIN, + y: MARGIN + }; + + // Center the overlay on the screen + properties.width = Window.innerWidth - MARGIN*2; + properties.height = Window.innerHeight - MARGIN*2; + + // Parse the metadata into text + parsed = [ 'Welcome to ' + place + '!',, ]; + if (metadata.description) { + parsed.push(description); } -// }(); + if (metadata.tags && metadata.tags.length) { + parsed.push('Tags: ' + metadata.tags.join(',')); + } + if (metadata.capacity) { + parsed.push('Capacity (max users): ' + metadata.capacity); + } + if (metadata.maturity) { + parsed.push('Maturity: ' + metadata.maturity); + } + if (metadata.hosts && metadata.hosts.length) { + parsed.push('Hosts: ' + metadata.tags.join(',')); + } + if (metadata.online_users) { + parsed.push('Users online: ' + metadata.online_users); + } + + properties.text = parsed.join('\n\n'); + + // Display the overlay + OVERLAY = Overlays.addOverlay('text', properties); + + // Fade out the overlay over 10 seconds + !function() { + var overlay = OVERLAY; + var alpha = STARTING_OPACITY; + + var fade = function() { + // Only fade so long as the same overlay is up + if (overlay == OVERLAY) { + alpha -= fade_per_sec / 10; + if (alpha <= 0) { + clearMetadata(); + } else { + Overlays.editOverlay(overlay, { alpha: alpha, backgroundAlpha: alpha }); + Script.setTimeout(fade, 100); + } + } + }; + Script.setTimeout(fade, FADE_AFTER_SEC * 1000); + }(); +} + +function clearMetadata() { + if (OVERLAY) { Overlays.deleteOverlay(OVERLAY); } +} + +// Request JSON from a url, synchronously +function request(url) { + var req = new XMLHttpRequest(); + req.responseType = 'json'; + req.open('GET', url, false); + req.send(); + return req.status == 200 ? req.response : null; +} + From 5f7e49b0870f72239e07ad5d7c575e9461c04768 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 11:50:56 -0700 Subject: [PATCH 18/76] possible fix, needs testing --- libraries/avatars/src/AvatarData.cpp | 25 ++++++++----------------- libraries/render-utils/src/Model.cpp | 3 --- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c98fec0d7d..33a6d1305f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -269,7 +269,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { _lastSentJointData.resize(_jointData.size()); for (int i=0; i < _jointData.size(); i++) { - const JointData& data = _jointData.at(i); + const JointData& data = _jointData[i]; if (sendAll || _lastSentJointData[i].rotation != data.rotation) { if (sendAll || !cullSmallChanges || @@ -294,7 +294,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validityBit = 0; validity = *validityPosition++; for (int i = 0; i < _jointData.size(); i ++) { - const JointData& data = _jointData[ i ]; + const JointData& data = _jointData[i]; if (validity & (1 << validityBit)) { destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); } @@ -317,7 +317,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { float maxTranslationDimension = 0.0; for (int i=0; i < _jointData.size(); i++) { - const JointData& data = _jointData.at(i); + const JointData& data = _jointData[i]; if (sendAll || _lastSentJointData[i].translation != data.translation) { if (sendAll || !cullSmallChanges || @@ -348,7 +348,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validityBit = 0; validity = *validityPosition++; for (int i = 0; i < _jointData.size(); i ++) { - const JointData& data = _jointData[ i ]; + const JointData& data = _jointData[i]; if (validity & (1 << validityBit)) { destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); @@ -425,7 +425,6 @@ bool AvatarData::shouldLogError(const quint64& now) { // read data in packet starting at byte offset and return number of bytes parsed int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { - // lazily allocate memory for HeadData in case we're not an Avatar instance if (!_headData) { _headData = new HeadData(this); @@ -575,14 +574,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } } - // If all the rotations were sent, this is a full packet - bool fullPacket = numValidJointRotations == numJoints; - - if (fullPacket) { - _hasNewJointRotations = true; - _hasNewJointTranslations = true; - } - // each joint rotation is stored in 6 bytes. const int COMPRESSED_QUATERNION_SIZE = 6; PACKET_READ_CHECK(JointRotations, numValidJointRotations * COMPRESSED_QUATERNION_SIZE); @@ -677,7 +668,9 @@ void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::v } JointData& data = _jointData[index]; data.rotation = rotation; + data.rotationSet = true; data.translation = translation; + data.translationSet = true; } void AvatarData::clearJointData(int index) { @@ -782,6 +775,7 @@ void AvatarData::setJointRotation(int index, const glm::quat& rotation) { } JointData& data = _jointData[index]; data.rotation = rotation; + data.rotationSet = true; } void AvatarData::setJointTranslation(int index, const glm::vec3& translation) { @@ -797,6 +791,7 @@ void AvatarData::setJointTranslation(int index, const glm::vec3& translation) { } JointData& data = _jointData[index]; data.translation = translation; + data.translationSet = true; } void AvatarData::clearJointData(const QString& name) { @@ -866,7 +861,6 @@ void AvatarData::setJointTranslations(QVector jointTranslations) { "setJointTranslations", Qt::BlockingQueuedConnection, Q_ARG(QVector, jointTranslations)); } - if (_jointData.size() < jointTranslations.size()) { _jointData.resize(jointTranslations.size()); } @@ -1060,8 +1054,6 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } - qDebug() << "set joint mapping froms network reply, num joints: " << _jointIndices.size(); - networkReply->deleteLater(); } @@ -1460,7 +1452,6 @@ void AvatarData::fromJson(const QJsonObject& json) { auto joint = jointDataFromJsonValue(jointJson); jointArray.push_back(joint); setJointData(i, joint.rotation, joint.translation); - _jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose i++; } setRawJointData(jointArray); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2112e64a39..ded1184c24 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -254,7 +254,6 @@ bool Model::updateGeometry() { _needsReload = false; if (_rig->jointStatesEmpty() && getFBXGeometry().joints.size() > 0) { - qDebug() << "initJointStates, num joints: " << getFBXGeometry().joints.size(); initJointStates(); const FBXGeometry& fbxGeometry = getFBXGeometry(); @@ -818,9 +817,7 @@ void Model::setURL(const QUrl& url) { invalidCalculatedMeshBoxes(); deleteGeometry(); - if (_geometry && _geometry->getGeometry()) qDebug() << "geometry1: " << _geometry->getGeometry()->getGeometry().joints.size(); _geometry = DependencyManager::get()->getGeometry(url); - if (_geometry && _geometry->getGeometry()) qDebug() << "geometry2: " << _geometry->getGeometry()->getGeometry().joints.size(); onInvalidate(); } From 7d602986cdd9688172cc739901096aa5ed4febe9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 12:01:02 -0700 Subject: [PATCH 19/76] removed multiple interface instances hack which you should never do anyways because it breaks everything --- interface/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index f0c7938b2a..8fc0384aee 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -90,11 +90,11 @@ int main(int argc, const char* argv[]) { qDebug() << "Interface instance appears to be running, exiting"; - //return EXIT_SUCCESS; + return EXIT_SUCCESS; } #ifdef Q_OS_WIN - //return EXIT_SUCCESS; + return EXIT_SUCCESS; #endif } From caf4a9fa34f0a52b9f4e89293f1106af248f1bb7 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 14:17:32 -0700 Subject: [PATCH 20/76] got rid of comparison warning --- libraries/animation/src/Rig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8f0bd3fd87..8aee2245c0 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1223,7 +1223,7 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { } void Rig::copyJointsFromJointData(const QVector& jointDataVec) { - if (_animSkeleton && jointDataVec.size() == _internalPoseSet._overrideFlags.size()) { + if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._overrideFlags.size()) { // transform all the default poses into rig space. const AnimPose geometryToRigPose(_geometryToRigTransform); From d8a67850f2108fae22898d9b6dc87c71ed9adcc7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 17 Jun 2016 15:17:51 -0700 Subject: [PATCH 21/76] treat usernames in permissions-grid on domain-server settings page as case-insensitive --- .../src/DomainServerSettingsManager.cpp | 6 ++--- .../src/DomainServerSettingsManager.h | 6 ++--- libraries/networking/src/NodePermissions.h | 23 ++++++++++++++++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 5790eb9178..b03d2c07ae 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -241,7 +241,7 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList } QList> permissionsSets; - permissionsSets << _standardAgentPermissions << _agentPermissions; + permissionsSets << _standardAgentPermissions.get() << _agentPermissions.get(); foreach (auto permissionsSet, permissionsSets) { foreach (QString userName, permissionsSet.keys()) { if (onlyEditorsAreRezzers) { @@ -267,7 +267,7 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList } void DomainServerSettingsManager::packPermissionsForMap(QString mapName, - QHash agentPermissions, + NodePermissionsMap& agentPermissions, QString keyPath) { QVariant* security = valueForKeyPath(_configMap.getUserConfig(), "security"); if (!security || !security->canConvert(QMetaType::QVariantMap)) { @@ -378,7 +378,7 @@ void DomainServerSettingsManager::unpackPermissions() { #ifdef WANT_DEBUG qDebug() << "--------------- permissions ---------------------"; QList> permissionsSets; - permissionsSets << _standardAgentPermissions << _agentPermissions; + permissionsSets << _standardAgentPermissions.get() << _agentPermissions.get(); foreach (auto permissionSet, permissionsSets) { QHashIterator i(permissionSet); while (i.hasNext()) { diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h index 446e9a2eed..ec1d3b637d 100644 --- a/domain-server/src/DomainServerSettingsManager.h +++ b/domain-server/src/DomainServerSettingsManager.h @@ -72,11 +72,11 @@ private: friend class DomainServer; - void packPermissionsForMap(QString mapName, QHash agentPermissions, QString keyPath); + void packPermissionsForMap(QString mapName, NodePermissionsMap& agentPermissions, QString keyPath); void packPermissions(); void unpackPermissions(); - QHash _standardAgentPermissions; // anonymous, logged-in, localhost - QHash _agentPermissions; // specific account-names + NodePermissionsMap _standardAgentPermissions; // anonymous, logged-in, localhost + NodePermissionsMap _agentPermissions; // specific account-names }; #endif // hifi_DomainServerSettingsManager_h diff --git a/libraries/networking/src/NodePermissions.h b/libraries/networking/src/NodePermissions.h index c153878a7e..de46a0dae5 100644 --- a/libraries/networking/src/NodePermissions.h +++ b/libraries/networking/src/NodePermissions.h @@ -24,9 +24,9 @@ using NodePermissionsPointer = std::shared_ptr; class NodePermissions { public: NodePermissions() { _id = QUuid::createUuid().toString(); } - NodePermissions(const QString& name) { _id = name; } + NodePermissions(const QString& name) { _id = name.toLower(); } NodePermissions(QMap perms) { - _id = perms["permissions_id"].toString(); + _id = perms["permissions_id"].toString().toLower(); canConnectToDomain = perms["id_can_connect"].toBool(); canAdjustLocks = perms["id_can_adjust_locks"].toBool(); canRezPermanentEntities = perms["id_can_rez"].toBool(); @@ -38,7 +38,7 @@ public: QString getID() const { return _id; } // the _id member isn't authenticated and _username is. - void setUserName(QString userName) { _userName = userName; } + void setUserName(QString userName) { _userName = userName.toLower(); } QString getUserName() { return _userName; } bool isAssignment { false }; @@ -88,6 +88,23 @@ protected: QString _userName; }; + +// wrap QHash in a class that forces all keys to be lowercase +class NodePermissionsMap { +public: + NodePermissionsMap() { } + NodePermissionsPointer& operator[](const QString& key) { return _data[key.toLower()]; } + NodePermissionsPointer operator[](const QString& key) const { return _data.value(key.toLower()); } + bool contains(const QString& key) const { return _data.contains(key.toLower()); } + QList keys() const { return _data.keys(); } + QHash get() { return _data; } + void clear() { _data.clear(); } + +private: + QHash _data; +}; + + const NodePermissions DEFAULT_AGENT_PERMISSIONS; QDebug operator<<(QDebug debug, const NodePermissions& perms); From c30c2b64b21bec14f3acf65f0d73fcb006e48259 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 17:49:27 -0700 Subject: [PATCH 22/76] first pass at preventing repeated compileShader error prints --- libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp | 7 +++++++ libraries/gpu/src/gpu/Shader.h | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp index 19cf798b19..fa54e7c8fe 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp @@ -24,8 +24,15 @@ GLPipeline* GLPipeline::sync(const Pipeline& pipeline) { // No object allocated yet, let's see if it's worth it... ShaderPointer shader = pipeline.getProgram(); + + // If this pipeline's shader has already failed to compile, don't try again + if (shader->compilationHasFailed()) { + return nullptr; + } + GLShader* programObject = GLShader::sync(*shader); if (programObject == nullptr) { + shader->setCompilationHasFailed(true); return nullptr; } diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index 59c6401150..ec712bfa78 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -120,6 +120,9 @@ public: bool isProgram() const { return getType() > NUM_DOMAINS; } bool isDomain() const { return getType() < NUM_DOMAINS; } + void setCompilationHasFailed(bool compilationHasFailed) { _compilationHasFailed = compilationHasFailed; } + bool compilationHasFailed() const { return _compilationHasFailed; } + const Source& getSource() const { return _source; } const Shaders& getShaders() const { return _shaders; } @@ -180,6 +183,9 @@ protected: // The type of the shader, the master key Type _type; + + // Whether or not the shader compilation failed + mutable bool _compilationHasFailed { false }; }; typedef Shader::Pointer ShaderPointer; From 6196c657f8e5fe8263bcd9bce09b4a4f0c860985 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sat, 18 Jun 2016 14:17:47 -0700 Subject: [PATCH 23/76] Minimize triggering distance to HUD. --- interface/src/ui/OverlayConductor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 74e27122e4..003de23030 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -32,7 +32,7 @@ bool OverlayConductor::headOutsideOverlay() const { glm::vec3 uiPos = uiTransform.getTranslation(); glm::vec3 uiForward = uiTransform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f); - const float MAX_COMPOSITOR_DISTANCE = 0.6f; + const float MAX_COMPOSITOR_DISTANCE = 0.99f; // If you're 1m from center of ui sphere, you're at the surface. const float MAX_COMPOSITOR_ANGLE = 180.0f; // rotation check is effectively disabled if (glm::distance(uiPos, hmdPos) > MAX_COMPOSITOR_DISTANCE || glm::dot(uiForward, hmdForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE))) { From 81300ec1270f1d11eda3d5a530be5d59a4ad3041 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sat, 18 Jun 2016 14:35:37 -0700 Subject: [PATCH 24/76] turn hud reset behavior on by default --- interface/src/avatar/MyAvatar.cpp | 4 ++-- interface/src/avatar/MyAvatar.h | 6 +++--- interface/src/ui/OverlayConductor.cpp | 2 +- interface/src/ui/PreferencesDialog.cpp | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5d1efca902..6a69ee9a9a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -722,7 +722,7 @@ void MyAvatar::saveData() { settings.setValue("displayName", _displayName); settings.setValue("collisionSoundURL", _collisionSoundURL); settings.setValue("useSnapTurn", _useSnapTurn); - settings.setValue("clearOverlayWhenDriving", _clearOverlayWhenDriving); + settings.setValue("clearOverlayWhenMoving", _clearOverlayWhenMoving); settings.endGroup(); } @@ -842,7 +842,7 @@ void MyAvatar::loadData() { setDisplayName(settings.value("displayName").toString()); setCollisionSoundURL(settings.value("collisionSoundURL", DEFAULT_AVATAR_COLLISION_SOUND_URL).toString()); setSnapTurn(settings.value("useSnapTurn", _useSnapTurn).toBool()); - setClearOverlayWhenDriving(settings.value("clearOverlayWhenDriving", _clearOverlayWhenDriving).toBool()); + setClearOverlayWhenMoving(settings.value("clearOverlayWhenMoving", _clearOverlayWhenMoving).toBool()); settings.endGroup(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 6fa6e1fd19..96fa999de5 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -159,8 +159,8 @@ public: Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; } Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; } - Q_INVOKABLE bool getClearOverlayWhenDriving() const { return _clearOverlayWhenDriving; } - Q_INVOKABLE void setClearOverlayWhenDriving(bool on) { _clearOverlayWhenDriving = on; } + Q_INVOKABLE bool getClearOverlayWhenMoving() const { return _clearOverlayWhenMoving; } + Q_INVOKABLE void setClearOverlayWhenMoving(bool on) { _clearOverlayWhenMoving = on; } Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; } Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; } @@ -405,7 +405,7 @@ private: QString _fullAvatarModelName; QUrl _animGraphUrl {""}; bool _useSnapTurn { true }; - bool _clearOverlayWhenDriving { false }; + bool _clearOverlayWhenMoving { true }; // cache of the current HMD sensor position and orientation // in sensor space. diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 74e27122e4..91046c4cc6 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -124,7 +124,7 @@ void OverlayConductor::update(float dt) { _flags &= ~SuppressedByDrive; } } else { - if (myAvatar->getClearOverlayWhenDriving() && drivingChanged && isDriving) { + if (myAvatar->getClearOverlayWhenMoving() && drivingChanged && isDriving) { _flags |= SuppressedByDrive; } } diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 6decef3240..c1705da206 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -62,9 +62,9 @@ void setupPreferences() { preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Snap turn when in HMD", getter, setter)); } { - auto getter = [=]()->bool {return myAvatar->getClearOverlayWhenDriving(); }; - auto setter = [=](bool value) { myAvatar->setClearOverlayWhenDriving(value); }; - preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when driving", getter, setter)); + auto getter = [=]()->bool {return myAvatar->getClearOverlayWhenMoving(); }; + auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); }; + preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when moving", getter, setter)); } { auto getter = []()->QString { return Snapshot::snapshotsLocation.get(); }; From e65e6dc9ce10d10522eab5ca6c9023cc81315fac Mon Sep 17 00:00:00 2001 From: humbletim Date: Sun, 19 Jun 2016 13:40:03 -0400 Subject: [PATCH 25/76] Fix entity lifetime guards (re: canRez/canRezTmp) --- libraries/entities/src/EntityTree.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 77a0c6d6fe..ec1f8a50bc 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -150,8 +150,10 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI if (!canRezPermanentEntities && (entity->getLifetime() != properties.getLifetime())) { // we don't allow a Node that can't create permanent entities to adjust lifetimes on existing ones - qCDebug(entities) << "Refusing disallowed entity lifetime adjustment."; - return false; + if (properties.lifetimeChanged()) { + qCDebug(entities) << "Refusing disallowed entity lifetime adjustment."; + return false; + } } // enforce support for locked entities. If an entity is currently locked, then the only @@ -322,8 +324,8 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI bool EntityTree::permissionsAllowRez(const EntityItemProperties& properties, bool canRez, bool canRezTmp) { float lifeTime = properties.getLifetime(); - if (lifeTime == 0.0f || lifeTime > _maxTmpEntityLifetime) { - // this is an attempt to rez a permanent entity. + if (lifeTime == ENTITY_ITEM_IMMORTAL_LIFETIME || lifeTime > _maxTmpEntityLifetime) { + // this is an attempt to rez a permanent or non-temporary entity. if (!canRez) { return false; } From 34d18da4e4ecd18f330c7ae5294003628e893dfa Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 20 Jun 2016 11:11:54 -0700 Subject: [PATCH 26/76] remove mutable --- libraries/gpu/src/gpu/Shader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index ec712bfa78..e4643f2b7c 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -185,7 +185,7 @@ protected: Type _type; // Whether or not the shader compilation failed - mutable bool _compilationHasFailed { false }; + bool _compilationHasFailed { false }; }; typedef Shader::Pointer ShaderPointer; From 40f2d364877c7566cf04f4530ae8f137362cf746 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 11:38:38 -0700 Subject: [PATCH 27/76] fix hosts/tags in domain-server settings --- domain-server/resources/describe-settings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index bad24dd3a1..dce6c3449f 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -116,6 +116,7 @@ "name": "hosts", "label": "Hosts", "type": "table", + "can_add_new_rows": true, "help": "Usernames of hosts who can reliably show your domain to new visitors.", "numbered": false, "columns": [ @@ -130,6 +131,7 @@ "name": "tags", "label": "Tags", "type": "table", + "can_add_new_rows": true, "help": "Common categories under which your domain falls.", "numbered": false, "columns": [ From cd1780efefc1f0ad1a8cbad53e98f08631ecfbb0 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 20 Jun 2016 13:21:06 -0700 Subject: [PATCH 28/76] brush clearing --- .../controllers/handControllerPointer.js | 115 ++++-------------- 1 file changed, 27 insertions(+), 88 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 0f1e23b45c..0fe199098d 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -14,15 +14,11 @@ // // Control the "mouse" using hand controller. (HMD and desktop.) -// For now: -// Hydra thumb button 3 is left-mouse, button 4 is right-mouse. -// A click in the center of the vive thumb pad is left mouse. Vive menu button is context menu (right mouse). // First-person only. // Starts right handed, but switches to whichever is free: Whichever hand was NOT most recently squeezed. // (For now, the thumb buttons on both controllers are always on.) -// When over a HUD element, the reticle is shown where the active hand controller beam intersects the HUD. -// Otherwise, the active hand controller shows a red ball where a click will act. - +// When partially squeezing over a HUD element, a laser or the reticle is shown where the active hand +// controller beam intersects the HUD. // UTILITIES ------------- @@ -102,7 +98,7 @@ function Trigger(label) { } that.state = state; }; - // Answer a controller source function (answering either 0.0 or 1.0), with hysteresis. + // Answer a controller source function (answering either 0.0 or 1.0). that.partial = function () { return that.state ? 1.0 : 0.0; // either 'partial' or 'full' }; @@ -369,24 +365,9 @@ clickMapping.enable(); // VISUAL AID ----------- // Same properties as handControllerGrab search sphere -var BALL_SIZE = 0.011; -var BALL_ALPHA = 0.5; -var LASER_SEARCH_COLOR_XYZW = {x: 10 / 255, y: 10 / 255, z: 255 / 255, w: BALL_ALPHA}; -var LASER_TRIGGER_COLOR_XYZW = {x: 250 / 255, y: 10 / 255, z: 10 / 255, w: BALL_ALPHA}; -var fakeProjectionBall = Overlays.addOverlay("sphere", { - size: 5 * BALL_SIZE, - color: {red: 255, green: 10, blue: 10}, - ignoreRayIntersection: true, - alpha: BALL_ALPHA, - visible: false, - solid: true, - drawInFront: true // Even when burried inside of something, show it. -}); -var overlays = [fakeProjectionBall]; // If we want to try showing multiple balls and lasers. -Script.scriptEnding.connect(function () { - overlays.forEach(Overlays.deleteOverlay); -}); -var visualizationIsShowing = false; // Not whether it desired, but simply whether it is. Just an optimziation. +var LASER_ALPHA = 0.5; +var LASER_SEARCH_COLOR_XYZW = {x: 10 / 255, y: 10 / 255, z: 255 / 255, w: LASER_ALPHA}; +var LASER_TRIGGER_COLOR_XYZW = {x: 250 / 255, y: 10 / 255, z: 10 / 255, w: LASER_ALPHA}; var SYSTEM_LASER_DIRECTION = {x: 0, y: 0, z: -1}; var systemLaserOn = false; function clearSystemLaser() { @@ -401,81 +382,30 @@ function setColoredLaser() { // answer trigger state if lasers supported, else f return HMD.setHandLasers(activeHudLaser, true, color, SYSTEM_LASER_DIRECTION) && activeTrigger.state; } -function turnOffVisualization(optionalEnableClicks) { // because we're showing cursor on HUD - if (!optionalEnableClicks) { - expireMouseCursor(); - clearSystemLaser(); - } else if (activeTrigger.state && (!systemLaserOn || (systemLaserOn !== activeTrigger.state))) { // last=>wrong color - // If the active plugin doesn't implement hand lasers, show the mouse reticle instead. - systemLaserOn = setColoredLaser(); - Reticle.visible = !systemLaserOn; - } else if ((systemLaserOn || Reticle.visible) && !activeTrigger.state) { - clearSystemLaser(); - Reticle.visible = false; - } - - if (!visualizationIsShowing) { - return; - } - visualizationIsShowing = false; - overlays.forEach(function (overlay) { - Overlays.editOverlay(overlay, {visible: false}); - }); -} -var MAX_RAY_SCALE = 32000; // Anything large. It's a scale, not a distance. -function updateVisualization(controllerPosition, controllerDirection, hudPosition3d, hudPosition2d) { - ignore(controllerPosition, controllerDirection, hudPosition2d); - clearSystemLaser(); - // Show an indication of where the cursor will appear when crossing a HUD element, - // and where in-world clicking will occur. - // - // There are a number of ways we could do this, but for now, it's a blue sphere that rolls along - // the HUD surface, and a red sphere that rolls along the 3d objects that will receive the click. - // We'll leave it to other scripts (like handControllerGrab) to show a search beam when desired. - - function intersection3d(position, direction) { - // Answer in-world intersection (entity or 3d overlay), or way-out point - var pickRay = {origin: position, direction: direction}; - var result = findRayIntersection(pickRay); - return result.intersects ? result.intersection : Vec3.sum(position, Vec3.multiply(MAX_RAY_SCALE, direction)); - } - - visualizationIsShowing = true; - // We'd rather in-world interactions be done at the termination of the hand beam - // -- intersection3d(controllerPosition, controllerDirection). Maybe have handControllerGrab - // direclty manipulate both entity and 3d overlay objects. - // For now, though, we present a false projection of the cursor onto whatever is below it. This is - // different from the hand beam termination because the false projection is from the camera, while - // the hand beam termination is from the hand. - /* // FIXME: We can tighten this up later, once we know what will and won't be included. - var eye = Camera.getPosition(); - var falseProjection = intersection3d(eye, Vec3.subtract(hudPosition3d, eye)); - Overlays.editOverlay(fakeProjectionBall, {visible: true, position: falseProjection}); - */ - Reticle.visible = false; - - return visualizationIsShowing; // In case we change caller to act conditionally. -} // MAIN OPERATIONS ----------- // function update() { var now = Date.now(); + function off() { + expireMouseCursor(); + clearSystemLaser(); + } if (!handControllerLockOut.expired(now)) { - return turnOffVisualization(); // Let them use mouse it in peace. + return off(); // Let them use mouse it in peace. } if (!Menu.isOptionChecked("First Person")) { - return turnOffVisualization(); // What to do? menus can be behind hand! + return off(); // What to do? menus can be behind hand! } if (!Window.hasFocus() || !Reticle.allowMouseCapture) { - return turnOffVisualization(); // Don't mess with other apps or paused mouse activity + return off(); // Don't mess with other apps or paused mouse activity } leftTrigger.update(); rightTrigger.update(); var controllerPose = Controller.getPoseValue(activeHand); // Valid if any plugged-in hand controller is "on". (uncradled Hydra, green-lighted Vive...) if (!controllerPose.valid) { - return turnOffVisualization(); // Controller is cradled. + return off(); // Controller is cradled. } var controllerPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation, controllerPose.translation), MyAvatar.position); @@ -487,7 +417,7 @@ function update() { if (Menu.isOptionChecked("Overlays")) { // With our hud resetting strategy, hudPoint3d should be valid here print('Controller is parallel to HUD'); // so let us know that our assumptions are wrong. } - return turnOffVisualization(); + return off(); } var hudPoint2d = overlayFromWorldPoint(hudPoint3d); @@ -499,13 +429,22 @@ function update() { if (HMD.active) { Reticle.depth = hudReticleDistance(); } - return turnOffVisualization(true); + if (activeTrigger.state && (!systemLaserOn || (systemLaserOn !== activeTrigger.state))) { // last=>wrong color + // If the active plugin doesn't implement hand lasers, show the mouse reticle instead. + systemLaserOn = setColoredLaser(); + Reticle.visible = !systemLaserOn; + } else if ((systemLaserOn || Reticle.visible) && !activeTrigger.state) { + clearSystemLaser(); + Reticle.visible = false; + } + return; } // We are not pointing at a HUD element (but it could be a 3d overlay). if (!activeTrigger.state) { - return turnOffVisualization(); // No trigger (with hysteresis). + return off(); // No trigger } - updateVisualization(controllerPosition, controllerDirection, hudPoint3d, hudPoint2d); + clearSystemLaser(); + Reticle.visible = false; } var UPDATE_INTERVAL = 50; // milliseconds. Script.update is too frequent. From 25b21dacda246e7ff691bdf4db9cf67d8b57cbd0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 12:57:32 -0700 Subject: [PATCH 29/76] clean domain metadata and update acl --- domain-server/src/DomainMetadata.cpp | 156 +++++++++++++++++++-------- domain-server/src/DomainMetadata.h | 60 ++++++----- domain-server/src/DomainServer.cpp | 30 ++---- domain-server/src/DomainServer.h | 8 +- 4 files changed, 154 insertions(+), 100 deletions(-) diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index 26d2bb87ce..d3eb7a97b0 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -10,16 +10,18 @@ #include "DomainMetadata.h" -#include +#include #include +#include #include +#include "DomainServer.h" #include "DomainServerNodeData.h" const QString DomainMetadata::USERS = "users"; -const QString DomainMetadata::USERS_NUM_TOTAL = "num_users"; -const QString DomainMetadata::USERS_NUM_ANON = "num_anon_users"; -const QString DomainMetadata::USERS_HOSTNAMES = "user_hostnames"; +const QString DomainMetadata::Users::NUM_TOTAL = "num_users"; +const QString DomainMetadata::Users::NUM_ANON = "num_anon_users"; +const QString DomainMetadata::Users::HOSTNAMES = "user_hostnames"; // users metadata will appear as (JSON): // { "num_users": Number, // "num_anon_users": Number, @@ -27,25 +29,20 @@ const QString DomainMetadata::USERS_HOSTNAMES = "user_hostnames"; // } const QString DomainMetadata::DESCRIPTORS = "descriptors"; -const QString DomainMetadata::DESCRIPTORS_DESCRIPTION = "description"; -const QString DomainMetadata::DESCRIPTORS_CAPACITY = "capacity"; // parsed from security -const QString DomainMetadata::DESCRIPTORS_RESTRICTION = "restriction"; // parsed from ACL -const QString DomainMetadata::DESCRIPTORS_MATURITY = "maturity"; -const QString DomainMetadata::DESCRIPTORS_HOSTS = "hosts"; -const QString DomainMetadata::DESCRIPTORS_TAGS = "tags"; +const QString DomainMetadata::Descriptors::DESCRIPTION = "description"; +const QString DomainMetadata::Descriptors::CAPACITY = "capacity"; // parsed from security +const QString DomainMetadata::Descriptors::HOURS = "hours"; +const QString DomainMetadata::Descriptors::RESTRICTION = "restriction"; // parsed from ACL +const QString DomainMetadata::Descriptors::MATURITY = "maturity"; +const QString DomainMetadata::Descriptors::HOSTS = "hosts"; +const QString DomainMetadata::Descriptors::TAGS = "tags"; // descriptors metadata will appear as (JSON): -// { "capacity": Number, -// TODO: "hours": String, // UTF-8 representation of the week, split into 15" segments +// { "description": String, // capped description +// "capacity": Number, +// "hours": String, // UTF-8 representation of the week, split into 15" segments // "restriction": String, // enum of either open, hifi, or acl // "maturity": String, // enum corresponding to ESRB ratings // "hosts": [ String ], // capped list of usernames -// "description": String, // capped description -// TODO: "img": { -// "src": String, -// "type": String, -// "size": Number, -// "updated_at": Number, -// }, // "tags": [ String ], // capped list of tags // } @@ -54,36 +51,103 @@ const QString DomainMetadata::DESCRIPTORS_TAGS = "tags"; // // it is meant to be sent to and consumed by an external API -DomainMetadata::DomainMetadata() { +DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { _metadata[USERS] = {}; _metadata[DESCRIPTORS] = {}; + + assert(dynamic_cast(domainServer)); + DomainServer* server = static_cast(domainServer); + + // update the metadata when a user (dis)connects + connect(server, &DomainServer::userConnected, this, &DomainMetadata::usersChanged); + connect(server, &DomainServer::userDisconnected, this, &DomainMetadata::usersChanged); + + // update the metadata when security changes + connect(&server->_settingsManager, &DomainServerSettingsManager::updateNodePermissions, + this, static_cast(&DomainMetadata::securityChanged)); + + // initialize the descriptors + descriptorsChanged(); } -void DomainMetadata::setDescriptors(QVariantMap& settings) { +QJsonObject DomainMetadata::get() { + maybeUpdateUsers(); + return QJsonObject::fromVariantMap(_metadata); +} + +QJsonObject DomainMetadata::get(const QString& group) { + maybeUpdateUsers(); + return QJsonObject::fromVariantMap(_metadata[group].toMap()); +} + +void DomainMetadata::descriptorsChanged() { const QString CAPACITY = "security.maximum_user_capacity"; + auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY); unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0; - // TODO: Keep parity with ACL development. - const QString RESTRICTION = "security.restricted_access"; - const QString RESTRICTION_OPEN = "open"; - // const QString RESTRICTION_HIFI = "hifi"; - const QString RESTRICTION_ACL = "acl"; - const QVariant* isRestrictedVariant = valueForKeyPath(settings, RESTRICTION); - bool isRestricted = isRestrictedVariant ? isRestrictedVariant->toBool() : false; - QString restriction = isRestricted ? RESTRICTION_ACL : RESTRICTION_OPEN; + auto descriptors = settings[DESCRIPTORS].toMap(); + descriptors[Descriptors::CAPACITY] = capacity; + _metadata[DESCRIPTORS] = descriptors; - QVariantMap descriptors = settings[DESCRIPTORS].toMap(); - descriptors[DESCRIPTORS_CAPACITY] = capacity; - descriptors[DESCRIPTORS_RESTRICTION] = restriction; + // update overwritten fields + securityChanged(false); + +#if DEV_BUILD || PR_BUILD + qDebug() << "Domain metadata descriptors set:" << _metadata[DESCRIPTORS]; +#endif + + sendDescriptors(); +} + +void DomainMetadata::securityChanged(bool send) { + const QString RESTRICTION_OPEN = "open"; + const QString RESTRICTION_ANON = "anon"; + const QString RESTRICTION_HIFI = "hifi"; + const QString RESTRICTION_ACL = "acl"; + + QString restriction; + + const auto& settingsManager = static_cast(parent())->_settingsManager; + bool hasAnonymousAccess = + settingsManager.getStandardPermissionsForName(NodePermissions::standardNameAnonymous).canConnectToDomain; + bool hasHifiAccess = + settingsManager.getStandardPermissionsForName(NodePermissions::standardNameLoggedIn).canConnectToDomain; + if (hasAnonymousAccess) { + restriction = hasHifiAccess ? RESTRICTION_OPEN : RESTRICTION_ANON; + } else if (hasHifiAccess) { + restriction = RESTRICTION_HIFI; + } else { + restriction = RESTRICTION_ACL; + } + + auto descriptors = _metadata[DESCRIPTORS].toMap(); + descriptors[Descriptors::RESTRICTION] = restriction; _metadata[DESCRIPTORS] = descriptors; #if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata descriptors set:" << descriptors; + qDebug() << "Domain metadata restriction set:" << restriction; +#endif + + if (send) { + sendDescriptors(); + } +} + +void DomainMetadata::usersChanged() { + ++_tic; + +#if DEV_BUILD || PR_BUILD + qDebug() << "Domain metadata users change detected"; #endif } -void DomainMetadata::updateUsers() { +void DomainMetadata::maybeUpdateUsers() { + if (_lastTic == _tic) { + return; + } + _lastTic = _tic; + static const QString DEFAULT_HOSTNAME = "*"; auto nodeList = DependencyManager::get(); @@ -113,20 +177,26 @@ void DomainMetadata::updateUsers() { }); QVariantMap users = { - { USERS_NUM_TOTAL, numConnected }, - { USERS_NUM_ANON, numConnectedAnonymously }, - { USERS_HOSTNAMES, userHostnames }}; + { Users::NUM_TOTAL, numConnected }, + { Users::NUM_ANON, numConnectedAnonymously }, + { Users::HOSTNAMES, userHostnames }}; _metadata[USERS] = users; + ++_tic; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata users updated:" << users; #endif } -void DomainMetadata::usersChanged() { - ++_tic; - -#if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata users change detected"; -#endif +void DomainMetadata::sendDescriptors() { + QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(get(DESCRIPTORS)).toJson(QJsonDocument::Compact))); + const QUuid& domainID = DependencyManager::get()->getSessionUUID(); + if (!domainID.isNull()) { + static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; + DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + AccountManagerAuth::Required, + QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), + domainUpdateJSON.toUtf8()); + } } diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 7d58d43182..86918f5c78 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -19,46 +19,48 @@ class DomainMetadata : public QObject { Q_OBJECT +public: + using Tic = uint32_t; + static const QString USERS; - static const QString USERS_NUM_TOTAL; - static const QString USERS_NUM_ANON; - static const QString USERS_HOSTNAMES; + class Users { + public: + static const QString NUM_TOTAL; + static const QString NUM_ANON; + static const QString HOSTNAMES; + }; static const QString DESCRIPTORS; - static const QString DESCRIPTORS_DESCRIPTION; - static const QString DESCRIPTORS_CAPACITY; - static const QString DESCRIPTORS_HOURS; - static const QString DESCRIPTORS_RESTRICTION; - static const QString DESCRIPTORS_MATURITY; - static const QString DESCRIPTORS_HOSTS; - static const QString DESCRIPTORS_TAGS; - static const QString DESCRIPTORS_IMG; - static const QString DESCRIPTORS_IMG_SRC; - static const QString DESCRIPTORS_IMG_TYPE; - static const QString DESCRIPTORS_IMG_SIZE; - static const QString DESCRIPTORS_IMG_UPDATED_AT; + class Descriptors { + public: + static const QString DESCRIPTION; + static const QString CAPACITY; + static const QString HOURS; + static const QString RESTRICTION; + static const QString MATURITY; + static const QString HOSTS; + static const QString TAGS; + }; -public: - DomainMetadata(); + DomainMetadata(QObject* domainServer); + DomainMetadata() = delete; - // Returns the last set metadata - // If connected users have changed, metadata may need to be updated - // this should be checked by storing tic = getTic() between calls - // and testing it for equality before the next get (tic == getTic()) - QJsonObject get() { return QJsonObject::fromVariantMap(_metadata); } - QJsonObject getUsers() { return QJsonObject::fromVariantMap(_metadata[USERS].toMap()); } - QJsonObject getDescriptors() { return QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); } - - uint32_t getTic() { return _tic; } - - void setDescriptors(QVariantMap& settings); - void updateUsers(); + // Get cached metadata + QJsonObject get(); + QJsonObject get(const QString& group); public slots: + void descriptorsChanged(); + void securityChanged(bool send); + void securityChanged() { securityChanged(true); } void usersChanged(); protected: + void maybeUpdateUsers(); + void sendDescriptors(); + QVariantMap _metadata; + uint32_t _lastTic{ -1 }; uint32_t _tic{ 0 }; }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 1f666455c6..223cab61da 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -94,10 +94,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : qRegisterMetaType("DomainServerWebSessionData"); qRegisterMetaTypeStreamOperators("DomainServerWebSessionData"); - // update the metadata when a user (dis)connects - connect(this, &DomainServer::userConnected, &_metadata, &DomainMetadata::usersChanged); - connect(this, &DomainServer::userDisconnected, &_metadata, &DomainMetadata::usersChanged); - // make sure we hear about newly connected nodes from our gatekeeper connect(&_gatekeeper, &DomainGatekeeper::connectedNode, this, &DomainServer::handleConnectedNode); @@ -108,9 +104,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : connect(&_settingsManager, &DomainServerSettingsManager::updateNodePermissions, &_gatekeeper, &DomainGatekeeper::updateNodePermissions); - // update the metadata with current descriptors - _metadata.setDescriptors(_settingsManager.getSettingsMap()); - if (optionallyReadX509KeyAndCertificate() && optionallySetupOAuth()) { // we either read a certificate and private key or were not passed one // and completed login or did not need to @@ -125,17 +118,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : _gatekeeper.preloadAllowedUserPublicKeys(); optionallyGetTemporaryName(args); - - // send metadata descriptors - QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(_metadata.getDescriptors()).toJson(QJsonDocument::Compact))); - const QUuid& domainID = DependencyManager::get()->getSessionUUID(); - static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; - DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), - AccountManagerAuth::Required, - QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), - domainUpdateJSON.toUtf8()); } + + _metadata = new DomainMetadata(this); } DomainServer::~DomainServer() { @@ -1111,14 +1096,11 @@ void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) { NodePermissions anonymousPermissions = _settingsManager.getPermissionsForName(NodePermissions::standardNameAnonymous); domainObject[RESTRICTED_ACCESS_FLAG] = !anonymousPermissions.canConnectToDomain; - // Add the metadata to the heartbeat - static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; - auto tic = _metadata.getTic(); - if (_metadataTic != tic) { - _metadataTic = tic; - _metadata.updateUsers(); + if (_metadata) { + // Add the metadata to the heartbeat + static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; + domainObject[DOMAIN_HEARTBEAT_KEY] = _metadata->get(DomainMetadata::USERS); } - domainObject[DOMAIN_HEARTBEAT_KEY] = _metadata.getUsers(); QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(domainObject).toJson(QJsonDocument::Compact))); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index bdcc36c1ac..c742dbc9b3 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -172,13 +172,12 @@ private: DomainServerSettingsManager _settingsManager; - DomainMetadata _metadata; - uint32_t _metadataTic{ 0 }; - HifiSockAddr _iceServerSocket; std::unique_ptr _iceServerHeartbeatPacket; - QTimer* _iceHeartbeatTimer { nullptr }; // this looks like it dangles when created but it's parented to the DomainServer + // These will be parented to this, they are not dangling + DomainMetadata* _metadata { nullptr }; + QTimer* _iceHeartbeatTimer { nullptr }; QList _iceServerAddresses; QSet _failedIceServerAddresses; @@ -190,6 +189,7 @@ private: bool _hasAccessToken { false }; friend class DomainGatekeeper; + friend class DomainMetadata; }; From cfe9ac32d4ff761fe07817959e9f89a19a0c4535 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 14:46:20 -0700 Subject: [PATCH 30/76] fix narrowing warning by casting -1 --- domain-server/src/DomainMetadata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 86918f5c78..0bfd6c611b 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -60,7 +60,7 @@ protected: void sendDescriptors(); QVariantMap _metadata; - uint32_t _lastTic{ -1 }; + uint32_t _lastTic{ (uint32_t)-1 }; uint32_t _tic{ 0 }; }; From 37e9f666390c6f92dcdd0d731d2404b5fa2b4781 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 20 Jun 2016 15:41:21 -0700 Subject: [PATCH 31/76] Additional toolbar work --- interface/resources/qml/hifi/Desktop.qml | 9 +- .../resources/qml/hifi/toolbars/Toolbar.qml | 128 +++++++++++------- .../qml/hifi/toolbars/ToolbarButton.qml | 34 ++++- interface/resources/qml/windows/Frame.qml | 2 +- interface/resources/qml/windows/ToolFrame.qml | 63 +++++++-- .../scripting/ToolbarScriptingInterface.cpp | 9 -- scripts/developer/tests/toolbarTest.js | 2 +- tests/ui/qml/main.qml | 2 +- 8 files changed, 174 insertions(+), 75 deletions(-) diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index c14d55cb00..169542c0f0 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -3,12 +3,12 @@ import QtQuick.Controls 1.4 import QtWebEngine 1.1; import Qt.labs.settings 1.0 -import "../desktop" +import "../desktop" as OriginalDesktop import ".." import "." import "./toolbars" -Desktop { +OriginalDesktop.Desktop { id: desktop MouseArea { @@ -54,12 +54,13 @@ Desktop { WebEngine.settings.localContentCanAccessRemoteUrls = true; var sysToolbar = desktop.getToolbar("com.highfidelity.interface.toolbar.system"); - //toolbars[sysToolbar.objectName] = sysToolbar var toggleHudButton = sysToolbar.addButton({ + objectName: "hudToggle", imageURL: "../../../icons/hud-01.svg", visible: true, - + pinned: true, }); + toggleHudButton.yOffset = Qt.binding(function(){ return desktop.pinned ? 50 : 0 }); diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index 35c816569b..75c06e4199 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -7,14 +7,16 @@ import "." Window { id: window - frame: ToolFrame { } + frame: ToolFrame { + horizontalSpacers: horizontal + verticalSpacers: !horizontal + } hideBackground: true resizable: false destroyOnCloseButton: false destroyOnHidden: false closable: false shown: true - pinned: true width: content.width height: content.height visible: true @@ -32,54 +34,77 @@ Window { } onHorizontalChanged: { - var oldParent = horizontal ? column : row; var newParent = horizontal ? row : column; - var move = []; - - var i; - for (i in oldParent.children) { - var child = oldParent.children[i]; - if (child.spacer) { - continue; - } - move.push(oldParent.children[i]); - } - for (i in move) { - move[i].parent = newParent; + for (var i in buttons) { + var child = buttons[i]; + child.parent = newParent; if (horizontal) { - move[i].y = 0 + child.y = 0 } else { - move[i].x = 0 + child.x = 0 } } - fixSpacers(); } Item { id: content implicitHeight: horizontal ? row.height : column.height implicitWidth: horizontal ? row.width : column.width + Row { id: row spacing: 6 - visible: window.horizontal - Rectangle{ readonly property bool spacer: true; id: rowSpacer1; width: 1; height: row.height } - Rectangle{ readonly property bool spacer: true; id: rowSpacer2; width: 1; height: row.height } - Rectangle{ readonly property bool spacer: true; id: rowSpacer3; width: 1; height: row.height } - Rectangle{ readonly property bool spacer: true; id: rowSpacer4; width: 1; height: row.height } } Column { id: column spacing: 6 - visible: !window.horizontal - Rectangle{ readonly property bool spacer: true; id: colSpacer1; width: column.width; height: 1 } - Rectangle{ readonly property bool spacer: true; id: colSpacer2; width: column.width; height: 1 } - Rectangle{ readonly property bool spacer: true; id: colSpacer3; width: column.width; height: 1 } - Rectangle{ readonly property bool spacer: true; id: colSpacer4; width: column.width; height: 1 } } Component { id: toolbarButtonBuilder; ToolbarButton { } } + + Connections { + target: desktop + onPinnedChanged: { + if (!window.pinned) { + return; + } + var newPinned = desktop.pinned; + for (var i in buttons) { + var child = buttons[i]; + if (desktop.pinned) { + if (!child.pinned) { + child.visible = false; + } + } else { + child.visible = true; + } + } + } + } + } + + + function findButtonIndex(name) { + if (!name) { + return -1; + } + + for (var i in buttons) { + var child = buttons[i]; + if (child.objectName === name) { + return i; + } + } + return -1; + } + + function findButton(name) { + var index = findButtonIndex(name); + if (index < 0) { + return; + } + return buttons[index]; } function addButton(properties) { @@ -88,30 +113,39 @@ Window { // If a name is specified, then check if there's an existing button with that name // and return it if so. This will allow multiple clients to listen to a single button, // and allow scripts to be idempotent so they don't duplicate buttons if they're reloaded - if (properties.objectName) { - for (var i in buttons) { - var child = buttons[i]; - if (child.objectName === properties.objectName) { - return child; - } - } + var result = findButton(properties.objectName); + if (result) { + return result; } - properties.toolbar = this; - var result = toolbarButtonBuilder.createObject(container, properties); + properties.opacity = 0; + result = toolbarButtonBuilder.createObject(container, properties); buttons.push(result); - fixSpacers(); + result.opacity = 1; + updatePinned(); return result; } - function fixSpacers() { - colSpacer3.parent = null - colSpacer4.parent = null - rowSpacer3.parent = null - rowSpacer4.parent = null - colSpacer3.parent = column - colSpacer4.parent = column - rowSpacer3.parent = row - rowSpacer4.parent = row + function removeButton(name) { + var index = findButtonIndex(name); + if (index < -1) { + console.warn("Tried to remove non-existent button " + name); + return; + } + buttons[index].destroy(); + buttons.splice(index, 1); + updatePinned(); + } + + function updatePinned() { + var newPinned = false; + for (var i in buttons) { + var child = buttons[i]; + if (child.pinned) { + newPinned = true; + break; + } + } + pinned = newPinned; } } diff --git a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml index a8514689e8..a3be4533d2 100644 --- a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml +++ b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml @@ -7,11 +7,40 @@ Item { property alias alpha: button.opacity property var subImage; property int yOffset: 0 + property int buttonState: 0 property var toolbar; property real size: 50 // toolbar ? toolbar.buttonSize : 50 width: size; height: size + property bool pinned: false clip: true + Behavior on opacity { + NumberAnimation { + duration: 150 + easing.type: Easing.InOutCubic + } + } + + property alias fadeTargetProperty: button.opacity + + onFadeTargetPropertyChanged: { + visible = (fadeTargetProperty !== 0.0); + } + + onVisibleChanged: { + if ((!visible && fadeTargetProperty != 0.0) || (visible && fadeTargetProperty == 0.0)) { + var target = visible; + visible = !visible; + fadeTargetProperty = target ? 1.0 : 0.0; + return; + } + } + + + onButtonStateChanged: { + yOffset = size * buttonState + } + Component.onCompleted: { if (subImage) { if (subImage.y) { @@ -30,10 +59,7 @@ Item { MouseArea { anchors.fill: parent - onClicked: { - console.log("Clicked on button " + image.source + " named " + button.objectName) - button.clicked(); - } + onClicked: button.clicked(); } } diff --git a/interface/resources/qml/windows/Frame.qml b/interface/resources/qml/windows/Frame.qml index bc8ecc35ec..88d8c3ad41 100644 --- a/interface/resources/qml/windows/Frame.qml +++ b/interface/resources/qml/windows/Frame.qml @@ -59,7 +59,7 @@ Item { height: 1.66 * window.height x: (window.width - width) / 2 y: window.height / 2 - 0.375 * height - visible: gradientsSupported && window && window.focus && pane.visible + visible: gradientsSupported && window && window.focus && window.content.visible gradient: Gradient { // GradientStop position 0.5 is at full circumference of circle that fits inside the square. GradientStop { position: 0.0; color: "#ff000000" } // black, 100% opacity diff --git a/interface/resources/qml/windows/ToolFrame.qml b/interface/resources/qml/windows/ToolFrame.qml index ac1093092e..eff5fc0377 100644 --- a/interface/resources/qml/windows/ToolFrame.qml +++ b/interface/resources/qml/windows/ToolFrame.qml @@ -16,20 +16,67 @@ import "../styles-uit" Frame { HifiConstants { id: hifi } + property bool horizontalSpacers: false + property bool verticalSpacers: false Rectangle { // Dialog frame id: frameContent readonly property int frameMargin: 6 - readonly property int frameMarginLeft: frameMargin - readonly property int frameMarginRight: frameMargin - readonly property int frameMarginTop: frameMargin - readonly property int frameMarginBottom: frameMargin + readonly property int frameMarginLeft: frameMargin + (horizontalSpacers ? 12 : 0) + readonly property int frameMarginRight: frameMargin + (horizontalSpacers ? 12 : 0) + readonly property int frameMarginTop: frameMargin + (verticalSpacers ? 12 : 0) + readonly property int frameMarginBottom: frameMargin + (verticalSpacers ? 12 : 0) + + Rectangle { + visible: horizontalSpacers + anchors.left: parent.left + anchors.leftMargin: 6 + anchors.verticalCenter: parent.verticalCenter + width: 8 + height: window.height + color: "gray"; + radius: 4 + } + + Rectangle { + visible: horizontalSpacers + anchors.right: parent.right + anchors.rightMargin: 6 + anchors.verticalCenter: parent.verticalCenter + width: 8 + height: window.height + color: "gray"; + radius: 4 + } + + Rectangle { + visible: verticalSpacers + anchors.top: parent.top + anchors.topMargin: 6 + anchors.horizontalCenter: parent.horizontalCenter + height: 8 + width: window.width + color: "gray"; + radius: 4 + } + + Rectangle { + visible: verticalSpacers + anchors.bottom: parent.bottom + anchors.bottomMargin: 6 + anchors.horizontalCenter: parent.horizontalCenter + height: 8 + width: window.width + color: "gray"; + radius: 4 + } + anchors { - topMargin: -frameMargin - leftMargin: -frameMargin - rightMargin: -frameMargin - bottomMargin: -frameMargin + leftMargin: -frameMarginLeft + rightMargin: -frameMarginRight + topMargin: -frameMarginTop + bottomMargin: -frameMarginBottom } anchors.fill: parent color: hifi.colors.baseGrayHighlight40 diff --git a/interface/src/scripting/ToolbarScriptingInterface.cpp b/interface/src/scripting/ToolbarScriptingInterface.cpp index fd96b6a809..82332b3187 100644 --- a/interface/src/scripting/ToolbarScriptingInterface.cpp +++ b/interface/src/scripting/ToolbarScriptingInterface.cpp @@ -15,15 +15,6 @@ class QmlWrapper : public QObject { public: QmlWrapper(QObject* qmlObject, QObject* parent = nullptr) : QObject(parent), _qmlObject(qmlObject) { - - const QMetaObject *metaobject = qmlObject->metaObject(); - int count = metaobject->propertyCount(); - qDebug() << "Scanning properties for " << qmlObject; - for (int i = 0; i < count; ++i) { - QMetaProperty metaproperty = metaobject->property(i); - const char *name = metaproperty.name(); - qDebug() << "Property " << name; - } } Q_INVOKABLE void writeProperty(QString propertyName, QVariant propertyValue) { diff --git a/scripts/developer/tests/toolbarTest.js b/scripts/developer/tests/toolbarTest.js index 20f349929f..e21fbd8e19 100644 --- a/scripts/developer/tests/toolbarTest.js +++ b/scripts/developer/tests/toolbarTest.js @@ -13,7 +13,7 @@ var toolBar = (function() { newZoneButton, newParticleButton - var toolIconUrl = Script.resolvePath("assets/images/tools/"); + var toolIconUrl = Script.resolvePath("../../system/assets/images/tools/"); function initialize() { print("Toolbars: " + Toolbars); diff --git a/tests/ui/qml/main.qml b/tests/ui/qml/main.qml index 19f6a55bfd..47d0f6d601 100644 --- a/tests/ui/qml/main.qml +++ b/tests/ui/qml/main.qml @@ -57,7 +57,7 @@ ApplicationWindow { "particle-01.svg", ] property int iconIndex: 0 - readonly property string toolIconUrl: "file:///C:/Users/bdavi/git/hifi/scripts/system/assets/images/tools/" + readonly property string toolIconUrl: "../../../../../scripts/system/assets/images/tools/" text: "Create Button" onClicked: { var name = icons[iconIndex]; From 1fa274a5270f4154ee490cf10e3b919164d68808 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:01:03 -0700 Subject: [PATCH 32/76] Fix GPUIdent name trailing whitespace --- libraries/shared/src/GPUIdent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index 19838964a4..02f92d87e7 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -122,7 +122,7 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) } if (count > bestCount) { bestCount = count; - _name = sString; + _name = QString(sString).trimmed(); hr = spInstance->Get(CComBSTR(_T("DriverVersion")), 0, &var, 0, 0); if (hr == S_OK) { From 0393777b036b7e17a16e8d7836027082ca204ae6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:01:44 -0700 Subject: [PATCH 33/76] Add getMemoryInfo helper function --- libraries/shared/src/SharedUtil.cpp | 25 +++++++++++++++++++++++++ libraries/shared/src/SharedUtil.h | 10 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index b80fac637c..a6866fdc93 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -28,6 +28,7 @@ #ifdef Q_OS_WIN #include "CPUIdent.h" +#include #endif @@ -843,3 +844,27 @@ void printSystemInformation() { (envVariables.contains(env) ? " = " + envVariables.value(env) : " NOT FOUND"); } } + +bool getMemoryInfo(MemoryInfo& info) { +#ifdef Q_OS_WIN + MEMORYSTATUSEX ms; + ms.dwLength = sizeof(ms); + if (!GlobalMemoryStatusEx(&ms)) { + return false; + } + + info.totalMemoryBytes = ms.ullTotalPhys; + info.availMemoryBytes = ms.ullAvailPhys; + info.usedMemoryBytes = ms.ullTotalPhys - ms.ullAvailPhys; + + + PROCESS_MEMORY_COUNTERS_EX pmc; + if (!GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&pmc), sizeof(pmc))) { + return false; + } + info.processUsedMemoryBytes = pmc.PrivateUsage; + info.processPeakUsedMemoryBytes = pmc.PeakPagefileUsage; +#endif + + return true; +} \ No newline at end of file diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 042396f474..f3e5625484 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -204,4 +204,14 @@ void disableQtBearerPoll(); void printSystemInformation(); +struct MemoryInfo { + uint64_t totalMemoryBytes; + uint64_t availMemoryBytes; + uint64_t usedMemoryBytes; + uint64_t processUsedMemoryBytes; + uint64_t processPeakUsedMemoryBytes; +}; + +bool getMemoryInfo(MemoryInfo& info); + #endif // hifi_SharedUtil_h From 7b3b01a96a54b03099a3bc5d8d7a469ab0c5b5cf Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:02:14 -0700 Subject: [PATCH 34/76] Add more values to launch UserActivity --- interface/src/Application.cpp | 39 +++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f2f265aae0..42cfa9484e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -151,6 +151,8 @@ #include "InterfaceParentFinder.h" #include "FrameTimingsScriptingInterface.h" +#include +#include // On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU // FIXME seems to be broken. @@ -669,10 +671,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : accountManager->setIsAgent(true); accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); - // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value. - // The value will be 0 if the user blew away settings this session, which is both a feature and a bug. - UserActivityLogger::getInstance().launch(applicationVersion(), _previousSessionCrashed, sessionRunTime.get()); - auto addressManager = DependencyManager::get(); // use our MyAvatar position and quat for address manager path @@ -762,6 +760,39 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Make sure we don't time out during slow operations at startup updateHeartbeat(); + + // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value. + // The value will be 0 if the user blew away settings this session, which is both a feature and a bug. + auto gpuIdent = GPUIdent::getInstance(); + auto glContextData = getGLContextData(); + QJsonObject properties = { + { "previousSessionCrashed", _previousSessionCrashed }, + { "previousSessionRuntime", sessionRunTime.get() }, + { "cpu_architecture", QSysInfo::currentCpuArchitecture() }, + { "kernel_type", QSysInfo::kernelType() }, + { "kernel_version", QSysInfo::kernelVersion() }, + { "os_type", QSysInfo::productType() }, + { "os_version", QSysInfo::productVersion() }, + { "gpu_name", gpuIdent->getName() }, + { "gpu_driver", gpuIdent->getDriver() }, + { "gpu_memory", static_cast(gpuIdent->getMemory()) }, + { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) }, + { "gl_version", glContextData["version"] }, + { "gl_vender", glContextData["vendor"] }, + { "gl_sl_version", glContextData["slVersion"] }, + { "gl_renderer", glContextData["renderer"] } + }; + auto macVersion = QSysInfo::macVersion(); + if (macVersion != QSysInfo::MV_None) { + properties["os_osx_version"] = QSysInfo::macVersion(); + } + auto windowsVersion = QSysInfo::windowsVersion(); + if (windowsVersion != QSysInfo::WV_None) { + properties["os_win_version"] = QSysInfo::windowsVersion(); + } + UserActivityLogger::getInstance().logAction("launch", properties); + + // Tell our entity edit sender about our known jurisdictions _entityEditSender.setServerJurisdictions(&_entityServerJurisdictions); _entityEditSender.setMyAvatar(getMyAvatar()); From 3aac0cc4fb17fce1b1c528e8a9c2fcfd02036397 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:02:36 -0700 Subject: [PATCH 35/76] Update fps useractivity with more general stats --- interface/src/Application.cpp | 54 +++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 42cfa9484e..8071a46e5f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1090,15 +1090,57 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Add periodic checks to send user activity data static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000; - static int SEND_FPS_INTERVAL_MS = 10000; + static int SEND_STATS_INTERVAL_MS = 10000; + static int NEARBY_AVATAR_RADIUS_METERS = 10; // Periodically send fps as a user activity event - QTimer* sendFPSTimer = new QTimer(this); - sendFPSTimer->setInterval(SEND_FPS_INTERVAL_MS); - connect(sendFPSTimer, &QTimer::timeout, this, [this]() { - UserActivityLogger::getInstance().logAction("fps", { { "rate", _frameCounter.rate() } }); + QTimer* sendStatsTimer = new QTimer(this); + sendStatsTimer->setInterval(SEND_STATS_INTERVAL_MS); + connect(sendStatsTimer, &QTimer::timeout, this, [this]() { + QJsonObject properties = {}; + MemoryInfo memInfo; + if (getMemoryInfo(memInfo)) { + properties["system_memory_total"] = static_cast(memInfo.totalMemoryBytes); + properties["system_memory_used"] = static_cast(memInfo.usedMemoryBytes); + properties["process_memory_used"] = static_cast(memInfo.processUsedMemoryBytes); + } + + auto displayPlugin = qApp->getActiveDisplayPlugin(); + + properties["fps"] = _frameCounter.rate(); + properties["present_rate"] = displayPlugin->presentRate(); + properties["new_frame_present_rate"] = displayPlugin->newFramePresentRate(); + properties["dropped_frame_rate"] = displayPlugin->droppedFrameRate(); + properties["sim_rate"] = getAverageSimsPerSecond(); + properties["avatar_sim_rate"] = getAvatarSimrate(); + + auto bandwidthRecorder = DependencyManager::get(); + properties["packet_rate_in"] = bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond(); + properties["packet_rate_out"] = bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond(); + properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); + properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); + + auto nodeList = DependencyManager::get(); + SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); + SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); + SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer); + SharedNodePointer assetServerNode = nodeList->soloNodeOfType(NodeType::AssetServer); + SharedNodePointer messagesMixerNode = nodeList->soloNodeOfType(NodeType::MessagesMixer); + properties["entity_ping"] = entityServerNode ? entityServerNode->getPingMs() : -1; + properties["audio_ping"] = audioMixerNode ? audioMixerNode->getPingMs() : -1; + properties["avatar_ping"] = avatarMixerNode ? avatarMixerNode->getPingMs() : -1; + properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1; + properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; + + auto loadingRequests = ResourceCache::getLoadingRequests(); + properties["active_downloads"] = loadingRequests.size(); + properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + + properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; + + UserActivityLogger::getInstance().logAction("stats", properties); }); - sendFPSTimer->start(); + sendStatsTimer->start(); // Periodically check for count of nearby avatars From 1eaa9e40cdc8fc365843e18b30a92076735318b5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:09:17 -0700 Subject: [PATCH 36/76] Cleanup nearby avatar tracking --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8071a46e5f..a3ab1ca8c0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1149,7 +1149,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : checkNearbyAvatarsTimer->setInterval(CHECK_NEARBY_AVATARS_INTERVAL_MS); connect(checkNearbyAvatarsTimer, &QTimer::timeout, this, [this]() { auto avatarManager = DependencyManager::get(); - int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(), 10) - 1; + int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(), + NEARBY_AVATAR_RADIUS_METERS) - 1; if (nearbyAvatars != lastCountOfNearbyAvatars) { UserActivityLogger::getInstance().logAction("nearby_avatars", { { "count", nearbyAvatars } }); } From ab057010d6c5c1c58880869ffc56b35c01edb135 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:09:34 -0700 Subject: [PATCH 37/76] Add changed display mode tracking --- interface/src/Application.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a3ab1ca8c0..93a6df2d3b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5266,6 +5266,11 @@ void Application::updateDisplayMode() { return; } + UserActivityLogger::getInstance().logAction("changed_display_mode", { + { "previous_display_mode", _displayPlugin ? _displayPlugin->getName() : "" }, + { "display_mode", newDisplayPlugin ? newDisplayPlugin->getName() : "" } + }); + auto offscreenUi = DependencyManager::get(); // Make the switch atomic from the perspective of other threads From 154ccb8932095f2f180cda149eb912c68fef0348 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:10:07 -0700 Subject: [PATCH 38/76] Add glVersionToInteger to GLHelpers --- libraries/gl/src/gl/GLHelpers.cpp | 8 ++++++++ libraries/gl/src/gl/GLHelpers.h | 1 + 2 files changed, 9 insertions(+) diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp index 302e0b8515..79b39a2331 100644 --- a/libraries/gl/src/gl/GLHelpers.cpp +++ b/libraries/gl/src/gl/GLHelpers.cpp @@ -5,6 +5,7 @@ #include #include #include +#include const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { static QSurfaceFormat format; @@ -39,6 +40,13 @@ const QGLFormat& getDefaultGLFormat() { return glFormat; } +int glVersionToInteger(QString glVersion) { + QStringList versionParts = glVersion.split(QRegularExpression("[\\.\\s]")); + int majorNumber = versionParts[0].toInt(); + int minorNumber = versionParts[1].toInt(); + return majorNumber * 100 + minorNumber * 10; +} + QJsonObject getGLContextData() { if (!QOpenGLContext::currentContext()) { return QJsonObject(); diff --git a/libraries/gl/src/gl/GLHelpers.h b/libraries/gl/src/gl/GLHelpers.h index ddb254f1c5..477bf7abc8 100644 --- a/libraries/gl/src/gl/GLHelpers.h +++ b/libraries/gl/src/gl/GLHelpers.h @@ -27,5 +27,6 @@ void setGLFormatVersion(F& format, int major = 4, int minor = 5) { format.setVer const QSurfaceFormat& getDefaultOpenGLSurfaceFormat(); const QGLFormat& getDefaultGLFormat(); QJsonObject getGLContextData(); +int glVersionToInteger(QString glVersion); #endif From 4e0aeea2b8715f33f0c15914e4751d38f7bc3a7b Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 16:19:19 -0700 Subject: [PATCH 39/76] add time offset to domain-server UI --- .../resources/describe-settings.json | 164 ++++++++++++++++++ domain-server/src/DomainMetadata.cpp | 7 +- 2 files changed, 170 insertions(+), 1 deletion(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index dce6c3449f..3633685365 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -141,6 +141,170 @@ "can_set": true } ] + }, + { + "name": "utc_offset", + "label": "Time Zone", + "help": "This server's time zone, used for searching open servers", + "type": "select", + "options": [ + { + "value": "-12", + "label": "UTC-12:00" + }, + { + "value": "-11", + "label": "UTC-11:00" + }, + { + "value": "-10", + "label": "UTC-10:00" + }, + { + "value": "-9.5", + "label": "UTC-09:30" + }, + { + "value": "-9", + "label": "UTC-09:00" + }, + { + "value": "-8", + "label": "UTC-08:00" + }, + { + "value": "-7", + "label": "UTC-07:00" + }, + { + "value": "-6", + "label": "UTC-06:00" + }, + { + "value": "-5", + "label": "UTC-05:00" + }, + { + "value": "-4", + "label": "UTC-04:00" + }, + { + "value": "-3.5", + "label": "UTC-03:30" + }, + { + "value": "-3", + "label": "UTC-03:00" + }, + { + "value": "-2", + "label": "UTC-02:00" + }, + { + "value": "-1", + "label": "UTC-01:00" + }, + { + "value": "", + "label": "UTC±00:00" + }, + { + "value": "1", + "label": "UTC+01:00" + }, + { + "value": "2", + "label": "UTC+02:00" + }, + { + "value": "3", + "label": "UTC+03:00" + }, + { + "value": "3.5", + "label": "UTC+03:30" + }, + { + "value": "4", + "label": "UTC+04:00" + }, + { + "value": "4.5", + "label": "UTC+04:30" + }, + { + "value": "5", + "label": "UTC+05:00" + }, + { + "value": "5.5", + "label": "UTC+05:30" + }, + { + "value": "5.75", + "label": "UTC+05:45" + }, + { + "value": "6", + "label": "UTC+06:00" + }, + { + "value": "6.5", + "label": "UTC+06:30" + }, + { + "value": "7", + "label": "UTC+07:00" + }, + { + "value": "8", + "label": "UTC+08:00" + }, + { + "value": "8.5", + "label": "UTC+08:30" + }, + { + "value": "8.75", + "label": "UTC+08:45" + }, + { + "value": "9", + "label": "UTC+09:00" + }, + { + "value": "9.5", + "label": "UTC+09:30" + }, + { + "value": "10", + "label": "UTC+10:00" + }, + { + "value": "10.5", + "label": "UTC+10:30" + }, + { + "value": "11", + "label": "UTC+11:00" + }, + { + "value": "12", + "label": "UTC+12:00" + }, + { + "value": "12.75", + "label": "UTC+12:45" + }, + { + "value": "13", + "label": "UTC+13:00" + }, + { + "value": "14", + "label": "UTC+14:00" + } + ] } ] }, diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index d3eb7a97b0..bdf24c000a 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -39,7 +39,11 @@ const QString DomainMetadata::Descriptors::TAGS = "tags"; // descriptors metadata will appear as (JSON): // { "description": String, // capped description // "capacity": Number, -// "hours": String, // UTF-8 representation of the week, split into 15" segments +// "hours": { +// "utc_offset": Number, +// "weekday": [ Number, Number ], +// "weekend": [ Number, Number ] +// } // "restriction": String, // enum of either open, hifi, or acl // "maturity": String, // enum corresponding to ESRB ratings // "hosts": [ String ], // capped list of usernames @@ -50,6 +54,7 @@ const QString DomainMetadata::Descriptors::TAGS = "tags"; // { users: , descriptors: } // // it is meant to be sent to and consumed by an external API +// NOTE: metadata may not appear as documented, as parts are generated by describe-settings.js DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { _metadata[USERS] = {}; From cee897d6d3e306a00704818336f4105c0377cc2a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Jun 2016 16:44:02 -0700 Subject: [PATCH 40/76] Fix osx warning --- 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 93a6df2d3b..b92fc2d3e6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -775,7 +775,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : { "os_version", QSysInfo::productVersion() }, { "gpu_name", gpuIdent->getName() }, { "gpu_driver", gpuIdent->getDriver() }, - { "gpu_memory", static_cast(gpuIdent->getMemory()) }, + { "gpu_memory", QJsonValue(static_cast(gpuIdent->getMemory())) }, { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) }, { "gl_version", glContextData["version"] }, { "gl_vender", glContextData["vendor"] }, From bfb697bc7789f5cd6dbb073be47f846fc39a66da Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 20 Jun 2016 17:04:23 -0700 Subject: [PATCH 41/76] No hysteresis. --- scripts/system/controllers/handControllerPointer.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 0fe199098d..c94325d3c0 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -85,15 +85,10 @@ function Trigger(label) { state = 'full'; } else if (that.triggerSmoothedReleased()) { state = null; - // These depend on previous state: - // null -> squeezed ==> partial - // full -> !squeezed ==> partial - // Otherwise no change. } else if (that.triggerSmoothedSqueezed()) { - if (!state) { - state = 'partial'; - } - } else if (state === 'full') { + // Another way to do this would be to have hysteresis in this branch, but that seems to make things harder to use. + // In particular, the vive has a nice detent as you release off of full, and we want that to be a transition from + // full to partial. state = 'partial'; } that.state = state; From 0bc4beeffd4e85d353ece1219cdd3697a2b14ce6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 20 Jun 2016 17:09:30 -0700 Subject: [PATCH 42/76] Fix initial toolbar positioning --- interface/resources/qml/desktop/Desktop.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index e269a63cde..58d1cba1b8 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -65,7 +65,7 @@ FocusScope { var oldChildren = expectedChildren; var newChildren = d.getRepositionChildren(); - if (oldRecommendedRect != Qt.rect(0,0,0,0) + if (oldRecommendedRect != Qt.rect(0,0,0,0) && oldRecommendedRect != Qt.rect(0,0,1,1) && (oldRecommendedRect != newRecommendedRect || oldChildren != newChildren) ) { From 7fa7abdb1df8c650e538d33d425ac60757174bdb Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 22:43:28 -0700 Subject: [PATCH 43/76] add operating hours to domain-server settings/UI --- .../resources/describe-settings.json | 54 +++++++++++++++++- .../resources/web/settings/js/settings.js | 14 ++++- domain-server/src/DomainMetadata.cpp | 56 ++++++++++++++----- domain-server/src/DomainMetadata.h | 8 ++- .../src/DomainServerSettingsManager.cpp | 27 ++++++++- 5 files changed, 139 insertions(+), 20 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 3633685365..59fa9c4f3d 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1,5 +1,5 @@ { - "version": 1.4, + "version": 1.5, "settings": [ { "name": "metaverse", @@ -143,9 +143,57 @@ ] }, { - "name": "utc_offset", + "label": "Operating Hours", + "help": "\"Open\" domains can be searched using their operating hours. Hours are entered in the local timezone, selected below.", + + "name": "weekday_hours", + "caption": "Weekday Hours (Monday-Friday)", + "type": "table", + "can_add_new_rows": false, + "columns": [ + { + "name": "open", + "label": "Opening Time", + "type": "time", + "default": "00:00", + "editable": true + }, + { + "name": "close", + "label": "Closing Time", + "type": "time", + "default": "23:59", + "editable": true + } + ] + }, + { + "name": "weekend_hours", + "label": "Weekend Hours (Saturday/Sunday)", + "type": "table", + "can_add_new_rows": false, + "columns": [ + { + "name": "open", + "label": "Opening Time", + "type": "time", + "default": "00:00", + "editable": true + }, + { + "name": "close", + "label": "Closing Time", + "type": "time", + "default": "23:59", + "editable": true + } + ] + }, + { "label": "Time Zone", - "help": "This server's time zone, used for searching open servers", + "name": "utc_offset", + "caption": "Time Zone", + "help": "This server's time zone. Used to define your server's operating hours.", "type": "select", "options": [ { diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index aecc48b31f..709e0e05ce 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -987,7 +987,7 @@ function makeTable(setting, keypath, setting_value, isLocked) { html += "" + rowIndexOrName + "" } - var isNonDeletableRow = false; + var isNonDeletableRow = !setting.can_add_new_rows; _.each(setting.columns, function(col) { @@ -1007,6 +1007,10 @@ function makeTable(setting, keypath, setting_value, isLocked) { html += "" + ""; + } else if (isArray && col.type === "time" && col.editable) { + html += "" + + ""; } else { // Use a hidden input so that the values are posted. html += "" @@ -1196,15 +1200,21 @@ function addTableRow(add_glyphicon) { // Hide inputs var input = $(element).find("input") var isCheckbox = false; + var isTime = false; if (input.hasClass("table-checkbox")) { input = $(input).parent(); isCheckbox = true; + } else if (input.hasClass("table-time")) { + input = $(input).parent(); + isTime = true; } var val = input.val(); if (isCheckbox) { - val = $(input).find("input").is(':checked'); // don't hide the checkbox + val = $(input).find("input").is(':checked'); + } else if (isTime) { + // don't hide the time } else { input.attr("type", "hidden") } diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index bdf24c000a..c1656af5b7 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -31,30 +31,32 @@ const QString DomainMetadata::Users::HOSTNAMES = "user_hostnames"; const QString DomainMetadata::DESCRIPTORS = "descriptors"; const QString DomainMetadata::Descriptors::DESCRIPTION = "description"; const QString DomainMetadata::Descriptors::CAPACITY = "capacity"; // parsed from security -const QString DomainMetadata::Descriptors::HOURS = "hours"; const QString DomainMetadata::Descriptors::RESTRICTION = "restriction"; // parsed from ACL const QString DomainMetadata::Descriptors::MATURITY = "maturity"; const QString DomainMetadata::Descriptors::HOSTS = "hosts"; const QString DomainMetadata::Descriptors::TAGS = "tags"; +const QString DomainMetadata::Descriptors::HOURS = "hours"; +const QString DomainMetadata::Descriptors::Hours::WEEKDAY = "weekday"; +const QString DomainMetadata::Descriptors::Hours::WEEKEND = "weekend"; +const QString DomainMetadata::Descriptors::Hours::UTC_OFFSET = "utc_offset"; // descriptors metadata will appear as (JSON): // { "description": String, // capped description // "capacity": Number, -// "hours": { -// "utc_offset": Number, -// "weekday": [ Number, Number ], -// "weekend": [ Number, Number ] -// } // "restriction": String, // enum of either open, hifi, or acl // "maturity": String, // enum corresponding to ESRB ratings // "hosts": [ String ], // capped list of usernames // "tags": [ String ], // capped list of tags +// "hours": { +// "utc_offset": Number, +// "weekday": [ { "open": Time, "close": Time } ], +// "weekend": [ { "open": Time, "close": Time } ], +// } // } // metadata will appear as (JSON): // { users: , descriptors: } // // it is meant to be sent to and consumed by an external API -// NOTE: metadata may not appear as documented, as parts are generated by describe-settings.js DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { _metadata[USERS] = {}; @@ -86,20 +88,42 @@ QJsonObject DomainMetadata::get(const QString& group) { } void DomainMetadata::descriptorsChanged() { - const QString CAPACITY = "security.maximum_user_capacity"; + // get descriptors auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); + auto descriptors = settings[DESCRIPTORS].toMap(); + + // parse capacity + const QString CAPACITY = "security.maximum_user_capacity"; const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY); unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0; - - auto descriptors = settings[DESCRIPTORS].toMap(); descriptors[Descriptors::CAPACITY] = capacity; + + // parse operating hours + const QString WEEKDAY_HOURS = "weekday_hours"; + const QString WEEKEND_HOURS = "weekday_hours"; + const QString UTC_OFFSET = "utc_offset"; + auto weekdayHours = descriptors[WEEKDAY_HOURS]; + auto weekendHours = descriptors[WEEKEND_HOURS]; + auto utcOffset = descriptors[UTC_OFFSET]; + descriptors.remove(WEEKDAY_HOURS); + descriptors.remove(WEEKEND_HOURS); + descriptors.remove(UTC_OFFSET); + QVariantMap hours { + { Descriptors::Hours::UTC_OFFSET, utcOffset }, + { Descriptors::Hours::WEEKDAY, weekdayHours }, + { Descriptors::Hours::WEEKEND, weekendHours } + }; + descriptors[Descriptors::HOURS] = hours; + + // update metadata _metadata[DESCRIPTORS] = descriptors; // update overwritten fields + // this further overwrites metadata, so it must be done after commiting descriptors securityChanged(false); #if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata descriptors set:" << _metadata[DESCRIPTORS]; + qDebug() << "Domain metadata descriptors set:" << QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); #endif sendDescriptors(); @@ -189,7 +213,7 @@ void DomainMetadata::maybeUpdateUsers() { ++_tic; #if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata users updated:" << users; + qDebug() << "Domain metadata users set:" << QJsonObject::fromVariantMap(_metadata[USERS].toMap()); #endif } @@ -198,10 +222,16 @@ void DomainMetadata::sendDescriptors() { const QUuid& domainID = DependencyManager::get()->getSessionUUID(); if (!domainID.isNull()) { static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; - DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + QString path { DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)) }; + DependencyManager::get()->sendRequest(path, AccountManagerAuth::Required, QNetworkAccessManager::PutOperation, JSONCallbackParameters(), domainUpdateJSON.toUtf8()); + +#if DEV_BUILD || PR_BUILD + qDebug() << "Domain metadata sent to" << path; + qDebug() << "Domain metadata update:" << domainUpdateJSON; +#endif } } diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 0bfd6c611b..6573a9076c 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -35,11 +35,17 @@ public: public: static const QString DESCRIPTION; static const QString CAPACITY; - static const QString HOURS; static const QString RESTRICTION; static const QString MATURITY; static const QString HOSTS; static const QString TAGS; + static const QString HOURS; + class Hours { + public: + static const QString WEEKDAY; + static const QString WEEKEND; + static const QString UTC_OFFSET; + }; }; DomainMetadata(QObject* domainServer); diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index b03d2c07ae..f5ff479cd3 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -69,7 +71,7 @@ DomainServerSettingsManager::DomainServerSettingsManager() : } static const QString MISSING_SETTINGS_DESC_MSG = - QString("Did not find settings decription in JSON at %1 - Unable to continue. domain-server will quit.\n%2 at %3") + QString("Did not find settings description in JSON at %1 - Unable to continue. domain-server will quit.\n%2 at %3") .arg(SETTINGS_DESCRIPTION_RELATIVE_PATH).arg(parseError.errorString()).arg(parseError.offset); static const int MISSING_SETTINGS_DESC_ERROR_CODE = 6; @@ -258,6 +260,29 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList _standardAgentPermissions.clear(); _agentPermissions.clear(); } + + if (oldVersion < 1.5) { + // This was prior to operating hours, so add default hours + static const QString WEEKDAY_HOURS{ "descriptors.weekday_hours" }; + static const QString WEEKEND_HOURS{ "descriptors.weekend_hours" }; + static const QString UTC_OFFSET{ "descriptors.utc_offset" }; + + QVariant* weekdayHours = valueForKeyPath(_configMap.getUserConfig(), WEEKDAY_HOURS, true); + QVariant* weekendHours = valueForKeyPath(_configMap.getUserConfig(), WEEKEND_HOURS, true); + QVariant* utcOffset = valueForKeyPath(_configMap.getUserConfig(), UTC_OFFSET, true); + + + QVariantList allHours { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; + *weekdayHours = allHours; + *weekendHours = allHours; + *utcOffset = QVariant(QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / (float)3600); + + // write the new settings to file + persistToFile(); + + // reload the master and user config so the merged config is correct + _configMap.loadMasterAndUserConfig(_argumentList); + } } unpackPermissions(); From 807596596f2923241f57f1349cafc7d0261aca5a Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 00:18:38 -0700 Subject: [PATCH 44/76] fix badging, parsing of operating hours --- .../resources/web/settings/js/settings.js | 12 +++- domain-server/src/DomainMetadata.cpp | 55 +++++++++++++++---- domain-server/src/DomainMetadata.h | 2 + .../src/DomainServerSettingsManager.cpp | 6 +- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 709e0e05ce..c2cb2ecb80 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -243,6 +243,16 @@ $(document).ready(function(){ } }); + $('#' + Settings.FORM_ID).on('change', 'input.table-time', function() { + // Bootstrap switches in table: set the changed data attribute for all rows in table. + var row = $(this).closest('tr'); + if (row.hasClass("value-row")) { // Don't set attribute on input row switches prior to it being added to table. + row.find('td.' + Settings.DATA_COL_CLASS + ' input').attr('data-changed', true); + updateDataChangedForSiblingRows(row, true); + badgeSidebarForDifferences($(this)); + } + }); + $('.advanced-toggle').click(function(){ Settings.showAdvanced = !Settings.showAdvanced var advancedSelector = $('.' + Settings.ADVANCED_CLASS) @@ -1009,7 +1019,7 @@ function makeTable(setting, keypath, setting_value, isLocked) { + "name='" + colName + "'" + (colValue ? " checked" : "") + " />"; } else if (isArray && col.type === "time" && col.editable) { html += "" - + ""; } else { // Use a hidden input so that the values are posted. diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index c1656af5b7..cfb48e6c49 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -39,6 +39,8 @@ const QString DomainMetadata::Descriptors::HOURS = "hours"; const QString DomainMetadata::Descriptors::Hours::WEEKDAY = "weekday"; const QString DomainMetadata::Descriptors::Hours::WEEKEND = "weekend"; const QString DomainMetadata::Descriptors::Hours::UTC_OFFSET = "utc_offset"; +const QString DomainMetadata::Descriptors::Hours::OPEN = "open"; +const QString DomainMetadata::Descriptors::Hours::CLOSE = "close"; // descriptors metadata will appear as (JSON): // { "description": String, // capped description // "capacity": Number, @@ -59,8 +61,13 @@ const QString DomainMetadata::Descriptors::Hours::UTC_OFFSET = "utc_offset"; // it is meant to be sent to and consumed by an external API DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { - _metadata[USERS] = {}; - _metadata[DESCRIPTORS] = {}; + _metadata[USERS] = QVariantMap {}; + _metadata[DESCRIPTORS] = QVariantMap { + { Descriptors::HOURS, QVariantMap { + { Descriptors::Hours::WEEKDAY, QVariantList() }, + { Descriptors::Hours::WEEKEND, QVariantList() } + } } + }; assert(dynamic_cast(domainServer)); DomainServer* server = static_cast(domainServer); @@ -87,10 +94,38 @@ QJsonObject DomainMetadata::get(const QString& group) { return QJsonObject::fromVariantMap(_metadata[group].toMap()); } +QVariant parseHours(QVariant base, QVariant delta) { + using Hours = DomainMetadata::Descriptors::Hours; + + auto& baseList = base.toList(); + auto& deltaList = delta.toList(); + if (baseList.isEmpty() || !baseList.length()) { + return delta; + } else if (deltaList.isEmpty() || !deltaList.length()) { + return base; + } + + auto& baseMap = baseList[0].toMap(); + auto& deltaMap = deltaList[0].toMap(); + if (baseMap.isEmpty()) { + return delta; + } else if (deltaMap.isEmpty()) { + return base; + } + + // merge delta into base + // hours should be of the form [ { open: Time, close: Time } ], so one level is sufficient + foreach(auto key, baseMap.keys()) { + deltaMap[key] = baseMap[key]; + } + + return base; +} + void DomainMetadata::descriptorsChanged() { // get descriptors auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); - auto descriptors = settings[DESCRIPTORS].toMap(); + auto& descriptors = settings[DESCRIPTORS].toMap(); // parse capacity const QString CAPACITY = "security.maximum_user_capacity"; @@ -100,20 +135,21 @@ void DomainMetadata::descriptorsChanged() { // parse operating hours const QString WEEKDAY_HOURS = "weekday_hours"; - const QString WEEKEND_HOURS = "weekday_hours"; + const QString WEEKEND_HOURS = "weekend_hours"; const QString UTC_OFFSET = "utc_offset"; - auto weekdayHours = descriptors[WEEKDAY_HOURS]; - auto weekendHours = descriptors[WEEKEND_HOURS]; + auto& hours = _metadata[DESCRIPTORS].toMap()[Descriptors::HOURS].toMap(); + assert(!hours.isEmpty()); + auto weekdayHours = parseHours(hours[Descriptors::Hours::WEEKDAY], descriptors[WEEKDAY_HOURS]); + auto weekendHours = parseHours(hours[Descriptors::Hours::WEEKEND], descriptors[WEEKEND_HOURS]); auto utcOffset = descriptors[UTC_OFFSET]; descriptors.remove(WEEKDAY_HOURS); descriptors.remove(WEEKEND_HOURS); descriptors.remove(UTC_OFFSET); - QVariantMap hours { + descriptors[Descriptors::HOURS] = QVariantMap { { Descriptors::Hours::UTC_OFFSET, utcOffset }, { Descriptors::Hours::WEEKDAY, weekdayHours }, { Descriptors::Hours::WEEKEND, weekendHours } }; - descriptors[Descriptors::HOURS] = hours; // update metadata _metadata[DESCRIPTORS] = descriptors; @@ -150,9 +186,8 @@ void DomainMetadata::securityChanged(bool send) { restriction = RESTRICTION_ACL; } - auto descriptors = _metadata[DESCRIPTORS].toMap(); + auto& descriptors = _metadata[DESCRIPTORS].toMap(); descriptors[Descriptors::RESTRICTION] = restriction; - _metadata[DESCRIPTORS] = descriptors; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata restriction set:" << restriction; diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 6573a9076c..41f3a60832 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -45,6 +45,8 @@ public: static const QString WEEKDAY; static const QString WEEKEND; static const QString UTC_OFFSET; + static const QString OPEN; + static const QString CLOSE; }; }; diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index f5ff479cd3..543e61f485 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -271,10 +271,8 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList QVariant* weekendHours = valueForKeyPath(_configMap.getUserConfig(), WEEKEND_HOURS, true); QVariant* utcOffset = valueForKeyPath(_configMap.getUserConfig(), UTC_OFFSET, true); - - QVariantList allHours { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; - *weekdayHours = allHours; - *weekendHours = allHours; + *weekdayHours = QVariantList { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; + *weekendHours = QVariantList { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; *utcOffset = QVariant(QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / (float)3600); // write the new settings to file From a77dea904876725d583638e8d382ff14917c3aef Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 08:31:40 -0700 Subject: [PATCH 45/76] Fix osx warning --- 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 b92fc2d3e6..17a6110ea2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -775,7 +775,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : { "os_version", QSysInfo::productVersion() }, { "gpu_name", gpuIdent->getName() }, { "gpu_driver", gpuIdent->getDriver() }, - { "gpu_memory", QJsonValue(static_cast(gpuIdent->getMemory())) }, + { "gpu_memory", QJsonValue(static_cast(gpuIdent->getMemory())) }, { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) }, { "gl_version", glContextData["version"] }, { "gl_vender", glContextData["vendor"] }, From 31706a39093c88b87b5a58884d18a1d306b7ddfd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 21 Jun 2016 10:38:44 -0700 Subject: [PATCH 46/76] force activate kinmatic objects when necessary --- libraries/physics/src/EntityMotionState.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 8f22c576f0..dc57a82fd3 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -135,7 +135,14 @@ void EntityMotionState::handleEasyChanges(uint32_t& flags) { _nextOwnershipBid = 0; } if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { - _body->activate(); + if (_body->isKinematicObject()) { + // only force activate kinematic bodies (dynamic shouldn't need force and + // active static bodies are special (see PhysicsEngine::_activeStaticBodies)) + _body->activate(true); + _lastKinematicStep = ObjectMotionState::getWorldSimulationStep(); + } else { + _body->activate(); + } } } From 6d753e317b60dfb3ee9b6c5b3be826b11e999bbe Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 10:51:31 -0700 Subject: [PATCH 47/76] Fix more osx warning --- interface/src/Application.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 17a6110ea2..0b6bc2e01a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -775,7 +775,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : { "os_version", QSysInfo::productVersion() }, { "gpu_name", gpuIdent->getName() }, { "gpu_driver", gpuIdent->getDriver() }, - { "gpu_memory", QJsonValue(static_cast(gpuIdent->getMemory())) }, + { "gpu_memory", static_cast(gpuIdent->getMemory()) }, { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) }, { "gl_version", glContextData["version"] }, { "gl_vender", glContextData["vendor"] }, @@ -1100,9 +1100,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : QJsonObject properties = {}; MemoryInfo memInfo; if (getMemoryInfo(memInfo)) { - properties["system_memory_total"] = static_cast(memInfo.totalMemoryBytes); - properties["system_memory_used"] = static_cast(memInfo.usedMemoryBytes); - properties["process_memory_used"] = static_cast(memInfo.processUsedMemoryBytes); + properties["system_memory_total"] = static_cast(memInfo.totalMemoryBytes); + properties["system_memory_used"] = static_cast(memInfo.usedMemoryBytes); + properties["process_memory_used"] = static_cast(memInfo.processUsedMemoryBytes); } auto displayPlugin = qApp->getActiveDisplayPlugin(); From 52170eb12e3a1bd4b12bc66b49a15043407a0a48 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 11:16:08 -0700 Subject: [PATCH 48/76] use refs for domain metadata parsing --- domain-server/src/DomainMetadata.cpp | 102 +++++++++++++-------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index cfb48e6c49..f18aa8c71b 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -61,11 +61,12 @@ const QString DomainMetadata::Descriptors::Hours::CLOSE = "close"; // it is meant to be sent to and consumed by an external API DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { + // set up the structure necessary for casting during parsing (see parseHours, esp.) _metadata[USERS] = QVariantMap {}; _metadata[DESCRIPTORS] = QVariantMap { { Descriptors::HOURS, QVariantMap { - { Descriptors::Hours::WEEKDAY, QVariantList() }, - { Descriptors::Hours::WEEKEND, QVariantList() } + { Descriptors::Hours::WEEKDAY, QVariantList { QVariantMap{} } }, + { Descriptors::Hours::WEEKEND, QVariantList { QVariantMap{} } } } } }; @@ -81,6 +82,7 @@ DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { this, static_cast(&DomainMetadata::securityChanged)); // initialize the descriptors + securityChanged(false); descriptorsChanged(); } @@ -94,69 +96,65 @@ QJsonObject DomainMetadata::get(const QString& group) { return QJsonObject::fromVariantMap(_metadata[group].toMap()); } -QVariant parseHours(QVariant base, QVariant delta) { +void parseHours(QVariant delta, QVariant& target) { using Hours = DomainMetadata::Descriptors::Hours; - auto& baseList = base.toList(); - auto& deltaList = delta.toList(); - if (baseList.isEmpty() || !baseList.length()) { - return delta; - } else if (deltaList.isEmpty() || !deltaList.length()) { - return base; - } + // hours should be of the form [ { open: Time, close: Time } ] + assert(target.canConvert()); + auto& targetList = *static_cast(target.data()); - auto& baseMap = baseList[0].toMap(); - auto& deltaMap = deltaList[0].toMap(); - if (baseMap.isEmpty()) { - return delta; - } else if (deltaMap.isEmpty()) { - return base; + // if/when multiple ranges are allowed, this list will need to be iterated + assert(targetList[0].canConvert()); + auto& targetMap = *static_cast(targetList[0].data()); + + auto deltaMap = delta.toList()[0].toMap(); + if (deltaMap.isEmpty()) { + return; } // merge delta into base - // hours should be of the form [ { open: Time, close: Time } ], so one level is sufficient - foreach(auto key, baseMap.keys()) { - deltaMap[key] = baseMap[key]; + auto open = deltaMap.find(Hours::OPEN); + if (open != deltaMap.end()) { + targetMap[Hours::OPEN] = open.value(); } - - return base; + assert(targetMap[Hours::OPEN].canConvert()); + auto close = deltaMap.find(Hours::CLOSE); + if (close != deltaMap.end()) { + targetMap[Hours::CLOSE] = close.value(); + } + assert(targetMap[Hours::CLOSE].canConvert()); } void DomainMetadata::descriptorsChanged() { // get descriptors + assert(_metadata[DESCRIPTORS].canConvert()); + auto& state = *static_cast(_metadata[DESCRIPTORS].data()); auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); - auto& descriptors = settings[DESCRIPTORS].toMap(); + auto descriptors = settings[DESCRIPTORS].toMap(); + + // copy simple descriptors (description/maturity) + state[Descriptors::DESCRIPTION] = descriptors[Descriptors::DESCRIPTION]; + state[Descriptors::MATURITY] = descriptors[Descriptors::MATURITY]; + + // copy array descriptors (hosts/tags) + state[Descriptors::HOSTS] = descriptors[Descriptors::HOSTS].toList(); + state[Descriptors::TAGS] = descriptors[Descriptors::TAGS].toList(); // parse capacity const QString CAPACITY = "security.maximum_user_capacity"; const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY); unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0; - descriptors[Descriptors::CAPACITY] = capacity; + state[Descriptors::CAPACITY] = capacity; // parse operating hours const QString WEEKDAY_HOURS = "weekday_hours"; const QString WEEKEND_HOURS = "weekend_hours"; const QString UTC_OFFSET = "utc_offset"; - auto& hours = _metadata[DESCRIPTORS].toMap()[Descriptors::HOURS].toMap(); - assert(!hours.isEmpty()); - auto weekdayHours = parseHours(hours[Descriptors::Hours::WEEKDAY], descriptors[WEEKDAY_HOURS]); - auto weekendHours = parseHours(hours[Descriptors::Hours::WEEKEND], descriptors[WEEKEND_HOURS]); - auto utcOffset = descriptors[UTC_OFFSET]; - descriptors.remove(WEEKDAY_HOURS); - descriptors.remove(WEEKEND_HOURS); - descriptors.remove(UTC_OFFSET); - descriptors[Descriptors::HOURS] = QVariantMap { - { Descriptors::Hours::UTC_OFFSET, utcOffset }, - { Descriptors::Hours::WEEKDAY, weekdayHours }, - { Descriptors::Hours::WEEKEND, weekendHours } - }; - - // update metadata - _metadata[DESCRIPTORS] = descriptors; - - // update overwritten fields - // this further overwrites metadata, so it must be done after commiting descriptors - securityChanged(false); + assert(state[Descriptors::HOURS].canConvert()); + auto& hours = *static_cast(state[Descriptors::HOURS].data()); + parseHours(descriptors.take(WEEKDAY_HOURS), hours[Descriptors::Hours::WEEKDAY]); + parseHours(descriptors.take(WEEKEND_HOURS), hours[Descriptors::Hours::WEEKEND]); + hours[Descriptors::Hours::UTC_OFFSET] = descriptors.take(UTC_OFFSET); #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata descriptors set:" << QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); @@ -166,6 +164,10 @@ void DomainMetadata::descriptorsChanged() { } void DomainMetadata::securityChanged(bool send) { + // get descriptors + assert(_metadata[DESCRIPTORS].canConvert()); + auto& state = *static_cast(_metadata[DESCRIPTORS].data()); + const QString RESTRICTION_OPEN = "open"; const QString RESTRICTION_ANON = "anon"; const QString RESTRICTION_HIFI = "hifi"; @@ -186,8 +188,7 @@ void DomainMetadata::securityChanged(bool send) { restriction = RESTRICTION_ACL; } - auto& descriptors = _metadata[DESCRIPTORS].toMap(); - descriptors[Descriptors::RESTRICTION] = restriction; + state[Descriptors::RESTRICTION] = restriction; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata restriction set:" << restriction; @@ -240,12 +241,11 @@ void DomainMetadata::maybeUpdateUsers() { } }); - QVariantMap users = { - { Users::NUM_TOTAL, numConnected }, - { Users::NUM_ANON, numConnectedAnonymously }, - { Users::HOSTNAMES, userHostnames }}; - _metadata[USERS] = users; - ++_tic; + assert(_metadata[USERS].canConvert()); + auto& users = *static_cast(_metadata[USERS].data()); + users[Users::NUM_TOTAL] = numConnected; + users[Users::NUM_ANON] = numConnectedAnonymously; + users[Users::HOSTNAMES] = userHostnames; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata users set:" << QJsonObject::fromVariantMap(_metadata[USERS].toMap()); From c784fa42e99e6b2862ddf73f80a7ae9a040dc9c6 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 11:34:23 -0700 Subject: [PATCH 49/76] log failure to fetch metadata --- scripts/tutorials/getDomainMetadata.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 0a6f742823..8c347a09ae 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -16,14 +16,21 @@ location.hostChanged.connect(function(host) { // Fetch the domain ID from the metaverse var placeData = request(SERVER + '/places/' + host); - if (!placeData) { return; } + if (!placeData) { + print('Cannot find place name - abandoning metadata request for', host); + return; + + } var domainID = placeData.data.place.domain.id; print('Domain ID:', domainID); // Fetch the domain metadata from the metaverse var domainData = request(SERVER + '/domains/' + domainID); print(SERVER + '/domains/' + domainID); - if (!domainData) { return; } + if (!domainData) { + print('Cannot find domain data - abandoning metadata request for', domainID); + return; + } var metadata = domainData.domain; print('Domain metadata:', JSON.stringify(metadata)); From c3223178783c8418bc8e468578d4393c03463abf Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 21 Jun 2016 12:07:05 -0700 Subject: [PATCH 50/76] rework plugins to not depend on PluginContainer unless they want to --- interface/CMakeLists.txt | 2 +- interface/src/Application.cpp | 63 +++++++++++++-- interface/src/Application.h | 26 +++++-- interface/src/PluginContainerProxy.cpp | 78 ------------------- interface/src/PluginContainerProxy.h | 33 -------- libraries/display-plugins/CMakeLists.txt | 2 +- .../AbstractHMDScriptingInterface.cpp | 2 +- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 2 - .../src/display-plugins/NullDisplayPlugin.cpp | 1 - .../src/display-plugins/NullDisplayPlugin.h | 2 + .../display-plugins/OpenGLDisplayPlugin.cpp | 25 ++++-- .../src/display-plugins/OpenGLDisplayPlugin.h | 7 ++ .../display-plugins/hmd/HmdDisplayPlugin.cpp | 1 - .../display-plugins/hmd/HmdDisplayPlugin.h | 2 + .../stereo/SideBySideStereoDisplayPlugin.cpp | 1 - .../stereo/StereoDisplayPlugin.cpp | 1 - libraries/input-plugins/CMakeLists.txt | 2 +- .../plugins/src/plugins/DisplayPlugin.cpp | 22 ------ libraries/plugins/src/plugins/DisplayPlugin.h | 2 - libraries/plugins/src/plugins/Plugin.cpp | 4 - libraries/plugins/src/plugins/Plugin.h | 11 ++- .../plugins/src/plugins/PluginManager.cpp | 11 +-- libraries/plugins/src/plugins/PluginManager.h | 3 + libraries/ui-plugins/CMakeLists.txt | 3 + .../src/ui-plugins}/PluginContainer.cpp | 0 .../src/ui-plugins}/PluginContainer.h | 17 +++- plugins/hifiSixense/CMakeLists.txt | 2 +- plugins/hifiSixense/src/SixenseManager.cpp | 1 - plugins/hifiSixense/src/SixenseManager.h | 2 + plugins/oculus/CMakeLists.txt | 2 +- .../oculus/src/OculusControllerManager.cpp | 2 +- plugins/oculusLegacy/CMakeLists.txt | 2 +- .../src/OculusLegacyDisplayPlugin.cpp | 1 - plugins/openvr/CMakeLists.txt | 2 +- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 1 - plugins/openvr/src/ViveControllerManager.cpp | 1 - plugins/openvr/src/ViveControllerManager.h | 4 +- tests/controllers/CMakeLists.txt | 2 +- tests/controllers/src/main.cpp | 6 +- 39 files changed, 159 insertions(+), 192 deletions(-) delete mode 100644 interface/src/PluginContainerProxy.cpp delete mode 100644 interface/src/PluginContainerProxy.h create mode 100644 libraries/ui-plugins/CMakeLists.txt rename libraries/{plugins/src/plugins => ui-plugins/src/ui-plugins}/PluginContainer.cpp (100%) rename libraries/{plugins/src/plugins => ui-plugins/src/ui-plugins}/PluginContainer.h (77%) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index ae84705da3..cf5a2b60ad 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -139,7 +139,7 @@ link_hifi_libraries(shared octree gpu gl gpu-gl procedural model render recording fbx networking model-networking entities avatars audio audio-client animation script-engine physics render-utils entities-renderer ui auto-updater - controllers plugins display-plugins input-plugins steamworks-wrapper) + controllers plugins ui-plugins display-plugins input-plugins steamworks-wrapper) # include the binary directory of render-utils for shader includes target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils") diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9bcd85fd02..babcd877c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -83,7 +83,6 @@ #include #include #include -#include #include #include #include @@ -119,7 +118,6 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" -#include "PluginContainerProxy.h" #include "scripting/AccountScriptingInterface.h" #include "scripting/AssetMappingsScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" @@ -464,7 +462,6 @@ bool setupEssentials(int& argc, char** argv) { // continuing to overburden Application.cpp Cube3DOverlay* _keyboardFocusHighlight{ nullptr }; int _keyboardFocusHighlightID{ -1 }; -PluginContainer* _pluginContainer; // FIXME hack access to the internal share context for the Chromium helper @@ -504,6 +501,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _maxOctreePPS(maxOctreePacketsPerSecond.get()), _lastFaceTrackerUpdate(0) { + + + PluginContainer* pluginContainer = dynamic_cast(this); // set the container for any plugins that care + PluginManager::getInstance()->setContainer(pluginContainer); + // FIXME this may be excessively conservative. On the other hand // maybe I'm used to having an 8-core machine // Perhaps find the ideal thread count and subtract 2 or 3 @@ -521,7 +523,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _entityClipboard->createRootElement(); - _pluginContainer = new PluginContainerProxy(); #ifdef Q_OS_WIN installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif @@ -2035,9 +2036,9 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Return: if (isOption) { if (_window->isFullScreen()) { - _pluginContainer->unsetFullscreen(); + unsetFullscreen(); } else { - _pluginContainer->setFullscreen(nullptr); + setFullscreen(nullptr); } } else { Menu::getInstance()->triggerOption(MenuOption::AddressBar); @@ -2951,9 +2952,10 @@ void Application::loadSettings() { //DependencyManager::get()->setAutomaticLODAdjust(false); Menu::getInstance()->loadSettings(); - // If there is a preferred plugin, we probably messed it up with the menu settings, so fix it. auto pluginManager = PluginManager::getInstance(); + + auto plugins = pluginManager->getPreferredDisplayPlugins(); for (auto plugin : plugins) { auto menu = Menu::getInstance(); @@ -5190,6 +5192,7 @@ void Application::updateDisplayMode() { // FIXME probably excessive and useless context switching _offscreenContext->makeCurrent(); + qDebug() << "Application::updateDisplayMode()... line:" << __LINE__ << "about to call newDisplayPlugin->activate()"; bool active = newDisplayPlugin->activate(); if (!active) { @@ -5308,3 +5311,49 @@ void Application::showDesktop() { CompositorHelper& Application::getApplicationCompositor() const { return *DependencyManager::get(); } + + +// virtual functions required for PluginContainer +ui::Menu* Application::getPrimaryMenu() { + auto appMenu = _window->menuBar(); + auto uiMenu = dynamic_cast(appMenu); + return uiMenu; +} + +void Application::showDisplayPluginsTools(bool show) { + DependencyManager::get()->hmdTools(show); +} + +GLWidget* Application::getPrimaryWidget() { + return _glWidget; +} + +MainWindow* Application::getPrimaryWindow() { + return getWindow(); +} + +QOpenGLContext* Application::getPrimaryContext() { + return _glWidget->context()->contextHandle(); +} + +bool Application::makeRenderingContextCurrent() { + return _offscreenContext->makeCurrent(); +} + +void Application::releaseSceneTexture(const gpu::TexturePointer& texture) { + Q_ASSERT(QThread::currentThread() == thread()); + auto& framebufferMap = _lockedFramebufferMap; + Q_ASSERT(framebufferMap.contains(texture)); + auto framebufferPointer = framebufferMap[texture]; + framebufferMap.remove(texture); + auto framebufferCache = DependencyManager::get(); + framebufferCache->releaseFramebuffer(framebufferPointer); +} + +void Application::releaseOverlayTexture(const gpu::TexturePointer& texture) { + _applicationOverlay.releaseOverlay(texture); +} + +bool Application::isForeground() const { + return _isForeground && !_window->isMinimized(); +} diff --git a/interface/src/Application.h b/interface/src/Application.h index 6b6148be32..114ce27144 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -86,14 +87,32 @@ class Application; #endif #define qApp (static_cast(QCoreApplication::instance())) -class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, public AbstractUriHandler { +class Application : public QApplication, + public AbstractViewStateInterface, + public AbstractScriptingServicesInterface, + public AbstractUriHandler, + public PluginContainer { Q_OBJECT // TODO? Get rid of those friend class OctreePacketProcessor; - friend class PluginContainerProxy; public: + + // virtual functions required for PluginContainer + virtual ui::Menu* getPrimaryMenu() override; + virtual void requestReset() override { resetSensors(true); } + virtual void showDisplayPluginsTools(bool show) override; + virtual GLWidget* getPrimaryWidget() override; + virtual MainWindow* getPrimaryWindow() override; + virtual QOpenGLContext* getPrimaryContext() override; + virtual bool makeRenderingContextCurrent() override; + virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override; + virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override; + virtual bool isForeground() const override; + + virtual DisplayPluginPointer getActiveDisplayPlugin() const override; + enum Event { Present = DisplayPlugin::Present, Paint = Present + 1, @@ -163,7 +182,6 @@ public: Overlays& getOverlays() { return _overlays; } - bool isForeground() const { return _isForeground; } size_t getFrameCount() const { return _frameCount; } float getFps() const { return _frameCounter.rate(); } @@ -185,8 +203,6 @@ public: void setActiveDisplayPlugin(const QString& pluginName); - DisplayPluginPointer getActiveDisplayPlugin() const; - FileLogger* getLogger() const { return _logger; } glm::vec2 getViewportDimensions() const; diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp deleted file mode 100644 index b651a1520d..0000000000 --- a/interface/src/PluginContainerProxy.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "PluginContainerProxy.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "Application.h" -#include "MainWindow.h" -#include "GLCanvas.h" -#include "ui/DialogsManager.h" - -#include -#include - -PluginContainerProxy::PluginContainerProxy() { -} - -PluginContainerProxy::~PluginContainerProxy() { -} - -ui::Menu* PluginContainerProxy::getPrimaryMenu() { - auto appMenu = qApp->_window->menuBar(); - auto uiMenu = dynamic_cast(appMenu); - return uiMenu; -} - -bool PluginContainerProxy::isForeground() { - return qApp->isForeground() && !qApp->getWindow()->isMinimized(); -} - -void PluginContainerProxy::requestReset() { - // We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway. - qApp->resetSensors(true); -} - -void PluginContainerProxy::showDisplayPluginsTools(bool show) { - DependencyManager::get()->hmdTools(show); -} - -GLWidget* PluginContainerProxy::getPrimaryWidget() { - return qApp->_glWidget; -} - -MainWindow* PluginContainerProxy::getPrimaryWindow() { - return qApp->getWindow(); -} - -QOpenGLContext* PluginContainerProxy::getPrimaryContext() { - return qApp->_glWidget->context()->contextHandle(); -} - -const DisplayPluginPointer PluginContainerProxy::getActiveDisplayPlugin() const { - return qApp->getActiveDisplayPlugin(); -} - -bool PluginContainerProxy::makeRenderingContextCurrent() { - return qApp->_offscreenContext->makeCurrent(); -} - -void PluginContainerProxy::releaseSceneTexture(const gpu::TexturePointer& texture) { - Q_ASSERT(QThread::currentThread() == qApp->thread()); - auto& framebufferMap = qApp->_lockedFramebufferMap; - Q_ASSERT(framebufferMap.contains(texture)); - auto framebufferPointer = framebufferMap[texture]; - framebufferMap.remove(texture); - auto framebufferCache = DependencyManager::get(); - framebufferCache->releaseFramebuffer(framebufferPointer); -} - -void PluginContainerProxy::releaseOverlayTexture(const gpu::TexturePointer& texture) { - qApp->_applicationOverlay.releaseOverlay(texture); -} - diff --git a/interface/src/PluginContainerProxy.h b/interface/src/PluginContainerProxy.h deleted file mode 100644 index a04a1b2977..0000000000 --- a/interface/src/PluginContainerProxy.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#ifndef hifi_PluginContainerProxy_h -#define hifi_PluginContainerProxy_h - -#include -#include - -#include -#include - -class QActionGroup; - -class PluginContainerProxy : public QObject, PluginContainer { - Q_OBJECT - PluginContainerProxy(); - virtual ~PluginContainerProxy(); - virtual void showDisplayPluginsTools(bool show = true) override; - virtual void requestReset() override; - virtual bool makeRenderingContextCurrent() override; - virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override; - virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override; - virtual GLWidget* getPrimaryWidget() override; - virtual MainWindow* getPrimaryWindow() override; - virtual ui::Menu* getPrimaryMenu() override; - virtual QOpenGLContext* getPrimaryContext() override; - virtual bool isForeground() override; - virtual const DisplayPluginPointer getActiveDisplayPlugin() const override; - - friend class Application; - -}; - -#endif diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index f2d58d825e..fe08647074 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME display-plugins) setup_hifi_library(OpenGL) -link_hifi_libraries(shared plugins gl gpu-gl ui) +link_hifi_libraries(shared plugins ui-plugins gl gpu-gl ui) target_opengl() diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp index 4b8d957e5f..d068bef3b0 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp @@ -11,7 +11,7 @@ #include #include "DisplayPlugin.h" -#include +#include static Setting::Handle IPD_SCALE_HANDLE("hmd.ipdScale", 1.0f); diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 48dda1f73d..3bdb96bde3 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -13,8 +13,6 @@ #include #include -#include - const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop"); static const QString FULLSCREEN = "Fullscreen"; diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 3f642072a0..8ebbf4d74b 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -10,7 +10,6 @@ #include "NullDisplayPlugin.h" #include -#include const QString NullDisplayPlugin::NAME("NullDisplayPlugin"); diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index dfa4232a86..c8770393c0 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -7,9 +7,11 @@ // #pragma once +#include #include "DisplayPlugin.h" class NullDisplayPlugin : public DisplayPlugin { + ACCESS_PLUGIN_CONTAINER_MIXIN public: virtual ~NullDisplayPlugin() final {} diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index d34b698410..2128488718 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -22,12 +22,12 @@ #include #include #include -#include #include #include #include #include #include "CompositorHelper.h" +#include #if THREADED_PRESENT @@ -202,6 +202,7 @@ private: #endif + OpenGLDisplayPlugin::OpenGLDisplayPlugin() { _sceneTextureEscrow.setRecycler([this](const gpu::TexturePointer& texture){ cleanupForSceneTexture(texture); @@ -233,10 +234,11 @@ bool OpenGLDisplayPlugin::activate() { cursorData.hotSpot = vec2(0.5f); } } - + if (!_container) { + return false; + } _vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported(); - #if THREADED_PRESENT // Start the present thread if necessary QSharedPointer presentThread; @@ -272,7 +274,11 @@ bool OpenGLDisplayPlugin::activate() { _container->makeRenderingContextCurrent(); #endif - return DisplayPlugin::activate(); + if (isHmd() && (getHmdScreen() >= 0)) { + _container->showDisplayPluginsTools(); + } + + return Parent::activate(); } void OpenGLDisplayPlugin::deactivate() { @@ -288,7 +294,16 @@ void OpenGLDisplayPlugin::deactivate() { _container->makeRenderingContextCurrent(); #endif internalDeactivate(); - DisplayPlugin::deactivate(); + + _container->showDisplayPluginsTools(false); + if (!_container->currentDisplayActions().isEmpty()) { + auto menu = _container->getPrimaryMenu(); + foreach(auto itemInfo, _container->currentDisplayActions()) { + menu->removeMenuItem(itemInfo.first, itemInfo.second); + } + _container->currentDisplayActions().clear(); + } + Parent::deactivate(); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index c87ff1bc93..10362b8181 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -21,9 +21,14 @@ #include #include +#include + #define THREADED_PRESENT 1 class OpenGLDisplayPlugin : public DisplayPlugin { + + ACCESS_PLUGIN_CONTAINER_MIXIN + protected: using Mutex = std::mutex; using Lock = std::unique_lock; @@ -135,7 +140,9 @@ protected: BasicFramebufferWrapperPtr _compositeFramebuffer; bool _lockCurrentTexture { false }; + private: + using Parent = DisplayPlugin; ProgramPtr _activeProgram; }; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 4e594d89ed..b7739a7fb6 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index e6ceb7e376..b87f68231c 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -13,6 +13,8 @@ #include "../OpenGLDisplayPlugin.h" +#include + class HmdDisplayPlugin : public OpenGLDisplayPlugin { using Parent = OpenGLDisplayPlugin; public: diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp index 5f55841be1..be095ecd39 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp @@ -9,7 +9,6 @@ #include "SideBySideStereoDisplayPlugin.h" #include #include -#include #include #include "../CompositorHelper.h" diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index 6c6716c8fa..afb99e3174 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include "../CompositorHelper.h" diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index b81554511d..b0ea13843b 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers) +link_hifi_libraries(shared plugins ui-plugins controllers) GroupSources("src/input-plugins") diff --git a/libraries/plugins/src/plugins/DisplayPlugin.cpp b/libraries/plugins/src/plugins/DisplayPlugin.cpp index a217041f4e..747c72c08e 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.cpp +++ b/libraries/plugins/src/plugins/DisplayPlugin.cpp @@ -1,28 +1,6 @@ #include "DisplayPlugin.h" #include -#include - -#include "PluginContainer.h" - -bool DisplayPlugin::activate() { - if (isHmd() && (getHmdScreen() >= 0)) { - _container->showDisplayPluginsTools(); - } - return Parent::activate(); -} - -void DisplayPlugin::deactivate() { - _container->showDisplayPluginsTools(false); - if (!_container->currentDisplayActions().isEmpty()) { - auto menu = _container->getPrimaryMenu(); - foreach(auto itemInfo, _container->currentDisplayActions()) { - menu->removeMenuItem(itemInfo.first, itemInfo.second); - } - _container->currentDisplayActions().clear(); - } - Parent::deactivate(); -} int64_t DisplayPlugin::getPaintDelayUsecs() const { std::lock_guard lock(_paintDelayMutex); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 19f803e11e..837694372a 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -64,8 +64,6 @@ public: Present = QEvent::User + 1 }; - bool activate() override; - void deactivate() override; virtual bool isHmd() const { return false; } virtual int getHmdScreen() const { return -1; } /// By default, all HMDs are stereo diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 7c30f252c9..54f76b3482 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -9,10 +9,6 @@ QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); -void Plugin::setContainer(PluginContainer* container) { - _container = container; -} - bool Plugin::isSupported() const { return true; } void Plugin::init() {} diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index fb5bf0ba55..cb03f67bd6 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -14,6 +14,8 @@ #include "Forward.h" +#include + class Plugin : public QObject { public: /// \return human-readable name @@ -28,8 +30,11 @@ public: virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } virtual bool isSupported() const; - - void setContainer(PluginContainer* container); + + /// Some plugins may need access to the PluginContainer, if the individual plugin + /// needs access to this, they should override these methods and store their own + /// type safe version of the pointer to the container. + virtual void setContainer(void* container) { } /// Called when plugin is initially loaded, typically at application start virtual void init(); @@ -65,7 +70,5 @@ public: protected: bool _active { false }; - PluginContainer* _container { nullptr }; static QString UNKNOWN_PLUGIN_ID; - }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 7161132c5e..2692de931f 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -17,7 +17,6 @@ #include "RuntimePlugin.h" #include "DisplayPlugin.h" #include "InputPlugin.h" -#include "PluginContainer.h" PluginManager* PluginManager::getInstance() { @@ -133,10 +132,11 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } } } - auto& container = PluginContainer::getInstance(); for (auto plugin : displayPlugins) { - plugin->setContainer(&container); plugin->init(); + if (_container) { + plugin->setContainer(_container); + } } }); @@ -171,10 +171,11 @@ const InputPluginList& PluginManager::getInputPlugins() { } } - auto& container = PluginContainer::getInstance(); for (auto plugin : inputPlugins) { - plugin->setContainer(&container); plugin->init(); + if (_container) { + plugin->setContainer(_container); + } } }); return inputPlugins; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 2a94e6490b..b0aa13d2d0 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -26,4 +26,7 @@ public: void disableDisplays(const QStringList& displays); void disableInputs(const QStringList& inputs); void saveSettings(); + void setContainer(void* container) { _container = container; } +private: + void* _container { nullptr }; }; diff --git a/libraries/ui-plugins/CMakeLists.txt b/libraries/ui-plugins/CMakeLists.txt new file mode 100644 index 0000000000..9ce189b117 --- /dev/null +++ b/libraries/ui-plugins/CMakeLists.txt @@ -0,0 +1,3 @@ +set(TARGET_NAME ui-plugins) +setup_hifi_library(OpenGL) +link_hifi_libraries(shared plugins ui) diff --git a/libraries/plugins/src/plugins/PluginContainer.cpp b/libraries/ui-plugins/src/ui-plugins/PluginContainer.cpp similarity index 100% rename from libraries/plugins/src/plugins/PluginContainer.cpp rename to libraries/ui-plugins/src/ui-plugins/PluginContainer.cpp diff --git a/libraries/plugins/src/plugins/PluginContainer.h b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h similarity index 77% rename from libraries/plugins/src/plugins/PluginContainer.h rename to libraries/ui-plugins/src/ui-plugins/PluginContainer.h index e1d1a212e2..57c3c62704 100644 --- a/libraries/plugins/src/plugins/PluginContainer.h +++ b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h @@ -7,16 +7,18 @@ // #pragma once +#include #include #include #include +#include #include #include #include #include -#include "Forward.h" +#include class QAction; class GLWidget; @@ -63,8 +65,8 @@ public: virtual GLWidget* getPrimaryWidget() = 0; virtual MainWindow* getPrimaryWindow() = 0; virtual QOpenGLContext* getPrimaryContext() = 0; - virtual bool isForeground() = 0; - virtual const DisplayPluginPointer getActiveDisplayPlugin() const = 0; + virtual bool isForeground() const = 0; + virtual DisplayPluginPointer getActiveDisplayPlugin() const = 0; /// settings interface bool getBoolSetting(const QString& settingName, bool defaultValue); @@ -84,3 +86,12 @@ protected: std::map _exclusiveGroups; QRect _savedGeometry { 10, 120, 800, 600 }; }; + +/// Mixin this class to your class to get easy access to the PluginContainer +#define ACCESS_PLUGIN_CONTAINER_MIXIN \ +public: \ + virtual void setContainer(void* container) override { \ + _container = static_cast(container); \ + } \ +protected: \ + PluginContainer* _container { nullptr }; diff --git a/plugins/hifiSixense/CMakeLists.txt b/plugins/hifiSixense/CMakeLists.txt index 589b5b8964..f907d7865f 100644 --- a/plugins/hifiSixense/CMakeLists.txt +++ b/plugins/hifiSixense/CMakeLists.txt @@ -8,5 +8,5 @@ set(TARGET_NAME hifiSixense) setup_hifi_plugin(Script Qml Widgets) -link_hifi_libraries(shared controllers ui plugins input-plugins) +link_hifi_libraries(shared controllers ui plugins ui-plugins input-plugins) target_sixense() diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 9ea79a8b96..4faec959ea 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index 6aec9fd4ad..c9e8f5d4ad 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -17,6 +17,7 @@ #include #include +#include #include struct _sixenseControllerData; @@ -24,6 +25,7 @@ using SixenseControllerData = _sixenseControllerData; // Handles interaction with the Sixense SDK (e.g., Razer Hydra). class SixenseManager : public InputPlugin { + ACCESS_PLUGIN_CONTAINER_MIXIN Q_OBJECT public: // Plugin functions diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt index a91690ecdd..778be08dcf 100644 --- a/plugins/oculus/CMakeLists.txt +++ b/plugins/oculus/CMakeLists.txt @@ -13,7 +13,7 @@ if (WIN32) set(TARGET_NAME oculus) setup_hifi_plugin(Multimedia) - link_hifi_libraries(shared gl gpu controllers ui plugins display-plugins input-plugins audio-client networking) + link_hifi_libraries(shared gl gpu controllers ui plugins ui-plugins display-plugins input-plugins audio-client networking) include_hifi_library_headers(octree) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 9f0e76363b..128b980558 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include diff --git a/plugins/oculusLegacy/CMakeLists.txt b/plugins/oculusLegacy/CMakeLists.txt index a4e00013f1..c1f2c6249f 100644 --- a/plugins/oculusLegacy/CMakeLists.txt +++ b/plugins/oculusLegacy/CMakeLists.txt @@ -12,7 +12,7 @@ if (APPLE) set(TARGET_NAME oculusLegacy) setup_hifi_plugin() - link_hifi_libraries(shared gl gpu plugins ui display-plugins input-plugins) + link_hifi_libraries(shared gl gpu plugins ui ui-plugins display-plugins input-plugins) include_hifi_library_headers(octree) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 8e044fbc16..3b2c9808ab 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -26,7 +26,6 @@ #include #include -#include "plugins/PluginContainer.h" #include "OculusHelpers.h" using namespace oglplus; diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt index 1ba8d05b92..8263e87767 100644 --- a/plugins/openvr/CMakeLists.txt +++ b/plugins/openvr/CMakeLists.txt @@ -12,7 +12,7 @@ if (WIN32) set(TARGET_NAME openvr) setup_hifi_plugin(OpenGL Script Qml Widgets) link_hifi_libraries(shared gl networking controllers ui - plugins display-plugins input-plugins script-engine + plugins display-plugins ui-plugins input-plugins script-engine render-utils model gpu render model-networking fbx) include_hifi_library_headers(octree) diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 3e7e5abbf3..552a62514d 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include "OpenVrHelpers.h" diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index b862aacb06..88c76a97b8 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 3a2ef1573f..f3cd2b4a93 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -23,12 +23,14 @@ #include #include #include +#include namespace vr { class IVRSystem; } -class ViveControllerManager : public InputPlugin { +class ViveControllerManager : public InputPlugin { + ACCESS_PLUGIN_CONTAINER_MIXIN Q_OBJECT public: // Plugin functions diff --git a/tests/controllers/CMakeLists.txt b/tests/controllers/CMakeLists.txt index cf1152da02..3aac4db0a8 100644 --- a/tests/controllers/CMakeLists.txt +++ b/tests/controllers/CMakeLists.txt @@ -6,7 +6,7 @@ setup_hifi_project(Script Qml) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared gl script-engine plugins render-utils input-plugins display-plugins controllers) +link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers) if (WIN32) diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index 36ed566ea7..15b768bb36 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include #include @@ -90,8 +90,8 @@ public: virtual MainWindow* getPrimaryWindow() override { return nullptr; } virtual QOpenGLContext* getPrimaryContext() override { return nullptr; } virtual ui::Menu* getPrimaryMenu() override { return nullptr; } - virtual bool isForeground() override { return true; } - virtual const DisplayPluginPointer getActiveDisplayPlugin() const override { return DisplayPluginPointer(); } + virtual bool isForeground() const override { return true; } + virtual DisplayPluginPointer getActiveDisplayPlugin() const override { return DisplayPluginPointer(); } }; class MyControllerScriptingInterface : public controller::ScriptingInterface { From 160a5de271ccf15d1dd708611c1dc12f2211a912 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 21 Jun 2016 12:34:42 -0700 Subject: [PATCH 51/76] CR feedback --- interface/src/Application.cpp | 3 --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 2 ++ .../src/display-plugins/NullDisplayPlugin.cpp | 1 + .../src/display-plugins/NullDisplayPlugin.h | 2 -- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 1 + .../src/display-plugins/OpenGLDisplayPlugin.h | 4 ---- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 1 + .../src/display-plugins/hmd/HmdDisplayPlugin.h | 2 -- .../stereo/SideBySideStereoDisplayPlugin.cpp | 1 + .../display-plugins/stereo/StereoDisplayPlugin.cpp | 1 + libraries/plugins/src/plugins/Plugin.cpp | 4 ++++ libraries/plugins/src/plugins/Plugin.h | 11 ++++------- libraries/plugins/src/plugins/PluginManager.cpp | 8 ++------ libraries/plugins/src/plugins/PluginManager.h | 4 ++-- libraries/ui-plugins/src/ui-plugins/PluginContainer.h | 10 ---------- plugins/hifiSixense/src/SixenseManager.cpp | 1 + plugins/hifiSixense/src/SixenseManager.h | 2 -- .../oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 1 + plugins/openvr/src/OpenVrDisplayPlugin.cpp | 1 + plugins/openvr/src/ViveControllerManager.cpp | 1 + plugins/openvr/src/ViveControllerManager.h | 4 +--- 21 files changed, 24 insertions(+), 41 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index babcd877c4..f553b4bbdf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2954,8 +2954,6 @@ void Application::loadSettings() { Menu::getInstance()->loadSettings(); // If there is a preferred plugin, we probably messed it up with the menu settings, so fix it. auto pluginManager = PluginManager::getInstance(); - - auto plugins = pluginManager->getPreferredDisplayPlugins(); for (auto plugin : plugins) { auto menu = Menu::getInstance(); @@ -5192,7 +5190,6 @@ void Application::updateDisplayMode() { // FIXME probably excessive and useless context switching _offscreenContext->makeCurrent(); - qDebug() << "Application::updateDisplayMode()... line:" << __LINE__ << "about to call newDisplayPlugin->activate()"; bool active = newDisplayPlugin->activate(); if (!active) { diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 3bdb96bde3..f488a805c6 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -13,6 +13,8 @@ #include #include +#include + const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop"); static const QString FULLSCREEN = "Fullscreen"; diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 8ebbf4d74b..4fadbdb94b 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -10,6 +10,7 @@ #include "NullDisplayPlugin.h" #include +#include const QString NullDisplayPlugin::NAME("NullDisplayPlugin"); diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index c8770393c0..dfa4232a86 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -7,11 +7,9 @@ // #pragma once -#include #include "DisplayPlugin.h" class NullDisplayPlugin : public DisplayPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN public: virtual ~NullDisplayPlugin() final {} diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 2128488718..4bca48aeb0 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 10362b8181..aa3699584a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -21,14 +21,10 @@ #include #include -#include - #define THREADED_PRESENT 1 class OpenGLDisplayPlugin : public DisplayPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN - protected: using Mutex = std::mutex; using Lock = std::unique_lock; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index b7739a7fb6..b29348f646 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index b87f68231c..e6ceb7e376 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -13,8 +13,6 @@ #include "../OpenGLDisplayPlugin.h" -#include - class HmdDisplayPlugin : public OpenGLDisplayPlugin { using Parent = OpenGLDisplayPlugin; public: diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp index be095ecd39..5d9f812edf 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp @@ -9,6 +9,7 @@ #include "SideBySideStereoDisplayPlugin.h" #include #include +#include #include #include "../CompositorHelper.h" diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index afb99e3174..cfdfb1fc21 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include "../CompositorHelper.h" diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 54f76b3482..7c30f252c9 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -9,6 +9,10 @@ QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); +void Plugin::setContainer(PluginContainer* container) { + _container = container; +} + bool Plugin::isSupported() const { return true; } void Plugin::init() {} diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index cb03f67bd6..fb5bf0ba55 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -14,8 +14,6 @@ #include "Forward.h" -#include - class Plugin : public QObject { public: /// \return human-readable name @@ -30,11 +28,8 @@ public: virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } virtual bool isSupported() const; - - /// Some plugins may need access to the PluginContainer, if the individual plugin - /// needs access to this, they should override these methods and store their own - /// type safe version of the pointer to the container. - virtual void setContainer(void* container) { } + + void setContainer(PluginContainer* container); /// Called when plugin is initially loaded, typically at application start virtual void init(); @@ -70,5 +65,7 @@ public: protected: bool _active { false }; + PluginContainer* _container { nullptr }; static QString UNKNOWN_PLUGIN_ID; + }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 2692de931f..d5c860200a 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -133,10 +133,8 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } } for (auto plugin : displayPlugins) { + plugin->setContainer(_container); plugin->init(); - if (_container) { - plugin->setContainer(_container); - } } }); @@ -172,10 +170,8 @@ const InputPluginList& PluginManager::getInputPlugins() { } for (auto plugin : inputPlugins) { + plugin->setContainer(_container); plugin->init(); - if (_container) { - plugin->setContainer(_container); - } } }); return inputPlugins; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index b0aa13d2d0..7903bdd724 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -26,7 +26,7 @@ public: void disableDisplays(const QStringList& displays); void disableInputs(const QStringList& inputs); void saveSettings(); - void setContainer(void* container) { _container = container; } + void setContainer(PluginContainer* container) { _container = container; } private: - void* _container { nullptr }; + PluginContainer* _container { nullptr }; }; diff --git a/libraries/ui-plugins/src/ui-plugins/PluginContainer.h b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h index 57c3c62704..74ac834057 100644 --- a/libraries/ui-plugins/src/ui-plugins/PluginContainer.h +++ b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h @@ -7,12 +7,10 @@ // #pragma once -#include #include #include #include -#include #include #include #include @@ -87,11 +85,3 @@ protected: QRect _savedGeometry { 10, 120, 800, 600 }; }; -/// Mixin this class to your class to get easy access to the PluginContainer -#define ACCESS_PLUGIN_CONTAINER_MIXIN \ -public: \ - virtual void setContainer(void* container) override { \ - _container = static_cast(container); \ - } \ -protected: \ - PluginContainer* _container { nullptr }; diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 4faec959ea..566f879f69 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index c9e8f5d4ad..6aec9fd4ad 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -17,7 +17,6 @@ #include #include -#include #include struct _sixenseControllerData; @@ -25,7 +24,6 @@ using SixenseControllerData = _sixenseControllerData; // Handles interaction with the Sixense SDK (e.g., Razer Hydra). class SixenseManager : public InputPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN Q_OBJECT public: // Plugin functions diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 3b2c9808ab..4aadb890d5 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -26,6 +26,7 @@ #include #include +#include #include "OculusHelpers.h" using namespace oglplus; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 552a62514d..c5d3be25b2 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include "OpenVrHelpers.h" diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 88c76a97b8..12813dae93 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index f3cd2b4a93..3a2ef1573f 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -23,14 +23,12 @@ #include #include #include -#include namespace vr { class IVRSystem; } -class ViveControllerManager : public InputPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN +class ViveControllerManager : public InputPlugin { Q_OBJECT public: // Plugin functions From c8ead2ad048845e46f5d127c132c7239e7c4d011 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 13:28:15 -0700 Subject: [PATCH 52/76] conform to coding braces standard --- scripts/tutorials/getDomainMetadata.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 8c347a09ae..54c356ae7b 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -113,7 +113,9 @@ function displayMetadata(place, metadata) { } function clearMetadata() { - if (OVERLAY) { Overlays.deleteOverlay(OVERLAY); } + if (OVERLAY) { + Overlays.deleteOverlay(OVERLAY); + } } // Request JSON from a url, synchronously From 6c2c7f1eec2213affbcc82bf8f5ac32c6d2c0f74 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 13:28:40 -0700 Subject: [PATCH 53/76] Fix connected_device user activity event --- libraries/networking/src/UserActivityLogger.cpp | 15 +++++++++++++++ libraries/plugins/src/plugins/PluginManager.cpp | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 83c6eb304e..8b20420a34 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -125,6 +125,21 @@ void UserActivityLogger::changedDomain(QString domainURL) { } void UserActivityLogger::connectedDevice(QString typeOfDevice, QString deviceName) { + static QStringList DEVICE_BLACKLIST = { + "Desktop", + "NullDisplayPlugin", + "3D TV - Side by Side Stereo", + "3D TV - Interleaved", + + "Keyboard/Mouse", + "Neuron", + "SDL2" + }; + + if (DEVICE_BLACKLIST.contains(deviceName)) { + return; + } + const QString ACTION_NAME = "connected_device"; QJsonObject actionDetails; const QString TYPE_OF_DEVICE = "type_of_device"; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index eb6465aab2..86bdcfe818 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -14,6 +14,9 @@ #include #include +#include +#include + #include "RuntimePlugin.h" #include "DisplayPlugin.h" #include "InputPlugin.h" @@ -81,6 +84,7 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } auto& container = PluginContainer::getInstance(); for (auto plugin : displayPlugins) { + UserActivityLogger::getInstance().connectedDevice("display", plugin->getName()); plugin->setContainer(&container); plugin->init(); } @@ -117,6 +121,7 @@ const InputPluginList& PluginManager::getInputPlugins() { auto& container = PluginContainer::getInstance(); for (auto plugin : inputPlugins) { + UserActivityLogger::getInstance().connectedDevice("input", plugin->getName()); plugin->setContainer(&container); plugin->init(); } From 251e2137d33b285c6e3db9c10c1382cb8c240751 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 13:31:10 -0700 Subject: [PATCH 54/76] Remove old use of connectedDevice --- plugins/hifiSpacemouse/src/SpacemouseManager.cpp | 2 -- plugins/openvr/src/ViveControllerManager.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp index 3d9b93ff44..dc60fe4cbb 100644 --- a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp @@ -59,7 +59,6 @@ bool SpacemouseManager::activate() { if (instance->getDeviceID() == controller::Input::INVALID_DEVICE) { auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(instance); - UserActivityLogger::getInstance().connectedDevice("controller", NAME); } return true; } @@ -330,7 +329,6 @@ bool SpacemouseManager::RawInputEventFilter(void* msg, long* result) { auto userInputMapper = DependencyManager::get(); if (Is3dmouseAttached() && instance->getDeviceID() == controller::Input::INVALID_DEVICE) { userInputMapper->registerDevice(instance); - UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse"); } else if (!Is3dmouseAttached() && instance->getDeviceID() != controller::Input::INVALID_DEVICE) { userInputMapper->removeDevice(instance->getDeviceID()); diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 953501ccec..d3e1690155 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -234,7 +234,6 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu if (!_registeredWithInputMapper && _inputDevice->_trackedControllers > 0) { userInputMapper->registerDevice(_inputDevice); _registeredWithInputMapper = true; - UserActivityLogger::getInstance().connectedDevice("spatial_controller", "steamVR"); } } From 0ea9c5c26da41848f112d2fad62135aa073648a8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 13:32:17 -0700 Subject: [PATCH 55/76] Fix getMemoryInfo not returning false on non-Windows --- libraries/shared/src/SharedUtil.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index a6866fdc93..edb6fe437d 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -864,7 +864,9 @@ bool getMemoryInfo(MemoryInfo& info) { } info.processUsedMemoryBytes = pmc.PrivateUsage; info.processPeakUsedMemoryBytes = pmc.PeakPagefileUsage; -#endif return true; +#endif + + return false; } \ No newline at end of file From 9a17f5b439a49498377d48c77d069c5283331103 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 21 Jun 2016 14:12:27 -0700 Subject: [PATCH 56/76] update homebrew instructions --- BUILD_OSX.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 44f27d3d02..ab84bc4711 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -13,11 +13,11 @@ We no longer require install of qt5 via our [homebrew formulas repository](https Assuming you've installed OpenSSL or Qt 5 using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR and QT_CMAKE_PREFIX_PATH so CMake can find your installations. For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR: - export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2d_1 + export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2h_1/ For Qt 5.5.1 installed via homebrew, set QT_CMAKE_PREFIX_PATH as follows. - export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.5.1_2/lib/cmake + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt55/5.5.1/lib/cmake Not that these use the versions from homebrew formulae at the time of this writing, and the version in the path will likely change. From f3bad3a63b5df2f2622e539bb02ff2c6f17afa23 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 21 Jun 2016 12:43:02 -0700 Subject: [PATCH 57/76] Don't trigger keyboard on revealing the overlay layer --- interface/resources/qml/desktop/Desktop.qml | 5 ++++ plugins/openvr/src/OpenVrDisplayPlugin.cpp | 2 +- plugins/openvr/src/OpenVrHelpers.cpp | 28 +++++++++++++++++--- plugins/openvr/src/OpenVrHelpers.h | 3 ++- plugins/openvr/src/ViveControllerManager.cpp | 2 +- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 58d1cba1b8..9f10cfc64a 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -297,6 +297,9 @@ FocusScope { onPinnedChanged: { if (pinned) { + nullFocus.focus = true; + nullFocus.forceActiveFocus(); + // recalculate our non-pinned children hiddenChildren = d.findMatchingChildren(desktop, function(child){ return !d.isTopLevelWindow(child) && child.visible && !child.pinned; @@ -478,6 +481,8 @@ FocusScope { FocusHack { id: focusHack; } + FocusScope { id: nullFocus; } + Rectangle { id: focusDebugger; objectName: "focusDebugger" diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 9c4313dc13..4f81f711e3 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -267,7 +267,7 @@ void OpenVrDisplayPlugin::unsuppressKeyboard() { return; } if (1 == _keyboardSupressionCount.fetch_sub(1)) { - enableOpenVrKeyboard(); + enableOpenVrKeyboard(_container); } } diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 4f02c0384d..1bff0073f6 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include "../../interface/src/Menu.h" Q_DECLARE_LOGGING_CATEGORY(displayplugins) Q_LOGGING_CATEGORY(displayplugins, "hifi.plugins.display") @@ -91,7 +94,7 @@ void releaseOpenVrSystem() { static char textArray[8192]; -static QMetaObject::Connection _focusConnection, _focusTextConnection; +static QMetaObject::Connection _focusConnection, _focusTextConnection, _overlayMenuConnection; extern bool _openVrDisplayActive; static vr::IVROverlay* _overlay { nullptr }; static QObject* _keyboardFocusObject { nullptr }; @@ -99,7 +102,8 @@ static QString _existingText; static Qt::InputMethodHints _currentHints; extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; static bool _keyboardShown { false }; -static const uint32_t SHOW_KEYBOARD_DELAY_MS = 100; +static bool _overlayRevealed { false }; +static const uint32_t SHOW_KEYBOARD_DELAY_MS = 400; void showOpenVrKeyboard(bool show = true) { if (!_overlay) { @@ -175,13 +179,25 @@ void finishOpenVrKeyboardInput() { static const QString DEBUG_FLAG("HIFI_DISABLE_STEAM_VR_KEYBOARD"); bool disableSteamVrKeyboard = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); -void enableOpenVrKeyboard() { +void enableOpenVrKeyboard(PluginContainer* container) { if (disableSteamVrKeyboard) { return; } auto offscreenUi = DependencyManager::get(); _overlay = vr::VROverlay(); + + auto menu = container->getPrimaryMenu(); + auto action = menu->getActionForOption(MenuOption::Overlays); + + // When the overlays are revealed, suppress the keyboard from appearing on text focus for a tenth of a second. + _overlayMenuConnection = QObject::connect(action, &QAction::triggered, [action] { + if (action->isChecked()) { + _overlayRevealed = true; + QTimer::singleShot(100, [&] { _overlayRevealed = false; }); + } + }); + _focusConnection = QObject::connect(offscreenUi->getWindow(), &QQuickWindow::focusObjectChanged, [](QObject* object) { if (object != _keyboardFocusObject) { showOpenVrKeyboard(false); @@ -190,6 +206,11 @@ void enableOpenVrKeyboard() { _focusTextConnection = QObject::connect(offscreenUi.data(), &OffscreenUi::focusTextChanged, [](bool focusText) { if (_openVrDisplayActive) { + if (_overlayRevealed) { + // suppress at most one text focus event + _overlayRevealed = false; + return; + } showOpenVrKeyboard(focusText); } }); @@ -200,6 +221,7 @@ void disableOpenVrKeyboard() { if (disableSteamVrKeyboard) { return; } + QObject::disconnect(_overlayMenuConnection); QObject::disconnect(_focusTextConnection); QObject::disconnect(_focusConnection); } diff --git a/plugins/openvr/src/OpenVrHelpers.h b/plugins/openvr/src/OpenVrHelpers.h index 131db517ab..19c9cbfff5 100644 --- a/plugins/openvr/src/OpenVrHelpers.h +++ b/plugins/openvr/src/OpenVrHelpers.h @@ -13,6 +13,7 @@ #include #include +#include bool openVrSupported(); @@ -20,7 +21,7 @@ vr::IVRSystem* acquireOpenVrSystem(); void releaseOpenVrSystem(); void handleOpenVrEvents(); bool openVrQuitRequested(); -void enableOpenVrKeyboard(); +void enableOpenVrKeyboard(PluginContainer* container); void disableOpenVrKeyboard(); bool isOpenVrKeyboardShown(); diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 7f78ab8553..6c272d2a27 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -63,7 +63,7 @@ bool ViveControllerManager::activate() { } Q_ASSERT(_system); - enableOpenVrKeyboard(); + enableOpenVrKeyboard(_container); // OpenVR provides 3d mesh representations of the controllers // Disabled controller rendering code From f2f7e21eaf3b56b777a2819f0c2499b039b97bf8 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 21 Jun 2016 16:17:43 -0700 Subject: [PATCH 58/76] remove dead refereince to PluginContainer.h from space mouse --- plugins/hifiSpacemouse/src/SpacemouseManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp index 3d9b93ff44..0c29ced6f9 100644 --- a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp @@ -18,7 +18,6 @@ #include #include -#include #include const QString SpacemouseManager::NAME { "Spacemouse" }; From da71fcb57fdffadcc320ab7092f8e0318746b929 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 16:37:58 -0700 Subject: [PATCH 59/76] Update connected device detection implementation --- libraries/plugins/src/plugins/Plugin.h | 8 +++++++ .../plugins/src/plugins/PluginManager.cpp | 23 ++++++++++++++++++- plugins/hifiNeuron/src/NeuronPlugin.cpp | 2 ++ plugins/hifiSdl2/src/SDL2Manager.cpp | 2 ++ plugins/hifiSixense/src/SixenseManager.cpp | 6 +++++ plugins/oculus/src/OculusDisplayPlugin.cpp | 6 +++++ plugins/oculus/src/OculusDisplayPlugin.h | 2 ++ plugins/openvr/src/OpenVrDisplayPlugin.cpp | 6 +++++ plugins/openvr/src/OpenVrDisplayPlugin.h | 2 ++ 9 files changed, 56 insertions(+), 1 deletion(-) diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index fb5bf0ba55..0452c7fbfe 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -15,6 +15,7 @@ #include "Forward.h" class Plugin : public QObject { + Q_OBJECT public: /// \return human-readable name virtual const QString& getName() const = 0; @@ -63,6 +64,13 @@ public: virtual void saveSettings() const {} virtual void loadSettings() {} +signals: + // These signals should be emitted when a device is first known to be available. In some cases this will + // be in `init()`, in other cases, like Neuron, this isn't known until activation. + // SDL2 isn't a device itself, but can have 0+ subdevices. subdeviceConnected is used in this case. + void deviceConnected(QString pluginName) const; + void subdeviceConnected(QString pluginName, QString subdeviceName) const; + protected: bool _active { false }; PluginContainer* _container { nullptr }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 86bdcfe818..64d771da6a 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -69,6 +69,15 @@ static DisplayPluginList displayPlugins; const DisplayPluginList& PluginManager::getDisplayPlugins() { static std::once_flag once; + static auto deviceAddedCallback = [](QString deviceName) { + qDebug() << "Added device: " << deviceName; + UserActivityLogger::getInstance().connectedDevice("display", deviceName); + }; + static auto subdeviceAddedCallback = [](QString pluginName, QString deviceName) { + qDebug() << "Added subdevice: " << deviceName; + UserActivityLogger::getInstance().connectedDevice("display", pluginName + " | " + deviceName); + }; + std::call_once(once, [&] { // Grab the built in plugins displayPlugins = ::getDisplayPlugins(); @@ -84,7 +93,8 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } auto& container = PluginContainer::getInstance(); for (auto plugin : displayPlugins) { - UserActivityLogger::getInstance().connectedDevice("display", plugin->getName()); + connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback); + connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback); plugin->setContainer(&container); plugin->init(); } @@ -106,6 +116,15 @@ void PluginManager::disableDisplayPlugin(const QString& name) { const InputPluginList& PluginManager::getInputPlugins() { static InputPluginList inputPlugins; static std::once_flag once; + static auto deviceAddedCallback = [](QString deviceName) { + qDebug() << "Added device: " << deviceName; + UserActivityLogger::getInstance().connectedDevice("input", deviceName); + }; + static auto subdeviceAddedCallback = [](QString pluginName, QString deviceName) { + qDebug() << "Added subdevice: " << deviceName; + UserActivityLogger::getInstance().connectedDevice("input", pluginName + " | " + deviceName); + }; + std::call_once(once, [&] { inputPlugins = ::getInputPlugins(); @@ -122,6 +141,8 @@ const InputPluginList& PluginManager::getInputPlugins() { auto& container = PluginContainer::getInstance(); for (auto plugin : inputPlugins) { UserActivityLogger::getInstance().connectedDevice("input", plugin->getName()); + connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback); + connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback); plugin->setContainer(&container); plugin->init(); } diff --git a/plugins/hifiNeuron/src/NeuronPlugin.cpp b/plugins/hifiNeuron/src/NeuronPlugin.cpp index 0a4bc7f8d2..e41472a8c5 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.cpp +++ b/plugins/hifiNeuron/src/NeuronPlugin.cpp @@ -387,6 +387,8 @@ bool NeuronPlugin::activate() { } else { qCDebug(inputplugins) << "NeuronPlugin: success connecting to " << _serverAddress.c_str() << ":" << _serverPort; + emit deviceConnected(getName()); + BRRegisterAutoSyncParmeter(_socketRef, Cmd_CombinationMode); return true; } diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index 0bdb68f830..14a1b0fbac 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -66,6 +66,7 @@ void SDL2Manager::init() { auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(joystick); emit joystickAdded(joystick.get()); + emit subdeviceConnected(getName(), SDL_GameControllerName(controller)); } } } @@ -157,6 +158,7 @@ void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrati _openJoysticks[id] = joystick; userInputMapper->registerDevice(joystick); emit joystickAdded(joystick.get()); + emit subdeviceConnected(getName(), SDL_GameControllerName(controller)); } } else if (event.type == SDL_CONTROLLERDEVICEREMOVED) { if (_openJoysticks.contains(event.cdevice.which)) { diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 9ea79a8b96..0993f9d12f 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -137,6 +137,12 @@ void SixenseManager::setSixenseFilter(bool filter) { void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { BAIL_IF_NOT_LOADED + static bool sixenseHasBeenConnected { false }; + if (!sixenseHasBeenConnected && sixenseIsBaseConnected(0)) { + sixenseHasBeenConnected = true; + emit deviceConnected(getName()); + } + auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { _inputDevice->update(deltaTime, inputCalibrationData); diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 1006d69f06..2b2ec5bdb0 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -28,6 +28,12 @@ bool OculusDisplayPlugin::internalActivate() { return result; } +void OculusDisplayPlugin::init() { + Plugin::init(); + + emit deviceConnected(getName()); +} + void OculusDisplayPlugin::cycleDebugOutput() { if (_session) { currentDebugMode = static_cast((currentDebugMode + 1) % ovrPerfHud_Count); diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index d6cd6f6f3d..ed6e0d13ea 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -17,6 +17,8 @@ class OculusDisplayPlugin : public OculusBaseDisplayPlugin { public: const QString& getName() const override { return NAME; } + void init() override; + QString getPreferredAudioInDevice() const override; QString getPreferredAudioOutDevice() const override; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index fe406cc29a..f805132edd 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -41,6 +41,12 @@ bool OpenVrDisplayPlugin::isSupported() const { return openVrSupported(); } +void OpenVrDisplayPlugin::init() { + Plugin::init(); + + emit deviceConnected(getName()); +} + bool OpenVrDisplayPlugin::internalActivate() { _container->setIsOptionChecked(StandingHMDSensorMode, true); diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index fda5e37c2a..2e31bfa2c6 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -21,6 +21,8 @@ public: bool isSupported() const override; const QString& getName() const override { return NAME; } + void init() override; + float getTargetFrameRate() const override { return TARGET_RATE_OpenVr; } void customizeContext() override; From 310adb0f45758db8a2ea7050a5d2d1a9b903a8ba Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 16:42:39 -0700 Subject: [PATCH 60/76] Update spacemouse deviceConnected implementation --- plugins/hifiSpacemouse/src/SpacemouseManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp index dc60fe4cbb..b4c15e6571 100644 --- a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp @@ -855,7 +855,7 @@ void SpacemouseManager::init() { if (Is3dmouseAttached() && instance->getDeviceID() == controller::Input::INVALID_DEVICE) { auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(instance); - UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse"); + emit deviceConnected(getName()); } //let one axis be dominant //ConnexionClientControl(fConnexionClientID, kConnexionCtlSetSwitches, kConnexionSwitchDominant | kConnexionSwitchEnableAll, NULL); From 4e52521f8cd05d4a30a0cc219c119d9f1fc37d79 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 16:43:16 -0700 Subject: [PATCH 61/76] Update UserActivityLogger device blacklist --- libraries/networking/src/UserActivityLogger.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 8b20420a34..9a5f0541e5 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -131,9 +131,7 @@ void UserActivityLogger::connectedDevice(QString typeOfDevice, QString deviceNam "3D TV - Side by Side Stereo", "3D TV - Interleaved", - "Keyboard/Mouse", - "Neuron", - "SDL2" + "Keyboard/Mouse" }; if (DEVICE_BLACKLIST.contains(deviceName)) { From db8190ad4985fd43162119d5b97819f3d93c9440 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 21 Jun 2016 16:56:00 -0700 Subject: [PATCH 62/76] fix typo --- BUILD_OSX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD_OSX.md b/BUILD_OSX.md index ab84bc4711..1c9c5a9796 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -19,7 +19,7 @@ For Qt 5.5.1 installed via homebrew, set QT_CMAKE_PREFIX_PATH as follows. export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt55/5.5.1/lib/cmake -Not that these use the versions from homebrew formulae at the time of this writing, and the version in the path will likely change. +Note that these use the versions from homebrew formulae at the time of this writing, and the version in the path will likely change. ###Xcode If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. From 223f9bda2e6dcf92487ab4dac4cd3b44a762eef7 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 21 Jun 2016 17:03:49 -0700 Subject: [PATCH 63/76] gratuitous change to force things. --- scripts/system/controllers/handControllerPointer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index c94325d3c0..374be0d1a1 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -1,6 +1,6 @@ "use strict"; /*jslint vars: true, plusplus: true*/ -/*globals Script, Overlays, Controller, Reticle, HMD, Camera, Entities, MyAvatar, Settings, Menu, ScriptDiscoveryService, Window, Vec3, Quat, print */ +/*globals Script, Overlays, Controller, Reticle, HMD, Camera, Entities, MyAvatar, Settings, Menu, ScriptDiscoveryService, Window, Vec3, Quat, print*/ // // handControllerPointer.js From e03974181acca42ee1a333ded811e09b2b951709 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 17:13:47 -0700 Subject: [PATCH 64/76] reformat operating hours to [[open,close]] --- domain-server/src/DomainMetadata.cpp | 46 ++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index f18aa8c71b..c5048ea9d8 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -63,12 +63,16 @@ const QString DomainMetadata::Descriptors::Hours::CLOSE = "close"; DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { // set up the structure necessary for casting during parsing (see parseHours, esp.) _metadata[USERS] = QVariantMap {}; - _metadata[DESCRIPTORS] = QVariantMap { - { Descriptors::HOURS, QVariantMap { - { Descriptors::Hours::WEEKDAY, QVariantList { QVariantMap{} } }, - { Descriptors::Hours::WEEKEND, QVariantList { QVariantMap{} } } - } } - }; + _metadata[DESCRIPTORS] = QVariantMap { { + Descriptors::HOURS, QVariantMap { + { Descriptors::Hours::WEEKDAY, QVariantList { + QVariantList{ QVariant{}, QVariant{} } } + }, + { Descriptors::Hours::WEEKEND, QVariantList { + QVariantList{ QVariant{}, QVariant{} } } + } + } + } }; assert(dynamic_cast(domainServer)); DomainServer* server = static_cast(domainServer); @@ -96,33 +100,37 @@ QJsonObject DomainMetadata::get(const QString& group) { return QJsonObject::fromVariantMap(_metadata[group].toMap()); } +// merge delta into target +// target should be of the form [ OpenTime, CloseTime ], +// delta should be of the form [ { open: Time, close: Time } ] void parseHours(QVariant delta, QVariant& target) { using Hours = DomainMetadata::Descriptors::Hours; - // hours should be of the form [ { open: Time, close: Time } ] assert(target.canConvert()); auto& targetList = *static_cast(target.data()); // if/when multiple ranges are allowed, this list will need to be iterated - assert(targetList[0].canConvert()); - auto& targetMap = *static_cast(targetList[0].data()); + assert(targetList[0].canConvert()); + auto& hours = *static_cast(targetList[0].data()); - auto deltaMap = delta.toList()[0].toMap(); - if (deltaMap.isEmpty()) { + auto deltaHours = delta.toList()[0].toMap(); + if (deltaHours.isEmpty()) { return; } // merge delta into base - auto open = deltaMap.find(Hours::OPEN); - if (open != deltaMap.end()) { - targetMap[Hours::OPEN] = open.value(); + static const int OPEN_INDEX = 0; + static const int CLOSE_INDEX = 1; + auto open = deltaHours.find(Hours::OPEN); + if (open != deltaHours.end()) { + hours[OPEN_INDEX] = open.value(); } - assert(targetMap[Hours::OPEN].canConvert()); - auto close = deltaMap.find(Hours::CLOSE); - if (close != deltaMap.end()) { - targetMap[Hours::CLOSE] = close.value(); + assert(hours[OPEN_INDEX].canConvert()); + auto close = deltaHours.find(Hours::CLOSE); + if (close != deltaHours.end()) { + hours[CLOSE_INDEX] = close.value(); } - assert(targetMap[Hours::CLOSE].canConvert()); + assert(hours[CLOSE_INDEX].canConvert()); } void DomainMetadata::descriptorsChanged() { From 89c50ab3df3585094c8752e341305c82b8d11dd7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 21 Jun 2016 16:46:10 -0700 Subject: [PATCH 65/76] Update neuron archive in cmakelists --- cmake/externals/neuron/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/neuron/CMakeLists.txt b/cmake/externals/neuron/CMakeLists.txt index 6936725571..76dda8f8c5 100644 --- a/cmake/externals/neuron/CMakeLists.txt +++ b/cmake/externals/neuron/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME neuron) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(NEURON_URL "https://s3.amazonaws.com/hifi-public/dependencies/neuron_datareader_b.12.zip") -set(NEURON_URL_MD5 "0ab54ca04c9cc8094e0fa046c226e574") +set(NEURON_URL "https://s3.amazonaws.com/hifi-public/dependencies/neuron_datareader_b.12.2.zip") +set(NEURON_URL_MD5 "84273ad2200bf86a9279d1f412a822ca") ExternalProject_Add(${EXTERNAL_NAME} URL ${NEURON_URL} From a1844d8c19ab2d28ffc2870829bfc424c57aadb0 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 21 Jun 2016 17:36:41 -0700 Subject: [PATCH 66/76] Fix plugin include. (How did this build for me locally?) --- plugins/openvr/src/OpenVrHelpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 1bff0073f6..436cd7fc30 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include "../../interface/src/Menu.h" @@ -347,4 +347,4 @@ controller::Pose openVrControllerPoseToHandPose(bool isLeftHand, const mat4& mat result.velocity = linearVelocity + glm::cross(angularVelocity, position - extractTranslation(mat)); result.angularVelocity = angularVelocity; return result; -} \ No newline at end of file +} From a7f30ced29516864b4c8f94367c1b02c3e23e534 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Jun 2016 21:39:40 -0700 Subject: [PATCH 67/76] Fix infinite recursion in PluginManager --- libraries/plugins/src/plugins/PluginManager.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index fcd17eeb9a..29658eeb6b 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -145,8 +145,8 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } } for (auto plugin : displayPlugins) { - connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback); - connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback); + connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback, Qt::QueuedConnection); + connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback, Qt::QueuedConnection); plugin->setContainer(_container); plugin->init(); } @@ -193,9 +193,8 @@ const InputPluginList& PluginManager::getInputPlugins() { } for (auto plugin : inputPlugins) { - UserActivityLogger::getInstance().connectedDevice("input", plugin->getName()); - connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback); - connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback); + connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback, Qt::QueuedConnection); + connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback, Qt::QueuedConnection); plugin->setContainer(_container); plugin->init(); } From 1be30ccce9806ad8900ed97aa630e8f4a70cdde1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Jun 2016 08:24:50 -0700 Subject: [PATCH 68/76] Fix enabled_edit firing on disable --- scripts/system/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index bb24a3c7a4..c10f938bde 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -340,7 +340,6 @@ var toolBar = (function() { Messages.sendLocalMessage("edit-events", JSON.stringify({ enabled: active })); - UserActivityLogger.enabledEdit(); isActive = active; if (!isActive) { entityListTool.setVisible(false); @@ -350,6 +349,7 @@ var toolBar = (function() { selectionManager.clearSelections(); cameraManager.disable(); } else { + UserActivityLogger.enabledEdit(); hasShownPropertiesTool = false; entityListTool.setVisible(true); gridTool.setVisible(true); From 890de1bfea6569b8b569d012638a70641bc9a470 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Jun 2016 08:54:58 -0700 Subject: [PATCH 69/76] Add went-to user activity back in --- libraries/networking/src/AddressManager.cpp | 13 ++++++++++ .../networking/src/UserActivityLogger.cpp | 25 ++++++++++++++++++- libraries/networking/src/UserActivityLogger.h | 3 ++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 80989acd2c..df9b4094b0 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -23,6 +23,7 @@ #include "AddressManager.h" #include "NodeList.h" #include "NetworkLogging.h" +#include "UserActivityLogger.h" const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; @@ -130,6 +131,10 @@ const JSONCallbackParameters& AddressManager::apiCallbackParameters() { } bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { + static QString URL_TYPE_USER = "user"; + static QString URL_TYPE_DOMAIN_ID = "domain_id"; + static QString URL_TYPE_PLACE = "place"; + static QString URL_TYPE_NETWORK_ADDRESS = "network_address"; if (lookupUrl.scheme() == HIFI_URL_SCHEME) { qCDebug(networking) << "Trying to go to URL" << lookupUrl.toString(); @@ -147,6 +152,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { if (handleUsername(lookupUrl.authority())) { // handled a username for lookup + UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_USER, lookupUrl.toString()); + // in case we're failing to connect to where we thought this user was // store their username as previous lookup so we can refresh their location via API _previousLookup = lookupUrl; @@ -157,6 +164,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { if (handleNetworkAddress(lookupUrl.host() + (lookupUrl.port() == -1 ? "" : ":" + QString::number(lookupUrl.port())), trigger, hostChanged)) { + UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_NETWORK_ADDRESS, lookupUrl.toString()); + // a network address lookup clears the previous lookup since we don't expect to re-attempt it _previousLookup.clear(); @@ -174,6 +183,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // we may have a path that defines a relative viewpoint - if so we should jump to that now handlePath(path, trigger); } else if (handleDomainID(lookupUrl.host())){ + UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_DOMAIN_ID, lookupUrl.toString()); + // store this domain ID as the previous lookup in case we're failing to connect and want to refresh API info _previousLookup = lookupUrl; @@ -181,6 +192,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // try to look up the domain ID on the metaverse API attemptDomainIDLookup(lookupUrl.host(), lookupUrl.path(), trigger); } else { + UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_PLACE, lookupUrl.toString()); + // store this place name as the previous lookup in case we fail to connect and want to refresh API info _previousLookup = lookupUrl; diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 9a5f0541e5..eba4d31167 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -18,6 +18,7 @@ #include "UserActivityLogger.h" #include +#include "AddressManager.h" static const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; @@ -161,12 +162,34 @@ void UserActivityLogger::loadedScript(QString scriptName) { } -void UserActivityLogger::wentTo(QString destinationType, QString destinationName) { +void UserActivityLogger::wentTo(AddressManager::LookupTrigger lookupTrigger, QString destinationType, QString destinationName) { + // Only accept these types of triggers. Other triggers are usually used internally in AddressManager. + QString trigger; + switch (lookupTrigger) { + case AddressManager::UserInput: + trigger = "UserInput"; + break; + case AddressManager::Back: + trigger = "Back"; + break; + case AddressManager::Forward: + trigger = "Forward"; + break; + case AddressManager::StartupFromSettings: + trigger = "StartupFromSettings"; + break; + default: + return; + } + + const QString ACTION_NAME = "went_to"; QJsonObject actionDetails; + const QString TRIGGER_TYPE_KEY = "trigger"; const QString DESTINATION_TYPE_KEY = "destination_type"; const QString DESTINATION_NAME_KEY = "detination_name"; + actionDetails.insert(TRIGGER_TYPE_KEY, trigger); actionDetails.insert(DESTINATION_TYPE_KEY, destinationType); actionDetails.insert(DESTINATION_NAME_KEY, destinationName); diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index c2ab93db2f..b41960a8ad 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -20,6 +20,7 @@ #include #include +#include "AddressManager.h" class UserActivityLogger : public QObject { Q_OBJECT @@ -42,7 +43,7 @@ public slots: void changedDomain(QString domainURL); void connectedDevice(QString typeOfDevice, QString deviceName); void loadedScript(QString scriptName); - void wentTo(QString destinationType, QString destinationName); + void wentTo(AddressManager::LookupTrigger trigger, QString destinationType, QString destinationName); private slots: void requestError(QNetworkReply& errorReply); From 847685d2243bcf6dc50531f2b2788140925cfa7f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Jun 2016 09:06:59 -0700 Subject: [PATCH 70/76] Add tracking of away.js --- .../networking/src/UserActivityLoggerScriptingInterface.cpp | 4 ++++ .../networking/src/UserActivityLoggerScriptingInterface.h | 1 + scripts/system/away.js | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index 012a569639..8b22b8ff58 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -20,6 +20,10 @@ void UserActivityLoggerScriptingInterface::openedMarketplace() { logAction("opened_marketplace"); } +void UserActivityLoggerScriptingInterface::toggledAway(bool isAway) { + logAction("toggled_away", { { "is_away", isAway } }); +} + void UserActivityLoggerScriptingInterface::logAction(QString action, QJsonObject details) { QMetaObject::invokeMethod(&UserActivityLogger::getInstance(), "logAction", Q_ARG(QString, action), diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index cad24b1967..9d60d666e2 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -22,6 +22,7 @@ class UserActivityLoggerScriptingInterface : public QObject, public Dependency { public: Q_INVOKABLE void enabledEdit(); Q_INVOKABLE void openedMarketplace(); + Q_INVOKABLE void toggledAway(bool isAway); private: void logAction(QString action, QJsonObject details = {}); diff --git a/scripts/system/away.js b/scripts/system/away.js index 38b0f13c00..8f252cc449 100644 --- a/scripts/system/away.js +++ b/scripts/system/away.js @@ -158,6 +158,8 @@ function goAway() { return; } + UserActivityLogger.toggledAway(true); + isAway = true; print('going "away"'); wasMuted = AudioDevice.getMuted(); @@ -189,6 +191,9 @@ function goActive() { if (!isAway) { return; } + + UserActivityLogger.toggledAway(false); + isAway = false; print('going "active"'); if (!wasMuted) { From 2621add8e30b8a9d766c74f5eabdfe92acc14d64 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Jun 2016 09:17:28 -0700 Subject: [PATCH 71/76] Fix nearby_avatars not tracking --- interface/src/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 319da861dc..d20a62fc7b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1157,9 +1157,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(), NEARBY_AVATAR_RADIUS_METERS) - 1; if (nearbyAvatars != lastCountOfNearbyAvatars) { + lastCountOfNearbyAvatars = nearbyAvatars; UserActivityLogger::getInstance().logAction("nearby_avatars", { { "count", nearbyAvatars } }); } }); + checkNearbyAvatarsTimer->start(); // Track user activity event when we receive a mute packet auto onMutedByMixer = []() { From e4dbb5e61a8ff9fd69f9a78039bb8ec95eb51f61 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 22 Jun 2016 09:57:38 -0700 Subject: [PATCH 72/76] Make mouse reticle be perpendicular to head. --- .../display-plugins/src/display-plugins/CompositorHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index a17fe2fd49..032350a07c 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -425,7 +425,7 @@ glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const d = glm::normalize(overlaySurfacePoint); } reticlePosition = headPosition + (d * getReticleDepth()); - quat reticleOrientation = quat(vec3(-spherical.y, spherical.x, 0.0f)); + quat reticleOrientation = glm::quat_cast(_currentDisplayPlugin->getHeadPose()); vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize * getReticleDepth()); return glm::inverse(eyePose) * createMatFromScaleQuatAndPos(reticleScale, reticleOrientation, reticlePosition); } else { From 2233b5ba64f7c2339a802ccbb95dcc1fd831096c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Jun 2016 11:57:41 -0700 Subject: [PATCH 73/76] Add user activity tracking for OculusLegacyDisplayPlugin --- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 6 ++++++ plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 4aadb890d5..efd9cbec88 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -36,6 +36,12 @@ const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift"); OculusLegacyDisplayPlugin::OculusLegacyDisplayPlugin() { } +void OculusDisplayPlugin::init() { + Plugin::init(); + + emit deviceConnected(getName()); +} + void OculusLegacyDisplayPlugin::resetSensors() { ovrHmd_RecenterPose(_hmd); } diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 453a6f9168..6ffc1a7f44 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -23,6 +23,8 @@ public: bool isSupported() const override; const QString& getName() const override { return NAME; } + void init() override; + int getHmdScreen() const override; // Stereo specific methods From 9ff742c97c4c400a0eea97ed366389d8005843c9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Jun 2016 12:09:12 -0700 Subject: [PATCH 74/76] Fix typo --- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index efd9cbec88..f1a803ee19 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -36,7 +36,7 @@ const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift"); OculusLegacyDisplayPlugin::OculusLegacyDisplayPlugin() { } -void OculusDisplayPlugin::init() { +void OculusLegacyDisplayPlugin::init() { Plugin::init(); emit deviceConnected(getName()); From d3735322a5c9baa97312d4504069a476b18a16f3 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 22 Jun 2016 13:03:13 -0700 Subject: [PATCH 75/76] Whitespace. --- interface/src/scripting/ToolbarScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/ToolbarScriptingInterface.h b/interface/src/scripting/ToolbarScriptingInterface.h index d3706cb6e1..9379284e55 100644 --- a/interface/src/scripting/ToolbarScriptingInterface.h +++ b/interface/src/scripting/ToolbarScriptingInterface.h @@ -20,7 +20,7 @@ class ToolbarProxy; class ToolbarScriptingInterface : public QObject, public Dependency { Q_OBJECT public: - Q_INVOKABLE QObject* getToolbar(const QString& toolbarId); + Q_INVOKABLE QObject* getToolbar(const QString& toolbarId); }; #endif // hifi_ToolbarScriptingInterface_h From 581d87d6536b45867ea751369d5a3bd534948014 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 22 Jun 2016 16:40:10 -0700 Subject: [PATCH 76/76] feedback re magic numbers and variable name. --- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 11 ++++++----- plugins/openvr/src/OpenVrHelpers.cpp | 3 ++- scripts/system/controllers/handControllerGrab.js | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index dbf264179e..f1aa1edc81 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -420,8 +420,9 @@ bool HmdDisplayPlugin::setHandLaser(uint32_t hands, HandLaserMode mode, const ve } void HmdDisplayPlugin::compositeExtra() { - std::array handLasers; - std::array renderHandPoses; + const int NUMBER_OF_HANDS = 2; + std::array handLasers; + std::array renderHandPoses; Transform uiModelTransform; withPresentThreadLock([&] { handLasers = _handLasers; @@ -443,9 +444,9 @@ void HmdDisplayPlugin::compositeExtra() { using namespace oglplus; useProgram(_laserProgram); _laserGeometry->Use(); - std::array handLaserModelMatrices; + std::array handLaserModelMatrices; - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < NUMBER_OF_HANDS; ++i) { if (renderHandPoses[i] == identity) { continue; } @@ -485,7 +486,7 @@ void HmdDisplayPlugin::compositeExtra() { auto eyePose = _currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye); auto view = glm::inverse(eyePose); const auto& projection = _eyeProjections[eye]; - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < NUMBER_OF_HANDS; ++i) { if (handLaserModelMatrices[i] == identity) { continue; } diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 436cd7fc30..e71c8942d6 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -194,7 +194,8 @@ void enableOpenVrKeyboard(PluginContainer* container) { _overlayMenuConnection = QObject::connect(action, &QAction::triggered, [action] { if (action->isChecked()) { _overlayRevealed = true; - QTimer::singleShot(100, [&] { _overlayRevealed = false; }); + const int KEYBOARD_DELAY_MS = 100; + QTimer::singleShot(KEYBOARD_DELAY_MS, [&] { _overlayRevealed = false; }); } }); diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 39d85f1224..7706132c58 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -877,8 +877,8 @@ function MyController(hand) { // find entities near the avatar that might be equipable. var entities = Entities.findEntities(MyAvatar.position, HOTSPOT_DRAW_DISTANCE); - var i, l = entities.length; - for (i = 0; i < l; i++) { + var i, length = entities.length; + for (i = 0; i < length; i++) { var grabProps = Entities.getEntityProperties(entities[i], GRABBABLE_PROPERTIES); // does this entity have an attach point? var wearableData = getEntityCustomData("wearable", entities[i], undefined);