From c5ebb8a279b57feb981709568b61cbbec9bce836 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 28 Nov 2017 16:16:30 -0800 Subject: [PATCH 01/13] expose Window.getDeviceSize() --- interface/src/Application.cpp | 10 +++------- interface/src/Application.h | 4 +--- interface/src/Application_render.cpp | 3 +-- interface/src/scripting/WindowScriptingInterface.cpp | 4 ++++ interface/src/scripting/WindowScriptingInterface.h | 3 +++ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d7fcbf6467..7bb88b0445 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7075,11 +7075,11 @@ QRect Application::getRecommendedHUDRect() const { return result; } -QSize Application::getDeviceSize() const { +glm::vec2 Application::getDeviceSize() const { static const int MIN_SIZE = 1; - QSize result(MIN_SIZE, MIN_SIZE); + glm::vec2 result(MIN_SIZE); if (_displayPlugin) { - result = fromGlm(getActiveDisplayPlugin()->getRecommendedRenderSize()); + result = getActiveDisplayPlugin()->getRecommendedRenderSize(); } return result; } @@ -7098,10 +7098,6 @@ bool Application::hasFocus() const { return (QApplication::activeWindow() != nullptr); } -glm::vec2 Application::getViewportDimensions() const { - return toGlm(getDeviceSize()); -} - void Application::setMaxOctreePacketsPerSecond(int maxOctreePPS) { if (maxOctreePPS != _maxOctreePPS) { _maxOctreePPS = maxOctreePPS; diff --git a/interface/src/Application.h b/interface/src/Application.h index 5d9028f835..9542c5ccb6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -158,7 +158,7 @@ public: glm::uvec2 getUiSize() const; QRect getRecommendedHUDRect() const; - QSize getDeviceSize() const; + glm::vec2 getDeviceSize() const; bool hasFocus() const; void showCursor(const Cursor::Icon& cursor); @@ -228,8 +228,6 @@ public: FileLogger* getLogger() const { return _logger; } - glm::vec2 getViewportDimensions() const; - NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; } float getRenderResolutionScale() const; diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 44d9dfee03..1231e5834b 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -104,8 +104,7 @@ void Application::paintGL() { PerformanceTimer perfTimer("renderOverlay"); // NOTE: There is no batch associated with this renderArgs // the ApplicationOverlay class assumes it's viewport is setup to be the device size - QSize size = getDeviceSize(); - renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); + renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize()); _applicationOverlay.renderOverlay(&renderArgs); } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index c99e190d12..4b355653b6 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -176,6 +176,10 @@ bool WindowScriptingInterface::isPointOnDesktopWindow(QVariant point) { return offscreenUi->isPointOnDesktopWindow(point); } +glm::vec2 WindowScriptingInterface::getDeviceSize() const { + return qApp->getDeviceSize(); +} + /// Makes sure that the reticle is visible, use this in blocking forms that require a reticle and /// might be in same thread as a script that sets the reticle to invisible void WindowScriptingInterface::ensureReticleVisible() const { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 61aaec7bea..d223f95af4 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -12,6 +12,8 @@ #ifndef hifi_WindowScriptingInterface_h #define hifi_WindowScriptingInterface_h +#include + #include #include #include @@ -73,6 +75,7 @@ public slots: bool isPhysicsEnabled(); bool setDisplayTexture(const QString& name); bool isPointOnDesktopWindow(QVariant point); + glm::vec2 getDeviceSize() const; int openMessageBox(QString title, QString text, int buttons, int defaultButton); void updateMessageBox(int id, QString title, QString text, int buttons, int defaultButton); From 4334bf8222935f8e4de987929d3aaa6251b1ee3e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 5 Dec 2017 13:09:09 -0800 Subject: [PATCH 02/13] Add data tracking for purchase and rez --- .../qml/hifi/commerce/checkout/Checkout.qml | 19 ++++++++++++++ .../hifi/commerce/purchases/PurchasedItem.qml | 6 +++++ .../UserActivityLoggerScriptingInterface.cpp | 25 +++++++++++++++++++ .../UserActivityLoggerScriptingInterface.h | 3 +++ 4 files changed, 53 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 6c4e020694..7d3c6e3f12 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -79,10 +79,23 @@ Rectangle { if (result.status !== 'success') { failureErrorText.text = result.message; root.activeView = "checkoutFailure"; + var data = { + "marketplaceID": root.itemId, + "cost": root.itemPrice, + "firstPurchaseOfThisItem": !root.alreadyOwned, + "errorDetails": result.message + } + UserActivityLogger.logAction("commercePurchaseFailure", data); } else { root.itemHref = result.data.download_url; root.isWearable = result.data.categories.indexOf("Wearables") > -1; root.activeView = "checkoutSuccess"; + var data = { + "marketplaceID": root.itemId, + "cost": root.itemPrice, + "firstPurchaseOfThisItem": !root.alreadyOwned + } + UserActivityLogger.logAction("commercePurchaseSuccess", data); } } @@ -599,6 +612,12 @@ Rectangle { sendToScript({method: 'checkout_rezClicked', itemHref: root.itemHref, isWearable: root.isWearable}); rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); + var data = { + "marketplaceID": root.itemId, + "source": "checkout", + "type": root.isWearable ? "rez" : "wear" + } + UserActivityLogger.logAction("commerceEntityRezzed", data); } } RalewaySemiBold { diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 15ebada0c4..17e5b21562 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -349,6 +349,12 @@ Item { sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, isWearable: root.isWearable}); rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); + var data = { + "marketplaceID": root.itemId, + "source": "purchases", + "type": root.isWearable ? "rez" : "wear" + } + UserActivityLogger.logAction("commerceEntityRezzed", data); } style: ButtonStyle { diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index 61f2071c5f..f9d8decfa6 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -88,3 +88,28 @@ void UserActivityLoggerScriptingInterface::doLogAction(QString action, QJsonObje Q_ARG(QString, action), Q_ARG(QJsonObject, details)); } + +void UserActivityLoggerScriptingInterface::commercePurchaseSuccess(QString marketplaceID, int cost, bool firstPurchaseOfThisItem) { + QJsonObject payload; + payload["marketplaceID"] = marketplaceID; + payload["cost"] = cost; + payload["firstPurchaseOfThisItem"] = firstPurchaseOfThisItem; + doLogAction("commercePurchaseSuccess", payload); +} + +void UserActivityLoggerScriptingInterface::commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails) { + QJsonObject payload; + payload["marketplaceID"] = marketplaceID; + payload["cost"] = cost; + payload["firstPurchaseOfThisItem"] = firstPurchaseOfThisItem; + payload["errorDetails"] = errorDetails; + doLogAction("commercePurchaseFailure", payload); +} + +void UserActivityLoggerScriptingInterface::commerceEntityRezzed(QString marketplaceID, QString source, QString type) { + QJsonObject payload; + payload["marketplaceID"] = marketplaceID; + payload["source"] = source; + payload["type"] = type; + doLogAction("commerceEntityRezzed", payload); +} diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index 885f637a62..37d3ab4c12 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -33,6 +33,9 @@ public: Q_INVOKABLE void bubbleToggled(bool newValue); Q_INVOKABLE void bubbleActivated(); Q_INVOKABLE void logAction(QString action, QVariantMap details = QVariantMap{}); + Q_INVOKABLE void commercePurchaseSuccess(QString marketplaceID, int cost, bool firstPurchaseOfThisItem); + Q_INVOKABLE void commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails); + Q_INVOKABLE void commerceEntityRezzed(QString marketplaceID, QString source, QString type); private: void doLogAction(QString action, QJsonObject details = {}); }; From 668f6d50b5040855f9b6eba4b952762d8c624706 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 5 Dec 2017 14:13:48 -0800 Subject: [PATCH 03/13] Add data tracking for wallet setup --- .../qml/hifi/commerce/wallet/Wallet.qml | 10 +++++++ .../qml/hifi/commerce/wallet/WalletSetup.qml | 22 ++++++++++++++ .../UserActivityLoggerScriptingInterface.cpp | 29 +++++++++++++++++++ .../UserActivityLoggerScriptingInterface.h | 3 ++ 4 files changed, 64 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 71a73e31db..3578485a01 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -48,6 +48,16 @@ Rectangle { if (root.activeView !== "walletSetup") { root.activeView = "walletSetup"; commerce.resetLocalWalletOnly(); + var timestamp = new Date(); + walletSetup.startingTimestamp = timestamp; + var data = { + "timestamp": timestamp, + "setupAttemptID": guid(), + "setupFlowVersion": walletSetup.setupFlowVersion, + "referrer": walletSetup.referrer, + "currentDomain": (AddressManager.placename || AddressManager.hostname || '') + (AddressManager.pathname ? AddressManager.pathname.match(/\/[^\/]+/)[0] : '') + } + UserActivityLogger.logAction("commerceWalletSetupStarted", data); } } else if (walletStatus === 2) { if (root.activeView !== "passphraseModal") { diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml index 8de831ef75..773407cf8a 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml @@ -31,6 +31,9 @@ Item { property bool hasShownSecurityImageTip: false; property string referrer; property string keyFilePath; + property date startingTimestamp; + readonly property int setupFlowVersion: 1; + readonly property var setupStepNames: [ "Setup Prompt", "Security Image Selection", "Passphrase Selection", "Private Keys Ready" ]; Image { anchors.fill: parent; @@ -67,6 +70,18 @@ Item { anchors.fill: parent; } + onActiveViewChanged: { + var timestamp = new Date(); + var currentStepNumber = root.activeView.substring(5); + var data = { + "timestamp": timestamp, + "secondsElapsed": (root.startingTimestamp - timestamp), + "currentStepNumber": currentStepNumber, + "currentStepName": root.setupStepNames[currentStepNumber] + } + UserActivityLogger.logAction("commerceWalletSetupProgress", data); + } + // // TITLE BAR START // @@ -730,6 +745,13 @@ Item { root.visible = false; root.hasShownSecurityImageTip = false; sendSignalToWallet({method: 'walletSetup_finished', referrer: root.referrer ? root.referrer : ""}); + + var timestamp = new Date(); + var data = { + "timestamp": timestamp, + "secondsToComplete": (root.startingTimestamp - timestamp) + } + UserActivityLogger.logAction("commerceWalletSetupFinished", data); } } } diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index f9d8decfa6..ba24d8dcbe 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -113,3 +113,32 @@ void UserActivityLoggerScriptingInterface::commerceEntityRezzed(QString marketpl payload["type"] = type; doLogAction("commerceEntityRezzed", payload); } + +void UserActivityLoggerScriptingInterface::commerceWalletSetupStarted(float timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain) { + QJsonObject payload; + payload["timestamp"] = timestamp; + payload["setupAttemptID"] = setupAttemptID; + payload["setupFlowVersion"] = setupFlowVersion; + payload["referrer"] = referrer; + payload["currentDomain"] = currentDomain; + qDebug() << "ZRF" << payload; + //doLogAction("commerceWalletSetupStarted", payload); +} + +void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(float timestamp, float secondsElapsed, int currentStepNumber, QString currentStepName) { + QJsonObject payload; + payload["timestamp"] = timestamp; + payload["secondsElapsed"] = secondsElapsed; + payload["currentStepNumber"] = currentStepNumber; + payload["currentStepName"] = currentStepName; + qDebug() << "ZRF" << payload; + //doLogAction("commerceWalletSetupProgress", payload); +} + +void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(float timestamp, float secondsToComplete) { + QJsonObject payload; + payload["timestamp"] = timestamp; + payload["secondsToComplete"] = secondsToComplete; + qDebug() << "ZRF" << payload; + //doLogAction("commerceWalletSetupFinished", payload); +} diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index 37d3ab4c12..3e8002e0aa 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -36,6 +36,9 @@ public: Q_INVOKABLE void commercePurchaseSuccess(QString marketplaceID, int cost, bool firstPurchaseOfThisItem); Q_INVOKABLE void commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails); Q_INVOKABLE void commerceEntityRezzed(QString marketplaceID, QString source, QString type); + Q_INVOKABLE void commerceWalletSetupStarted(float timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain); + Q_INVOKABLE void commerceWalletSetupProgress(float timestamp, float secondsElapsed, int currentStepNumber, QString currentStepName); + Q_INVOKABLE void commerceWalletSetupFinished(float timestamp, float secondsToComplete); private: void doLogAction(QString action, QJsonObject details = {}); }; From 7521e4870e82c943eb1afa55eb707ef82640461a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 5 Dec 2017 14:56:47 -0800 Subject: [PATCH 04/13] Bugfixes --- .../qml/hifi/commerce/checkout/Checkout.qml | 22 ++---------- .../hifi/commerce/purchases/PurchasedItem.qml | 7 +--- .../qml/hifi/commerce/wallet/Help.qml | 34 ++++++++++++++++++- .../qml/hifi/commerce/wallet/Wallet.qml | 26 +++++++++----- .../qml/hifi/commerce/wallet/WalletSetup.qml | 14 ++------ .../UserActivityLoggerScriptingInterface.cpp | 6 ++-- .../UserActivityLoggerScriptingInterface.h | 6 ++-- scripts/system/marketplaces/marketplaces.js | 1 + 8 files changed, 64 insertions(+), 52 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 7d3c6e3f12..c8a63a4d2d 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -79,23 +79,12 @@ Rectangle { if (result.status !== 'success') { failureErrorText.text = result.message; root.activeView = "checkoutFailure"; - var data = { - "marketplaceID": root.itemId, - "cost": root.itemPrice, - "firstPurchaseOfThisItem": !root.alreadyOwned, - "errorDetails": result.message - } - UserActivityLogger.logAction("commercePurchaseFailure", data); + UserActivityLogger.commercePurchaseFailure(root.itemId, root.itemPrice, !root.alreadyOwned, result.message); } else { root.itemHref = result.data.download_url; root.isWearable = result.data.categories.indexOf("Wearables") > -1; root.activeView = "checkoutSuccess"; - var data = { - "marketplaceID": root.itemId, - "cost": root.itemPrice, - "firstPurchaseOfThisItem": !root.alreadyOwned - } - UserActivityLogger.logAction("commercePurchaseSuccess", data); + UserActivityLogger.commercePurchaseSuccess(root.itemId, root.itemPrice, !root.alreadyOwned); } } @@ -612,12 +601,7 @@ Rectangle { sendToScript({method: 'checkout_rezClicked', itemHref: root.itemHref, isWearable: root.isWearable}); rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); - var data = { - "marketplaceID": root.itemId, - "source": "checkout", - "type": root.isWearable ? "rez" : "wear" - } - UserActivityLogger.logAction("commerceEntityRezzed", data); + UserActivityLogger.commerceEntityRezzed(root.itemId, "checkout", root.isWearable ? "rez" : "wear"); } } RalewaySemiBold { diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 17e5b21562..f7913e5b1e 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -349,12 +349,7 @@ Item { sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, isWearable: root.isWearable}); rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); - var data = { - "marketplaceID": root.itemId, - "source": "purchases", - "type": root.isWearable ? "rez" : "wear" - } - UserActivityLogger.logAction("commerceEntityRezzed", data); + UserActivityLogger.commerceEntityRezzed(root.itemId, "purchases", root.isWearable ? "rez" : "wear"); } style: ButtonStyle { diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index ebba2b87c6..8cccb10533 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -55,6 +55,38 @@ Item { // Style color: hifi.colors.blueHighlight; } + + HifiControlsUit.Button { + id: clearCachedPassphraseButton; + visible: root.showDebugButtons; + color: hifi.buttons.black; + colorScheme: hifi.colorSchemes.dark; + anchors.top: parent.top; + anchors.left: helpTitleText.right; + anchors.leftMargin: 20; + height: 40; + width: 150; + text: "DBG: Clear Pass"; + onClicked: { + commerce.setPassphrase(""); + sendSignalToWallet({method: 'passphraseReset'}); + } + } + HifiControlsUit.Button { + id: resetButton; + visible: root.showDebugButtons; + color: hifi.buttons.red; + colorScheme: hifi.colorSchemes.dark; + anchors.top: clearCachedPassphraseButton.top; + anchors.left: clearCachedPassphraseButton.right; + height: 40; + width: 150; + text: "DBG: RST Wallet"; + onClicked: { + commerce.reset(); + sendSignalToWallet({method: 'walletReset'}); + } + } ListModel { id: helpModel; @@ -147,7 +179,7 @@ Item { text: model.isExpanded ? "-" : "+"; // Anchors anchors.top: parent.top; - anchors.topMargin: model.isExpanded ? -9 : 0; + anchors.topMargin: model.isExpanded ?9 : 0; anchors.bottom: parent.bottom; anchors.left: parent.left; width: 60; diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 3578485a01..d7e4536fed 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -50,14 +50,8 @@ Rectangle { commerce.resetLocalWalletOnly(); var timestamp = new Date(); walletSetup.startingTimestamp = timestamp; - var data = { - "timestamp": timestamp, - "setupAttemptID": guid(), - "setupFlowVersion": walletSetup.setupFlowVersion, - "referrer": walletSetup.referrer, - "currentDomain": (AddressManager.placename || AddressManager.hostname || '') + (AddressManager.pathname ? AddressManager.pathname.match(/\/[^\/]+/)[0] : '') - } - UserActivityLogger.logAction("commerceWalletSetupStarted", data); + UserActivityLogger.commerceWalletSetupStarted(timestamp, generateUUID(), walletSetup.setupFlowVersion, walletSetup.referrer ? walletSetup.referrer : "wallet app", + (AddressManager.placename || AddressManager.hostname || '') + (AddressManager.pathname ? AddressManager.pathname.match(/\/[^\/]+/)[0] : '')); } } else if (walletStatus === 2) { if (root.activeView !== "passphraseModal") { @@ -711,12 +705,28 @@ Rectangle { case 'updateWalletReferrer': walletSetup.referrer = message.referrer; break; + case 'inspectionCertificate_resetCert': + // NOP + break; default: console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); } } signal sendToScript(var message); + // generateUUID() taken from: + // https://stackoverflow.com/a/8809472 + function generateUUID() { // Public Domain/MIT + var d = new Date().getTime(); + if (typeof performance !== 'undefined' && typeof performance.now === 'function'){ + d += performance.now(); //use high-precision timer if available + } + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = (d + Math.random() * 16) % 16 | 0; + d = Math.floor(d / 16); + return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); + } // // FUNCTION DEFINITIONS END // diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml index 773407cf8a..9bb578f7d6 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml @@ -73,13 +73,7 @@ Item { onActiveViewChanged: { var timestamp = new Date(); var currentStepNumber = root.activeView.substring(5); - var data = { - "timestamp": timestamp, - "secondsElapsed": (root.startingTimestamp - timestamp), - "currentStepNumber": currentStepNumber, - "currentStepName": root.setupStepNames[currentStepNumber] - } - UserActivityLogger.logAction("commerceWalletSetupProgress", data); + UserActivityLogger.commerceWalletSetupProgress(timestamp, Math.round((timestamp - root.startingTimestamp)/1000), currentStepNumber, root.setupStepNames[currentStepNumber - 1]); } // @@ -747,11 +741,7 @@ Item { sendSignalToWallet({method: 'walletSetup_finished', referrer: root.referrer ? root.referrer : ""}); var timestamp = new Date(); - var data = { - "timestamp": timestamp, - "secondsToComplete": (root.startingTimestamp - timestamp) - } - UserActivityLogger.logAction("commerceWalletSetupFinished", data); + UserActivityLogger.commerceWalletSetupFinished(timestamp, Math.round((timestamp - root.startingTimestamp)/1000)); } } } diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index ba24d8dcbe..79fa7dad0f 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -114,7 +114,7 @@ void UserActivityLoggerScriptingInterface::commerceEntityRezzed(QString marketpl doLogAction("commerceEntityRezzed", payload); } -void UserActivityLoggerScriptingInterface::commerceWalletSetupStarted(float timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain) { +void UserActivityLoggerScriptingInterface::commerceWalletSetupStarted(int timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain) { QJsonObject payload; payload["timestamp"] = timestamp; payload["setupAttemptID"] = setupAttemptID; @@ -125,7 +125,7 @@ void UserActivityLoggerScriptingInterface::commerceWalletSetupStarted(float time //doLogAction("commerceWalletSetupStarted", payload); } -void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(float timestamp, float secondsElapsed, int currentStepNumber, QString currentStepName) { +void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(int timestamp, int secondsElapsed, int currentStepNumber, QString currentStepName) { QJsonObject payload; payload["timestamp"] = timestamp; payload["secondsElapsed"] = secondsElapsed; @@ -135,7 +135,7 @@ void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(float tim //doLogAction("commerceWalletSetupProgress", payload); } -void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(float timestamp, float secondsToComplete) { +void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(int timestamp, int secondsToComplete) { QJsonObject payload; payload["timestamp"] = timestamp; payload["secondsToComplete"] = secondsToComplete; diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index 3e8002e0aa..aafbbb7df0 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -36,9 +36,9 @@ public: Q_INVOKABLE void commercePurchaseSuccess(QString marketplaceID, int cost, bool firstPurchaseOfThisItem); Q_INVOKABLE void commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails); Q_INVOKABLE void commerceEntityRezzed(QString marketplaceID, QString source, QString type); - Q_INVOKABLE void commerceWalletSetupStarted(float timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain); - Q_INVOKABLE void commerceWalletSetupProgress(float timestamp, float secondsElapsed, int currentStepNumber, QString currentStepName); - Q_INVOKABLE void commerceWalletSetupFinished(float timestamp, float secondsToComplete); + Q_INVOKABLE void commerceWalletSetupStarted(int timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain); + Q_INVOKABLE void commerceWalletSetupProgress(int timestamp, int secondsElapsed, int currentStepNumber, QString currentStepName); + Q_INVOKABLE void commerceWalletSetupFinished(int timestamp, int secondsToComplete); private: void doLogAction(QString action, QJsonObject details = {}); }; diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 646e5452df..24b2947bcf 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -399,6 +399,7 @@ referrer: "purchases" }); openWallet(); + break; case 'checkout_walletNotSetUp': wireEventBridge(true); tablet.sendToQml({ From c807fc80e3a0a24c1831a0f53a7685f013e82423 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 5 Dec 2017 15:25:05 -0800 Subject: [PATCH 05/13] Add marketplace cta referrer --- .../resources/qml/hifi/commerce/wallet/Wallet.qml | 2 +- scripts/system/marketplaces/marketplaces.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index d7e4536fed..22cec52b48 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -177,7 +177,7 @@ Rectangle { Connections { onSendSignalToWallet: { if (msg.method === 'walletSetup_finished') { - if (msg.referrer === '') { + if (msg.referrer === '' || msg.referrer === 'marketplace cta') { root.activeView = "initialize"; commerce.getWalletStatus(); } else if (msg.referrer === 'purchases') { diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 24b2947bcf..cfb0f4cc8e 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -110,8 +110,9 @@ var filterText; // Used for updating Purchases QML function onScreenChanged(type, url) { onMarketplaceScreen = type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1; - onCommerceScreen = type === "QML" && (url.indexOf(MARKETPLACE_CHECKOUT_QML_PATH_BASE) !== -1 || url === MARKETPLACE_PURCHASES_QML_PATH || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1); - wireEventBridge(onCommerceScreen); + onCommerceScreen = type === "QML" && (url.indexOf(MARKETPLACE_CHECKOUT_QML_PATH_BASE) !== -1 || url === MARKETPLACE_PURCHASES_QML_PATH + || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1 || url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1); + wireEventBridge(onMarketplaceScreen || onCommerceScreen); if (url === MARKETPLACE_PURCHASES_QML_PATH) { tablet.sendToQml({ @@ -322,6 +323,11 @@ } else if (parsedJsonMessage.type === "LOGIN") { openLoginWindow(); } else if (parsedJsonMessage.type === "WALLET_SETUP") { + wireEventBridge(true); + tablet.sendToQml({ + method: 'updateWalletReferrer', + referrer: "marketplace cta" + }); openWallet(); } else if (parsedJsonMessage.type === "MY_ITEMS") { referrerURL = MARKETPLACE_URL_INITIAL; From 902064ed373c271eac433d8508bbfe382881538c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 5 Dec 2017 15:26:55 -0800 Subject: [PATCH 06/13] Cleanup debug stuff --- .../qml/hifi/commerce/wallet/Help.qml | 34 +------------------ .../UserActivityLoggerScriptingInterface.cpp | 9 ++--- 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index 8cccb10533..ebba2b87c6 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -55,38 +55,6 @@ Item { // Style color: hifi.colors.blueHighlight; } - - HifiControlsUit.Button { - id: clearCachedPassphraseButton; - visible: root.showDebugButtons; - color: hifi.buttons.black; - colorScheme: hifi.colorSchemes.dark; - anchors.top: parent.top; - anchors.left: helpTitleText.right; - anchors.leftMargin: 20; - height: 40; - width: 150; - text: "DBG: Clear Pass"; - onClicked: { - commerce.setPassphrase(""); - sendSignalToWallet({method: 'passphraseReset'}); - } - } - HifiControlsUit.Button { - id: resetButton; - visible: root.showDebugButtons; - color: hifi.buttons.red; - colorScheme: hifi.colorSchemes.dark; - anchors.top: clearCachedPassphraseButton.top; - anchors.left: clearCachedPassphraseButton.right; - height: 40; - width: 150; - text: "DBG: RST Wallet"; - onClicked: { - commerce.reset(); - sendSignalToWallet({method: 'walletReset'}); - } - } ListModel { id: helpModel; @@ -179,7 +147,7 @@ Item { text: model.isExpanded ? "-" : "+"; // Anchors anchors.top: parent.top; - anchors.topMargin: model.isExpanded ?9 : 0; + anchors.topMargin: model.isExpanded ? -9 : 0; anchors.bottom: parent.bottom; anchors.left: parent.left; width: 60; diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index 79fa7dad0f..b58537f8ef 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -121,8 +121,7 @@ void UserActivityLoggerScriptingInterface::commerceWalletSetupStarted(int timest payload["setupFlowVersion"] = setupFlowVersion; payload["referrer"] = referrer; payload["currentDomain"] = currentDomain; - qDebug() << "ZRF" << payload; - //doLogAction("commerceWalletSetupStarted", payload); + doLogAction("commerceWalletSetupStarted", payload); } void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(int timestamp, int secondsElapsed, int currentStepNumber, QString currentStepName) { @@ -131,14 +130,12 @@ void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(int times payload["secondsElapsed"] = secondsElapsed; payload["currentStepNumber"] = currentStepNumber; payload["currentStepName"] = currentStepName; - qDebug() << "ZRF" << payload; - //doLogAction("commerceWalletSetupProgress", payload); + doLogAction("commerceWalletSetupProgress", payload); } void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(int timestamp, int secondsToComplete) { QJsonObject payload; payload["timestamp"] = timestamp; payload["secondsToComplete"] = secondsToComplete; - qDebug() << "ZRF" << payload; - //doLogAction("commerceWalletSetupFinished", payload); + doLogAction("commerceWalletSetupFinished", payload); } From 3183a1a8b983dcf79ef7d7fd5657c92831f4b01c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 5 Dec 2017 16:48:30 -0800 Subject: [PATCH 07/13] Add setupAttemptID to every step (thanks Dave) --- interface/resources/qml/hifi/commerce/wallet/Wallet.qml | 3 ++- .../resources/qml/hifi/commerce/wallet/WalletSetup.qml | 6 ++++-- .../networking/src/UserActivityLoggerScriptingInterface.cpp | 6 ++++-- .../networking/src/UserActivityLoggerScriptingInterface.h | 4 ++-- scripts/system/marketplaces/marketplaces.js | 5 +++-- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 22cec52b48..ac05bf7c84 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -50,7 +50,8 @@ Rectangle { commerce.resetLocalWalletOnly(); var timestamp = new Date(); walletSetup.startingTimestamp = timestamp; - UserActivityLogger.commerceWalletSetupStarted(timestamp, generateUUID(), walletSetup.setupFlowVersion, walletSetup.referrer ? walletSetup.referrer : "wallet app", + walletSetup.setupAttemptID = generateUUID(); + UserActivityLogger.commerceWalletSetupStarted(timestamp, setupAttemptID, walletSetup.setupFlowVersion, walletSetup.referrer ? walletSetup.referrer : "wallet app", (AddressManager.placename || AddressManager.hostname || '') + (AddressManager.pathname ? AddressManager.pathname.match(/\/[^\/]+/)[0] : '')); } } else if (walletStatus === 2) { diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml index 9bb578f7d6..d7859d2800 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml @@ -32,6 +32,7 @@ Item { property string referrer; property string keyFilePath; property date startingTimestamp; + property string setupAttemptID; readonly property int setupFlowVersion: 1; readonly property var setupStepNames: [ "Setup Prompt", "Security Image Selection", "Passphrase Selection", "Private Keys Ready" ]; @@ -73,7 +74,8 @@ Item { onActiveViewChanged: { var timestamp = new Date(); var currentStepNumber = root.activeView.substring(5); - UserActivityLogger.commerceWalletSetupProgress(timestamp, Math.round((timestamp - root.startingTimestamp)/1000), currentStepNumber, root.setupStepNames[currentStepNumber - 1]); + UserActivityLogger.commerceWalletSetupProgress(timestamp, root.setupAttemptID, + Math.round((timestamp - root.startingTimestamp)/1000), currentStepNumber, root.setupStepNames[currentStepNumber - 1]); } // @@ -741,7 +743,7 @@ Item { sendSignalToWallet({method: 'walletSetup_finished', referrer: root.referrer ? root.referrer : ""}); var timestamp = new Date(); - UserActivityLogger.commerceWalletSetupFinished(timestamp, Math.round((timestamp - root.startingTimestamp)/1000)); + UserActivityLogger.commerceWalletSetupFinished(timestamp, setupAttemptID, Math.round((timestamp - root.startingTimestamp)/1000)); } } } diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index b58537f8ef..0965c9834f 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -124,18 +124,20 @@ void UserActivityLoggerScriptingInterface::commerceWalletSetupStarted(int timest doLogAction("commerceWalletSetupStarted", payload); } -void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(int timestamp, int secondsElapsed, int currentStepNumber, QString currentStepName) { +void UserActivityLoggerScriptingInterface::commerceWalletSetupProgress(int timestamp, QString setupAttemptID, int secondsElapsed, int currentStepNumber, QString currentStepName) { QJsonObject payload; payload["timestamp"] = timestamp; + payload["setupAttemptID"] = setupAttemptID; payload["secondsElapsed"] = secondsElapsed; payload["currentStepNumber"] = currentStepNumber; payload["currentStepName"] = currentStepName; doLogAction("commerceWalletSetupProgress", payload); } -void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(int timestamp, int secondsToComplete) { +void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(int timestamp, QString setupAttemptID, int secondsToComplete) { QJsonObject payload; payload["timestamp"] = timestamp; + payload["setupAttemptID"] = setupAttemptID; payload["secondsToComplete"] = secondsToComplete; doLogAction("commerceWalletSetupFinished", payload); } diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index aafbbb7df0..e71723f03c 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -37,8 +37,8 @@ public: Q_INVOKABLE void commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails); Q_INVOKABLE void commerceEntityRezzed(QString marketplaceID, QString source, QString type); Q_INVOKABLE void commerceWalletSetupStarted(int timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain); - Q_INVOKABLE void commerceWalletSetupProgress(int timestamp, int secondsElapsed, int currentStepNumber, QString currentStepName); - Q_INVOKABLE void commerceWalletSetupFinished(int timestamp, int secondsToComplete); + Q_INVOKABLE void commerceWalletSetupProgress(int timestamp, QString setupAttemptID, int secondsElapsed, int currentStepNumber, QString currentStepName); + Q_INVOKABLE void commerceWalletSetupFinished(int timestamp, QString setupAttemptID, int secondsToComplete); private: void doLogAction(QString action, QJsonObject details = {}); }; diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index cfb0f4cc8e..1893c2d097 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -110,8 +110,9 @@ var filterText; // Used for updating Purchases QML function onScreenChanged(type, url) { onMarketplaceScreen = type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1; + onWalletScreen = url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1; onCommerceScreen = type === "QML" && (url.indexOf(MARKETPLACE_CHECKOUT_QML_PATH_BASE) !== -1 || url === MARKETPLACE_PURCHASES_QML_PATH - || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1 || url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1); + || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1 || onWalletScreen); wireEventBridge(onMarketplaceScreen || onCommerceScreen); if (url === MARKETPLACE_PURCHASES_QML_PATH) { @@ -123,7 +124,7 @@ } // for toolbar mode: change button to active when window is first openend, false otherwise. - marketplaceButton.editProperties({ isActive: onMarketplaceScreen || onCommerceScreen }); + marketplaceButton.editProperties({ isActive: (onMarketplaceScreen || onCommerceScreen) && !onWalletScreen }); if (type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1) { ContextOverlay.isInMarketplaceInspectionMode = true; } else { From c329a58c1468363a592b9a59c6dddbccaa529b3d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 6 Dec 2017 11:26:34 -0800 Subject: [PATCH 08/13] ignore vcredist when performing fixup_bundle --- cmake/templates/FixupBundlePostBuild.cmake.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/templates/FixupBundlePostBuild.cmake.in b/cmake/templates/FixupBundlePostBuild.cmake.in index d4726884c2..57379bb48b 100644 --- a/cmake/templates/FixupBundlePostBuild.cmake.in +++ b/cmake/templates/FixupBundlePostBuild.cmake.in @@ -45,5 +45,4 @@ else() endif() file(GLOB EXTRA_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}") -fixup_bundle("${BUNDLE_EXECUTABLE}" "${EXTRA_PLUGINS}" "@FIXUP_LIBS@") - +fixup_bundle("${BUNDLE_EXECUTABLE}" "${EXTRA_PLUGINS}" "@FIXUP_LIBS@" IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe") From 008b4285f5a2ca9e4f63c26a57861e3a4ba32586 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 6 Dec 2017 11:35:14 -0800 Subject: [PATCH 09/13] don't use cmake sys library install, grab vcredist as external --- cmake/externals/vcredist/CMakeLists.txt | 21 +++++++++++++++++++++ cmake/macros/GenerateInstallers.cmake | 5 ----- 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 cmake/externals/vcredist/CMakeLists.txt diff --git a/cmake/externals/vcredist/CMakeLists.txt b/cmake/externals/vcredist/CMakeLists.txt new file mode 100644 index 0000000000..ac242cf451 --- /dev/null +++ b/cmake/externals/vcredist/CMakeLists.txt @@ -0,0 +1,21 @@ +if (WIN32) + set(EXTERNAL_NAME vcredist) + string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + + include(ExternalProject) + ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://go.microsoft.com/fwlink/?LinkId=746572 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + ) + + # Hide this external target (for ide users) + set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") + + ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + + set(${EXTERNAL_NAME_UPPER}_PATH ${SOURCE_DIR} CACHE FILEPATH "Location of VC Redistributable") +endif() diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 6c131168d5..20ab32bf62 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -29,10 +29,6 @@ macro(GENERATE_INSTALLERS) if (WIN32) - # Do not install the Visual Studio C runtime libraries. The installer will do this automatically - set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE) - - include(InstallRequiredSystemLibraries) set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico") # install and reference the Add/Remove icon @@ -84,4 +80,3 @@ macro(GENERATE_INSTALLERS) include(CPack) endmacro() - From 99b5b8942a24a3c94bac4f9719beda03b04e013f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 6 Dec 2017 12:08:18 -0800 Subject: [PATCH 10/13] add file download command to install step --- cmake/externals/vcredist/CMakeLists.txt | 21 --------------------- cmake/macros/GenerateInstallers.cmake | 4 ++++ 2 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 cmake/externals/vcredist/CMakeLists.txt diff --git a/cmake/externals/vcredist/CMakeLists.txt b/cmake/externals/vcredist/CMakeLists.txt deleted file mode 100644 index ac242cf451..0000000000 --- a/cmake/externals/vcredist/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -if (WIN32) - set(EXTERNAL_NAME vcredist) - string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) - - include(ExternalProject) - ExternalProject_Add( - ${EXTERNAL_NAME} - URL https://go.microsoft.com/fwlink/?LinkId=746572 - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - LOG_DOWNLOAD 1 - ) - - # Hide this external target (for ide users) - set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") - - ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) - - set(${EXTERNAL_NAME_UPPER}_PATH ${SOURCE_DIR} CACHE FILEPATH "Location of VC Redistributable") -endif() diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 20ab32bf62..702636dd01 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -45,6 +45,10 @@ macro(GENERATE_INSTALLERS) set(_UNINSTALLER_HEADER_BAD_PATH "${HF_CMAKE_DIR}/installer/uninstaller-header.bmp") set(UNINSTALLER_HEADER_IMAGE "") fix_path_for_nsis(${_UNINSTALLER_HEADER_BAD_PATH} UNINSTALLER_HEADER_IMAGE) + + # grab the latest VC redist (2017) and add it to the installer, our NSIS template + # will call it during the install + install(CODE "file(DOWNLOAD https://go.microsoft.com/fwlink/?LinkId=746572 \"\${CMAKE_INSTALL_PREFIX}/vcredist_x64.exe\")") elseif (APPLE) # produce a drag and drop DMG on OS X set(CPACK_GENERATOR "DragNDrop") From 5f3b148baaefd327890504c11d584373633da317 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 6 Dec 2017 13:01:23 -0800 Subject: [PATCH 11/13] Fix marketplace icon incorrectly appearing active --- scripts/system/marketplaces/marketplaces.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 1893c2d097..80ef79a543 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -112,8 +112,8 @@ onMarketplaceScreen = type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1; onWalletScreen = url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1; onCommerceScreen = type === "QML" && (url.indexOf(MARKETPLACE_CHECKOUT_QML_PATH_BASE) !== -1 || url === MARKETPLACE_PURCHASES_QML_PATH - || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1 || onWalletScreen); - wireEventBridge(onMarketplaceScreen || onCommerceScreen); + || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1); + wireEventBridge(onMarketplaceScreen || onCommerceScreen || onWalletScreen); if (url === MARKETPLACE_PURCHASES_QML_PATH) { tablet.sendToQml({ From e626ca3ccde903681977e6390f8f9c73ecbe11e6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 3 Dec 2017 13:40:00 -0800 Subject: [PATCH 12/13] Working on scene threading optimizations --- libraries/render/src/render/Scene.cpp | 162 ++++++++++++++++++++------ libraries/render/src/render/Scene.h | 14 ++- 2 files changed, 137 insertions(+), 39 deletions(-) diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 88e25b6d27..508cd6cefb 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -32,23 +32,23 @@ void Transaction::removeItem(ItemID id) { } void Transaction::addTransitionToItem(ItemID id, Transition::Type transition, ItemID boundId) { - _addedTransitions.emplace_back(TransitionAdd{ id, transition, boundId }); + _addedTransitions.emplace_back(id, transition, boundId); } void Transaction::removeTransitionFromItem(ItemID id) { - _addedTransitions.emplace_back(TransitionAdd{ id, Transition::NONE, render::Item::INVALID_ITEM_ID }); + _addedTransitions.emplace_back(id, Transition::NONE, render::Item::INVALID_ITEM_ID); } void Transaction::reApplyTransitionToItem(ItemID id) { - _reAppliedTransitions.emplace_back(TransitionReApply{ id }); + _reAppliedTransitions.emplace_back(id); } void Transaction::queryTransitionOnItem(ItemID id, TransitionQueryFunc func) { - _queriedTransitions.emplace_back(TransitionQuery{ id, func }); + _queriedTransitions.emplace_back(id, func); } void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) { - _updatedItems.emplace_back(Update{ id, functor }); + _updatedItems.emplace_back(id, functor); } void Transaction::resetSelection(const Selection& selection) { @@ -56,28 +56,122 @@ void Transaction::resetSelection(const Selection& selection) { } void Transaction::resetSelectionHighlight(const std::string& selectionName, const HighlightStyle& style) { - _highlightResets.emplace_back(HighlightReset{ selectionName, style }); + _highlightResets.emplace_back(selectionName, style ); } void Transaction::removeHighlightFromSelection(const std::string& selectionName) { _highlightRemoves.emplace_back(selectionName); } -void Transaction::querySelectionHighlight(const std::string& selectionName, SelectionHighlightQueryFunc func) { - _highlightQueries.emplace_back(HighlightQuery{ selectionName, func }); +void Transaction::querySelectionHighlight(const std::string& selectionName, const SelectionHighlightQueryFunc& func) { + _highlightQueries.emplace_back(selectionName, func); +} + +void Transaction::reserve(const std::vector& transactionContainer) { + size_t resetItemsCount = 0; + size_t removedItemsCount = 0; + size_t updatedItemsCount = 0; + size_t resetSelectionsCount = 0; + size_t addedTransitionsCount = 0; + size_t queriedTransitionsCount = 0; + size_t reAppliedTransitionsCount = 0; + size_t highlightResetsCount = 0; + size_t highlightRemovesCount = 0; + size_t highlightQueriesCount = 0; + + for (const auto& transaction : transactionContainer) { + resetItemsCount += transaction._resetItems.size(); + removedItemsCount += transaction._removedItems.size(); + updatedItemsCount += transaction._updatedItems.size(); + resetSelectionsCount += transaction._resetSelections.size(); + addedTransitionsCount += transaction._addedTransitions.size(); + queriedTransitionsCount += transaction._queriedTransitions.size(); + reAppliedTransitionsCount += transaction._reAppliedTransitions.size(); + highlightResetsCount += transaction._highlightResets.size(); + highlightRemovesCount += transaction._highlightRemoves.size(); + highlightQueriesCount += transaction._highlightQueries.size(); + } + + _resetItems.reserve(resetItemsCount); + _removedItems.reserve(removedItemsCount); + _updatedItems.reserve(updatedItemsCount); + _resetSelections.reserve(resetSelectionsCount); + _addedTransitions.reserve(addedTransitionsCount); + _queriedTransitions.reserve(queriedTransitionsCount); + _reAppliedTransitions.reserve(reAppliedTransitionsCount); + _highlightResets.reserve(highlightResetsCount); + _highlightRemoves.reserve(highlightRemovesCount); + _highlightQueries.reserve(highlightQueriesCount); +} + +void Transaction::merge(const std::vector& transactionContainer) { + reserve(transactionContainer); + for (const auto& transaction : transactionContainer) { + merge(transaction); + } +} + + +void Transaction::merge(std::vector&& transactionContainer) { + reserve(transactionContainer); + auto begin = std::make_move_iterator(transactionContainer.begin()); + auto end = std::make_move_iterator(transactionContainer.end()); + for (auto itr = begin; itr != end; ++itr) { + merge(*itr); + } + transactionContainer.clear(); +} + + +template +void moveElements(T& target, T& source) { + target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.begin())); + source.clear(); +} + +template +void copyElements(T& target, const T& source) { + target.insert(target.end(), source.begin(), source.begin()); +} + + +void Transaction::merge(Transaction&& transaction) { + moveElements(_resetItems, transaction._resetItems); + moveElements(_removedItems, transaction._removedItems); + moveElements(_updatedItems, transaction._updatedItems); + moveElements(_resetSelections, transaction._resetSelections); + moveElements(_addedTransitions, transaction._addedTransitions); + moveElements(_queriedTransitions, transaction._queriedTransitions); + moveElements(_reAppliedTransitions, transaction._reAppliedTransitions); + moveElements(_highlightResets, transaction._highlightResets); + moveElements(_highlightRemoves, transaction._highlightRemoves); + moveElements(_highlightQueries, transaction._highlightQueries); } void Transaction::merge(const Transaction& transaction) { - _resetItems.insert(_resetItems.end(), transaction._resetItems.begin(), transaction._resetItems.end()); - _removedItems.insert(_removedItems.end(), transaction._removedItems.begin(), transaction._removedItems.end()); - _updatedItems.insert(_updatedItems.end(), transaction._updatedItems.begin(), transaction._updatedItems.end()); - _resetSelections.insert(_resetSelections.end(), transaction._resetSelections.begin(), transaction._resetSelections.end()); - _addedTransitions.insert(_addedTransitions.end(), transaction._addedTransitions.begin(), transaction._addedTransitions.end()); - _queriedTransitions.insert(_queriedTransitions.end(), transaction._queriedTransitions.begin(), transaction._queriedTransitions.end()); - _reAppliedTransitions.insert(_reAppliedTransitions.end(), transaction._reAppliedTransitions.begin(), transaction._reAppliedTransitions.end()); - _highlightResets.insert(_highlightResets.end(), transaction._highlightResets.begin(), transaction._highlightResets.end()); - _highlightRemoves.insert(_highlightRemoves.end(), transaction._highlightRemoves.begin(), transaction._highlightRemoves.end()); - _highlightQueries.insert(_highlightQueries.end(), transaction._highlightQueries.begin(), transaction._highlightQueries.end()); + copyElements(_resetItems, transaction._resetItems); + copyElements(_removedItems, transaction._removedItems); + copyElements(_updatedItems, transaction._updatedItems); + copyElements(_resetSelections, transaction._resetSelections); + copyElements(_addedTransitions, transaction._addedTransitions); + copyElements(_queriedTransitions, transaction._queriedTransitions); + copyElements(_reAppliedTransitions, transaction._reAppliedTransitions); + copyElements(_highlightResets, transaction._highlightResets); + copyElements(_highlightRemoves, transaction._highlightRemoves); + copyElements(_highlightQueries, transaction._highlightQueries); +} + +void Transaction::clear() { + _resetItems.clear(); + _removedItems.clear(); + _updatedItems.clear(); + _resetSelections.clear(); + _addedTransitions.clear(); + _queriedTransitions.clear(); + _reAppliedTransitions.clear(); + _highlightResets.clear(); + _highlightRemoves.clear(); + _highlightQueries.clear(); } @@ -102,54 +196,50 @@ bool Scene::isAllocatedID(const ItemID& id) const { /// Enqueue change batch to the scene void Scene::enqueueTransaction(const Transaction& transaction) { - _transactionQueueMutex.lock(); - _transactionQueue.push(transaction); - _transactionQueueMutex.unlock(); + std::unique_lock lock(_transactionQueueMutex); + _transactionQueue.emplace_back(transaction); } -void consolidateTransaction(TransactionQueue& queue, Transaction& singleBatch) { - while (!queue.empty()) { - const auto& transaction = queue.front(); - singleBatch.merge(transaction); - queue.pop(); - }; +void Scene::enqueueTransaction(Transaction&& transaction) { + std::unique_lock lock(_transactionQueueMutex); + _transactionQueue.emplace_back(std::move(transaction)); } uint32_t Scene::enqueueFrame() { PROFILE_RANGE(render, __FUNCTION__); - Transaction consolidatedTransaction; + TransactionQueue localTransactionQueue; { std::unique_lock lock(_transactionQueueMutex); - consolidateTransaction(_transactionQueue, consolidatedTransaction); + localTransactionQueue.swap(_transactionQueue); } - uint32_t frameNumber = 0; + Transaction consolidatedTransaction; + consolidatedTransaction.merge(std::move(localTransactionQueue)); { std::unique_lock lock(_transactionFramesMutex); _transactionFrames.push_back(consolidatedTransaction); - _transactionFrameNumber++; - frameNumber = _transactionFrameNumber; } - return frameNumber; + return ++_transactionFrameNumber; } void Scene::processTransactionQueue() { PROFILE_RANGE(render, __FUNCTION__); - TransactionFrames queuedFrames; + static TransactionFrames queuedFrames; { // capture the queued frames and clear the queue std::unique_lock lock(_transactionFramesMutex); - queuedFrames = _transactionFrames; - _transactionFrames.clear(); + queuedFrames.swap(_transactionFrames); } // go through the queue of frames and process them for (auto& frame : queuedFrames) { processTransactionFrame(frame); } + + queuedFrames.clear(); } void Scene::processTransactionFrame(const Transaction& transaction) { diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index af6204acb4..2d8bc7f4dd 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -65,9 +65,14 @@ public: void resetSelectionHighlight(const std::string& selectionName, const HighlightStyle& style = HighlightStyle()); void removeHighlightFromSelection(const std::string& selectionName); - void querySelectionHighlight(const std::string& selectionName, SelectionHighlightQueryFunc func); + void querySelectionHighlight(const std::string& selectionName, const SelectionHighlightQueryFunc& func); + void reserve(const std::vector& transactionContainer); + void merge(const std::vector& transactionContainer); + void merge(std::vector&& transactionContainer); void merge(const Transaction& transaction); + void merge(Transaction&& transaction); + void clear(); // Checkers if there is work to do when processing the transaction bool touchTransactions() const { return !_resetSelections.empty(); } @@ -107,7 +112,7 @@ protected: HighlightRemoves _highlightRemoves; HighlightQueries _highlightQueries; }; -typedef std::queue TransactionQueue; +typedef std::vector TransactionQueue; // Scene is a container for Items @@ -133,6 +138,9 @@ public: // Enqueue transaction to the scene void enqueueTransaction(const Transaction& transaction); + // Enqueue transaction to the scene + void enqueueTransaction(Transaction&& transaction); + // Enqueue end of frame transactions boundary uint32_t enqueueFrame(); @@ -187,7 +195,7 @@ protected: std::mutex _transactionFramesMutex; - using TransactionFrames = std::list; + using TransactionFrames = std::vector; TransactionFrames _transactionFrames; uint32_t _transactionFrameNumber{ 0 }; From 2a91e98813f7eb2dd0c4988fd499e7ea85c0e8f0 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Wed, 6 Dec 2017 14:25:03 -0800 Subject: [PATCH 13/13] Fix iterator names --- libraries/render/src/render/Scene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 508cd6cefb..4b337a1046 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -125,13 +125,13 @@ void Transaction::merge(std::vector&& transactionContainer) { template void moveElements(T& target, T& source) { - target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.begin())); + target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end())); source.clear(); } template void copyElements(T& target, const T& source) { - target.insert(target.end(), source.begin(), source.begin()); + target.insert(target.end(), source.begin(), source.end()); }