Merge branch 'master' into menu-updates

This commit is contained in:
vladest 2018-04-28 20:22:28 +02:00
commit be22f49c32
60 changed files with 1022 additions and 1057 deletions

View file

@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC67-v3.zip URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC67-v4.zip
URL_MD5 327292eb87bc249cbb4d670d8a6ce746 URL_MD5 ba32aed18bfeaac4ccaf5ebb8ea3e804
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "" INSTALL_COMMAND ""

View file

@ -258,7 +258,9 @@ Item {
anchors.topMargin: 26; anchors.topMargin: 26;
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 20; anchors.leftMargin: 20;
width: paintedWidth; anchors.right: parent.right;
anchors.rightMargin: 20;
elide: Text.ElideRight;
height: 30; height: 30;
// Text size // Text size
size: 22; size: 22;
@ -844,7 +846,7 @@ Item {
property string selectedRecipientUserName; property string selectedRecipientUserName;
property string selectedRecipientProfilePic; property string selectedRecipientProfilePic;
visible: root.currentActiveView === "sendAssetStep"; visible: root.currentActiveView === "sendAssetStep" || paymentSuccess.visible || paymentFailure.visible;
anchors.fill: parent; anchors.fill: parent;
anchors.topMargin: root.parentAppTitleBarHeight; anchors.topMargin: root.parentAppTitleBarHeight;
@ -856,7 +858,9 @@ Item {
anchors.topMargin: 26; anchors.topMargin: 26;
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 20; anchors.leftMargin: 20;
width: paintedWidth; anchors.right: parent.right;
anchors.rightMargin: 20;
elide: Text.ElideRight;
height: 30; height: 30;
// Text size // Text size
size: 22; size: 22;
@ -907,7 +911,7 @@ Item {
// "CHANGE" button // "CHANGE" button
HifiControlsUit.Button { HifiControlsUit.Button {
id: changeButton; id: changeButton;
color: root.assetName === "" ? hifi.buttons.none : hifi.buttons.noneBorderlessGray; color: root.assetName === "" ? hifi.buttons.none : hifi.buttons.white;
colorScheme: hifi.colorSchemes.dark; colorScheme: hifi.colorSchemes.dark;
anchors.right: parent.right; anchors.right: parent.right;
anchors.verticalCenter: parent.verticalCenter; anchors.verticalCenter: parent.verticalCenter;
@ -1238,7 +1242,7 @@ Item {
// Sending Asset Overlay START // Sending Asset Overlay START
Rectangle { Rectangle {
id: sendingAssetOverlay; id: sendingAssetOverlay;
z: 998; z: 999;
visible: root.isCurrentlySendingAsset; visible: root.isCurrentlySendingAsset;
anchors.fill: parent; anchors.fill: parent;
@ -1281,26 +1285,43 @@ Item {
// Payment Success BEGIN // Payment Success BEGIN
Rectangle { Rectangle {
id: paymentSuccess; id: paymentSuccess;
z: 998;
visible: root.currentActiveView === "paymentSuccess"; visible: root.currentActiveView === "paymentSuccess";
anchors.fill: parent; anchors.fill: parent;
color: Qt.rgba(0.0, 0.0, 0.0, 0.8); color: Qt.rgba(0.0, 0.0, 0.0, 0.8);
// This object is always used in a popup or full-screen Wallet section.
// This MouseArea is used to prevent a user from being
// able to click on a button/mouseArea underneath the popup/section.
MouseArea {
anchors.fill: parent;
propagateComposedEvents: false;
hoverEnabled: true;
}
Rectangle { Rectangle {
anchors.centerIn: parent; anchors.top: parent.top;
width: parent.width - 30; anchors.topMargin: root.assetName === "" ? 15 : 150;
height: parent.height - 30; anchors.left: parent.left;
anchors.leftMargin: root.assetName === "" ? 15 : 50;
anchors.right: parent.right;
anchors.rightMargin: root.assetName === "" ? 15 : 50;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 15 : 240;
color: "#FFFFFF"; color: "#FFFFFF";
RalewaySemiBold { RalewaySemiBold {
id: paymentSentText; id: paymentSentText;
text: root.assetName === "" ? "Payment Sent" : '"' + root.assetName + '"'; text: root.assetName === "" ? "Payment Sent" : "Gift Sent";
// Anchors // Anchors
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: 26; anchors.topMargin: 26;
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 20; anchors.leftMargin: 20;
width: paintedWidth; anchors.right: parent.right;
anchors.rightMargin: 20;
elide: Text.ElideRight;
height: 30; height: 30;
// Text size // Text size
size: 22; size: 22;
@ -1310,6 +1331,7 @@ Item {
HiFiGlyphs { HiFiGlyphs {
id: closeGlyphButton_paymentSuccess; id: closeGlyphButton_paymentSuccess;
visible: root.assetName === "";
text: hifi.glyphs.close; text: hifi.glyphs.close;
color: hifi.colors.lightGrayText; color: hifi.colors.lightGrayText;
size: 26; size: 26;
@ -1375,6 +1397,49 @@ Item {
isDisplayingNearby: sendAssetStep.referrer === "nearby"; isDisplayingNearby: sendAssetStep.referrer === "nearby";
} }
} }
Item {
id: giftContainer_paymentSuccess;
visible: root.assetName !== "";
anchors.top: sendToContainer_paymentSuccess.bottom;
anchors.topMargin: 8;
anchors.left: parent.left;
anchors.leftMargin: 20;
anchors.right: parent.right;
anchors.rightMargin: 20;
height: 30;
RalewaySemiBold {
id: gift_paymentSuccess;
text: "Gift:";
// Anchors
anchors.top: parent.top;
anchors.left: parent.left;
anchors.bottom: parent.bottom;
width: 90;
// Text size
size: 18;
// Style
color: hifi.colors.baseGray;
verticalAlignment: Text.AlignVCenter;
}
RalewaySemiBold {
text: root.assetName;
// Anchors
anchors.top: parent.top;
anchors.left: gift_paymentSuccess.right;
anchors.right: parent.right;
height: parent.height;
// Text size
size: 18;
// Style
elide: Text.ElideRight;
color: hifi.colors.baseGray;
verticalAlignment: Text.AlignVCenter;
}
}
Item { Item {
id: amountContainer_paymentSuccess; id: amountContainer_paymentSuccess;
@ -1433,6 +1498,7 @@ Item {
RalewaySemiBold { RalewaySemiBold {
id: optionalMessage_paymentSuccess; id: optionalMessage_paymentSuccess;
visible: root.assetName === "";
text: optionalMessage.text; text: optionalMessage.text;
// Anchors // Anchors
anchors.top: amountContainer_paymentSuccess.visible ? amountContainer_paymentSuccess.bottom : sendToContainer_paymentSuccess.bottom; anchors.top: amountContainer_paymentSuccess.visible ? amountContainer_paymentSuccess.bottom : sendToContainer_paymentSuccess.bottom;
@ -1457,7 +1523,7 @@ Item {
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.horizontalCenter: parent.horizontalCenter; anchors.horizontalCenter: parent.horizontalCenter;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
anchors.bottomMargin: 80; anchors.bottomMargin: root.assetName === "" ? 80 : 30;
height: 50; height: 50;
width: 120; width: 120;
text: "Close"; text: "Close";
@ -1476,26 +1542,43 @@ Item {
// Payment Failure BEGIN // Payment Failure BEGIN
Rectangle { Rectangle {
id: paymentFailure; id: paymentFailure;
z: 998;
visible: root.currentActiveView === "paymentFailure"; visible: root.currentActiveView === "paymentFailure";
anchors.fill: parent; anchors.fill: parent;
color: Qt.rgba(0.0, 0.0, 0.0, 0.8); color: Qt.rgba(0.0, 0.0, 0.0, 0.8);
// This object is always used in a popup or full-screen Wallet section.
// This MouseArea is used to prevent a user from being
// able to click on a button/mouseArea underneath the popup/section.
MouseArea {
anchors.fill: parent;
propagateComposedEvents: false;
hoverEnabled: true;
}
Rectangle { Rectangle {
anchors.centerIn: parent; anchors.top: parent.top;
width: parent.width - 30; anchors.topMargin: root.assetName === "" ? 15 : 150;
height: parent.height - 30; anchors.left: parent.left;
anchors.leftMargin: root.assetName === "" ? 15 : 50;
anchors.right: parent.right;
anchors.rightMargin: root.assetName === "" ? 15 : 50;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 15 : 300;
color: "#FFFFFF"; color: "#FFFFFF";
RalewaySemiBold { RalewaySemiBold {
id: paymentFailureText; id: paymentFailureText;
text: root.assetName === "" ? "Payment Failed" : '"' + root.assetName + '"'; text: root.assetName === "" ? "Payment Failed" : "Failed";
// Anchors // Anchors
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: 26; anchors.topMargin: 26;
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 20; anchors.leftMargin: 20;
width: paintedWidth; anchors.right: parent.right;
anchors.rightMargin: 20;
elide: Text.ElideRight;
height: 30; height: 30;
// Text size // Text size
size: 22; size: 22;
@ -1505,6 +1588,7 @@ Item {
HiFiGlyphs { HiFiGlyphs {
id: closeGlyphButton_paymentFailure; id: closeGlyphButton_paymentFailure;
visible: root.assetName === "";
text: hifi.glyphs.close; text: hifi.glyphs.close;
color: hifi.colors.lightGrayText; color: hifi.colors.lightGrayText;
size: 26; size: 26;
@ -1551,6 +1635,7 @@ Item {
Item { Item {
id: sendToContainer_paymentFailure; id: sendToContainer_paymentFailure;
visible: root.assetName === "";
anchors.top: paymentFailureDetailText.bottom; anchors.top: paymentFailureDetailText.bottom;
anchors.topMargin: 8; anchors.topMargin: 8;
anchors.left: parent.left; anchors.left: parent.left;
@ -1645,7 +1730,8 @@ Item {
} }
RalewaySemiBold { RalewaySemiBold {
id: optionalMessage_paymentFailuire; id: optionalMessage_paymentFailure;
visible: root.assetName === "";
text: optionalMessage.text; text: optionalMessage.text;
// Anchors // Anchors
anchors.top: amountContainer_paymentFailure.visible ? amountContainer_paymentFailure.bottom : sendToContainer_paymentFailure.bottom; anchors.top: amountContainer_paymentFailure.visible ? amountContainer_paymentFailure.bottom : sendToContainer_paymentFailure.bottom;
@ -1663,14 +1749,15 @@ Item {
verticalAlignment: Text.AlignTop; verticalAlignment: Text.AlignTop;
} }
// "Close" button // "Cancel" button
HifiControlsUit.Button { HifiControlsUit.Button {
id: closeButton_paymentFailure; id: closeButton_paymentFailure;
color: hifi.buttons.noneBorderless; color: hifi.buttons.noneBorderless;
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light; colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.horizontalCenter: parent.horizontalCenter; anchors.right: retryButton_paymentFailure.left;
anchors.rightMargin: 12;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
anchors.bottomMargin: 80; anchors.bottomMargin: root.assetName === "" ? 80 : 30;
height: 50; height: 50;
width: 120; width: 120;
text: "Cancel"; text: "Cancel";
@ -1691,7 +1778,7 @@ Item {
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 12; anchors.rightMargin: 12;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
anchors.bottomMargin: 80; anchors.bottomMargin: root.assetName === "" ? 80 : 30;
height: 50; height: 50;
width: 120; width: 120;
text: "Retry"; text: "Retry";
@ -1768,7 +1855,7 @@ Item {
switch (message.method) { switch (message.method) {
case 'selectRecipient': case 'selectRecipient':
if (message.isSelected) { if (message.isSelected) {
chooseRecipientNearby.selectedRecipient = message.id[0]; chooseRecipientNearby.selectedRecipient = message.id;
sendAssetStep.selectedRecipientDisplayName = message.displayName; sendAssetStep.selectedRecipientDisplayName = message.displayName;
sendAssetStep.selectedRecipientUserName = message.userName; sendAssetStep.selectedRecipientUserName = message.userName;
} else { } else {

View file

@ -239,7 +239,6 @@ Item {
width: 62; width: 62;
onLoaded: { onLoaded: {
item.enabled = (root.purchaseStatus === "confirmed");
item.buttonGlyphText = hifi.glyphs.gift; item.buttonGlyphText = hifi.glyphs.gift;
item.buttonText = "Gift"; item.buttonText = "Gift";
item.buttonClicked = function() { item.buttonClicked = function() {

View file

@ -145,6 +145,16 @@
#include <avatars-renderer/ScriptAvatar.h> #include <avatars-renderer/ScriptAvatar.h>
#include <RenderableEntityItem.h> #include <RenderableEntityItem.h>
#include <AnimationLogging.h>
#include <AvatarLogging.h>
#include <ScriptEngineLogging.h>
#include <ModelFormatLogging.h>
#include <controllers/Logging.h>
#include <NetworkLogging.h>
#include <shared/StorageLogging.h>
#include <ScriptEngineLogging.h>
#include <ui/Logging.h>
#include "AudioClient.h" #include "AudioClient.h"
#include "audio/AudioScope.h" #include "audio/AudioScope.h"
#include "avatar/AvatarManager.h" #include "avatar/AvatarManager.h"
@ -1306,6 +1316,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// Needs to happen AFTER the render engine initialization to access its configuration // Needs to happen AFTER the render engine initialization to access its configuration
initializeUi(); initializeUi();
updateVerboseLogging();
init(); init();
qCDebug(interfaceapp, "init() complete."); qCDebug(interfaceapp, "init() complete.");
@ -2174,6 +2186,46 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
} }
void Application::updateVerboseLogging() {
bool enable = Menu::getInstance()->isOptionChecked(MenuOption::VerboseLogging);
const_cast<QLoggingCategory*>(&animation())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&animation())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&avatars())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&avatars())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&scriptengine())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&scriptengine())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&modelformat())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&modelformat())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&controllers())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&controllers())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&resourceLog())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&resourceLog())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&networking())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&networking())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&asset_client())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&asset_client())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&messages_client())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&messages_client())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&storagelogging())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&storagelogging())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&uiLogging())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&uiLogging())->setEnabled(QtInfoMsg, enable);
const_cast<QLoggingCategory*>(&glLogging())->setEnabled(QtDebugMsg, enable);
const_cast<QLoggingCategory*>(&glLogging())->setEnabled(QtInfoMsg, enable);
}
void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) {
DomainHandler::ConnectionRefusedReason reasonCode = static_cast<DomainHandler::ConnectionRefusedReason>(reasonCodeInt); DomainHandler::ConnectionRefusedReason reasonCode = static_cast<DomainHandler::ConnectionRefusedReason>(reasonCodeInt);
@ -3042,7 +3094,6 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
PROFILE_RANGE(render, __FUNCTION__); PROFILE_RANGE(render, __FUNCTION__);
bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll()); bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll());
qDebug() << "HandleSandboxStatus" << sandboxIsRunning;
enum HandControllerType { enum HandControllerType {
Vive, Vive,

View file

@ -399,6 +399,8 @@ public slots:
Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); } Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); }
void updateVerboseLogging();
private slots: private slots:
void onDesktopRootItemCreated(QQuickItem* qmlContext); void onDesktopRootItemCreated(QQuickItem* qmlContext);
void onDesktopRootContextCreated(QQmlContext* qmlContext); void onDesktopRootContextCreated(QQmlContext* qmlContext);

View file

@ -16,7 +16,8 @@
#include "Bookmarks.h" #include "Bookmarks.h"
/**jsdoc /**jsdoc
* This API helps manage adding and deleting Avatar bookmarks * This API helps manage adding and deleting avatar bookmarks.
* @namespace AvatarBookmarks
*/ */
class AvatarBookmarks: public Bookmarks, public Dependency { class AvatarBookmarks: public Bookmarks, public Dependency {
@ -27,16 +28,12 @@ public:
AvatarBookmarks(); AvatarBookmarks();
void setupMenus(Menu* menubar, MenuWrapper* menu) override; void setupMenus(Menu* menubar, MenuWrapper* menu) override;
/**jsdoc
* Add the current Avatar to your Avatar Bookmarks
* @function AvatarBookmarks.addBookMark
*/
/**jsdoc
* @function AvatarBookmarks.deleteBookMark
*/
public slots: public slots:
/**jsdoc
* Add the current Avatar to your avatar bookmarks.
* @function AvatarBookmarks.addBookMark
*/
void addBookmark(); void addBookmark();
protected: protected:

View file

@ -49,7 +49,6 @@ protected:
protected slots: protected slots:
/**jsdoc /**jsdoc
* Delete
* @function AvatarBookmarks.deleteBookmark * @function AvatarBookmarks.deleteBookmark
*/ */
void deleteBookmark(); void deleteBookmark();

View file

@ -43,12 +43,10 @@ void ConnectionMonitor::init() {
} }
void ConnectionMonitor::startTimer() { void ConnectionMonitor::startTimer() {
qDebug() << "ConnectionMonitor: Starting timer";
_timer.start(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS); _timer.start(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS);
} }
void ConnectionMonitor::stopTimer() { void ConnectionMonitor::stopTimer() {
qDebug() << "ConnectionMonitor: Stopping timer";
_timer.stop(); _timer.stop();
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(false); DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(false);
} }

View file

@ -49,21 +49,18 @@ public:
* @function LODManager.setAutomaticLODAdjust * @function LODManager.setAutomaticLODAdjust
* @param {boolean} value * @param {boolean} value
*/ */
Q_INVOKABLE void setAutomaticLODAdjust(bool value) { _automaticLODAdjust = value; } Q_INVOKABLE void setAutomaticLODAdjust(bool value) { _automaticLODAdjust = value; }
/**jsdoc /**jsdoc
* @function LODManager.getAutomaticLODAdjust * @function LODManager.getAutomaticLODAdjust
* @returns {boolean} * @returns {boolean}
*/ */
Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; } Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; }
/**jsdoc /**jsdoc
* @function LODManager.setDesktopLODDecreaseFPS * @function LODManager.setDesktopLODDecreaseFPS
* @param {float} value * @param {number} value
*/ */
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value); Q_INVOKABLE void setDesktopLODDecreaseFPS(float value);
/**jsdoc /**jsdoc
@ -77,28 +74,25 @@ public:
* @function LODManager.getDesktopLODIncreaseFPS * @function LODManager.getDesktopLODIncreaseFPS
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getDesktopLODIncreaseFPS() const; Q_INVOKABLE float getDesktopLODIncreaseFPS() const;
/**jsdoc /**jsdoc
* @function LODManager.setHMDLODDecreaseFPS * @function LODManager.setHMDLODDecreaseFPS
* @param {number} value * @param {number} value
*/ */
Q_INVOKABLE void setHMDLODDecreaseFPS(float value); Q_INVOKABLE void setHMDLODDecreaseFPS(float value);
/**jsdoc /**jsdoc
* @function LODManager.getHMDLODDecreaseFPS * @function LODManager.getHMDLODDecreaseFPS
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getHMDLODDecreaseFPS() const; Q_INVOKABLE float getHMDLODDecreaseFPS() const;
/**jsdoc /**jsdoc
* @function LODManager.getHMDLODIncreaseFPS * @function LODManager.getHMDLODIncreaseFPS
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getHMDLODIncreaseFPS() const; Q_INVOKABLE float getHMDLODIncreaseFPS() const;
// User Tweakable LOD Items // User Tweakable LOD Items
@ -106,61 +100,54 @@ public:
* @function LODManager.getLODFeedbackText * @function LODManager.getLODFeedbackText
* @returns {string} * @returns {string}
*/ */
Q_INVOKABLE QString getLODFeedbackText(); Q_INVOKABLE QString getLODFeedbackText();
/**jsdoc /**jsdoc
* @function LODManager.setOctreeSizeScale * @function LODManager.setOctreeSizeScale
* @param {number} sizeScale * @param {number} sizeScale
*/ */
Q_INVOKABLE void setOctreeSizeScale(float sizeScale); Q_INVOKABLE void setOctreeSizeScale(float sizeScale);
/**jsdoc /**jsdoc
* @function LODManager.getOctreeSizeScale * @function LODManager.getOctreeSizeScale
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getOctreeSizeScale() const { return _octreeSizeScale; } Q_INVOKABLE float getOctreeSizeScale() const { return _octreeSizeScale; }
/**jsdoc /**jsdoc
* @function LODManager.setBoundaryLevelAdjust * @function LODManager.setBoundaryLevelAdjust
* @param {number} boundaryLevelAdjust * @param {number} boundaryLevelAdjust
*/ */
Q_INVOKABLE void setBoundaryLevelAdjust(int boundaryLevelAdjust); Q_INVOKABLE void setBoundaryLevelAdjust(int boundaryLevelAdjust);
/**jsdoc /**jsdoc
* @function LODManager.getBoundaryLevelAdjust * @function LODManager.getBoundaryLevelAdjust
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
/**jsdoc /**jsdoc
* @function LODManager.getLODDecreaseFPS * @function LODManager.getLODDecreaseFPS
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getLODDecreaseFPS() const; Q_INVOKABLE float getLODDecreaseFPS() const;
/**jsdoc /**jsdoc
* @function LODManager.getLODIncreaseFPS * @function LODManager.getLODIncreaseFPS
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getLODIncreaseFPS() const; Q_INVOKABLE float getLODIncreaseFPS() const;
/**jsdoc /**jsdoc
* @namespace LODManager * @namespace LODManager
* @property presentTime {number} * @property {number} presentTime <em>Read-only.</em>
* @property engineRunTime {number} * @property {number} engineRunTime <em>Read-only.</em>
* @property gpuTime {number} * @property {number} gpuTime <em>Read-only.</em>
* @property avgRenderTime {number} * @property {number} avgRenderTime <em>Read-only.</em>
* @property fps {number} * @property {number} fps <em>Read-only.</em>
* @property lodLevel {number} * @property {number} lodLevel <em>Read-only.</em>
* @property lodDecreaseFPS {number} * @property {number} lodDecreaseFPS <em>Read-only.</em>
* @property lodIncreaseFPS {number} * @property {number} lodIncreaseFPS <em>Read-only.</em>
*/ */
Q_PROPERTY(float presentTime READ getPresentTime) Q_PROPERTY(float presentTime READ getPresentTime)
@ -195,14 +182,12 @@ signals:
* @function LODManager.LODIncreased * @function LODManager.LODIncreased
* @returns {Signal} * @returns {Signal}
*/ */
void LODIncreased(); void LODIncreased();
/**jsdoc /**jsdoc
* @function LODManager.LODDecreased * @function LODManager.LODDecreased
* @returns {Signal} * @returns {Signal}
*/ */
void LODDecreased(); void LODDecreased();
private: private:

View file

@ -738,6 +738,9 @@ Menu::Menu() {
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
#endif #endif
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::VerboseLogging, 0, false,
qApp, SLOT(updateVerboseLogging()));
#if 0 /// -------------- REMOVED FOR NOW -------------- #if 0 /// -------------- REMOVED FOR NOW --------------
addDisabledActionAndSeparator(navigateMenu, "History"); addDisabledActionAndSeparator(navigateMenu, "History");
QAction* backAction = addActionToQMenuAndActionHash(navigateMenu, MenuOption::Back, 0, addressManager.data(), SLOT(goBack())); QAction* backAction = addActionToQMenuAndActionHash(navigateMenu, MenuOption::Back, 0, addressManager.data(), SLOT(goBack()));

View file

@ -142,6 +142,7 @@ namespace MenuOption {
const QString Pair = "Pair"; const QString Pair = "Pair";
const QString PhysicsShowHulls = "Draw Collision Shapes"; const QString PhysicsShowHulls = "Draw Collision Shapes";
const QString PhysicsShowOwned = "Highlight Simulation Ownership"; const QString PhysicsShowOwned = "Highlight Simulation Ownership";
const QString VerboseLogging = "Verbose Logging";
const QString PipelineWarnings = "Log Render Pipeline Warnings"; const QString PipelineWarnings = "Log Render Pipeline Warnings";
const QString Preferences = "General..."; const QString Preferences = "General...";
const QString Quit = "Quit"; const QString Quit = "Quit";

View file

@ -28,12 +28,12 @@ class AudioScope : public QObject, public Dependency {
/**jsdoc /**jsdoc
* The AudioScope API helps control the Audio Scope features in Interface * The AudioScope API helps control the Audio Scope features in Interface
* @namespace AudioScope * @namespace AudioScope
* @property {int} scopeInput * @property {number} scopeInput <em>Read-only.</em>
* @property {int} scopeOutputLeft * @property {number} scopeOutputLeft <em>Read-only.</em>
* @property {int} scopeOutputRight * @property {number} scopeOutputRight <em>Read-only.</em>
* @property {int} triggerInput * @property {number} triggerInput <em>Read-only.</em>
* @property {int} triggerOutputLeft * @property {number} triggerOutputLeft <em>Read-only.</em>
* @property {int} triggerOutputRight * @property {number} triggerOutputRight <em>Read-only.</em>
*/ */
Q_PROPERTY(QVector<int> scopeInput READ getScopeInput) Q_PROPERTY(QVector<int> scopeInput READ getScopeInput)
@ -55,62 +55,52 @@ public slots:
/**jsdoc /**jsdoc
* @function AudioScope.toggle * @function AudioScope.toggle
*/ */
void toggle() { setVisible(!_isEnabled); } void toggle() { setVisible(!_isEnabled); }
/**jsdoc /**jsdoc
* @function AudioScope.setVisible * @function AudioScope.setVisible
* @param {boolean} visible * @param {boolean} visible
*/ */
void setVisible(bool visible); void setVisible(bool visible);
/**jsdoc /**jsdoc
* @function AudioScope.getVisible * @function AudioScope.getVisible
* @param {boolean} visible
* @returns {boolean} * @returns {boolean}
*/ */
bool getVisible() const { return _isEnabled; } bool getVisible() const { return _isEnabled; }
/**jsdoc /**jsdoc
* @function AudioScope.togglePause * @function AudioScope.togglePause
*/ */
void togglePause() { setPause(!_isPaused); } void togglePause() { setPause(!_isPaused); }
/**jsdoc /**jsdoc
* @function AudioScope.setPause * @function AudioScope.setPause
* @param {boolean} * @param {boolean} paused
*/ */
void setPause(bool paused) { _isPaused = paused; emit pauseChanged(); } void setPause(bool paused) { _isPaused = paused; emit pauseChanged(); }
/**jsdoc /**jsdoc
* @function AudioScope.getPause * @function AudioScope.getPause
* @returns {boolean} * @returns {boolean}
*/ */
bool getPause() { return _isPaused; } bool getPause() { return _isPaused; }
/**jsdoc /**jsdoc
* @function AudioScope.toggleTrigger * @function AudioScope.toggleTrigger
*/ */
void toggleTrigger() { _autoTrigger = !_autoTrigger; } void toggleTrigger() { _autoTrigger = !_autoTrigger; }
/**jsdoc /**jsdoc
* @function AudioScope.getAutoTrigger * @function AudioScope.getAutoTrigger
* @returns {boolean} * @returns {boolean}
*/ */
bool getAutoTrigger() { return _autoTrigger; } bool getAutoTrigger() { return _autoTrigger; }
/**jsdoc /**jsdoc
* @function AudioScope.setAutoTrigger * @function AudioScope.setAutoTrigger
* @param {boolean} autoTrigger * @param {boolean} autoTrigger
*/ */
void setAutoTrigger(bool autoTrigger) { _isTriggered = false; _autoTrigger = autoTrigger; } void setAutoTrigger(bool autoTrigger) { _isTriggered = false; _autoTrigger = autoTrigger; }
/**jsdoc /**jsdoc
@ -118,109 +108,93 @@ public slots:
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
*/ */
void setTriggerValues(int x, int y) { _triggerValues.x = x; _triggerValues.y = y; } void setTriggerValues(int x, int y) { _triggerValues.x = x; _triggerValues.y = y; }
/**jsdoc /**jsdoc
* @function AudioScope.setTriggered * @function AudioScope.setTriggered
* @param {boolean} triggered * @param {boolean} triggered
*/ */
void setTriggered(bool triggered) { _isTriggered = triggered; } void setTriggered(bool triggered) { _isTriggered = triggered; }
/**jsdoc /**jsdoc
* @function AudioScope.getTriggered * @function AudioScope.getTriggered
* @returns {boolean} * @returns {boolean}
*/ */
bool getTriggered() { return _isTriggered; } bool getTriggered() { return _isTriggered; }
/**jsdoc /**jsdoc
* @function AudioScope.getFramesPerSecond * @function AudioScope.getFramesPerSecond
* @returns {number} * @returns {number}
*/ */
float getFramesPerSecond(); float getFramesPerSecond();
/**jsdoc /**jsdoc
* @function AudioScope.getFramesPerScope * @function AudioScope.getFramesPerScope
* @returns {number} * @returns {number}
*/ */
int getFramesPerScope() { return _framesPerScope; } int getFramesPerScope() { return _framesPerScope; }
/**jsdoc /**jsdoc
* @function AudioScope.selectAudioScopeFiveFrames * @function AudioScope.selectAudioScopeFiveFrames
*/ */
void selectAudioScopeFiveFrames(); void selectAudioScopeFiveFrames();
/**jsdoc /**jsdoc
* @function AudioScope.selectAudioScopeTwentyFrames * @function AudioScope.selectAudioScopeTwentyFrames
*/ */
void selectAudioScopeTwentyFrames(); void selectAudioScopeTwentyFrames();
/**jsdoc /**jsdoc
* @function AudioScope.selectAudioScopeFiftyFrames * @function AudioScope.selectAudioScopeFiftyFrames
*/ */
void selectAudioScopeFiftyFrames(); void selectAudioScopeFiftyFrames();
/**jsdoc /**jsdoc
* @function AudioScope.getScopeInput * @function AudioScope.getScopeInput
* @returns {number} * @returns {number[]}
*/ */
QVector<int> getScopeInput() { return _scopeInputData; }; QVector<int> getScopeInput() { return _scopeInputData; };
/**jsdoc /**jsdoc
* @function AudioScope.getScopeOutputLeft * @function AudioScope.getScopeOutputLeft
* @returns {number} * @returns {number[]}
*/ */
QVector<int> getScopeOutputLeft() { return _scopeOutputLeftData; }; QVector<int> getScopeOutputLeft() { return _scopeOutputLeftData; };
/**jsdoc /**jsdoc
* @function AudioScope.getScopeOutputRight * @function AudioScope.getScopeOutputRight
* @returns {number} * @returns {number[]}
*/ */
QVector<int> getScopeOutputRight() { return _scopeOutputRightData; }; QVector<int> getScopeOutputRight() { return _scopeOutputRightData; };
/**jsdoc /**jsdoc
* @function AudioScope.getTriggerInput * @function AudioScope.getTriggerInput
* @returns {number} * @returns {number[]}
*/ */
QVector<int> getTriggerInput() { return _triggerInputData; }; QVector<int> getTriggerInput() { return _triggerInputData; };
/**jsdoc /**jsdoc
* @function AudioScope.getTriggerOutputLeft * @function AudioScope.getTriggerOutputLeft
* @returns {number} * @returns {number[]}
*/ */
QVector<int> getTriggerOutputLeft() { return _triggerOutputLeftData; }; QVector<int> getTriggerOutputLeft() { return _triggerOutputLeftData; };
/**jsdoc /**jsdoc
* @function AudioScope.getTriggerOutputRight * @function AudioScope.getTriggerOutputRight
* @returns {number} * @returns {number[]}
*/ */
QVector<int> getTriggerOutputRight() { return _triggerOutputRightData; }; QVector<int> getTriggerOutputRight() { return _triggerOutputRightData; };
/**jsdoc /**jsdoc
* @function AudioScope.setLocalEcho * @function AudioScope.setLocalEcho
* @parm {boolean} serverEcho * @parm {boolean} localEcho
*/ */
void setLocalEcho(bool localEcho);
void setLocalEcho(bool serverEcho);
/**jsdoc /**jsdoc
* @function AudioScope.setServerEcho * @function AudioScope.setServerEcho
* @parm {boolean} serverEcho * @parm {boolean} serverEcho
*/ */
void setServerEcho(bool serverEcho); void setServerEcho(bool serverEcho);
signals: signals:
@ -229,14 +203,12 @@ signals:
* @function AudioScope.pauseChanged * @function AudioScope.pauseChanged
* @returns {Signal} * @returns {Signal}
*/ */
void pauseChanged(); void pauseChanged();
/**jsdoc /**jsdoc
* @function AudioScope.triggered * @function AudioScope.triggered
* @returns {Signal} * @returns {Signal}
*/ */
void triggered(); void triggered();
protected: protected:

View file

@ -38,75 +38,6 @@ class AvatarManager : public AvatarHashMap {
public: public:
// JSDOCS Copied over from AvatarHashMap (see AvatarHashMap.h for reason)
/**jsdoc
* @function AvatarManager.getAvatarIdentifiers
*/
/**jsdoc
* @function AvatarManager.getAvatarsInRange
* @param {Vec3} position
* @param {float} rangeMeters
* @returns {string[]}
*/
/**jsdoc
* @function AvatarManager.getAvatar
* @param {string} avatarID
* @returns {ScriptAvatarData}
*/
/**jsdoc
* @function AvatarManager.avatarAddedEvent
* @param {string} sessionUUID
* @returns {Signal}
*/
/**jsdoc
* @function AvatarManager.avatarRemovedEvent
* @param {string} sessionUUID
* @returns {Signal}
*/
/**jsdoc
* @function AvatarManager.avatarSessionChangedEvent
* @param {string} sessionUUID
* @param {string} oldUUID
* @returns {Signal}
*/
/**jsdoc
* @function AvatarManager.isAvatarInRange
* @param {string} position
* @param {string} range
* @returns {boolean}
*/
/**jsdoc
* @function AvatarManager.sessionUUIDChanged
* @param {string} sessionUUID
* @param {string} oldUUID
*/
/**jsdoc
* @function AvatarManager.processAvatarDataPacket
* @param {} message
* @param {} sendingNode
*/
/**jsdoc
* @function AvatarManager.processAvatarIdentityPacket
* @param {} message
* @param {} sendingNode
*/
/**jsdoc
* @function AvatarManager.processKillAvatar
* @param {} message
* @param {} sendingNode
*/
/// Registers the script types associated with the avatar manager. /// Registers the script types associated with the avatar manager.
static void registerMetaTypes(QScriptEngine* engine); static void registerMetaTypes(QScriptEngine* engine);
@ -119,10 +50,9 @@ public:
/**jsdoc /**jsdoc
* @function AvatarManager.getAvatar * @function AvatarManager.getAvatar
* @param {string} avatarID * @param {Uuid} avatarID
* @returns {} * @returns {AvatarData}
*/ */
// Null/Default-constructed QUuids will return MyAvatar // Null/Default-constructed QUuids will return MyAvatar
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) override { return new ScriptAvatar(getAvatarBySessionID(avatarID)); } Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) override { return new ScriptAvatar(getAvatarBySessionID(avatarID)); }
@ -148,16 +78,15 @@ public:
/**jsdoc /**jsdoc
* @function AvatarManager.getAvatarDataRate * @function AvatarManager.getAvatarDataRate
* @param {string} sessionID * @param {Uuid} sessionID
* @param {string} [rateName=""] * @param {string} [rateName=""]
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getAvatarDataRate(const QUuid& sessionID, const QString& rateName = QString("")) const; Q_INVOKABLE float getAvatarDataRate(const QUuid& sessionID, const QString& rateName = QString("")) const;
/**jsdoc /**jsdoc
* @function AvatarManager.getAvatarUpdateRate * @function AvatarManager.getAvatarUpdateRate
* @param {string} sessionID * @param {Uuid} sessionID
* @param {string} [rateName=""] * @param {string} [rateName=""]
* @returns {number} * @returns {number}
*/ */
@ -166,51 +95,47 @@ public:
/**jsdoc /**jsdoc
* @function AvatarManager.getAvatarSimulationRate * @function AvatarManager.getAvatarSimulationRate
* @param {string} sessionID * @param {Uuid} sessionID
* @param {string} [rateName=""] * @param {string} [rateName=""]
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName = QString("")) const; Q_INVOKABLE float getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName = QString("")) const;
/**jsdoc /**jsdoc
* @function AvatarManager.findRayIntersection * @function AvatarManager.findRayIntersection
* @param {PickRay} ray * @param {PickRay} ray
* @param {} avatarIdsToInclude * @param {Uuid[]} [avatarsToInclude=[]]
* @param {} avatarIdsToDiscard * @param {Uuid[]} [avatarsToDiscard=[]]
* @returns {RayToAvatarIntersectionResult} * @returns {RayToAvatarIntersectionResult}
*/ */
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray, Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray,
const QScriptValue& avatarIdsToInclude = QScriptValue(), const QScriptValue& avatarIdsToInclude = QScriptValue(),
const QScriptValue& avatarIdsToDiscard = QScriptValue()); const QScriptValue& avatarIdsToDiscard = QScriptValue());
/**jsdoc /**jsdoc
* @function AvatarManager.findRayIntersectionVector * @function AvatarManager.findRayIntersectionVector
* @param {PickRay} ray * @param {PickRay} ray
* @param {} avatarsToInclude * @param {Uuid[]} avatarsToInclude
* @param {} avatarIdsToDiscard * @param {Uuid[]} avatarsToDiscard
* @returns {RayToAvatarIntersectionResult} * @returns {RayToAvatarIntersectionResult}
*/ */
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVector(const PickRay& ray, Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVector(const PickRay& ray,
const QVector<EntityItemID>& avatarsToInclude, const QVector<EntityItemID>& avatarsToInclude,
const QVector<EntityItemID>& avatarsToDiscard); const QVector<EntityItemID>& avatarsToDiscard);
// TODO: remove this HACK once we settle on optimal default sort coefficients
/**jsdoc /**jsdoc
* @function AvatarManager.getAvatarSortCoefficient * @function AvatarManager.getAvatarSortCoefficient
* @param {string} name * @param {string} name
* @returns {number} * @returns {number}
*/ */
// TODO: remove this HACK once we settle on optimal default sort coefficients
Q_INVOKABLE float getAvatarSortCoefficient(const QString& name); Q_INVOKABLE float getAvatarSortCoefficient(const QString& name);
/**jsdoc /**jsdoc
* @function AvatarManager.setAvatarSortCoefficient * @function AvatarManager.setAvatarSortCoefficient
* @param {string} name * @param {string} name
* @param {string} value * @param {number} value
*/ */
Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value); Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value);
float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); } float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); }
@ -221,7 +146,6 @@ public slots:
* @function AvatarManager.updateAvatarRenderStatus * @function AvatarManager.updateAvatarRenderStatus
* @param {boolean} shouldRenderAvatars * @param {boolean} shouldRenderAvatars
*/ */
void updateAvatarRenderStatus(bool shouldRenderAvatars); void updateAvatarRenderStatus(bool shouldRenderAvatars);
private: private:

View file

@ -60,6 +60,10 @@ class MyAvatar : public Avatar {
* change the avatar's position within the domain, or manage the avatar's collisions with other objects. * change the avatar's position within the domain, or manage the avatar's collisions with other objects.
* *
* @namespace MyAvatar * @namespace MyAvatar
*
* @hifi-interface
* @hifi-client-entity
*
* @property {Vec3} qmlPosition - A synonym for <code>position</code> for use by QML. * @property {Vec3} qmlPosition - A synonym for <code>position</code> for use by QML.
* @property {boolean} shouldRenderLocally=true - If <code>true</code> then your avatar is rendered for you in Interface, * @property {boolean} shouldRenderLocally=true - If <code>true</code> then your avatar is rendered for you in Interface,
* otherwise it is not rendered for you (but it is still rendered for other users). * otherwise it is not rendered for you (but it is still rendered for other users).

View file

@ -67,13 +67,11 @@ public slots:
* @function FaceTracker.setEnabled * @function FaceTracker.setEnabled
* @param {boolean} enabled * @param {boolean} enabled
*/ */
void setEnabled(bool enabled) override; void setEnabled(bool enabled) override;
/**jsdoc /**jsdoc
* @function FaceTracker.calibrate * @function FaceTracker.calibrate
*/ */
void calibrate(); void calibrate();
private slots: private slots:

View file

@ -109,7 +109,7 @@ public:
* *
* @typedef {Object} Picks.RayPickResult * @typedef {Object} Picks.RayPickResult
* @property {number} type The intersection type. * @property {number} type The intersection type.
* @property {bool} intersects If there was a valid intersection (type != INTERSECTED_NONE) * @property {boolean} intersects If there was a valid intersection (type != INTERSECTED_NONE)
* @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections. * @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections.
* @property {float} distance The distance to the intersection point from the origin of the ray. * @property {float} distance The distance to the intersection point from the origin of the ray.
* @property {Vec3} intersection The intersection point in world-space. * @property {Vec3} intersection The intersection point in world-space.
@ -123,7 +123,7 @@ public:
* *
* @typedef {Object} Picks.StylusPickResult * @typedef {Object} Picks.StylusPickResult
* @property {number} type The intersection type. * @property {number} type The intersection type.
* @property {bool} intersects If there was a valid intersection (type != INTERSECTED_NONE) * @property {boolean} intersects If there was a valid intersection (type != INTERSECTED_NONE)
* @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections. * @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections.
* @property {float} distance The distance to the intersection point from the origin of the ray. * @property {float} distance The distance to the intersection point from the origin of the ray.
* @property {Vec3} intersection The intersection point in world-space. * @property {Vec3} intersection The intersection point in world-space.

View file

@ -39,10 +39,10 @@ class AccountServicesScriptingInterface : public QObject {
* The AccountServices API contains helper functions related to user connectivity * The AccountServices API contains helper functions related to user connectivity
* *
* @namespace AccountServices * @namespace AccountServices
* @property {string} username * @property {string} username <em>Read-only.</em>
* @property {boolean} loggedIn * @property {boolean} loggedIn <em>Read-only.</em>
* @property {string} findableBy * @property {string} findableBy
* @property {string} metaverseServerURL * @property {string} metaverseServerURL <em>Read-only.</em>
*/ */
Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged) Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged)
@ -63,33 +63,28 @@ public slots:
* @function AccountServices.getDownloadInfo * @function AccountServices.getDownloadInfo
* @returns {DownloadInfoResult} * @returns {DownloadInfoResult}
*/ */
DownloadInfoResult getDownloadInfo(); DownloadInfoResult getDownloadInfo();
/**jsdoc /**jsdoc
* @function AccountServices.updateDownloadInfo * @function AccountServices.updateDownloadInfo
*/ */
void updateDownloadInfo(); void updateDownloadInfo();
/**jsdoc /**jsdoc
* @function AccountServices.isLoggedIn * @function AccountServices.isLoggedIn
* @returns {boolean} * @returns {boolean}
*/ */
bool isLoggedIn(); bool isLoggedIn();
/**jsdoc /**jsdoc
* @function AccountServices.checkAndSignalForAccessToken * @function AccountServices.checkAndSignalForAccessToken
* @returns {boolean} * @returns {boolean}
*/ */
bool checkAndSignalForAccessToken(); bool checkAndSignalForAccessToken();
/**jsdoc /**jsdoc
* @function AccountServices.logOut * @function AccountServices.logOut
*/ */
void logOut(); void logOut();
private slots: private slots:
@ -108,47 +103,41 @@ signals:
* @function AccountServices.connected * @function AccountServices.connected
* @returns {Signal} * @returns {Signal}
*/ */
void connected(); void connected();
/**jsdoc /**jsdoc
* @function AccountServices.disconnected * @function AccountServices.disconnected
* @params {string} reason * @param {string} reason
* @returns {Signal} * @returns {Signal}
*/ */
void disconnected(const QString& reason); void disconnected(const QString& reason);
/**jsdoc /**jsdoc
* @function AccountServices.myUsernameChanged * @function AccountServices.myUsernameChanged
* @params {string} username * @param {string} username
* @returns {Signal} * @returns {Signal}
*/ */
void myUsernameChanged(const QString& username); void myUsernameChanged(const QString& username);
/**jsdoc /**jsdoc
* @function AccountServices.downloadInfoChanged * @function AccountServices.downloadInfoChanged
* @params {} info * @param {} info
* @returns {Signal} * @returns {Signal}
*/ */
void downloadInfoChanged(DownloadInfoResult info); void downloadInfoChanged(DownloadInfoResult info);
/**jsdoc /**jsdoc
* @function AccountServices.findableByChanged * @function AccountServices.findableByChanged
* @params {string} discoverabilityMode * @param {string} discoverabilityMode
* @returns {Signal} * @returns {Signal}
*/ */
void findableByChanged(const QString& discoverabilityMode); void findableByChanged(const QString& discoverabilityMode);
/**jsdoc /**jsdoc
* @function AccountServices.loggedInChanged * @function AccountServices.loggedInChanged
* @params {boolean} loggedIn * @param {boolean} loggedIn
* @returns {Signal} * @returns {Signal}
*/ */
void loggedInChanged(bool loggedIn); void loggedInChanged(bool loggedIn);
private: private:

View file

@ -31,10 +31,10 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
* @namespace Audio * @namespace Audio
* @property {boolean} muted * @property {boolean} muted
* @property {boolean} noiseReduction * @property {boolean} noiseReduction
* @property {boolean} inputVolume * @property {number} inputVolume
* @property {boolean} inputLevel * @property {number} inputLevel <em>Read-only.</em>
* @property {string} context * @property {string} context <em>Read-only.</em>
* @property {} devices * @property {} devices <em>Read-only.</em>
*/ */
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
@ -66,7 +66,6 @@ public:
* @param {} device * @param {} device
* @param {boolean} isHMD * @param {boolean} isHMD
*/ */
Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device, bool isHMD); Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device, bool isHMD);
/**jsdoc /**jsdoc
@ -74,40 +73,36 @@ public:
* @param {} device * @param {} device
* @param {boolean} isHMD * @param {boolean} isHMD
*/ */
Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device, bool isHMD); Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device, bool isHMD);
/**jsdoc /**jsdoc
* @function Audio.setReverb * @function Audio.setReverb
* @param {boolean} enable * @param {boolean} enable
*/ */
Q_INVOKABLE void setReverb(bool enable); Q_INVOKABLE void setReverb(bool enable);
/**jsdoc /**jsdoc
* @function Audio.setReverbOptions * @function Audio.setReverbOptions
* @param {} options * @param {} options
*/ */
Q_INVOKABLE void setReverbOptions(const AudioEffectOptions* options); Q_INVOKABLE void setReverbOptions(const AudioEffectOptions* options);
/**jsdoc /**jsdoc
* @function Audio.setReverbOptions * @function Audio.startRecording
* @param {string} filename * @param {string} filename
* @returns {boolean}
*/ */
Q_INVOKABLE bool startRecording(const QString& filename); Q_INVOKABLE bool startRecording(const QString& filename);
/**jsdoc /**jsdoc
* @function Audio.stopRecording * @function Audio.stopRecording
*/ */
Q_INVOKABLE void stopRecording(); Q_INVOKABLE void stopRecording();
/**jsdoc /**jsdoc
* @function Audio.getRecording * @function Audio.getRecording
* @returns {boolean}
*/ */
Q_INVOKABLE bool getRecording(); Q_INVOKABLE bool getRecording();
signals: signals:
@ -116,39 +111,34 @@ signals:
* @function Audio.nop * @function Audio.nop
* @returns {Signal} * @returns {Signal}
*/ */
void nop(); void nop();
/**jsdoc /**jsdoc
* @function Audio.nop * @function Audio.mutedChanged
* @param {bool} isMuted * @param {boolean} isMuted
* @returns {Signal} * @returns {Signal}
*/ */
void mutedChanged(bool isMuted); void mutedChanged(bool isMuted);
/**jsdoc /**jsdoc
* @function Audio.noiseReductionChanged * @function Audio.noiseReductionChanged
* @param {bool} isEnabled * @param {boolean} isEnabled
* @returns {Signal} * @returns {Signal}
*/ */
void noiseReductionChanged(bool isEnabled); void noiseReductionChanged(bool isEnabled);
/**jsdoc /**jsdoc
* @function Audio.inputVolumeChanged * @function Audio.inputVolumeChanged
* @param {float} volume * @param {number} volume
* @returns {Signal} * @returns {Signal}
*/ */
void inputVolumeChanged(float volume); void inputVolumeChanged(float volume);
/**jsdoc /**jsdoc
* @function Audio.inputLevelChanged * @function Audio.inputLevelChanged
* @param {float} level * @param {number} level
* @returns {Signal} * @returns {Signal}
*/ */
void inputLevelChanged(float level); void inputLevelChanged(float level);
/**jsdoc /**jsdoc
@ -156,7 +146,6 @@ signals:
* @param {string} context * @param {string} context
* @returns {Signal} * @returns {Signal}
*/ */
void contextChanged(const QString& context); void contextChanged(const QString& context);
public slots: public slots:
@ -165,7 +154,6 @@ public slots:
* @function Audio.onContextChanged * @function Audio.onContextChanged
* @returns {Signal} * @returns {Signal}
*/ */
void onContextChanged(); void onContextChanged();
private slots: private slots:

View file

@ -108,11 +108,9 @@ AudioDeviceList::~AudioDeviceList() {
// store the selected device // store the selected device
foreach(std::shared_ptr<AudioDevice> adevice, _devices) { foreach(std::shared_ptr<AudioDevice> adevice, _devices) {
if (adevice->selectedDesktop) { if (adevice->selectedDesktop) {
qDebug() << "Saving Desktop for" << _mode << "name" << adevice->info.deviceName();
settingDesktop.set(adevice->info.deviceName()); settingDesktop.set(adevice->info.deviceName());
} }
if (adevice->selectedHMD) { if (adevice->selectedHMD) {
qDebug() << "Saving HMD for" << _mode << "name" << adevice->info.deviceName();
settingHMD.set(adevice->info.deviceName()); settingHMD.set(adevice->info.deviceName());
} }
} }
@ -311,7 +309,6 @@ void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
} }
} }
qDebug() << "adding audio device:" << device.display << device.selectedDesktop << device.selectedHMD << _mode;
newDevices.push_back(newDevice(device)); newDevices.push_back(newDevice(device));
} }

View file

@ -32,7 +32,6 @@ public slots:
* @function GooglePoly.setAPIKey * @function GooglePoly.setAPIKey
* @param {string} key * @param {string} key
*/ */
void setAPIKey(const QString& key); void setAPIKey(const QString& key);
/**jsdoc /**jsdoc
@ -42,7 +41,6 @@ public slots:
* @param {string} format * @param {string} format
* @returns {string} * @returns {string}
*/ */
QString getAssetList(const QString& keyword, const QString& category, const QString& format); QString getAssetList(const QString& keyword, const QString& category, const QString& format);
/**jsdoc /**jsdoc
@ -51,7 +49,6 @@ public slots:
* @param {string} category * @param {string} category
* @returns {string} * @returns {string}
*/ */
QString getFBX(const QString& keyword, const QString& category); QString getFBX(const QString& keyword, const QString& category);
/**jsdoc /**jsdoc
@ -60,7 +57,6 @@ public slots:
* @param {string} category * @param {string} category
* @returns {string} * @returns {string}
*/ */
QString getOBJ(const QString& keyword, const QString& category); QString getOBJ(const QString& keyword, const QString& category);
/**jsdoc /**jsdoc
@ -69,7 +65,6 @@ public slots:
* @param {string} category * @param {string} category
* @returns {string} * @returns {string}
*/ */
QString getBlocks(const QString& keyword, const QString& category); QString getBlocks(const QString& keyword, const QString& category);
/**jsdoc /**jsdoc
@ -78,7 +73,6 @@ public slots:
* @param {string} category * @param {string} category
* @returns {string} * @returns {string}
*/ */
QString getGLTF(const QString& keyword, const QString& category); QString getGLTF(const QString& keyword, const QString& category);
/**jsdoc /**jsdoc
@ -87,7 +81,6 @@ public slots:
* @param {string} category * @param {string} category
* @returns {string} * @returns {string}
*/ */
QString getGLTF2(const QString& keyword, const QString& category); QString getGLTF2(const QString& keyword, const QString& category);
/**jsdoc /**jsdoc
@ -96,7 +89,6 @@ public slots:
* @param {string} category * @param {string} category
* @returns {string} * @returns {string}
*/ */
QString getTilt(const QString& keyword, const QString& category); QString getTilt(const QString& keyword, const QString& category);
/**jsdoc /**jsdoc
@ -104,7 +96,6 @@ public slots:
* @param {string} input * @param {string} input
* @returns {string} * @returns {string}
*/ */
QString getModelInfo(const QString& input); QString getModelInfo(const QString& input);
private: private:

View file

@ -87,7 +87,7 @@ public slots:
* Display a dialog with the specified message and an "OK" button. The dialog is non-modal; the script continues without * Display a dialog with the specified message and an "OK" button. The dialog is non-modal; the script continues without
* waiting for a user response. * waiting for a user response.
* @function Window.alert * @function Window.alert
* @param {string} message="" - The message to display. * @param {string} [message=""] - The message to display.
* @example <caption>Display a friendly greeting.</caption> * @example <caption>Display a friendly greeting.</caption>
* Window.alert("Welcome!"); * Window.alert("Welcome!");
* print("Script continues without waiting"); * print("Script continues without waiting");
@ -98,7 +98,7 @@ public slots:
* Prompt the user to confirm something. Displays a modal dialog with a message plus "Yes" and "No" buttons. * Prompt the user to confirm something. Displays a modal dialog with a message plus "Yes" and "No" buttons.
* responds. * responds.
* @function Window.confirm * @function Window.confirm
* @param {string} message="" - The question to display. * @param {string} [message=""] - The question to display.
* @returns {boolean} <code>true</code> if the user selects "Yes", otherwise <code>false</code>. * @returns {boolean} <code>true</code> if the user selects "Yes", otherwise <code>false</code>.
* @example <caption>Ask the user a question requiring a yes/no answer.</caption> * @example <caption>Ask the user a question requiring a yes/no answer.</caption>
* var answer = Window.confirm("Are you sure?"); * var answer = Window.confirm("Are you sure?");
@ -128,8 +128,8 @@ public slots:
* buttons. A {@link Window.promptTextChanged|promptTextChanged} signal is emitted when the user OKs the dialog; no signal * buttons. A {@link Window.promptTextChanged|promptTextChanged} signal is emitted when the user OKs the dialog; no signal
* is emitted if the user cancels the dialog. * is emitted if the user cancels the dialog.
* @function Window.promptAsync * @function Window.promptAsync
* @param {string} message - The question to display. * @param {string} [message=""] - The question to display.
* @param {string} defaultText - The default answer text. * @param {string} [defaultText=""] - The default answer text.
* @example <caption>Ask the user a question requiring a text answer without waiting for the answer.</caption> * @example <caption>Ask the user a question requiring a text answer without waiting for the answer.</caption>
* function onPromptTextChanged(text) { * function onPromptTextChanged(text) {
* print("User answer: " + text); * print("User answer: " + text);
@ -144,8 +144,8 @@ public slots:
/**jsdoc /**jsdoc
* Prompt the user to choose a directory. Displays a modal dialog that navigates the directory tree. * Prompt the user to choose a directory. Displays a modal dialog that navigates the directory tree.
* @function Window.browseDir * @function Window.browseDir
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @returns {string} The path of the directory if one is chosen, otherwise <code>null</code>. * @returns {string} The path of the directory if one is chosen, otherwise <code>null</code>.
* @example <caption>Ask the user to choose a directory.</caption> * @example <caption>Ask the user to choose a directory.</caption>
* var directory = Window.browseDir("Select Directory", Paths.resources); * var directory = Window.browseDir("Select Directory", Paths.resources);
@ -158,8 +158,8 @@ public slots:
* {@link Window.browseDirChanged|browseDirChanged} signal is emitted when a directory is chosen; no signal is emitted if * {@link Window.browseDirChanged|browseDirChanged} signal is emitted when a directory is chosen; no signal is emitted if
* the user cancels the dialog. * the user cancels the dialog.
* @function Window.browseDirAsync * @function Window.browseDirAsync
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @example <caption>Ask the user to choose a directory without waiting for the answer.</caption> * @example <caption>Ask the user to choose a directory without waiting for the answer.</caption>
* function onBrowseDirChanged(directory) { * function onBrowseDirChanged(directory) {
* print("Directory: " + directory); * print("Directory: " + directory);
@ -174,9 +174,9 @@ public slots:
/**jsdoc /**jsdoc
* Prompt the user to choose a file. Displays a modal dialog that navigates the directory tree. * Prompt the user to choose a file. Displays a modal dialog that navigates the directory tree.
* @function Window.browse * @function Window.browse
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and * @param {string} [nameFilter=""] - The types of files to display. Examples: <code>"*.json"</code> and
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified. * <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
* @returns {string} The path and name of the file if one is chosen, otherwise <code>null</code>. * @returns {string} The path and name of the file if one is chosen, otherwise <code>null</code>.
* @example <caption>Ask the user to choose an image file.</caption> * @example <caption>Ask the user to choose an image file.</caption>
@ -190,9 +190,9 @@ public slots:
* {@link Window.browseChanged|browseChanged} signal is emitted when a file is chosen; no signal is emitted if the user * {@link Window.browseChanged|browseChanged} signal is emitted when a file is chosen; no signal is emitted if the user
* cancels the dialog. * cancels the dialog.
* @function Window.browseAsync * @function Window.browseAsync
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and * @param {string} [nameFilter=""] - The types of files to display. Examples: <code>"*.json"</code> and
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified. * <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
* @example <caption>Ask the user to choose an image file without waiting for the answer.</caption> * @example <caption>Ask the user to choose an image file without waiting for the answer.</caption>
* function onBrowseChanged(filename) { * function onBrowseChanged(filename) {
@ -209,9 +209,9 @@ public slots:
* Prompt the user to specify the path and name of a file to save to. Displays a model dialog that navigates the directory * Prompt the user to specify the path and name of a file to save to. Displays a model dialog that navigates the directory
* tree and allows the user to type in a file name. * tree and allows the user to type in a file name.
* @function Window.save * @function Window.save
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and * @param {string} [nameFilter=""] - The types of files to display. Examples: <code>"*.json"</code> and
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified. * <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
* @returns {string} The path and name of the file if one is specified, otherwise <code>null</code>. If a single file type * @returns {string} The path and name of the file if one is specified, otherwise <code>null</code>. If a single file type
* is specified in the nameFilter, that file type extension is automatically appended to the result when appropriate. * is specified in the nameFilter, that file type extension is automatically appended to the result when appropriate.
@ -226,9 +226,9 @@ public slots:
* directory tree and allows the user to type in a file name. A {@link Window.saveFileChanged|saveFileChanged} signal is * directory tree and allows the user to type in a file name. A {@link Window.saveFileChanged|saveFileChanged} signal is
* emitted when a file is specified; no signal is emitted if the user cancels the dialog. * emitted when a file is specified; no signal is emitted if the user cancels the dialog.
* @function Window.saveAsync * @function Window.saveAsync
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and * @param {string} [nameFilter=""] - The types of files to display. Examples: <code>"*.json"</code> and
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified. * <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
* @example <caption>Ask the user to specify a file to save to without waiting for an answer.</caption> * @example <caption>Ask the user to specify a file to save to without waiting for an answer.</caption>
* function onSaveFileChanged(filename) { * function onSaveFileChanged(filename) {
@ -245,9 +245,9 @@ public slots:
* Prompt the user to choose an Asset Server item. Displays a modal dialog that navigates the tree of assets on the Asset * Prompt the user to choose an Asset Server item. Displays a modal dialog that navigates the tree of assets on the Asset
* Server. * Server.
* @function Window.browseAssets * @function Window.browseAssets
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and * @param {string} [nameFilter=""] - The types of files to display. Examples: <code>"*.json"</code> and
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified. * <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
* @returns {string} The path and name of the asset if one is chosen, otherwise <code>null</code>. * @returns {string} The path and name of the asset if one is chosen, otherwise <code>null</code>.
* @example <caption>Ask the user to select an FBX asset.</caption> * @example <caption>Ask the user to select an FBX asset.</caption>
@ -261,9 +261,9 @@ public slots:
* Asset Server. A {@link Window.assetsDirChanged|assetsDirChanged} signal is emitted when an asset is chosen; no signal is * Asset Server. A {@link Window.assetsDirChanged|assetsDirChanged} signal is emitted when an asset is chosen; no signal is
* emitted if the user cancels the dialog. * emitted if the user cancels the dialog.
* @function Window.browseAssetsAsync * @function Window.browseAssetsAsync
* @param {string} title="" - The title to display at the top of the dialog. * @param {string} [title=""] - The title to display at the top of the dialog.
* @param {string} directory="" - The initial directory to start browsing at. * @param {string} [directory=""] - The initial directory to start browsing at.
* @param {string} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and * @param {string} [nameFilter=""] - The types of files to display. Examples: <code>"*.json"</code> and
* <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified. * <code>"Images (*.png *.jpg *.svg)"</code>. All files are displayed if a filter isn't specified.
* @example * @example
* function onAssetsDirChanged(asset) { * function onAssetsDirChanged(asset) {
@ -280,7 +280,7 @@ public slots:
* Open the Asset Browser dialog. If a file to upload is specified, the user is prompted to enter the folder and name to * Open the Asset Browser dialog. If a file to upload is specified, the user is prompted to enter the folder and name to
* map the file to on the asset server. * map the file to on the asset server.
* @function Window.showAssetServer * @function Window.showAssetServer
* @param {string} uploadFile="" - The path and name of a file to upload to the asset server. * @param {string} [uploadFile=""] - The path and name of a file to upload to the asset server.
* @example <caption>Upload a file to the asset server.</caption> * @example <caption>Upload a file to the asset server.</caption>
* var filename = Window.browse("Select File to Add to Asset Server", Paths.resources); * var filename = Window.browse("Select File to Add to Asset Server", Paths.resources);
* print("File: " + filename); * print("File: " + filename);
@ -317,14 +317,14 @@ public slots:
* NOTE: to provide a non-default value - all previous parameters must be provided. * NOTE: to provide a non-default value - all previous parameters must be provided.
* General > Snapshots. * General > Snapshots.
* @function Window.takeSnapshot * @function Window.takeSnapshot
* @param {boolean} notify=true - This value is passed on through the {@link Window.stillSnapshotTaken|stillSnapshotTaken} * @param {boolean} [notify=true] - This value is passed on through the {@link Window.stillSnapshotTaken|stillSnapshotTaken}
* signal. * signal.
* @param {boolean} includeAnimated=false - If <code>true</code>, a moving image is captured as an animated GIF in addition * @param {boolean} [includeAnimated=false] - If <code>true</code>, a moving image is captured as an animated GIF in addition
* to a still image. * to a still image.
* @param {number} aspectRatio=0 - The width/height ratio of the snapshot required. If the value is <code>0</code> the * @param {number} [aspectRatio=0] - The width/height ratio of the snapshot required. If the value is <code>0</code> the
* full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the * full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the
* dimensions is adjusted in order to match the aspect ratio. * dimensions is adjusted in order to match the aspect ratio.
* @param {string} filename="" - If this parameter is not given, the image will be saved as 'hifi-snap-by-<user name>-YYYY-MM-DD_HH-MM-SS'. * @param {string} [filename=""] - If this parameter is not given, the image will be saved as 'hifi-snap-by-<user name>-YYYY-MM-DD_HH-MM-SS'.
* If this parameter is <code>""</code> then the image will be saved as ".jpg". * If this parameter is <code>""</code> then the image will be saved as ".jpg".
* Otherwise, the image will be saved to this filename, with an appended ".jpg". * Otherwise, the image will be saved to this filename, with an appended ".jpg".
* *
@ -358,7 +358,7 @@ public slots:
* Takes a still snapshot of the current view from the secondary camera that can be set up through the {@link Render} API. * Takes a still snapshot of the current view from the secondary camera that can be set up through the {@link Render} API.
* NOTE: to provide a non-default value - all previous parameters must be provided. * NOTE: to provide a non-default value - all previous parameters must be provided.
* @function Window.takeSecondaryCameraSnapshot * @function Window.takeSecondaryCameraSnapshot
* @param {string} filename="" - If this parameter is not given, the image will be saved as 'hifi-snap-by-<user name>-YYYY-MM-DD_HH-MM-SS'. * @param {string} [filename=""] - If this parameter is not given, the image will be saved as 'hifi-snap-by-<user name>-YYYY-MM-DD_HH-MM-SS'.
* If this parameter is <code>""</code> then the image will be saved as ".jpg". * If this parameter is <code>""</code> then the image will be saved as ".jpg".
* Otherwise, the image will be saved to this filename, with an appended ".jpg". * Otherwise, the image will be saved to this filename, with an appended ".jpg".
* *
@ -397,7 +397,7 @@ public slots:
* has been prepared. * has been prepared.
* @function Window.shareSnapshot * @function Window.shareSnapshot
* @param {string} path - The path and name of the image file to share. * @param {string} path - The path and name of the image file to share.
* @param {string} href="" - The metaverse location where the snapshot was taken. * @param {string} [href=""] - The metaverse location where the snapshot was taken.
*/ */
void shareSnapshot(const QString& path, const QUrl& href = QUrl("")); void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));

View file

@ -26,10 +26,10 @@ class AvatarInputs : public QObject {
/**jsdoc /**jsdoc
* API to help manage your Avatar's input * API to help manage your Avatar's input
* @namespace AvatarInputs * @namespace AvatarInputs
* @param {boolean} cameraEnabled * @property {boolean} cameraEnabled <em>Read-only.</em>
* @param {boolean} cameraMuted * @property {boolean} cameraMuted <em>Read-only.</em>
* @param {boolean} isHMD * @property {boolean} isHMD <em>Read-only.</em>
* @param {boolean} showAudioTools * @property {boolean} showAudioTools
*/ */
AI_PROPERTY(bool, cameraEnabled, false) AI_PROPERTY(bool, cameraEnabled, false)
@ -46,8 +46,8 @@ public:
* @param {number} loudness * @param {number} loudness
* @returns {number} * @returns {number}
*/ */
Q_INVOKABLE float loudnessToAudioLevel(float loudness); Q_INVOKABLE float loudnessToAudioLevel(float loudness);
AvatarInputs(QObject* parent = nullptr); AvatarInputs(QObject* parent = nullptr);
void update(); void update();
bool showAudioTools() const { return _showAudioTools; } bool showAudioTools() const { return _showAudioTools; }
@ -58,7 +58,6 @@ public slots:
* @function AvatarInputs.setShowAudioTools * @function AvatarInputs.setShowAudioTools
* @param {boolean} showAudioTools * @param {boolean} showAudioTools
*/ */
void setShowAudioTools(bool showAudioTools); void setShowAudioTools(bool showAudioTools);
signals: signals:
@ -67,14 +66,12 @@ signals:
* @function AvatarInputs.cameraEnabledChanged * @function AvatarInputs.cameraEnabledChanged
* @returns {Signal} * @returns {Signal}
*/ */
void cameraEnabledChanged(); void cameraEnabledChanged();
/**jsdoc /**jsdoc
* @function AvatarInputs.cameraMutedChanged * @function AvatarInputs.cameraMutedChanged
* @returns {Signal} * @returns {Signal}
*/ */
void cameraMutedChanged(); void cameraMutedChanged();
/**jsdoc /**jsdoc
@ -89,7 +86,6 @@ signals:
* @param {boolean} show * @param {boolean} show
* @returns {Signal} * @returns {Signal}
*/ */
void showAudioToolsChanged(bool show); void showAudioToolsChanged(bool show);
protected: protected:
@ -97,13 +93,11 @@ protected:
/**jsdoc /**jsdoc
* @function AvatarInputs.resetSensors * @function AvatarInputs.resetSensors
*/ */
Q_INVOKABLE void resetSensors(); Q_INVOKABLE void resetSensors();
/**jsdoc /**jsdoc
* @function AvatarInputs.toggleCameraMute * @function AvatarInputs.toggleCameraMute
*/ */
Q_INVOKABLE void toggleCameraMute(); Q_INVOKABLE void toggleCameraMute();
private: private:

View file

@ -80,7 +80,6 @@ void DialogsManager::showFeed() {
} }
void DialogsManager::setDomainConnectionFailureVisibility(bool visible) { void DialogsManager::setDomainConnectionFailureVisibility(bool visible) {
qDebug() << "DialogsManager::setDomainConnectionFailureVisibility: visible" << visible;
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));

View file

@ -20,11 +20,6 @@
#include <FBXReader.h> #include <FBXReader.h>
#include <ResourceCache.h> #include <ResourceCache.h>
/**jsdoc
* API to manage Animation Cache resources
* @namespace AnimationCache
*/
class Animation; class Animation;
typedef QSharedPointer<Animation> AnimationPointer; typedef QSharedPointer<Animation> AnimationPointer;
@ -35,79 +30,67 @@ class AnimationCache : public ResourceCache, public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
// Copied over from ResourceCache (see ResourceCache.h for reason)
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
/**jsdoc /**jsdoc
* API to manage animation cache resources.
* @namespace AnimationCache * @namespace AnimationCache
* @property numTotal {number} total number of total resources *
* @property numCached {number} total number of cached resource * @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
* @property sizeTotal {number} size in bytes of all resources * @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
* @property sizeCached {number} size in bytes of all cached resources * @property {number} sizeTotal - Size in bytes of all resources. <em>Read-only.</em>
* @property {number} sizeCached - Size in bytes of all cached resources. <em>Read-only.</em>
*/ */
/**jsdoc // Functions are copied over from ResourceCache (see ResourceCache.h for reason).
* Returns the total number of resources
* @function AnimationCache.getNumTotalResources
* @returns {number}
*/
/**jsdoc /**jsdoc
* Returns the total size in bytes of all resources * Get the list of all resource URLs.
* @function AnimationCache.getSizeTotalResources
* @returns {number}
*/
/**jsdoc
* Returns the total number of cached resources
* @function AnimationCache.getNumCachedResources
* @returns {number}
*/
/**jsdoc
* Returns the total size in bytes of cached resources
* @function AnimationCache.getSizeCachedResources
* @returns {number}
*/
/**jsdoc
* Returns list of all resource urls
* @function AnimationCache.getResourceList * @function AnimationCache.getResourceList
* @returns {string[]} * @return {string[]}
*/ */
/**jsdoc /**jsdoc
* Asynchronously loads a resource from the spedified URL and returns it.
* @param url {string} url of resource to load
* @param fallback {string} fallback URL if load of the desired url fails
* @function AnimationCache.getResource
* @returns {Resource}
*/
/**jsdoc
* Prefetches a resource.
* @param url {string} url of resource to load
* @function AnimationCache.prefetch
* @returns {Resource}
*/
/**jsdoc
* @param {number} deltaSize
* @function AnimationCache.updateTotalSize
* @returns {Resource}
*/
/**jsdoc
* @function AnimationCache.dirty * @function AnimationCache.dirty
* @returns {Signal} * @returns {Signal}
*/ */
/**jsdoc
* @function AnimationCache.updateTotalSize
* @param {number} deltaSize
*/
/**jsdoc
* @function AnimationCache.prefetch
* @param {string} url
* @param {object} extra
* @returns {object}
*/
/**jsdoc
* Asynchronously loads a resource from the specified URL and returns it.
* @function AnimationCache.getResource
* @param {string} url - URL of the resource to load.
* @param {string} [fallback=""] - Fallback URL if load of the desired URL fails.
* @param {} [extra=null]
* @return {Resource}
*/
/**jsdoc
* Prefetches a resource.
* @function AnimationCache.prefetch
* @param {string} url - URL of the resource to prefetch.
* @return {Resource}
*/
/**jsdoc /**jsdoc
* Returns animation resource for particular animation * Returns animation resource for particular animation.
* @function AnimationCache.getAnimation * @function AnimationCache.getAnimation
* @param url {string} url to load * @param {string} url - URL to load.
* @returns {Resource} animation * @returns {Resource} animation
*/ */
Q_INVOKABLE AnimationPointer getAnimation(const QString& url) { return getAnimation(QUrl(url)); } Q_INVOKABLE AnimationPointer getAnimation(const QString& url) { return getAnimation(QUrl(url)); }
Q_INVOKABLE AnimationPointer getAnimation(const QUrl& url); Q_INVOKABLE AnimationPointer getAnimation(const QUrl& url);

View file

@ -40,65 +40,135 @@ class AudioStreamStatsInterface : public QObject {
Q_OBJECT Q_OBJECT
/**jsdoc /**jsdoc
* Audio stats from the Audio Mixer * @class AudioStats.AudioStreamStats
* @namespace AudioStats.mixerStream * @property {number} lossRate <em>Read-only.</em>
* @param {number} lossRate * @property {number} lossCount <em>Read-only.</em>
* @param {number} lossCount * @property {number} lossRateWindow <em>Read-only.</em>
* @param {number} lossRateWindow * @property {number} lossCountWindow <em>Read-only.</em>
* @param {number} lossCountWindow * @property {number} framesDesired <em>Read-only.</em>
* @param {number} framesDesired * @property {number} framesAvailable <em>Read-only.</em>
* @param {number} framesAvailable * @property {number} framesAvailableAvg <em>Read-only.</em>
* @param {number} framesAvailableAvg * @property {number} unplayedMsMax <em>Read-only.</em>
* @param {number} unplayedMsMax * @property {number} starveCount <em>Read-only.</em>
* @param {number} starveCount * @property {number} lastStarveDurationCount <em>Read-only.</em>
* @param {number} lastStarveDurationCount * @property {number} dropCount <em>Read-only.</em>
* @param {number} dropCount * @property {number} overflowCount <em>Read-only.</em>
* @param {number} overflowCount * @property {number} timegapMsMax <em>Read-only.</em>
* @param {number} timegapMsMax * @property {number} timegapMsAvg <em>Read-only.</em>
* @param {number} timegapMsAvg * @property {number} timegapMsMaxWindow <em>Read-only.</em>
* @param {number} timegapMsMaxWindow * @property {number} timegapMsAvgWindow <em>Read-only.</em>
* @param {number} timegapMsAvgWindow
*/ */
/**jsdoc /**jsdoc
* Audio stats from the Client Mixer * @function AudioStats.AudioStreamStats.lossRateChanged
* @namespace AudioStats.clientMixer
* @param {number} lossRate * @param {number} lossRate
* @param {number} lossCount * @returns {Signal}
* @param {number} lossRateWindow
* @param {number} lossCountWindow
* @param {number} framesDesired
* @param {number} framesAvailable
* @param {number} framesAvailableAvg
* @param {number} unplayedMsMax
* @param {number} starveCount
* @param {number} lastStarveDurationCount
* @param {number} dropCount
* @param {number} overflowCount
* @param {number} timegapMsMax
* @param {number} timegapMsAvg
* @param {number} timegapMsMaxWindow
* @param {number} timegapMsAvgWindow
*/ */
AUDIO_PROPERTY(float, lossRate) AUDIO_PROPERTY(float, lossRate)
/**jsdoc
* @function AudioStats.AudioStreamStats.lossCountChanged
* @param {number} lossCount
* @returns {Signal}
*/
AUDIO_PROPERTY(float, lossCount) AUDIO_PROPERTY(float, lossCount)
/**jsdoc
* @function AudioStats.AudioStreamStats.lossRateWindowChanged
* @param {number} lossRateWindow
* @returns {Signal}
*/
AUDIO_PROPERTY(float, lossRateWindow) AUDIO_PROPERTY(float, lossRateWindow)
/**jsdoc
* @function AudioStats.AudioStreamStats.lossCountWindowChanged
* @param {number} lossCountWindow
* @returns {Signal}
*/
AUDIO_PROPERTY(float, lossCountWindow) AUDIO_PROPERTY(float, lossCountWindow)
/**jsdoc
* @function AudioStats.AudioStreamStats.framesDesiredChanged
* @param {number} framesDesired
* @returns {Signal}
*/
AUDIO_PROPERTY(int, framesDesired) AUDIO_PROPERTY(int, framesDesired)
/**jsdoc
* @function AudioStats.AudioStreamStats.framesAvailableChanged
* @param {number} framesAvailable
* @returns {Signal}
*/
AUDIO_PROPERTY(int, framesAvailable) AUDIO_PROPERTY(int, framesAvailable)
/**jsdoc
* @function AudioStats.AudioStreamStats.framesAvailableAvgChanged
* @param {number} framesAvailableAvg
* @returns {Signal}
*/
AUDIO_PROPERTY(int, framesAvailableAvg) AUDIO_PROPERTY(int, framesAvailableAvg)
/**jsdoc
* @function AudioStats.AudioStreamStats.unplayedMsMaxChanged
* @param {number} unplayedMsMax
* @returns {Signal}
*/
AUDIO_PROPERTY(float, unplayedMsMax) AUDIO_PROPERTY(float, unplayedMsMax)
/**jsdoc
* @function AudioStats.AudioStreamStats.starveCountChanged
* @param {number} starveCount
* @returns {Signal}
*/
AUDIO_PROPERTY(int, starveCount) AUDIO_PROPERTY(int, starveCount)
/**jsdoc
* @function AudioStats.AudioStreamStats.lastStarveDurationCountChanged
* @param {number} lastStarveDurationCount
* @returns {Signal}
*/
AUDIO_PROPERTY(int, lastStarveDurationCount) AUDIO_PROPERTY(int, lastStarveDurationCount)
/**jsdoc
* @function AudioStats.AudioStreamStats.dropCountChanged
* @param {number} dropCount
* @returns {Signal}
*/
AUDIO_PROPERTY(int, dropCount) AUDIO_PROPERTY(int, dropCount)
/**jsdoc
* @function AudioStats.AudioStreamStats.overflowCountChanged
* @param {number} overflowCount
* @returns {Signal}
*/
AUDIO_PROPERTY(int, overflowCount) AUDIO_PROPERTY(int, overflowCount)
/**jsdoc
* @function AudioStats.AudioStreamStats.timegapMsMaxChanged
* @param {number} timegapMsMax
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, timegapMsMax) AUDIO_PROPERTY(quint64, timegapMsMax)
/**jsdoc
* @function AudioStats.AudioStreamStats.timegapMsAvgChanged
* @param {number} timegapMsAvg
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, timegapMsAvg) AUDIO_PROPERTY(quint64, timegapMsAvg)
/**jsdoc
* @function AudioStats.AudioStreamStats.timegapMsMaxWindowChanged
* @param {number} timegapMsMaxWindow
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, timegapMsMaxWindow) AUDIO_PROPERTY(quint64, timegapMsMaxWindow)
/**jsdoc
* @function AudioStats.AudioStreamStats.timegapMsAvgWindowChanged
* @param {number} timegapMsAvgWindow
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, timegapMsAvgWindow) AUDIO_PROPERTY(quint64, timegapMsAvgWindow)
public: public:
@ -113,31 +183,82 @@ class AudioStatsInterface : public QObject {
Q_OBJECT Q_OBJECT
/**jsdoc /**jsdoc
* Audio stats from the client * Audio stats from the client.
* @namespace AudioStats * @namespace AudioStats
* @param {number} pingMs * @property {number} pingMs <em>Read-only.</em>
* @param {number} inputReadMsMax * @property {number} inputReadMsMax <em>Read-only.</em>
* @param {number} inputUnplayedMsMax * @property {number} inputUnplayedMsMax <em>Read-only.</em>
* @param {number} outputUnplayedMsMax * @property {number} outputUnplayedMsMax <em>Read-only.</em>
* @param {number} sentTimegapMsMax * @property {number} sentTimegapMsMax <em>Read-only.</em>
* @param {number} sentTimegapMsAvg * @property {number} sentTimegapMsAvg <em>Read-only.</em>
* @param {number} sentTimegapMsMaxWindow * @property {number} sentTimegapMsMaxWindow <em>Read-only.</em>
* @param {number} sentTimegapMsAvgWindow * @property {number} sentTimegapMsAvgWindow <em>Read-only.</em>
* @property {AudioStats.AudioStreamStats} clientStream <em>Read-only.</em>
* @property {AudioStats.AudioStreamStats} mixerStream <em>Read-only.</em>
*/ */
/**jsdoc
* @function AudioStats.pingMsChanged
* @param {number} pingMs
* @returns {Signal}
*/
AUDIO_PROPERTY(float, pingMs); AUDIO_PROPERTY(float, pingMs);
/**jsdoc
* @function AudioStats.inputReadMsMaxChanged
* @param {number} inputReadMsMax
* @returns {Signal}
*/
AUDIO_PROPERTY(float, inputReadMsMax); AUDIO_PROPERTY(float, inputReadMsMax);
/**jsdoc
* @function AudioStats.inputUnplayedMsMaxChanged
* @param {number} inputUnplayedMsMax
* @returns {Signal}
*/
AUDIO_PROPERTY(float, inputUnplayedMsMax); AUDIO_PROPERTY(float, inputUnplayedMsMax);
/**jsdoc
* @function AudioStats.outputUnplayedMsMaxChanged
* @param {number} outputUnplayedMsMax
* @returns {Signal}
*/
AUDIO_PROPERTY(float, outputUnplayedMsMax); AUDIO_PROPERTY(float, outputUnplayedMsMax);
/**jsdoc
* @function AudioStats.sentTimegapMsMaxChanged
* @param {number} sentTimegapMsMax
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, sentTimegapMsMax); AUDIO_PROPERTY(quint64, sentTimegapMsMax);
/**jsdoc
* @function AudioStats.sentTimegapMsAvgChanged
* @param {number} sentTimegapMsAvg
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, sentTimegapMsAvg); AUDIO_PROPERTY(quint64, sentTimegapMsAvg);
/**jsdoc
* @function AudioStats.sentTimegapMsMaxWindowChanged
* @param {number} sentTimegapMsMaxWindow
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, sentTimegapMsMaxWindow); AUDIO_PROPERTY(quint64, sentTimegapMsMaxWindow);
/**jsdoc
* @function AudioStats.sentTimegapMsAvgWindowChanged
* @param {number} sentTimegapMsAvgWindow
* @returns {Signal}
*/
AUDIO_PROPERTY(quint64, sentTimegapMsAvgWindow); AUDIO_PROPERTY(quint64, sentTimegapMsAvgWindow);
Q_PROPERTY(AudioStreamStatsInterface* mixerStream READ getMixerStream NOTIFY mixerStreamChanged); Q_PROPERTY(AudioStreamStatsInterface* mixerStream READ getMixerStream NOTIFY mixerStreamChanged);
Q_PROPERTY(AudioStreamStatsInterface* clientStream READ getClientStream NOTIFY clientStreamChanged); Q_PROPERTY(AudioStreamStatsInterface* clientStream READ getClientStream NOTIFY clientStreamChanged);
// FIXME: The injectorStreams property isn't available in JavaScript but the notification signal is.
Q_PROPERTY(QObject* injectorStreams READ getInjectorStreams NOTIFY injectorStreamsChanged); Q_PROPERTY(QObject* injectorStreams READ getInjectorStreams NOTIFY injectorStreamsChanged);
public: public:
@ -159,21 +280,18 @@ signals:
* @function AudioStats.mixerStreamChanged * @function AudioStats.mixerStreamChanged
* @returns {Signal} * @returns {Signal}
*/ */
void mixerStreamChanged(); void mixerStreamChanged();
/**jsdoc /**jsdoc
* @function AudioStats.clientStreamChanged * @function AudioStats.clientStreamChanged
* @returns {Signal} * @returns {Signal}
*/ */
void clientStreamChanged(); void clientStreamChanged();
/**jsdoc /**jsdoc
* @function AudioStats.injectorStreamsChanged * @function AudioStats.injectorStreamsChanged
* @returns {Signal} * @returns {Signal}
*/ */
void injectorStreamsChanged(); void injectorStreamsChanged();
private: private:

View file

@ -10,6 +10,7 @@
// Inline functions to implement audio dynamics processing // Inline functions to implement audio dynamics processing
// //
#include <stddef.h>
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>

View file

@ -16,84 +16,32 @@
#include "Sound.h" #include "Sound.h"
/**jsdoc
* API to manage Sound Cache resources
* @namespace SoundCache
*/
/// Scriptable interface for sound loading. /// Scriptable interface for sound loading.
class SoundCache : public ResourceCache, public Dependency { class SoundCache : public ResourceCache, public Dependency {
Q_OBJECT Q_OBJECT
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
// Copied over from ResourceCache (see ResourceCache.h for reason)
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
/**jsdoc /**jsdoc
* API to manage sound cache resources.
* @namespace SoundCache * @namespace SoundCache
* @property numTotal {number} total number of total resources *
* @property numCached {number} total number of cached resource * @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
* @property sizeTotal {number} size in bytes of all resources * @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
* @property sizeCached {number} size in bytes of all cached resources * @property {number} sizeTotal - Size in bytes of all resources. <em>Read-only.</em>
* @property {number} sizeCached - Size in bytes of all cached resources. <em>Read-only.</em>
*/ */
/**jsdoc
* Returns the total number of resources // Functions are copied over from ResourceCache (see ResourceCache.h for reason).
* @function SoundCache.getNumTotalResources
* @returns {number}
*/
/**jsdoc /**jsdoc
* Returns the total size in bytes of all resources * Get the list of all resource URLs.
* @function SoundCache.getSizeTotalResources
* @returns {number}
*/
/**jsdoc
* Returns the total number of cached resources
* @function SoundCache.getNumCachedResources
* @returns {number}
*/
/**jsdoc
* Returns the total size in bytes of cached resources
* @function SoundCache.getSizeCachedResources
* @returns {number}
*/
/**jsdoc
* Returns list of all resource urls
* @function SoundCache.getResourceList * @function SoundCache.getResourceList
* @returns {string[]} * @return {string[]}
*/
/**jsdoc
* Returns animation resource for particular animation
* @function SoundCache.getAnimation
* @param url {string} url to load
* @returns {Resource} animation
*/
/**jsdoc
* Asynchronously loads a resource from the spedified URL and returns it.
* @param url {string} url of resource to load
* @param fallback {string} fallback URL if load of the desired url fails
* @function SoundCache.getResource
* @returns {Resource}
*/
/**jsdoc
* Prefetches a resource.
* @param url {string} url of resource to load
* @function SoundCache.prefetch
* @returns {Resource}
*/
/**jsdoc
* @param {number} deltaSize
* @function SoundCache.updateTotalSize
* @returns {Resource}
*/ */
/**jsdoc /**jsdoc
@ -101,12 +49,40 @@ public:
* @returns {Signal} * @returns {Signal}
*/ */
/**jsdoc
* @function SoundCache.updateTotalSize
* @param {number} deltaSize
*/
/**jsdoc
* @function SoundCache.prefetch
* @param {string} url
* @param {object} extra
* @returns {object}
*/
/**jsdoc
* Asynchronously loads a resource from the specified URL and returns it.
* @function SoundCache.getResource
* @param {string} url - URL of the resource to load.
* @param {string} [fallback=""] - Fallback URL if load of the desired URL fails.
* @param {} [extra=null]
* @return {Resource}
*/
/**jsdoc
* Prefetches a resource.
* @function SoundCache.prefetch
* @param {string} url - URL of the resource to prefetch.
* @return {Resource}
*/
/**jsdoc /**jsdoc
* @function SoundCache.getSound * @function SoundCache.getSound
* @param {string} url * @param {string} url
* @returns {} * @returns {object}
*/ */
Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url); Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url);
protected: protected:
virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback, virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,

View file

@ -30,15 +30,6 @@
#include "AvatarData.h" #include "AvatarData.h"
/**jsdoc
* The AvatarHashMap API deals with functionality related to Avatar information and connectivity
* @namespace AvatarHashMap
*/
// JSDoc 3.5.5 doesn't augment @property definitions.
// These functions are being copied into Avatar classes which inherit the AvatarHashMap
class AvatarHashMap : public QObject, public Dependency { class AvatarHashMap : public QObject, public Dependency {
Q_OBJECT Q_OBJECT
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
@ -51,26 +42,20 @@ public:
// Currently, your own avatar will be included as the null avatar id. // Currently, your own avatar will be included as the null avatar id.
/**jsdoc /**jsdoc
* @function AvatarHashMap.getAvatarIdentifiers * @function AvatarManager.getAvatarIdentifiers
* @returns {Uuid[]}
*/ */
Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers(); Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers();
/**jsdoc /**jsdoc
* @function AvatarHashMap.getAvatarsInRange * @function AvatarManager.getAvatarsInRange
* @param {Vec3} position * @param {Vec3} position
* @param {float} rangeMeters * @param {number} range
* @returns {string[]} * @returns {Uuid[]}
*/ */
Q_INVOKABLE QVector<QUuid> getAvatarsInRange(const glm::vec3& position, float rangeMeters) const; Q_INVOKABLE QVector<QUuid> getAvatarsInRange(const glm::vec3& position, float rangeMeters) const;
/**jsdoc // No JSDod because it's documwented in AvatarManager.
* @function AvatarHashMap.getAvatar
* @param {string} avatarID
* @returns {ScriptAvatarData}
*/
// Null/Default-constructed QUuids will return MyAvatar // Null/Default-constructed QUuids will return MyAvatar
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
@ -80,73 +65,65 @@ public:
signals: signals:
/**jsdoc /**jsdoc
* @function AvatarHashMap.avatarAddedEvent * @function AvatarManager.avatarAddedEvent
* @param {string} sessionUUID * @param {Uuid} sessionUUID
* @returns {Signal} * @returns {Signal}
*/ */
void avatarAddedEvent(const QUuid& sessionUUID); void avatarAddedEvent(const QUuid& sessionUUID);
/**jsdoc /**jsdoc
* @function AvatarHashMap.avatarRemovedEvent * @function AvatarManager.avatarRemovedEvent
* @param {string} sessionUUID * @param {Uuid} sessionUUID
* @returns {Signal} * @returns {Signal}
*/ */
void avatarRemovedEvent(const QUuid& sessionUUID); void avatarRemovedEvent(const QUuid& sessionUUID);
/**jsdoc /**jsdoc
* @function AvatarHashMap.avatarSessionChangedEvent * @function AvatarManager.avatarSessionChangedEvent
* @param {string} sessionUUID * @param {Uuid} sessionUUID
* @param {string} oldUUID * @param {Uuid} oldSessionUUID
* @returns {Signal} * @returns {Signal}
*/ */
void avatarSessionChangedEvent(const QUuid& sessionUUID,const QUuid& oldUUID); void avatarSessionChangedEvent(const QUuid& sessionUUID,const QUuid& oldUUID);
public slots: public slots:
/**jsdoc /**jsdoc
* @function AvatarHashMap.isAvatarInRange * @function AvatarManager.isAvatarInRange
* @param {string} position * @param {string} position
* @param {string} range * @param {string} range
* @returns {boolean} * @returns {boolean}
*/ */
bool isAvatarInRange(const glm::vec3 & position, const float range); bool isAvatarInRange(const glm::vec3 & position, const float range);
protected slots: protected slots:
/**jsdoc /**jsdoc
* @function AvatarHashMap.sessionUUIDChanged * @function AvatarManager.sessionUUIDChanged
* @param {string} sessionUUID * @param {Uuid} sessionUUID
* @param {string} oldUUID * @param {Uuid} oldSessionUUID
*/ */
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
/**jsdoc /**jsdoc
* @function AvatarHashMap.processAvatarDataPacket * @function AvatarManager.processAvatarDataPacket
* @param {} message * @param {} message
* @param {} sendingNode * @param {} sendingNode
*/ */
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
/**jsdoc /**jsdoc
* @function AvatarHashMap.processAvatarIdentityPacket * @function AvatarManager.processAvatarIdentityPacket
* @param {} message * @param {} message
* @param {} sendingNode * @param {} sendingNode
*/ */
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
/**jsdoc /**jsdoc
* @function AvatarHashMap.processKillAvatar * @function AvatarManager.processKillAvatar
* @param {} message * @param {} message
* @param {} sendingNode * @param {} sendingNode
*/ */
void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
protected: protected:

View file

@ -393,7 +393,7 @@ public slots:
* @param {Entities.EntityType} entityName - The name of the entity to search for. * @param {Entities.EntityType} entityName - The name of the entity to search for.
* @param {Vec3} center - The point about which to search. * @param {Vec3} center - The point about which to search.
* @param {number} radius - The radius within which to search. * @param {number} radius - The radius within which to search.
* @param {bool} caseSensitiveSearch - Choose whether to to return case sensitive results back. * @param {boolean} caseSensitiveSearch - Choose whether to to return case sensitive results back.
* @returns {Uuid[]} An array of entity IDs of the specified type that intersect the search sphere. The array is empty if * @returns {Uuid[]} An array of entity IDs of the specified type that intersect the search sphere. The array is empty if
* no entities could be found. * no entities could be found.
* @example <caption>Get back a list of entities</caption> * @example <caption>Get back a list of entities</caption>

View file

@ -1172,16 +1172,6 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID)
_challengeOwnershipTimeoutTimer->start(5000); _challengeOwnershipTimeoutTimer->start(5000);
} }
void EntityTree::startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode) {
qCDebug(entities) << "'transfer_status' is 'pending', checking again in 90 seconds..." << entityItemID;
QTimer* transferStatusRetryTimer = new QTimer(this);
connect(transferStatusRetryTimer, &QTimer::timeout, this, [=]() {
validatePop(certID, entityItemID, senderNode, true);
});
transferStatusRetryTimer->setSingleShot(true);
transferStatusRetryTimer->start(90000);
}
QByteArray EntityTree::computeNonce(const QString& certID, const QString ownerKey) { QByteArray EntityTree::computeNonce(const QString& certID, const QString ownerKey) {
QUuid nonce = QUuid::createUuid(); //random, 5-hex value, separated by "-" QUuid nonce = QUuid::createUuid(); //random, 5-hex value, separated by "-"
QByteArray nonceBytes = nonce.toByteArray(); QByteArray nonceBytes = nonce.toByteArray();
@ -1321,7 +1311,7 @@ void EntityTree::sendChallengeOwnershipRequestPacket(const QByteArray& certID, c
nodeList->sendPacket(std::move(challengeOwnershipPacket), *(nodeList->nodeWithUUID(QUuid::fromRfc4122(nodeToChallenge)))); nodeList->sendPacket(std::move(challengeOwnershipPacket), *(nodeList->nodeWithUUID(QUuid::fromRfc4122(nodeToChallenge))));
} }
void EntityTree::validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation) { void EntityTree::validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode) {
// Start owner verification. // Start owner verification.
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
// First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint. // First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint.
@ -1352,30 +1342,13 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt
withWriteLock([&] { withWriteLock([&] {
deleteEntity(entityItemID, true); deleteEntity(entityItemID, true);
}); });
} else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") {
if (isRetryingValidation) {
qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID;
withWriteLock([&] {
deleteEntity(entityItemID, true);
});
} else {
if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer",
Q_ARG(const QString&, certID),
Q_ARG(const EntityItemID&, entityItemID),
Q_ARG(const SharedNodePointer&, senderNode));
return;
} else {
startPendingTransferStatusTimer(certID, entityItemID, senderNode);
}
}
} else { } else {
// Second, challenge ownership of the PoP cert // Second, challenge ownership of the PoP cert
// (ignore pending status; a failure will be cleaned up during DDV)
sendChallengeOwnershipPacket(certID, sendChallengeOwnershipPacket(certID,
jsonObject["transfer_recipient_key"].toString(), jsonObject["transfer_recipient_key"].toString(),
entityItemID, entityItemID,
senderNode); senderNode);
} }
} else { } else {
qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID
@ -1619,7 +1592,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
// Delete the entity we just added if it doesn't pass static certificate verification // Delete the entity we just added if it doesn't pass static certificate verification
deleteEntity(entityItemID, true); deleteEntity(entityItemID, true);
} else { } else {
validatePop(properties.getCertificateID(), entityItemID, senderNode, false); validatePop(properties.getCertificateID(), entityItemID, senderNode);
} }
} }

View file

@ -397,12 +397,11 @@ protected:
QHash<EntityItemID, EntityItemPointer> _entitiesToAdd; QHash<EntityItemID, EntityItemPointer> _entitiesToAdd;
Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID); Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID);
Q_INVOKABLE void startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode);
private: private:
void sendChallengeOwnershipPacket(const QString& certID, const QString& ownerKey, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); void sendChallengeOwnershipPacket(const QString& certID, const QString& ownerKey, const EntityItemID& entityItemID, const SharedNodePointer& senderNode);
void sendChallengeOwnershipRequestPacket(const QByteArray& certID, const QByteArray& text, const QByteArray& nodeToChallenge, const SharedNodePointer& senderNode); void sendChallengeOwnershipRequestPacket(const QByteArray& certID, const QByteArray& text, const QByteArray& nodeToChallenge, const SharedNodePointer& senderNode);
void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode);
std::shared_ptr<AvatarData> _myAvatar{ nullptr }; std::shared_ptr<AvatarData> _myAvatar{ nullptr };

View file

@ -996,14 +996,12 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
QByteArray filename = subobject.properties.at(0).toByteArray(); QByteArray filename = subobject.properties.at(0).toByteArray();
QByteArray filepath = filename.replace('\\', '/'); QByteArray filepath = filename.replace('\\', '/');
filename = fileOnUrl(filepath, url); filename = fileOnUrl(filepath, url);
qDebug() << "Filename" << filepath << filename;
_textureFilepaths.insert(getID(object.properties), filepath); _textureFilepaths.insert(getID(object.properties), filepath);
_textureFilenames.insert(getID(object.properties), filename); _textureFilenames.insert(getID(object.properties), filename);
} else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) { } else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) {
// trim the name from the timestamp // trim the name from the timestamp
QString name = QString(subobject.properties.at(0).toByteArray()); QString name = QString(subobject.properties.at(0).toByteArray());
name = name.left(name.indexOf('[')); name = name.left(name.indexOf('['));
qDebug() << "Filename" << name;
_textureNames.insert(getID(object.properties), name); _textureNames.insert(getID(object.properties), name);
} else if (subobject.name == "Texture_Alpha_Source" && subobject.properties.length() >= TEXTURE_ALPHA_SOURCE_MIN_SIZE) { } else if (subobject.name == "Texture_Alpha_Source" && subobject.properties.length() >= TEXTURE_ALPHA_SOURCE_MIN_SIZE) {
tex.assign<uint8_t>(tex.alphaSource, subobject.properties.at(0).value<int>()); tex.assign<uint8_t>(tex.alphaSource, subobject.properties.at(0).value<int>());

View file

@ -21,11 +21,6 @@
#include "FBXReader.h" #include "FBXReader.h"
#include "TextureCache.h" #include "TextureCache.h"
/**jsdoc
* API to manage Model Cache resources
* @namespace ModelCache
*/
// Alias instead of derive to avoid copying // Alias instead of derive to avoid copying
class NetworkTexture; class NetworkTexture;
@ -141,72 +136,62 @@ class ModelCache : public ResourceCache, public Dependency {
Q_OBJECT Q_OBJECT
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
/**jsdoc // Properties are copied over from ResourceCache (see ResourceCache.h for reason).
* @namespace ModelCache
* @property numTotal {number} total number of total resources
* @property numCached {number} total number of cached resource
* @property sizeTotal {number} size in bytes of all resources
* @property sizeCached {number} size in bytes of all cached resources
*/
/**jsdoc /**jsdoc
* Returns the total number of resources * API to manage model cache resources.
* @function ModelCache.getNumTotalResources * @namespace ModelCache
* @returns {number} *
*/ * @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
* @property {number} sizeTotal - Size in bytes of all resources. <em>Read-only.</em>
* @property {number} sizeCached - Size in bytes of all cached resources. <em>Read-only.</em>
*/
// Functions are copied over from ResourceCache (see ResourceCache.h for reason).
/**jsdoc /**jsdoc
* Returns the total size in bytes of all resources * Get the list of all resource URLs.
* @function ModelCache.getSizeTotalResources * @function ModelCache.getResourceList
* @returns {number} * @return {string[]}
*/ */
/**jsdoc /**jsdoc
* Returns the total number of cached resources * @function ModelCache.dirty
* @function ModelCache.getNumCachedResources * @returns {Signal}
* @returns {number} */
*/
/**jsdoc /**jsdoc
* Returns the total size in bytes of cached resources * @function ModelCache.updateTotalSize
* @function ModelCache.getSizeCachedResources * @param {number} deltaSize
* @returns {number} */
*/
/**jsdoc /**jsdoc
* Returns list of all resource urls * @function ModelCache.prefetch
* @function ModelCache.getResourceList * @param {string} url
* @returns {string[]} * @param {object} extra
*/ * @returns {object}
*/
/**jsdoc /**jsdoc
* Asynchronously loads a resource from the spedified URL and returns it. * Asynchronously loads a resource from the specified URL and returns it.
* @param url {string} url of resource to load * @function ModelCache.getResource
* @param fallback {string} fallback URL if load of the desired url fails * @param {string} url - URL of the resource to load.
* @function ModelCache.getResource * @param {string} [fallback=""] - Fallback URL if load of the desired URL fails.
* @returns {Resource} * @param {} [extra=null]
*/ * @return {Resource}
*/
/**jsdoc /**jsdoc
* Prefetches a resource. * Prefetches a resource.
* @param url {string} url of resource to load * @function ModelCache.prefetch
* @function ModelCache.prefetch * @param {string} url - URL of the resource to prefetch.
* @returns {Resource} * @return {Resource}
*/ */
/**jsdoc
* @param {number} deltaSize
* @function ModelCache.updateTotalSize
* @returns {Resource}
*/
/**jsdoc
* @function ModelCache.dirty
* @returns {Signal}
*/
GeometryResource::Pointer getGeometryResource(const QUrl& url, GeometryResource::Pointer getGeometryResource(const QUrl& url,
const QVariantHash& mapping = QVariantHash(), const QVariantHash& mapping = QVariantHash(),

View file

@ -137,10 +137,6 @@ using NetworkTexturePointer = QSharedPointer<NetworkTexture>;
Q_DECLARE_METATYPE(QWeakPointer<NetworkTexture>) Q_DECLARE_METATYPE(QWeakPointer<NetworkTexture>)
/**jsdoc
* API to manage Texture Cache resources
* @namespace TextureCache
*/
/// Stores cached textures, including render-to-texture targets. /// Stores cached textures, including render-to-texture targets.
class TextureCache : public ResourceCache, public Dependency { class TextureCache : public ResourceCache, public Dependency {
@ -148,78 +144,61 @@ class TextureCache : public ResourceCache, public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
// Copied over from ResourceCache (see ResourceCache.h for reason)
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
/**jsdoc /**jsdoc
* @namespace TextureCache * API to manage texture cache resources.
* @property numTotal {number} total number of total resources * @namespace TextureCache
* @property numCached {number} total number of cached resource *
* @property sizeTotal {number} size in bytes of all resources * @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
* @property sizeCached {number} size in bytes of all cached resources * @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
*/ * @property {number} sizeTotal - Size in bytes of all resources. <em>Read-only.</em>
* @property {number} sizeCached - Size in bytes of all cached resources. <em>Read-only.</em>
*/
/**jsdoc
* Returns the total number of resources
* @function TextureCache.getNumTotalResources
* @returns {number}
*/
/**jsdoc // Functions are copied over from ResourceCache (see ResourceCache.h for reason).
* Returns the total size in bytes of all resources
* @function TextureCache.getSizeTotalResources
* @returns {number}
*/
/**jsdoc /**jsdoc
* Returns the total number of cached resources * Get the list of all resource URLs.
* @function TextureCache.getNumCachedResources * @function TextureCache.getResourceList
* @returns {number} * @return {string[]}
*/ */
/**jsdoc /**jsdoc
* Returns the total size in bytes of cached resources * @function TextureCache.dirty
* @function TextureCache.getSizeCachedResources * @returns {Signal}
* @returns {number} */
*/
/**jsdoc /**jsdoc
* Returns list of all resource urls * @function TextureCache.updateTotalSize
* @function TextureCache.getResourceList * @param {number} deltaSize
* @returns {string[]} */
*/
/**jsdoc /**jsdoc
* Returns animation resource for particular animation * @function TextureCache.prefetch
* @function TextureCache.getAnimation * @param {string} url
* @param url {string} url to load * @param {object} extra
* @returns {Resource} animation * @returns {object}
*/ */
/**jsdoc /**jsdoc
* Asynchronously loads a resource from the spedified URL and returns it. * Asynchronously loads a resource from the specified URL and returns it.
* @param url {string} url of resource to load * @function TextureCache.getResource
* @param fallback {string} fallback URL if load of the desired url fails * @param {string} url - URL of the resource to load.
* @function TextureCache.getResource * @param {string} [fallback=""] - Fallback URL if load of the desired URL fails.
* @returns {Resource} * @param {} [extra=null]
*/ * @return {Resource}
*/
/**jsdoc /**jsdoc
* Prefetches a resource. * Prefetches a resource.
* @param url {string} url of resource to load * @function TextureCache.prefetch
* @function TextureCache.prefetch * @param {string} url - URL of the resource to prefetch.
* @returns {Resource} * @return {Resource}
*/ */
/**jsdoc
* @param {number} deltaSize
* @function TextureCache.updateTotalSize
* @returns {Resource}
*/
/**jsdoc
* @function TextureCache.dirty
* @returns {Signal}
*/
/// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture /// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture
/// has two lines: the first, a set of random numbers in [0, 255] to be used as permutation offsets, and /// has two lines: the first, a set of random numbers in [0, 255] to be used as permutation offsets, and
@ -265,6 +244,13 @@ signals:
void spectatorCameraFramebufferReset(); void spectatorCameraFramebufferReset();
protected: protected:
/**jsdoc
* @function TextureCache.prefect
* @param {string} url
* @param {number} type
* @param {number} [maxNumPixels=67108864]
*/
// Overload ResourceCache::prefetch to allow specifying texture type for loads // Overload ResourceCache::prefetch to allow specifying texture type for loads
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS); Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);

View file

@ -31,12 +31,54 @@ public:
BaseAssetScriptingInterface(QObject* parent = nullptr); BaseAssetScriptingInterface(QObject* parent = nullptr);
public slots: public slots:
/**jsdoc
* @function Assets.isValidPath
* @param {string} input
* @returns {boolean}
*/
bool isValidPath(QString input) { return AssetUtils::isValidPath(input); } bool isValidPath(QString input) { return AssetUtils::isValidPath(input); }
/**jsdoc
* @function Assets.isValidFilePath
* @param {string} input
* @returns {boolean}
*/
bool isValidFilePath(QString input) { return AssetUtils::isValidFilePath(input); } bool isValidFilePath(QString input) { return AssetUtils::isValidFilePath(input); }
/**jsdoc
* @function Assets.getATPUrl
* @param {string} input
* @returns {string}
*/
QUrl getATPUrl(QString input) { return AssetUtils::getATPUrl(input); } QUrl getATPUrl(QString input) { return AssetUtils::getATPUrl(input); }
/**jsdoc
* @function Assets.extractAssetHash
* @param {string} input
* @returns {string}
*/
QString extractAssetHash(QString input) { return AssetUtils::extractAssetHash(input); } QString extractAssetHash(QString input) { return AssetUtils::extractAssetHash(input); }
/**jsdoc
* @function Assets.isValidHash
* @param {string} input
* @returns {boolean}
*/
bool isValidHash(QString input) { return AssetUtils::isValidHash(input); } bool isValidHash(QString input) { return AssetUtils::isValidHash(input); }
/**jsdoc
* @function Assets.hashData
* @param {} data
* @returns {object}
*/
QByteArray hashData(const QByteArray& data) { return AssetUtils::hashData(data); } QByteArray hashData(const QByteArray& data) { return AssetUtils::hashData(data); }
/**jsdoc
* @function Assets.hashDataHex
* @param {} data
* @returns {string}
*/
QString hashDataHex(const QByteArray& data) { return hashData(data).toHex(); } QString hashDataHex(const QByteArray& data) { return hashData(data).toHex(); }
protected: protected:

View file

@ -192,8 +192,6 @@ void EntityScriptClient::handleNodeClientConnectionReset(SharedNodePointer node)
return; return;
} }
//qCDebug(entity_script_client) << "EntityScriptClient detected client connection reset handshake with Asset Server - failing any pending requests";
forceFailureOfPendingRequests(node); forceFailureOfPendingRequests(node);
} }

View file

@ -17,7 +17,6 @@
Q_DECLARE_LOGGING_CATEGORY(resourceLog) Q_DECLARE_LOGGING_CATEGORY(resourceLog)
Q_DECLARE_LOGGING_CATEGORY(networking) Q_DECLARE_LOGGING_CATEGORY(networking)
Q_DECLARE_LOGGING_CATEGORY(asset_client) Q_DECLARE_LOGGING_CATEGORY(asset_client)
Q_DECLARE_LOGGING_CATEGORY(entity_script_client)
Q_DECLARE_LOGGING_CATEGORY(messages_client) Q_DECLARE_LOGGING_CATEGORY(messages_client)
#endif // hifi_NetworkLogging_h #endif // hifi_NetworkLogging_h

View file

@ -89,14 +89,13 @@ class ScriptableResource : public QObject {
/**jsdoc /**jsdoc
* @constructor Resource * @constructor Resource
* @property url {string} url of this resource * @property {string} url - URL of this resource.
* @property state {Resource.State} current loading state * @property {Resource.State} state - Current loading state.
*/ */
Q_OBJECT Q_OBJECT
Q_PROPERTY(QUrl url READ getURL) Q_PROPERTY(QUrl url READ getURL)
Q_PROPERTY(int state READ getState NOTIFY stateChanged) Q_PROPERTY(int state READ getState NOTIFY stateChanged)
public: public:
@ -104,11 +103,11 @@ public:
/**jsdoc /**jsdoc
* @name Resource.State * @name Resource.State
* @static * @static
* @property QUEUED {int} The resource is queued up, waiting to be loaded. * @property {number} QUEUED - The resource is queued up, waiting to be loaded.
* @property LOADING {int} The resource is downloading * @property {number} LOADING - The resource is downloading.
* @property LOADED {int} The resource has finished downloaded by is not complete * @property {number} LOADED - The resource has finished downloaded by is not complete.
* @property FINISHED {int} The resource has completly finished loading and is ready. * @property {number} FINISHED - The resource has completely finished loading and is ready.
* @property FAILED {int} Downloading the resource has failed. * @property {number} FAILED - Downloading the resource has failed.
*/ */
enum State { enum State {
@ -124,7 +123,7 @@ public:
virtual ~ScriptableResource() = default; virtual ~ScriptableResource() = default;
/**jsdoc /**jsdoc
* Release this resource * Release this resource.
* @function Resource#release * @function Resource#release
*/ */
Q_INVOKABLE void release(); Q_INVOKABLE void release();
@ -139,18 +138,18 @@ public:
signals: signals:
/**jsdoc /**jsdoc
* Signaled when download progress for this resource has changed * Triggered when download progress for this resource has changed.
* @function Resource#progressChanged * @function Resource#progressChanged
* @param bytesReceived {int} bytes downloaded so far * @param {number} bytesReceived - Byytes downloaded so far.
* @param bytesTotal {int} total number of bytes in the resource * @param {number} bytesTotal - Total number of bytes in the resource.
* @returns {Signal} * @returns {Signal}
*/ */
void progressChanged(uint64_t bytesReceived, uint64_t bytesTotal); void progressChanged(uint64_t bytesReceived, uint64_t bytesTotal);
/**jsdoc /**jsdoc
* Signaled when resource loading state has changed * Triggered when resource loading state has changed.
* @function Resource#stateChanged * @function Resource#stateChanged
* @param bytesReceived {Resource.State} new state * @param {Resource.State} state - New state.
* @returns {Signal} * @returns {Signal}
*/ */
void stateChanged(int state); void stateChanged(int state);
@ -185,14 +184,15 @@ Q_DECLARE_METATYPE(ScriptableResource*);
/// Base class for resource caches. /// Base class for resource caches.
class ResourceCache : public QObject { class ResourceCache : public QObject {
Q_OBJECT Q_OBJECT
// JSDoc 3.5.5 doesn't augment @property definitions.
// These functions are being copied into the different exposed cache classes // JSDoc 3.5.5 doesn't augment namespaces with @property or @function definitions.
// The ResourceCache properties and functions are copied to the different exposed cache classes.
/**jsdoc /**jsdoc
* @namespace ResourceCache * @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
* @property numTotal {number} total number of total resources * @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
* @property numCached {number} total number of cached resource * @property {number} sizeTotal - Size in bytes of all resources. <em>Read-only.</em>
* @property sizeTotal {number} size in bytes of all resources * @property {number} sizeCached - Size in bytes of all cached resources. <em>Read-only.</em>
* @property sizeCached {number} size in bytes of all cached resources
*/ */
Q_PROPERTY(size_t numTotal READ getNumTotalResources NOTIFY dirty) Q_PROPERTY(size_t numTotal READ getNumTotalResources NOTIFY dirty)
Q_PROPERTY(size_t numCached READ getNumCachedResources NOTIFY dirty) Q_PROPERTY(size_t numCached READ getNumCachedResources NOTIFY dirty)
@ -200,36 +200,14 @@ class ResourceCache : public QObject {
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
public: public:
/**jsdoc
* Returns the total number of resources
* @function ResourceCache.getNumTotalResources
* @return {number}
*/
size_t getNumTotalResources() const { return _numTotalResources; } size_t getNumTotalResources() const { return _numTotalResources; }
/**jsdoc
* Returns the total size in bytes of all resources
* @function ResourceCache.getSizeTotalResources
* @return {number}
*/
size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getSizeTotalResources() const { return _totalResourcesSize; }
/**jsdoc
* Returns the total number of cached resources
* @function ResourceCache.getNumCachedResources
* @return {number}
*/
size_t getNumCachedResources() const { return _numUnusedResources; } size_t getNumCachedResources() const { return _numUnusedResources; }
/**jsdoc
* Returns the total size in bytes of cached resources
* @function ResourceCache.getSizeCachedResources
* @return {number}
*/
size_t getSizeCachedResources() const { return _unusedResourcesSize; } size_t getSizeCachedResources() const { return _unusedResourcesSize; }
/**jsdoc /**jsdoc
* Returns list of all resource urls * Get the list of all resource URLs.
* @function ResourceCache.getResourceList * @function ResourceCache.getResourceList
* @return {string[]} * @return {string[]}
*/ */
@ -257,28 +235,45 @@ public:
void clearUnusedResources(); void clearUnusedResources();
signals: signals:
/**jsdoc
* @function ResourceCache.dirty
* @returns {Signal}
*/
void dirty(); void dirty();
protected slots: protected slots:
/**jsdoc
* @function ResourceCache.updateTotalSize
* @param {number} deltaSize
*/
void updateTotalSize(const qint64& deltaSize); void updateTotalSize(const qint64& deltaSize);
/**jsdoc
* @function ResourceCache.prefetch
* @param {string} url
* @param {object} extra
* @returns {object}
*/
// Prefetches a resource to be held by the QScriptEngine. // Prefetches a resource to be held by the QScriptEngine.
// Left as a protected member so subclasses can overload prefetch // Left as a protected member so subclasses can overload prefetch
// and delegate to it (see TextureCache::prefetch(const QUrl&, int). // and delegate to it (see TextureCache::prefetch(const QUrl&, int).
ScriptableResource* prefetch(const QUrl& url, void* extra); ScriptableResource* prefetch(const QUrl& url, void* extra);
/**jsdoc
* Asynchronously loads a resource from the specified URL and returns it.
* @function ResourceCache.getResource
* @param {string} url - URL of the resource to load.
* @param {string} [fallback=""] - Fallback URL if load of the desired URL fails.
* @param {} [extra=null]
* @return {Resource}
*/
/// Loads a resource from the specified URL and returns it. /// Loads a resource from the specified URL and returns it.
/// If the caller is on a different thread than the ResourceCache, /// If the caller is on a different thread than the ResourceCache,
/// returns an empty smart pointer and loads its asynchronously. /// returns an empty smart pointer and loads its asynchronously.
/// \param fallback a fallback URL to load if the desired one is unavailable /// \param fallback a fallback URL to load if the desired one is unavailable
/// \param extra extra data to pass to the creator, if appropriate /// \param extra extra data to pass to the creator, if appropriate
/**jsdoc
* Asynchronously loads a resource from the spedified URL and returns it.
* @param url {string} url of resource to load
* @param fallback {string} fallback URL if load of the desired url fails
* @function ResourceCache.getResource
* @return {Resource}
*/
QSharedPointer<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(), QSharedPointer<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(),
void* extra = NULL); void* extra = NULL);
@ -292,8 +287,8 @@ protected:
// the QScriptEngine will delete the pointer when it is garbage collected. // the QScriptEngine will delete the pointer when it is garbage collected.
/**jsdoc /**jsdoc
* Prefetches a resource. * Prefetches a resource.
* @param url {string} url of resource to load
* @function ResourceCache.prefetch * @function ResourceCache.prefetch
* @param {string} url - URL of the resource to prefetch.
* @return {Resource} * @return {Resource}
*/ */
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url) { return prefetch(url, nullptr); } Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url) { return prefetch(url, nullptr); }

View file

@ -795,9 +795,10 @@ QString getMarketplaceID(const QString& urlString) {
} }
bool Octree::readFromURL(const QString& urlString) { bool Octree::readFromURL(const QString& urlString) {
QString marketplaceID = getMarketplaceID(urlString); QString trimmedUrl = urlString.trimmed();
QString marketplaceID = getMarketplaceID(trimmedUrl);
auto request = auto request =
std::unique_ptr<ResourceRequest>(DependencyManager::get<ResourceManager>()->createResourceRequest(this, urlString)); std::unique_ptr<ResourceRequest>(DependencyManager::get<ResourceManager>()->createResourceRequest(this, trimmedUrl));
if (!request) { if (!request) {
return false; return false;

View file

@ -16,6 +16,7 @@
#include "AbstractViewStateInterface.h" #include "AbstractViewStateInterface.h"
#include "RenderUtilsLogging.h" #include "RenderUtilsLogging.h"
#include "DebugDraw.h" #include "DebugDraw.h"
#include "StencilMaskPass.h"
#include "animdebugdraw_vert.h" #include "animdebugdraw_vert.h"
#include "animdebugdraw_frag.h" #include "animdebugdraw_frag.h"
@ -70,7 +71,7 @@ public:
typedef render::Payload<AnimDebugDrawData> AnimDebugDrawPayload; typedef render::Payload<AnimDebugDrawData> AnimDebugDrawPayload;
namespace render { namespace render {
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return (data->_isVisible ? ItemKey::Builder::opaqueShape() : ItemKey::Builder::opaqueShape().withInvisible()).withTagBits(ItemKey::TAG_BITS_ALL); } template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return (data->_isVisible ? ItemKey::Builder::transparentShape() : ItemKey::Builder::transparentShape().withInvisible()).withTagBits(ItemKey::TAG_BITS_ALL); }
template <> const Item::Bound payloadGetBound(const AnimDebugDrawData::Pointer& data) { return data->_bound; } template <> const Item::Bound payloadGetBound(const AnimDebugDrawData::Pointer& data) { return data->_bound; }
template <> void payloadRender(const AnimDebugDrawData::Pointer& data, RenderArgs* args) { template <> void payloadRender(const AnimDebugDrawData::Pointer& data, RenderArgs* args) {
data->render(args); data->render(args);
@ -104,6 +105,7 @@ AnimDebugDraw::AnimDebugDraw() :
state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA,
gpu::State::BLEND_OP_ADD, gpu::State::ONE); gpu::State::BLEND_OP_ADD, gpu::State::ONE);
PrepareStencil::testMaskDrawShape(*state.get());
auto vertShader = animdebugdraw_vert::getShader(); auto vertShader = animdebugdraw_vert::getShader();
auto fragShader = animdebugdraw_frag::getShader(); auto fragShader = animdebugdraw_frag::getShader();
auto program = gpu::Shader::createProgram(vertShader, fragShader); auto program = gpu::Shader::createProgram(vertShader, fragShader);

View file

@ -198,7 +198,7 @@ Antialiasing::~Antialiasing() {
_antialiasingTextures[1].reset(); _antialiasingTextures[1].reset();
} }
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(const render::RenderContextPointer& renderContext) {
if (!_antialiasingPipeline) { if (!_antialiasingPipeline) {
@ -207,17 +207,6 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings; gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("taaParamsBuffer"), AntialiasingPass_ParamsSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), AntialiasingPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("historyMap"), AntialiasingPass_HistoryMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), AntialiasingPass_SourceMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("velocityMap"), AntialiasingPass_VelocityMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), AntialiasingPass_DepthMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); gpu::StatePointer state = gpu::StatePointer(new gpu::State());
@ -225,6 +214,21 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
// Good to go add the brand new pipeline // Good to go add the brand new pipeline
_antialiasingPipeline = gpu::Pipeline::create(program, state); _antialiasingPipeline = gpu::Pipeline::create(program, state);
gpu::doInBatch("SurfaceGeometryPass::CurvaturePipeline", renderContext->args->_context, [program](gpu::Batch& batch) {
batch.runLambda([program]() {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("taaParamsBuffer"), AntialiasingPass_ParamsSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), AntialiasingPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("historyMap"), AntialiasingPass_HistoryMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), AntialiasingPass_SourceMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("velocityMap"), AntialiasingPass_VelocityMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), AntialiasingPass_DepthMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
});
});
} }
return _antialiasingPipeline; return _antialiasingPipeline;
@ -347,7 +351,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
batch.setViewportTransform(args->_viewport); batch.setViewportTransform(args->_viewport);
// TAA step // TAA step
getAntialiasingPipeline(); getAntialiasingPipeline(renderContext);
batch.setResourceFramebufferSwapChainTexture(AntialiasingPass_HistoryMapSlot, _antialiasingBuffers, 0); batch.setResourceFramebufferSwapChainTexture(AntialiasingPass_HistoryMapSlot, _antialiasingBuffers, 0);
batch.setResourceTexture(AntialiasingPass_SourceMapSlot, sourceBuffer->getRenderBuffer(0)); batch.setResourceTexture(AntialiasingPass_SourceMapSlot, sourceBuffer->getRenderBuffer(0));
batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, velocityBuffer->getVelocityTexture()); batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, velocityBuffer->getVelocityTexture());
@ -358,7 +362,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, deferredFrameTransform->getFrameTransformBuffer()); batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, deferredFrameTransform->getFrameTransformBuffer());
batch.setFramebufferSwapChain(_antialiasingBuffers, 1); batch.setFramebufferSwapChain(_antialiasingBuffers, 1);
batch.setPipeline(getAntialiasingPipeline()); batch.setPipeline(getAntialiasingPipeline(renderContext));
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
// Blend step // Blend step

View file

@ -174,7 +174,7 @@ public:
void configure(const Config& config); void configure(const Config& config);
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
const gpu::PipelinePointer& getAntialiasingPipeline(); const gpu::PipelinePointer& getAntialiasingPipeline(const render::RenderContextPointer& renderContext);
const gpu::PipelinePointer& getBlendPipeline(); const gpu::PipelinePointer& getBlendPipeline();
const gpu::PipelinePointer& getDebugBlendPipeline(); const gpu::PipelinePointer& getDebugBlendPipeline();

View file

@ -168,7 +168,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
outputs.edit4() = halfNormalTexture; outputs.edit4() = halfNormalTexture;
auto linearDepthPipeline = getLinearDepthPipeline(renderContext); auto linearDepthPipeline = getLinearDepthPipeline(renderContext);
auto downsamplePipeline = getDownsamplePipeline(); auto downsamplePipeline = getDownsamplePipeline(renderContext);
auto depthViewport = args->_viewport; auto depthViewport = args->_viewport;
auto halfViewport = depthViewport >> 1; auto halfViewport = depthViewport >> 1;
@ -241,19 +241,12 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline(const render
} }
const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() { const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline(const render::RenderContextPointer& renderContext) {
if (!_downsamplePipeline) { if (!_downsamplePipeline) {
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
auto ps = surfaceGeometry_downsampleDepthNormal_frag::getShader(); auto ps = surfaceGeometry_downsampleDepthNormal_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DepthLinearPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), DepthLinearPass_DepthMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DepthLinearPass_NormalMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); gpu::StatePointer state = gpu::StatePointer(new gpu::State());
PrepareStencil::testShape(*state); PrepareStencil::testShape(*state);
@ -261,6 +254,16 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() {
// Good to go add the brand new pipeline // Good to go add the brand new pipeline
_downsamplePipeline = gpu::Pipeline::create(program, state); _downsamplePipeline = gpu::Pipeline::create(program, state);
gpu::doInBatch("LinearDepthPass::run", renderContext->args->_context, [program](gpu::Batch& batch) {
batch.runLambda([program]() {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("deferredFrameTransformBuffer", DepthLinearPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding("linearDepthMap", DepthLinearPass_DepthMapSlot));
slotBindings.insert(gpu::Shader::Binding("normalMap", DepthLinearPass_NormalMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
});
});
} }
return _downsamplePipeline; return _downsamplePipeline;

View file

@ -84,7 +84,7 @@ private:
const gpu::PipelinePointer& getLinearDepthPipeline(const render::RenderContextPointer& renderContext); const gpu::PipelinePointer& getLinearDepthPipeline(const render::RenderContextPointer& renderContext);
gpu::PipelinePointer _linearDepthPipeline; gpu::PipelinePointer _linearDepthPipeline;
const gpu::PipelinePointer& getDownsamplePipeline(); const gpu::PipelinePointer& getDownsamplePipeline(const render::RenderContextPointer& renderContext);
gpu::PipelinePointer _downsamplePipeline; gpu::PipelinePointer _downsamplePipeline;
gpu::RangeTimerPointer _gpuTimer; gpu::RangeTimerPointer _gpuTimer;

View file

@ -113,7 +113,7 @@ void VelocityBufferPass::run(const render::RenderContextPointer& renderContext,
outputs.edit1() = velocityFBO; outputs.edit1() = velocityFBO;
outputs.edit2() = velocityTexture; outputs.edit2() = velocityTexture;
auto cameraMotionPipeline = getCameraMotionPipeline(); auto cameraMotionPipeline = getCameraMotionPipeline(renderContext);
auto fullViewport = args->_viewport; auto fullViewport = args->_viewport;
@ -143,18 +143,12 @@ void VelocityBufferPass::run(const render::RenderContextPointer& renderContext,
} }
const gpu::PipelinePointer& VelocityBufferPass::getCameraMotionPipeline() { const gpu::PipelinePointer& VelocityBufferPass::getCameraMotionPipeline(const render::RenderContextPointer& renderContext) {
if (!_cameraMotionPipeline) { if (!_cameraMotionPipeline) {
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
auto ps = velocityBuffer_cameraMotion_frag::getShader(); auto ps = velocityBuffer_cameraMotion_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), VelocityBufferPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), VelocityBufferPass_DepthMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); gpu::StatePointer state = gpu::StatePointer(new gpu::State());
// Stencil test the curvature pass for objects pixels only, not the background // Stencil test the curvature pass for objects pixels only, not the background
@ -164,6 +158,16 @@ const gpu::PipelinePointer& VelocityBufferPass::getCameraMotionPipeline() {
// Good to go add the brand new pipeline // Good to go add the brand new pipeline
_cameraMotionPipeline = gpu::Pipeline::create(program, state); _cameraMotionPipeline = gpu::Pipeline::create(program, state);
gpu::doInBatch("VelocityBufferPass::CameraMotionPipeline", renderContext->args->_context,
[program](gpu::Batch& batch) {
batch.runLambda([program]() {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), VelocityBufferPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), VelocityBufferPass_DepthMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
});
});
} }
return _cameraMotionPipeline; return _cameraMotionPipeline;

View file

@ -79,7 +79,7 @@ private:
VelocityFramebufferPointer _velocityFramebuffer; VelocityFramebufferPointer _velocityFramebuffer;
const gpu::PipelinePointer& getCameraMotionPipeline(); const gpu::PipelinePointer& getCameraMotionPipeline(const render::RenderContextPointer& renderContext);
gpu::PipelinePointer _cameraMotionPipeline; gpu::PipelinePointer _cameraMotionPipeline;
gpu::RangeTimerPointer _gpuTimer; gpu::RangeTimerPointer _gpuTimer;

View file

@ -25,7 +25,7 @@
#include <QtNetwork/QNetworkDiskCache> #include <QtNetwork/QNetworkDiskCache>
/**jsdoc /**jsdoc
* The Assets API allows you to communicate with the Asset Browser * The Assets API allows you to communicate with the Asset Browser.
* @namespace Assets * @namespace Assets
*/ */
class AssetScriptingInterface : public BaseAssetScriptingInterface, QScriptable { class AssetScriptingInterface : public BaseAssetScriptingInterface, QScriptable {
@ -41,14 +41,12 @@ public:
* @param data {string} content to upload * @param data {string} content to upload
* @param callback {Assets~uploadDataCallback} called when upload is complete * @param callback {Assets~uploadDataCallback} called when upload is complete
*/ */
/**jsdoc /**jsdoc
* Called when uploadData is complete * Called when uploadData is complete
* @callback Assets~uploadDataCallback * @callback Assets~uploadDataCallback
* @param {string} url * @param {string} url
* @param {string} hash * @param {string} hash
*/ */
Q_INVOKABLE void uploadData(QString data, QScriptValue callback); Q_INVOKABLE void uploadData(QString data, QScriptValue callback);
/**jsdoc /**jsdoc
@ -57,13 +55,11 @@ public:
* @param url {string} URL of asset to download, must be ATP scheme URL. * @param url {string} URL of asset to download, must be ATP scheme URL.
* @param callback {Assets~downloadDataCallback} * @param callback {Assets~downloadDataCallback}
*/ */
/**jsdoc /**jsdoc
* Called when downloadData is complete * Called when downloadData is complete
* @callback Assets~downloadDataCallback * @callback Assets~downloadDataCallback
* @param data {string} content that was downloaded * @param data {string} content that was downloaded
*/ */
Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete); Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete);
/**jsdoc /**jsdoc
@ -73,13 +69,11 @@ public:
* @param hash {string} * @param hash {string}
* @param callback {Assets~setMappingCallback} * @param callback {Assets~setMappingCallback}
*/ */
/**jsdoc /**jsdoc
* Called when setMapping is complete * Called when setMapping is complete
* @callback Assets~setMappingCallback * @callback Assets~setMappingCallback
* @param {string} error * @param {string} error
*/ */
Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback); Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback);
/**jsdoc /**jsdoc
@ -88,21 +82,12 @@ public:
* @param path {string} * @param path {string}
* @param callback {Assets~getMappingCallback} * @param callback {Assets~getMappingCallback}
*/ */
/**jsdoc /**jsdoc
* Called when getMapping is complete. * Called when getMapping is complete.
* @callback Assets~getMappingCallback * @callback Assets~getMappingCallback
* @param assetID {string} hash value if found, else an empty string * @param assetID {string} hash value if found, else an empty string
* @param error {string} error description if the path could not be resolved; otherwise a null value. * @param error {string} error description if the path could not be resolved; otherwise a null value.
*/ */
/**jsdoc
* Called when getMapping is complete.
* @callback Assets~getMappingCallback
* @param assetID {string} hash value if found, else an empty string
* @param error {string} error description if the path could not be resolved; otherwise a null value.
*/
Q_INVOKABLE void getMapping(QString path, QScriptValue callback); Q_INVOKABLE void getMapping(QString path, QScriptValue callback);
/**jsdoc /**jsdoc
@ -111,7 +96,10 @@ public:
* @param enabled {boolean} * @param enabled {boolean}
* @param callback {} * @param callback {}
*/ */
/**jsdoc
* Called when setBakingEnabled is complete.
* @callback Assets~setBakingEnabledCallback
*/
Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback); Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback);
#if (PR_BUILD || DEV_BUILD) #if (PR_BUILD || DEV_BUILD)
@ -122,13 +110,14 @@ public:
* Request Asset data from the ATP Server * Request Asset data from the ATP Server
* @function Assets.getAsset * @function Assets.getAsset
* @param {URL|Assets.GetOptions} options An atp: style URL, hash, or relative mapped path; or an {@link Assets.GetOptions} object with request parameters * @param {URL|Assets.GetOptions} options An atp: style URL, hash, or relative mapped path; or an {@link Assets.GetOptions} object with request parameters
* @param {Assets~getAssetCallback} scope[callback] A scope callback function to receive (error, results) values * @param {Assets~getAssetCallback} scope A scope callback function to receive (error, results) values
* @param {function} [callback=undefined]
*/ */
/**jsdoc /**jsdoc
* A set of properties that can be passed to {@link Assets.getAsset}. * A set of properties that can be passed to {@link Assets.getAsset}.
* @typedef {Object} Assets.GetOptions * @typedef {Object} Assets.GetOptions
* @property {URL} [url] an "atp:" style URL, hash, or relative mapped path to fetch * @property {string} [url] an "atp:" style URL, hash, or relative mapped path to fetch
* @property {string} [responseType=text] the desired reponse type (text | arraybuffer | json) * @property {string} [responseType=text] the desired reponse type (text | arraybuffer | json)
* @property {boolean} [decompress=false] whether to attempt gunzip decompression on the fetched data * @property {boolean} [decompress=false] whether to attempt gunzip decompression on the fetched data
* See: {@link Assets.putAsset} and its .compress=true option * See: {@link Assets.putAsset} and its .compress=true option
@ -144,7 +133,7 @@ public:
/**jsdoc /**jsdoc
* Result value returned by {@link Assets.getAsset}. * Result value returned by {@link Assets.getAsset}.
* @typedef {Object} Assets~getAssetResult * @typedef {Object} Assets~getAssetResult
* @property {url} [url] the resolved "atp:" style URL for the fetched asset * @property {string} [url] the resolved "atp:" style URL for the fetched asset
* @property {string} [hash] the resolved hash for the fetched asset * @property {string} [hash] the resolved hash for the fetched asset
* @property {string|ArrayBuffer|Object} [response] response data (possibly converted per .responseType value) * @property {string|ArrayBuffer|Object} [response] response data (possibly converted per .responseType value)
* @property {string} [responseType] response type (text | arraybuffer | json) * @property {string} [responseType] response type (text | arraybuffer | json)
@ -160,6 +149,7 @@ public:
* @function Assets.putAsset * @function Assets.putAsset
* @param {Assets.PutOptions} options A PutOptions object with upload parameters * @param {Assets.PutOptions} options A PutOptions object with upload parameters
* @param {Assets~putAssetCallback} scope[callback] A scoped callback function invoked with (error, results) * @param {Assets~putAssetCallback} scope[callback] A scoped callback function invoked with (error, results)
* @param {function} [callback=undefined]
*/ */
/**jsdoc /**jsdoc
@ -180,7 +170,7 @@ public:
/**jsdoc /**jsdoc
* Result value returned by {@link Assets.putAsset}. * Result value returned by {@link Assets.putAsset}.
* @typedef {Object} Assets~putAssetResult * @typedef {Object} Assets~putAssetResult
* @property {url} [url] the resolved "atp:" style URL for the uploaded asset (based on .path if specified, otherwise on the resulting ATP hash) * @property {string} [url] the resolved "atp:" style URL for the uploaded asset (based on .path if specified, otherwise on the resulting ATP hash)
* @property {string} [path] the uploaded asset's resulting ATP path (or undefined if no path mapping was assigned) * @property {string} [path] the uploaded asset's resulting ATP path (or undefined if no path mapping was assigned)
* @property {string} [hash] the uploaded asset's resulting ATP hash * @property {string} [hash] the uploaded asset's resulting ATP hash
* @property {boolean} [compressed] flag indicating whether the data was compressed before upload * @property {boolean} [compressed] flag indicating whether the data was compressed before upload
@ -243,7 +233,7 @@ public:
/**jsdoc /**jsdoc
* @function Assets.getCacheStatus * @function Assets.getCacheStatus
* @property {} scope * @property {} scope
* @property {} [callback = ""] * @property {} [callback=undefined]
*/ */
Q_INVOKABLE void getCacheStatus(QScriptValue scope, QScriptValue callback = QScriptValue()) { Q_INVOKABLE void getCacheStatus(QScriptValue scope, QScriptValue callback = QScriptValue()) {
@ -254,7 +244,7 @@ public:
* @function Assets.queryCacheMeta * @function Assets.queryCacheMeta
* @property {} options * @property {} options
* @property {} scope * @property {} scope
* @property {} [callback = ""] * @property {} [callback=undefined]
*/ */
Q_INVOKABLE void queryCacheMeta(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); Q_INVOKABLE void queryCacheMeta(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue());
@ -263,7 +253,7 @@ public:
* @function Assets.loadFromCache * @function Assets.loadFromCache
* @property {} options * @property {} options
* @property {} scope * @property {} scope
* @property {} [callback = ""] * @property {} [callback=undefined]
*/ */
Q_INVOKABLE void loadFromCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); Q_INVOKABLE void loadFromCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue());
@ -272,7 +262,7 @@ public:
* @function Assets.saveToCache * @function Assets.saveToCache
* @property {} options * @property {} options
* @property {} scope * @property {} scope
* @property {} [callback = ""] * @property {} [callback=undefined]
*/ */
Q_INVOKABLE void saveToCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); Q_INVOKABLE void saveToCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue());
@ -283,7 +273,7 @@ public:
* @property {} data * @property {} data
* @property {} metadata * @property {} metadata
* @property {} scope * @property {} scope
* @property {} [callback = ""] * @property {} [callback=undefined]
*/ */
Q_INVOKABLE void saveToCache(const QUrl& url, const QByteArray& data, const QVariantMap& metadata, Q_INVOKABLE void saveToCache(const QUrl& url, const QByteArray& data, const QVariantMap& metadata,

View file

@ -31,21 +31,88 @@ protected:
AudioScriptingInterface() {} AudioScriptingInterface() {}
// these methods are protected to stop C++ callers from calling, but invokable from script // these methods are protected to stop C++ callers from calling, but invokable from script
/**jsdoc
* @function Audio.playSound
* @param {} sound
* @param {} [injectorOptions=null]
* @returns {object}
*/
Q_INVOKABLE ScriptAudioInjector* playSound(SharedSoundPointer sound, const AudioInjectorOptions& injectorOptions = AudioInjectorOptions()); Q_INVOKABLE ScriptAudioInjector* playSound(SharedSoundPointer sound, const AudioInjectorOptions& injectorOptions = AudioInjectorOptions());
/**jsdoc
* @function Audio.playSystemSound
* @param {} sound
* @param {} position
* @returns {object}
*/
// FIXME: there is no way to play a positionless sound // FIXME: there is no way to play a positionless sound
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position); Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position);
/**jsdoc
* @function Audio.setStereoInput
* @param {boolean} stereo
* @returns {boolean}
*/
Q_INVOKABLE bool setStereoInput(bool stereo); Q_INVOKABLE bool setStereoInput(bool stereo);
/**jsdoc
* @function Audio.isStereoInput
* @returns {boolean}
*/
Q_INVOKABLE bool isStereoInput(); Q_INVOKABLE bool isStereoInput();
signals: signals:
void mutedByMixer(); /// the client has been muted by the mixer
void environmentMuted(); /// the entire environment has been muted by the mixer /**jsdoc
void receivedFirstPacket(); /// the client has received its first packet from the audio mixer * The client has been muted by the mixer.
void disconnected(); /// the client has been disconnected from the audio mixer * @function Audio.mutedByMixer
void noiseGateOpened(); /// the noise gate has opened * @returns {Signal}
void noiseGateClosed(); /// the noise gate has closed */
void inputReceived(const QByteArray& inputSamples); /// a frame of mic input audio has been received and processed void mutedByMixer();
/**jsdoc
* The entire environment has been muted by the mixer.
* @function Audio.environmentMuted
* @returns {Signal}
*/
void environmentMuted();
/**jsdoc
* The client has received its first packet from the audio mixer.
* @function Audio.receivedFirstPacket
* @returns {Signal}
*/
void receivedFirstPacket();
/**jsdoc
* The client has been disconnected from the audio mixer.
* @function Audio.disconnected
* @returns {Signal}
*/
void disconnected();
/**jsdoc
* The noise gate has opened.
* @function Audio.noiseGateOpened
* @returns {Signal}
*/
void noiseGateOpened();
/**jsdoc
* The noise gate has closed.
* @function Audio.noiseGateClosed
* @returns {Signal}
*/
void noiseGateClosed();
/**jsdoc
* A frame of mic input audio has been received and processed.
* @function Audio.inputReceived
* @param {} inputSamples
* @returns {Signal}
*/
void inputReceived(const QByteArray& inputSamples);
private: private:
AbstractAudioInterface* _localAudioInterface { nullptr }; AbstractAudioInterface* _localAudioInterface { nullptr };

View file

@ -273,9 +273,9 @@ QVariantList ScriptEngines::getRunning() {
} else { } else {
displayURLString = displayURL.toDisplayString(QUrl::FormattingOptions(QUrl::FullyEncoded)); displayURLString = displayURL.toDisplayString(QUrl::FormattingOptions(QUrl::FullyEncoded));
} }
resultNode.insert("url", displayURLString);
// The path contains the exact path/URL of the script, which also is used in the stopScript function. // The path contains the exact path/URL of the script, which also is used in the stopScript function.
resultNode.insert("path", normalizeScriptURL(runningScript).toString()); resultNode.insert("path", displayURLString);
resultNode.insert("url", normalizeScriptURL(runningScript).toString());
resultNode.insert("local", runningScriptURL.isLocalFile()); resultNode.insert("local", runningScriptURL.isLocalFile());
result.append(resultNode); result.append(resultNode);
} }
@ -538,7 +538,6 @@ int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) {
int ii=0; int ii=0;
for (auto initializer : _scriptInitializers) { for (auto initializer : _scriptInitializers) {
ii++; ii++;
qDebug() << "initializer" << ii;
initializer(scriptEngine); initializer(scriptEngine);
} }
return ii; return ii;

View file

@ -213,7 +213,7 @@ void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectio
int byteForSection = (BITS_IN_OCTAL * section / BITS_IN_BYTE); int byteForSection = (BITS_IN_OCTAL * section / BITS_IN_BYTE);
unsigned char* byteAt = octalCode + 1 + byteForSection; unsigned char* byteAt = octalCode + 1 + byteForSection;
char bitInByte = (BITS_IN_OCTAL * section) % BITS_IN_BYTE; char bitInByte = (BITS_IN_OCTAL * section) % BITS_IN_BYTE;
char shiftBy = BITS_IN_BYTE - bitInByte - BITS_IN_OCTAL; int8_t shiftBy = BITS_IN_BYTE - bitInByte - BITS_IN_OCTAL;
const unsigned char UNSHIFTED_MASK = 0x07; const unsigned char UNSHIFTED_MASK = 0x07;
unsigned char shiftedMask; unsigned char shiftedMask;
unsigned char shiftedValue; unsigned char shiftedValue;

View file

@ -22,6 +22,5 @@ namespace {
} }
void MiniPromise::registerMetaTypes(QObject* engine) { void MiniPromise::registerMetaTypes(QObject* engine) {
auto scriptEngine = qobject_cast<QScriptEngine*>(engine); auto scriptEngine = qobject_cast<QScriptEngine*>(engine);
qDebug() << "----------------------- MiniPromise::registerMetaTypes ------------" << scriptEngine;
qScriptRegisterMetaType(scriptEngine, promiseToScriptValue, promiseFromScriptValue); qScriptRegisterMetaType(scriptEngine, promiseToScriptValue, promiseFromScriptValue);
} }

View file

@ -10,7 +10,7 @@
#include <QtCore/QFileInfo> #include <QtCore/QFileInfo>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QLoggingCategory> #include "StorageLogging.h"
Q_LOGGING_CATEGORY(storagelogging, "hifi.core.storage") Q_LOGGING_CATEGORY(storagelogging, "hifi.core.storage")
@ -102,4 +102,4 @@ FileStorage::~FileStorage() {
if (_file.isOpen()) { if (_file.isOpen()) {
_file.close(); _file.close();
} }
} }

View file

@ -0,0 +1,18 @@
//
// StorageLogging.h
//
// Created by Seth Alves on 2018-4-20
// Copyright 2018 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_StorageLogging_h
#define hifi_StorageLogging_h
#include <QtCore/QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(storagelogging)
#endif // hifi_StorageLogging_h

View file

@ -64,29 +64,22 @@ signals:
* @function FaceTracker.muteToggled * @function FaceTracker.muteToggled
* @returns {Signal} * @returns {Signal}
*/ */
void muteToggled(); void muteToggled();
public slots: public slots:
/**jsdoc // No JSDoc here because it's overridden in DdeFaceTracker.
* @function FaceTracker.setEnabled
* @param {boolean} enabled
*/
virtual void setEnabled(bool enabled) = 0; virtual void setEnabled(bool enabled) = 0;
/**jsdoc /**jsdoc
* @function FaceTracker.toggleMute * @function FaceTracker.toggleMute
*/ */
void toggleMute(); void toggleMute();
/**jsdoc /**jsdoc
* @function FaceTracker.getMuted * @function FaceTracker.getMuted
* @returns {boolean} * @returns {boolean}
*/ */
bool getMuted() { return _isMuted; } bool getMuted() { return _isMuted; }
protected: protected:

View file

@ -6,8 +6,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#ifndef hifi_Controllers_Logging_h #ifndef hifi_UI_Logging_h
#define hifi_Controllers_Logging_h #define hifi_UI_Logging_h
#include <QLoggingCategory> #include <QLoggingCategory>

View file

@ -102,7 +102,7 @@ class AudioHandler : public QObject, QRunnable {
public: public:
AudioHandler(OffscreenQmlSurface* surface, const QString& deviceName, QObject* parent = nullptr); AudioHandler(OffscreenQmlSurface* surface, const QString& deviceName, QObject* parent = nullptr);
virtual ~AudioHandler() { qDebug() << "Audio Handler Destroyed"; } virtual ~AudioHandler() { }
void run() override; void run() override;

View file

@ -21,40 +21,16 @@
// BEGIN AVATAR SELECTOR LOGIC // BEGIN AVATAR SELECTOR LOGIC
var UNSELECTED_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png")
};
var SELECTED_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png")
};
var HOVER_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png")
};
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 }; var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 }; var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 }; var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 };
var conserveResources = true;
var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier. var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier.
function ExtendedOverlay(key, type, properties, selected, hasModel) { // A wrapper around overlays to store the key it is associated with. function ExtendedOverlay(key, type, properties) { // A wrapper around overlays to store the key it is associated with.
overlays[key] = this; overlays[key] = this;
if (hasModel) {
var modelKey = key + "-m";
this.model = new ExtendedOverlay(modelKey, "model", {
url: Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx"),
textures: textures(selected),
ignoreRayIntersection: true
}, false, false);
} else {
this.model = undefined;
}
this.key = key; this.key = key;
this.selected = selected || false; // not undefined this.selected = false;
this.hovering = false; this.hovering = false;
this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected... this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected...
} }
@ -76,10 +52,6 @@
} }
return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) }; return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) };
} }
function textures(selected, hovering) {
return hovering ? HOVER_TEXTURES : selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES;
}
// so we don't have to traverse the overlays to get the last one // so we don't have to traverse the overlays to get the last one
var lastHoveringId = 0; var lastHoveringId = 0;
ExtendedOverlay.prototype.hover = function (hovering) { ExtendedOverlay.prototype.hover = function (hovering) {
@ -91,9 +63,6 @@
lastHoveringId = 0; lastHoveringId = 0;
} }
this.editOverlay({ color: color(this.selected, hovering) }); this.editOverlay({ color: color(this.selected, hovering) });
if (this.model) {
this.model.editOverlay({ textures: textures(this.selected, hovering) });
}
if (hovering) { if (hovering) {
// un-hover the last hovering overlay // un-hover the last hovering overlay
if (lastHoveringId && lastHoveringId !== this.key) { if (lastHoveringId && lastHoveringId !== this.key) {
@ -108,15 +77,12 @@
} }
this.editOverlay({ color: color(selected, this.hovering) }); this.editOverlay({ color: color(selected, this.hovering) });
if (this.model) {
this.model.editOverlay({ textures: textures(selected) });
}
this.selected = selected; this.selected = selected;
}; };
// Class methods: // Class methods:
var selectedIds = []; var selectedId = false;
ExtendedOverlay.isSelected = function (id) { ExtendedOverlay.isSelected = function (id) {
return -1 !== selectedIds.indexOf(id); return selectedId === id;
}; };
ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier
return overlays[key]; return overlays[key];
@ -153,51 +119,14 @@
}); });
}; };
function HighlightedEntity(id, entityProperties) {
this.id = id;
this.overlay = Overlays.addOverlay('cube', {
position: entityProperties.position,
rotation: entityProperties.rotation,
dimensions: entityProperties.dimensions,
solid: false,
color: {
red: 0xF3,
green: 0x91,
blue: 0x29
},
ignoreRayIntersection: true,
drawInFront: false // Arguable. For now, let's not distract with mysterious wires around the scene.
});
HighlightedEntity.overlays.push(this);
}
HighlightedEntity.overlays = [];
HighlightedEntity.clearOverlays = function clearHighlightedEntities() {
HighlightedEntity.overlays.forEach(function (highlighted) {
Overlays.deleteOverlay(highlighted.overlay);
});
HighlightedEntity.overlays = [];
};
HighlightedEntity.updateOverlays = function updateHighlightedEntities() {
HighlightedEntity.overlays.forEach(function (highlighted) {
var properties = Entities.getEntityProperties(highlighted.id, ['position', 'rotation', 'dimensions']);
Overlays.editOverlay(highlighted.overlay, {
position: properties.position,
rotation: properties.rotation,
dimensions: properties.dimensions
});
});
};
function addAvatarNode(id) { function addAvatarNode(id) {
var selected = ExtendedOverlay.isSelected(id);
return new ExtendedOverlay(id, "sphere", { return new ExtendedOverlay(id, "sphere", {
drawInFront: true, drawInFront: true,
solid: true, solid: true,
alpha: 0.8, alpha: 0.8,
color: color(selected, false), color: color(false, false),
ignoreRayIntersection: false ignoreRayIntersection: false
}, selected, !conserveResources); });
} }
var pingPong = true; var pingPong = true;
@ -236,14 +165,6 @@
position: target, position: target,
dimensions: 0.032 * distance dimensions: 0.032 * distance
}); });
if (overlay.model) {
overlay.model.ping = pingPong;
overlay.model.editOverlay({
position: target,
scale: 0.2 * distance, // constant apparent size
rotation: Camera.orientation
});
}
}); });
pingPong = !pingPong; pingPong = !pingPong;
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.) ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)
@ -251,13 +172,10 @@
overlay.deleteOverlay(); overlay.deleteOverlay();
} }
}); });
// We could re-populateNearbyUserList if anything added or removed, but not for now.
HighlightedEntity.updateOverlays();
} }
function removeOverlays() { function removeOverlays() {
selectedIds = []; selectedId = false;
lastHoveringId = 0; lastHoveringId = 0;
HighlightedEntity.clearOverlays();
ExtendedOverlay.some(function (overlay) { ExtendedOverlay.some(function (overlay) {
overlay.deleteOverlay(); overlay.deleteOverlay();
}); });
@ -267,7 +185,7 @@
// Clicks. // Clicks.
// //
function usernameFromIDReply(id, username, machineFingerprint, isAdmin) { function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
if (selectedIds[0] === id) { if (selectedId === id) {
var message = { var message = {
method: 'updateSelectedRecipientUsername', method: 'updateSelectedRecipientUsername',
userName: username === "" ? "unknown username" : username userName: username === "" ? "unknown username" : username
@ -279,13 +197,13 @@
ExtendedOverlay.applyPickRay(pickRay, function (overlay) { ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
var nextSelectedStatus = !overlay.selected; var nextSelectedStatus = !overlay.selected;
var avatarId = overlay.key; var avatarId = overlay.key;
selectedIds = nextSelectedStatus ? [avatarId] : []; selectedId = nextSelectedStatus ? avatarId : false;
if (nextSelectedStatus) { if (nextSelectedStatus) {
Users.requestUsernameFromID(avatarId); Users.requestUsernameFromID(avatarId);
} }
var message = { var message = {
method: 'selectRecipient', method: 'selectRecipient',
id: [avatarId], id: avatarId,
isSelected: nextSelectedStatus, isSelected: nextSelectedStatus,
displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"', displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"',
userName: '' userName: ''
@ -298,24 +216,6 @@
overlay.select(selected); overlay.select(selected);
}); });
HighlightedEntity.clearOverlays();
if (selectedIds.length) {
Entities.findEntitiesInFrustum(Camera.frustum).forEach(function (id) {
// Because lastEditedBy is per session, the vast majority of entities won't match,
// so it would probably be worth reducing marshalling costs by asking for just we need.
// However, providing property name(s) is advisory and some additional properties are
// included anyway. As it turns out, asking for 'lastEditedBy' gives 'position', 'rotation',
// and 'dimensions', too, so we might as well make use of them instead of making a second
// getEntityProperties call.
// It would be nice if we could harden this against future changes by specifying all
// and only these four in an array, but see
// https://highfidelity.fogbugz.com/f/cases/2728/Entities-getEntityProperties-id-lastEditedBy-name-lastEditedBy-doesn-t-work
var properties = Entities.getEntityProperties(id, 'lastEditedBy');
if (ExtendedOverlay.isSelected(properties.lastEditedBy)) {
new HighlightedEntity(id, properties);
}
});
}
return true; return true;
}); });
} }
@ -657,12 +557,14 @@
} }
if (onWalletScreen) { if (onWalletScreen) {
if (!isWired) {
Users.usernameFromIDReply.connect(usernameFromIDReply);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
triggerMapping.enable();
triggerPressMapping.enable();
}
isWired = true; isWired = true;
Users.usernameFromIDReply.connect(usernameFromIDReply);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
triggerMapping.enable();
triggerPressMapping.enable();
} else { } else {
off(); off();
} }

View file

@ -796,7 +796,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
}; };
var onMousePress = function(event) { var onMousePress = function(event) {
if (isInEditMode()) { // don't consider any mouse clicks on the entity while in edit if (isInEditMode() || !event.isLeftButton) { // don't consider any left clicks on the entity while in edit
return; return;
} }
var pickRay = Camera.computePickRay(event.x, event.y); var pickRay = Camera.computePickRay(event.x, event.y);

View file

@ -153,40 +153,16 @@ var selectionDisplay = null; // for gridTool.js to ignore
} }
// BEGIN AVATAR SELECTOR LOGIC // BEGIN AVATAR SELECTOR LOGIC
var UNSELECTED_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png")
};
var SELECTED_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png")
};
var HOVER_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png")
};
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 }; var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 }; var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 }; var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 };
var conserveResources = true;
var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier. var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier.
function ExtendedOverlay(key, type, properties, selected, hasModel) { // A wrapper around overlays to store the key it is associated with. function ExtendedOverlay(key, type, properties) { // A wrapper around overlays to store the key it is associated with.
overlays[key] = this; overlays[key] = this;
if (hasModel) {
var modelKey = key + "-m";
this.model = new ExtendedOverlay(modelKey, "model", {
url: Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx"),
textures: textures(selected),
ignoreRayIntersection: true
}, false, false);
} else {
this.model = undefined;
}
this.key = key; this.key = key;
this.selected = selected || false; // not undefined this.selected = false;
this.hovering = false; this.hovering = false;
this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected... this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected...
} }
@ -208,10 +184,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
} }
return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) }; return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) };
} }
function textures(selected, hovering) {
return hovering ? HOVER_TEXTURES : selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES;
}
// so we don't have to traverse the overlays to get the last one // so we don't have to traverse the overlays to get the last one
var lastHoveringId = 0; var lastHoveringId = 0;
ExtendedOverlay.prototype.hover = function (hovering) { ExtendedOverlay.prototype.hover = function (hovering) {
@ -223,9 +195,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
lastHoveringId = 0; lastHoveringId = 0;
} }
this.editOverlay({ color: color(this.selected, hovering) }); this.editOverlay({ color: color(this.selected, hovering) });
if (this.model) {
this.model.editOverlay({ textures: textures(this.selected, hovering) });
}
if (hovering) { if (hovering) {
// un-hover the last hovering overlay // un-hover the last hovering overlay
if (lastHoveringId && lastHoveringId !== this.key) { if (lastHoveringId && lastHoveringId !== this.key) {
@ -240,15 +209,12 @@ var selectionDisplay = null; // for gridTool.js to ignore
} }
this.editOverlay({ color: color(selected, this.hovering) }); this.editOverlay({ color: color(selected, this.hovering) });
if (this.model) {
this.model.editOverlay({ textures: textures(selected) });
}
this.selected = selected; this.selected = selected;
}; };
// Class methods: // Class methods:
var selectedIds = []; var selectedId = false;
ExtendedOverlay.isSelected = function (id) { ExtendedOverlay.isSelected = function (id) {
return -1 !== selectedIds.indexOf(id); return selectedId === id;
}; };
ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier
return overlays[key]; return overlays[key];
@ -285,51 +251,14 @@ var selectionDisplay = null; // for gridTool.js to ignore
}); });
}; };
function HighlightedEntity(id, entityProperties) {
this.id = id;
this.overlay = Overlays.addOverlay('cube', {
position: entityProperties.position,
rotation: entityProperties.rotation,
dimensions: entityProperties.dimensions,
solid: false,
color: {
red: 0xF3,
green: 0x91,
blue: 0x29
},
ignoreRayIntersection: true,
drawInFront: false // Arguable. For now, let's not distract with mysterious wires around the scene.
});
HighlightedEntity.overlays.push(this);
}
HighlightedEntity.overlays = [];
HighlightedEntity.clearOverlays = function clearHighlightedEntities() {
HighlightedEntity.overlays.forEach(function (highlighted) {
Overlays.deleteOverlay(highlighted.overlay);
});
HighlightedEntity.overlays = [];
};
HighlightedEntity.updateOverlays = function updateHighlightedEntities() {
HighlightedEntity.overlays.forEach(function (highlighted) {
var properties = Entities.getEntityProperties(highlighted.id, ['position', 'rotation', 'dimensions']);
Overlays.editOverlay(highlighted.overlay, {
position: properties.position,
rotation: properties.rotation,
dimensions: properties.dimensions
});
});
};
function addAvatarNode(id) { function addAvatarNode(id) {
var selected = ExtendedOverlay.isSelected(id);
return new ExtendedOverlay(id, "sphere", { return new ExtendedOverlay(id, "sphere", {
drawInFront: true, drawInFront: true,
solid: true, solid: true,
alpha: 0.8, alpha: 0.8,
color: color(selected, false), color: color(false, false),
ignoreRayIntersection: false ignoreRayIntersection: false
}, selected, !conserveResources); });
} }
var pingPong = true; var pingPong = true;
@ -368,14 +297,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
position: target, position: target,
dimensions: 0.032 * distance dimensions: 0.032 * distance
}); });
if (overlay.model) {
overlay.model.ping = pingPong;
overlay.model.editOverlay({
position: target,
scale: 0.2 * distance, // constant apparent size
rotation: Camera.orientation
});
}
}); });
pingPong = !pingPong; pingPong = !pingPong;
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.) ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)
@ -383,13 +304,10 @@ var selectionDisplay = null; // for gridTool.js to ignore
overlay.deleteOverlay(); overlay.deleteOverlay();
} }
}); });
// We could re-populateNearbyUserList if anything added or removed, but not for now.
HighlightedEntity.updateOverlays();
} }
function removeOverlays() { function removeOverlays() {
selectedIds = []; selectedId = false;
lastHoveringId = 0; lastHoveringId = 0;
HighlightedEntity.clearOverlays();
ExtendedOverlay.some(function (overlay) { ExtendedOverlay.some(function (overlay) {
overlay.deleteOverlay(); overlay.deleteOverlay();
}); });
@ -399,7 +317,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
// Clicks. // Clicks.
// //
function usernameFromIDReply(id, username, machineFingerprint, isAdmin) { function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
if (selectedIds[0] === id) { if (selectedId === id) {
var message = { var message = {
method: 'updateSelectedRecipientUsername', method: 'updateSelectedRecipientUsername',
userName: username === "" ? "unknown username" : username userName: username === "" ? "unknown username" : username
@ -411,13 +329,13 @@ var selectionDisplay = null; // for gridTool.js to ignore
ExtendedOverlay.applyPickRay(pickRay, function (overlay) { ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
var nextSelectedStatus = !overlay.selected; var nextSelectedStatus = !overlay.selected;
var avatarId = overlay.key; var avatarId = overlay.key;
selectedIds = nextSelectedStatus ? [avatarId] : []; selectedId = nextSelectedStatus ? avatarId : false;
if (nextSelectedStatus) { if (nextSelectedStatus) {
Users.requestUsernameFromID(avatarId); Users.requestUsernameFromID(avatarId);
} }
var message = { var message = {
method: 'selectRecipient', method: 'selectRecipient',
id: [avatarId], id: avatarId,
isSelected: nextSelectedStatus, isSelected: nextSelectedStatus,
displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"', displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"',
userName: '' userName: ''
@ -430,24 +348,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
overlay.select(selected); overlay.select(selected);
}); });
HighlightedEntity.clearOverlays();
if (selectedIds.length) {
Entities.findEntitiesInFrustum(Camera.frustum).forEach(function (id) {
// Because lastEditedBy is per session, the vast majority of entities won't match,
// so it would probably be worth reducing marshalling costs by asking for just we need.
// However, providing property name(s) is advisory and some additional properties are
// included anyway. As it turns out, asking for 'lastEditedBy' gives 'position', 'rotation',
// and 'dimensions', too, so we might as well make use of them instead of making a second
// getEntityProperties call.
// It would be nice if we could harden this against future changes by specifying all
// and only these four in an array, but see
// https://highfidelity.fogbugz.com/f/cases/2728/Entities-getEntityProperties-id-lastEditedBy-name-lastEditedBy-doesn-t-work
var properties = Entities.getEntityProperties(id, 'lastEditedBy');
if (ExtendedOverlay.isSelected(properties.lastEditedBy)) {
new HighlightedEntity(id, properties);
}
});
}
return true; return true;
}); });
} }
@ -1155,12 +1055,14 @@ var selectionDisplay = null; // for gridTool.js to ignore
} }
if (onCommerceScreen) { if (onCommerceScreen) {
if (!isWired) {
Users.usernameFromIDReply.connect(usernameFromIDReply);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
triggerMapping.enable();
triggerPressMapping.enable();
}
isWired = true; isWired = true;
Users.usernameFromIDReply.connect(usernameFromIDReply);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
triggerMapping.enable();
triggerPressMapping.enable();
Wallet.refreshWalletStatus(); Wallet.refreshWalletStatus();
} else { } else {
off(); off();

View file

@ -9,21 +9,25 @@ function endsWith(path, exts) {
} }
exports.handlers = { exports.handlers = {
// This event is triggered before parsing has even started.
// We use this event to scan the C++ files for jsdoc comments
// and reformat them into a form digestable by jsdoc.
beforeParse: function(e) { beforeParse: function(e) {
const pathTools = require('path'); var pathTools = require('path');
var rootFolder = pathTools.dirname(e.filename); var rootFolder = pathTools.dirname(e.filename);
console.log("Scanning hifi source for jsdoc comments..."); console.log("Scanning hifi source for jsdoc comments...");
// directories to scan for jsdoc comments // directories to scan for jsdoc comments
var dirList = [ var dirList = [
'../../interface/src', '../../interface/src',
'../../interface/src/assets', '../../interface/src/assets',
'../../interface/src/audio', '../../interface/src/audio',
'../../interface/src/avatar', '../../interface/src/avatar',
'../../interface/src/commerce', '../../interface/src/commerce',
'../../interface/src/devices', '../../interface/src/devices',
'../../interface/src/java', '../../interface/src/java',
'../../interface/src/networking', '../../interface/src/networking',
'../../interface/src/ui/', '../../interface/src/ui/',
'../../interface/src/scripting', '../../interface/src/scripting',
'../../interface/src/ui/overlays', '../../interface/src/ui/overlays',
@ -47,27 +51,96 @@ exports.handlers = {
'../../libraries/script-engine/src', '../../libraries/script-engine/src',
'../../libraries/shared/src', '../../libraries/shared/src',
'../../libraries/shared/src/shared', '../../libraries/shared/src/shared',
'../../libraries/trackers/src/trackers',
'../../libraries/ui/src/ui', '../../libraries/ui/src/ui',
'../../plugins/oculus/src', '../../plugins/oculus/src',
'../../plugins/openvr/src', '../../plugins/openvr/src'
]; ];
// only files with this extension will be searched for jsdoc comments.
var exts = ['.h', '.cpp']; var exts = ['.h', '.cpp'];
const fs = require('fs'); var fs = require('fs');
dirList.forEach(function (dir) { dirList.forEach(function (dir) {
var joinedDir = pathTools.join(rootFolder, dir); var joinedDir = pathTools.join(rootFolder, dir);
var files = fs.readdirSync(joinedDir) var files = fs.readdirSync(joinedDir);
files.forEach(function (file) { files.forEach(function (file) {
var path = pathTools.join(joinedDir, file); var path = pathTools.join(joinedDir, file);
if (fs.lstatSync(path).isFile() && endsWith(path, exts)) { if (fs.lstatSync(path).isFile() && endsWith(path, exts)) {
// load entire file into a string
var data = fs.readFileSync(path, "utf8"); var data = fs.readFileSync(path, "utf8");
// this regex searches for blocks starting with /**jsdoc and end with */
var reg = /(\/\*\*jsdoc(.|[\r\n])*?\*\/)/gm; var reg = /(\/\*\*jsdoc(.|[\r\n])*?\*\/)/gm;
var matches = data.match(reg); var matches = data.match(reg);
if (matches) { if (matches) {
e.source += matches.map(function (s) { return s.replace('/**jsdoc', '/**'); }).join('\n'); // add to source, but strip off c-comment asterisks
e.source += matches.map(function (s) {
return s.replace('/**jsdoc', '/**');
}).join('\n');
} }
} }
}); });
}); });
},
// This event is triggered when a new doclet has been created
// but before it is passed to the template for output
newDoclet: function (e) {
// we only care about hifi custom tags on namespace and class doclets
if (e.doclet.kind === "namespace" || e.doclet.kind === "class") {
var rows = [];
if (e.doclet.hifiInterface) {
rows.push("Interface Scripts");
}
if (e.doclet.hifiAssignmentClient) {
rows.push("Assignment Client Scripts");
}
if (e.doclet.hifiClientEntity) {
rows.push("Client Entity Scripts");
}
if (e.doclet.hifiServerEntity) {
rows.push("Server Entity Scripts");
}
// Append an Available In: table at the end of the namespace description.
if (rows.length > 0) {
var table = "<br><br><table><td>Available In:<td>" + rows.join("<td>") + "</table>";
e.doclet.description = e.doclet.description + table;
}
}
} }
}; };
// Define custom hifi tags here
exports.defineTags = function (dictionary) {
// @hifi-interface
dictionary.defineTag("hifi-interface", {
onTagged: function (doclet, tag) {
doclet.hifiInterface = true;
}
});
// @hifi-assignment-client
dictionary.defineTag("hifi-assigment-client", {
onTagged: function (doclet, tag) {
doclet.hifiAssignmentClient = true;
}
});
// @hifi-client-entity
dictionary.defineTag("hifi-client-entity", {
onTagged: function (doclet, tag) {
doclet.hifiClientEntity = true;
}
});
// @hifi-server-entity
dictionary.defineTag("hifi-server-entity", {
onTagged: function (doclet, tag) {
doclet.hifiServerEntity = true;
}
});
};