mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge branch 'master' of https://github.com/highfidelity/hifi into upstream-workload
This commit is contained in:
commit
b3408ae4c0
84 changed files with 1546 additions and 1201 deletions
|
@ -115,11 +115,7 @@ public:
|
|||
uint64_t getLastOtherAvatarEncodeTime(QUuid otherAvatar) const;
|
||||
void setLastOtherAvatarEncodeTime(const QUuid& otherAvatar, uint64_t time);
|
||||
|
||||
QVector<JointData>& getLastOtherAvatarSentJoints(QUuid otherAvatar) {
|
||||
auto& lastOtherAvatarSentJoints = _lastOtherAvatarSentJoints[otherAvatar];
|
||||
lastOtherAvatarSentJoints.resize(_avatar->getJointCount());
|
||||
return lastOtherAvatarSentJoints;
|
||||
}
|
||||
QVector<JointData>& getLastOtherAvatarSentJoints(QUuid otherAvatar) { return _lastOtherAvatarSentJoints[otherAvatar]; }
|
||||
|
||||
void queuePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node);
|
||||
int processPackets(); // returns number of packets processed
|
||||
|
|
|
@ -381,6 +381,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
|||
bool includeThisAvatar = true;
|
||||
auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
|
||||
QVector<JointData>& lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID());
|
||||
|
||||
lastSentJointsForOther.resize(otherAvatar->getJointCount());
|
||||
|
||||
bool distanceAdjust = true;
|
||||
glm::vec3 viewerPosition = myPosition;
|
||||
AvatarDataPacket::HasFlags hasFlagsOut; // the result of the toByteArray
|
||||
|
|
3
cmake/externals/quazip/CMakeLists.txt
vendored
3
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -41,6 +41,9 @@ if (APPLE)
|
|||
elseif (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/quazip5.lib CACHE FILEPATH "Location of QuaZip release library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/quazip5d.lib CACHE FILEPATH "Location of QuaZip release library")
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/libquazip5d.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
else ()
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
|
|
|
@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content)
|
|||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC67-v2.zip
|
||||
URL_MD5 2c69a1df69816b4b0b81630396fbd36e
|
||||
URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC67-v4.zip
|
||||
URL_MD5 ba32aed18bfeaac4ccaf5ebb8ea3e804
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
|
|
@ -254,7 +254,7 @@ ModalWindow {
|
|||
text: root.warning;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.italic: true;
|
||||
maximumLineCount: 2;
|
||||
maximumLineCount: 3;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
|
|
|
@ -254,7 +254,7 @@ ModalWindow {
|
|||
text: root.warning;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.italic: true;
|
||||
maximumLineCount: 2;
|
||||
maximumLineCount: 3;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
|
|
|
@ -282,7 +282,7 @@ TabletModalWindow {
|
|||
text: root.warning;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.italic: true;
|
||||
maximumLineCount: 2;
|
||||
maximumLineCount: 3;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
|
|
|
@ -258,7 +258,9 @@ Item {
|
|||
anchors.topMargin: 26;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: paintedWidth;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
elide: Text.ElideRight;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
|
@ -844,7 +846,7 @@ Item {
|
|||
property string selectedRecipientUserName;
|
||||
property string selectedRecipientProfilePic;
|
||||
|
||||
visible: root.currentActiveView === "sendAssetStep";
|
||||
visible: root.currentActiveView === "sendAssetStep" || paymentSuccess.visible || paymentFailure.visible;
|
||||
anchors.fill: parent;
|
||||
anchors.topMargin: root.parentAppTitleBarHeight;
|
||||
|
||||
|
@ -856,7 +858,9 @@ Item {
|
|||
anchors.topMargin: 26;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: paintedWidth;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
elide: Text.ElideRight;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
|
@ -907,7 +911,7 @@ Item {
|
|||
// "CHANGE" button
|
||||
HifiControlsUit.Button {
|
||||
id: changeButton;
|
||||
color: root.assetName === "" ? hifi.buttons.none : hifi.buttons.noneBorderlessGray;
|
||||
color: root.assetName === "" ? hifi.buttons.none : hifi.buttons.white;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.right: parent.right;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
|
@ -1238,7 +1242,7 @@ Item {
|
|||
// Sending Asset Overlay START
|
||||
Rectangle {
|
||||
id: sendingAssetOverlay;
|
||||
z: 998;
|
||||
z: 999;
|
||||
|
||||
visible: root.isCurrentlySendingAsset;
|
||||
anchors.fill: parent;
|
||||
|
@ -1281,26 +1285,43 @@ Item {
|
|||
// Payment Success BEGIN
|
||||
Rectangle {
|
||||
id: paymentSuccess;
|
||||
z: 998;
|
||||
|
||||
visible: root.currentActiveView === "paymentSuccess";
|
||||
anchors.fill: parent;
|
||||
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 {
|
||||
anchors.centerIn: parent;
|
||||
width: parent.width - 30;
|
||||
height: parent.height - 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: root.assetName === "" ? 15 : 150;
|
||||
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";
|
||||
|
||||
RalewaySemiBold {
|
||||
id: paymentSentText;
|
||||
text: root.assetName === "" ? "Payment Sent" : '"' + root.assetName + '"';
|
||||
text: root.assetName === "" ? "Payment Sent" : "Gift Sent";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 26;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: paintedWidth;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
elide: Text.ElideRight;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
|
@ -1310,6 +1331,7 @@ Item {
|
|||
|
||||
HiFiGlyphs {
|
||||
id: closeGlyphButton_paymentSuccess;
|
||||
visible: root.assetName === "";
|
||||
text: hifi.glyphs.close;
|
||||
color: hifi.colors.lightGrayText;
|
||||
size: 26;
|
||||
|
@ -1375,6 +1397,49 @@ Item {
|
|||
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 {
|
||||
id: amountContainer_paymentSuccess;
|
||||
|
@ -1433,6 +1498,7 @@ Item {
|
|||
|
||||
RalewaySemiBold {
|
||||
id: optionalMessage_paymentSuccess;
|
||||
visible: root.assetName === "";
|
||||
text: optionalMessage.text;
|
||||
// Anchors
|
||||
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;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 80;
|
||||
anchors.bottomMargin: root.assetName === "" ? 80 : 30;
|
||||
height: 50;
|
||||
width: 120;
|
||||
text: "Close";
|
||||
|
@ -1476,26 +1542,43 @@ Item {
|
|||
// Payment Failure BEGIN
|
||||
Rectangle {
|
||||
id: paymentFailure;
|
||||
z: 998;
|
||||
|
||||
visible: root.currentActiveView === "paymentFailure";
|
||||
anchors.fill: parent;
|
||||
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 {
|
||||
anchors.centerIn: parent;
|
||||
width: parent.width - 30;
|
||||
height: parent.height - 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: root.assetName === "" ? 15 : 150;
|
||||
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";
|
||||
|
||||
RalewaySemiBold {
|
||||
id: paymentFailureText;
|
||||
text: root.assetName === "" ? "Payment Failed" : '"' + root.assetName + '"';
|
||||
text: root.assetName === "" ? "Payment Failed" : "Failed";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 26;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: paintedWidth;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
elide: Text.ElideRight;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
|
@ -1505,6 +1588,7 @@ Item {
|
|||
|
||||
HiFiGlyphs {
|
||||
id: closeGlyphButton_paymentFailure;
|
||||
visible: root.assetName === "";
|
||||
text: hifi.glyphs.close;
|
||||
color: hifi.colors.lightGrayText;
|
||||
size: 26;
|
||||
|
@ -1551,6 +1635,7 @@ Item {
|
|||
|
||||
Item {
|
||||
id: sendToContainer_paymentFailure;
|
||||
visible: root.assetName === "";
|
||||
anchors.top: paymentFailureDetailText.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
|
@ -1645,7 +1730,8 @@ Item {
|
|||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: optionalMessage_paymentFailuire;
|
||||
id: optionalMessage_paymentFailure;
|
||||
visible: root.assetName === "";
|
||||
text: optionalMessage.text;
|
||||
// Anchors
|
||||
anchors.top: amountContainer_paymentFailure.visible ? amountContainer_paymentFailure.bottom : sendToContainer_paymentFailure.bottom;
|
||||
|
@ -1663,14 +1749,15 @@ Item {
|
|||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
|
||||
// "Close" button
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
id: closeButton_paymentFailure;
|
||||
color: hifi.buttons.noneBorderless;
|
||||
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.bottomMargin: 80;
|
||||
anchors.bottomMargin: root.assetName === "" ? 80 : 30;
|
||||
height: 50;
|
||||
width: 120;
|
||||
text: "Cancel";
|
||||
|
@ -1691,7 +1778,7 @@ Item {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 12;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 80;
|
||||
anchors.bottomMargin: root.assetName === "" ? 80 : 30;
|
||||
height: 50;
|
||||
width: 120;
|
||||
text: "Retry";
|
||||
|
@ -1768,7 +1855,7 @@ Item {
|
|||
switch (message.method) {
|
||||
case 'selectRecipient':
|
||||
if (message.isSelected) {
|
||||
chooseRecipientNearby.selectedRecipient = message.id[0];
|
||||
chooseRecipientNearby.selectedRecipient = message.id;
|
||||
sendAssetStep.selectedRecipientDisplayName = message.displayName;
|
||||
sendAssetStep.selectedRecipientUserName = message.userName;
|
||||
} else {
|
||||
|
|
|
@ -239,7 +239,6 @@ Item {
|
|||
width: 62;
|
||||
|
||||
onLoaded: {
|
||||
item.enabled = (root.purchaseStatus === "confirmed");
|
||||
item.buttonGlyphText = hifi.glyphs.gift;
|
||||
item.buttonText = "Gift";
|
||||
item.buttonClicked = function() {
|
||||
|
|
|
@ -124,6 +124,14 @@ Rectangle {
|
|||
root.numUpdatesAvailable = result.data.updates.length;
|
||||
}
|
||||
}
|
||||
|
||||
onAppInstalled: {
|
||||
root.installedApps = Commerce.getInstalledApps();
|
||||
}
|
||||
|
||||
onAppUninstalled: {
|
||||
root.installedApps = Commerce.getInstalledApps();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
|
@ -249,6 +257,145 @@ Rectangle {
|
|||
Commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: installedAppsContainer;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
|
||||
RalewayRegular {
|
||||
id: installedAppsHeader;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 10;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
height: 80;
|
||||
width: paintedWidth;
|
||||
text: "All Installed Marketplace Apps";
|
||||
color: hifi.colors.black;
|
||||
size: 22;
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: installedAppsList;
|
||||
clip: true;
|
||||
model: installedAppsModel;
|
||||
snapMode: ListView.SnapToItem;
|
||||
// Anchors
|
||||
anchors.top: installedAppsHeader.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: sideloadAppButton.top;
|
||||
width: parent.width;
|
||||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: 40;
|
||||
|
||||
RalewayRegular {
|
||||
text: model.appUrl;
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
height: parent.height;
|
||||
anchors.right: sideloadAppOpenButton.left;
|
||||
anchors.rightMargin: 8;
|
||||
elide: Text.ElideRight;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
// Alignment
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
Window.copyToClipboard((model.appUrl).slice(0, -9));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: sideloadAppOpenButton;
|
||||
text: "OPEN";
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 2;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 2;
|
||||
anchors.right: uninstallGlyph.left;
|
||||
anchors.rightMargin: 8;
|
||||
width: 80;
|
||||
onClicked: {
|
||||
Commerce.openApp(model.appUrl);
|
||||
}
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: uninstallGlyph;
|
||||
text: hifi.glyphs.close;
|
||||
color: hifi.colors.black;
|
||||
size: 22;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
width: 35;
|
||||
height: parent.height;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
parent.text = hifi.glyphs.closeInverted;
|
||||
}
|
||||
onExited: {
|
||||
parent.text = hifi.glyphs.close;
|
||||
}
|
||||
onClicked: {
|
||||
Commerce.uninstallApp(model.appUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: sideloadAppButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: closeAppListButton.left;
|
||||
anchors.rightMargin: 8;
|
||||
height: 40;
|
||||
text: "SIDELOAD APP FROM LOCAL DISK";
|
||||
onClicked: {
|
||||
Window.browseChanged.connect(onFileOpenChanged);
|
||||
Window.browseAsync("Locate your app's .app.json file", "", "*.app.json");
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: closeAppListButton;
|
||||
color: hifi.buttons.white;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
width: 100;
|
||||
height: 40;
|
||||
text: "BACK";
|
||||
onClicked: {
|
||||
installedAppsContainer.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiWallet.NeedsLogIn {
|
||||
id: needsLogIn;
|
||||
|
@ -317,7 +464,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: purchasesContentsContainer;
|
||||
visible: root.activeView === "purchasesMain";
|
||||
visible: root.activeView === "purchasesMain" && !installedAppsList.visible;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
@ -959,6 +1106,39 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if ((event.key == Qt.Key_F) && (event.modifiers & Qt.ControlModifier)) {
|
||||
installedAppsContainer.visible = !installedAppsContainer.visible;
|
||||
console.log("User changed visibility of installedAppsContainer to " + installedAppsContainer.visible);
|
||||
}
|
||||
}
|
||||
function onFileOpenChanged(filename) {
|
||||
// disconnect the event, otherwise the requests will stack up
|
||||
try { // Not all calls to onFileOpenChanged() connect an event.
|
||||
Window.browseChanged.disconnect(onFileOpenChanged);
|
||||
} catch (e) {
|
||||
console.log('Purchases.qml ignoring', e);
|
||||
}
|
||||
if (filename) {
|
||||
Commerce.installApp(filename);
|
||||
}
|
||||
}
|
||||
ListModel {
|
||||
id: installedAppsModel;
|
||||
}
|
||||
onInstalledAppsChanged: {
|
||||
installedAppsModel.clear();
|
||||
var installedAppsArray = root.installedApps.split(",");
|
||||
var installedAppsObject = [];
|
||||
// "- 1" because the last app string ends with ","
|
||||
for (var i = 0; i < installedAppsArray.length - 1; i++) {
|
||||
installedAppsObject[i] = {
|
||||
"appUrl": installedAppsArray[i]
|
||||
}
|
||||
}
|
||||
installedAppsModel.append(installedAppsObject);
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
|
|
|
@ -145,6 +145,16 @@
|
|||
#include <avatars-renderer/ScriptAvatar.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 "audio/AudioScope.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
|
@ -1060,6 +1070,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
if (steamClient) {
|
||||
qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID();
|
||||
}
|
||||
setCrashAnnotation("steam", property(hifi::properties::STEAM).toBool() ? "1" : "0");
|
||||
|
||||
qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion());
|
||||
qCDebug(interfaceapp) << "[VERSION] MODIFIED_ORGANIZATION:" << BuildInfo::MODIFIED_ORGANIZATION;
|
||||
qCDebug(interfaceapp) << "[VERSION] VERSION:" << BuildInfo::VERSION;
|
||||
|
@ -1145,6 +1157,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
const DomainHandler& domainHandler = nodeList->getDomainHandler();
|
||||
|
||||
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
|
||||
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
|
||||
setCrashAnnotation("domain", domainURL.toString().toStdString());
|
||||
});
|
||||
connect(&domainHandler, SIGNAL(resetting()), SLOT(resettingDomain()));
|
||||
connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle()));
|
||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
|
||||
|
@ -1190,6 +1205,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||
connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
||||
connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
||||
connect(accountManager.data(), &AccountManager::usernameChanged, [](QString username){
|
||||
setCrashAnnotation("username", username.toStdString());
|
||||
});
|
||||
|
||||
// set the account manager's root URL and trigger a login request if we don't have the access token
|
||||
accountManager->setIsAgent(true);
|
||||
|
@ -1207,6 +1225,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateThreadPoolCount);
|
||||
connect(this, &Application::activeDisplayPluginChanged, this, [](){
|
||||
qApp->setProperty(hifi::properties::HMD, qApp->isHMDMode());
|
||||
auto displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
setCrashAnnotation("display_plugin", displayPlugin->getName().toStdString());
|
||||
setCrashAnnotation("hmd", displayPlugin->isHmd() ? "1" : "0");
|
||||
});
|
||||
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateSystemTabletMode);
|
||||
|
||||
|
@ -1214,6 +1235,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
connect(myAvatar.get(), &MyAvatar::positionGoneTo,
|
||||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
connect(myAvatar.get(), &MyAvatar::skeletonModelURLChanged, [](){
|
||||
QUrl avatarURL = qApp->getMyAvatar()->getSkeletonModelURL();
|
||||
setCrashAnnotation("avatar", avatarURL.toString().toStdString());
|
||||
});
|
||||
|
||||
|
||||
// Inititalize sample before registering
|
||||
_sampleSound = DependencyManager::get<SoundCache>()->getSound(PathUtils::resourcesUrl("sounds/sample.wav"));
|
||||
|
||||
|
@ -1306,6 +1333,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Needs to happen AFTER the render engine initialization to access its configuration
|
||||
initializeUi();
|
||||
|
||||
updateVerboseLogging();
|
||||
|
||||
init();
|
||||
qCDebug(interfaceapp, "init() complete.");
|
||||
|
||||
|
@ -1322,49 +1351,48 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
// sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
|
||||
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
|
||||
static const QString TESTER = "HIFI_TESTER";
|
||||
auto gpuIdent = GPUIdent::getInstance();
|
||||
auto glContextData = getGLContextData();
|
||||
QJsonObject properties = {
|
||||
{ "version", applicationVersion() },
|
||||
{ "tester", QProcessEnvironment::systemEnvironment().contains(TESTER) },
|
||||
{ "previousSessionCrashed", _previousSessionCrashed },
|
||||
{ "previousSessionRuntime", sessionRunTime.get() },
|
||||
{ "cpu_architecture", QSysInfo::currentCpuArchitecture() },
|
||||
{ "kernel_type", QSysInfo::kernelType() },
|
||||
{ "kernel_version", QSysInfo::kernelVersion() },
|
||||
{ "os_type", QSysInfo::productType() },
|
||||
{ "os_version", QSysInfo::productVersion() },
|
||||
{ "gpu_name", gpuIdent->getName() },
|
||||
{ "gpu_driver", gpuIdent->getDriver() },
|
||||
{ "gpu_memory", static_cast<qint64>(gpuIdent->getMemory()) },
|
||||
{ "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) },
|
||||
{ "gl_version", glContextData["version"] },
|
||||
{ "gl_vender", glContextData["vendor"] },
|
||||
{ "gl_sl_version", glContextData["sl_version"] },
|
||||
{ "gl_renderer", glContextData["renderer"] },
|
||||
{ "ideal_thread_count", QThread::idealThreadCount() }
|
||||
};
|
||||
auto macVersion = QSysInfo::macVersion();
|
||||
if (macVersion != QSysInfo::MV_None) {
|
||||
properties["os_osx_version"] = QSysInfo::macVersion();
|
||||
}
|
||||
auto windowsVersion = QSysInfo::windowsVersion();
|
||||
if (windowsVersion != QSysInfo::WV_None) {
|
||||
properties["os_win_version"] = QSysInfo::windowsVersion();
|
||||
constexpr auto INSTALLER_INI_NAME = "installer.ini";
|
||||
auto iniPath = QDir(applicationDirPath()).filePath(INSTALLER_INI_NAME);
|
||||
QFile installerFile { iniPath };
|
||||
std::unordered_map<QString, QString> installerKeyValues;
|
||||
if (installerFile.open(QIODevice::ReadOnly)) {
|
||||
while (!installerFile.atEnd()) {
|
||||
auto line = installerFile.readLine();
|
||||
if (!line.isEmpty()) {
|
||||
auto index = line.indexOf("=");
|
||||
if (index >= 0) {
|
||||
installerKeyValues[line.mid(0, index).trimmed()] = line.mid(index + 1).trimmed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProcessorInfo procInfo;
|
||||
if (getProcessorInfo(procInfo)) {
|
||||
properties["processor_core_count"] = procInfo.numProcessorCores;
|
||||
properties["logical_processor_count"] = procInfo.numLogicalProcessors;
|
||||
properties["processor_l1_cache_count"] = procInfo.numProcessorCachesL1;
|
||||
properties["processor_l2_cache_count"] = procInfo.numProcessorCachesL2;
|
||||
properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3;
|
||||
// In practice we shouldn't run across installs that don't have a known installer type.
|
||||
// Client or Client+Server installs should always have the installer.ini next to their
|
||||
// respective interface.exe, and Steam installs will be detected as such. If a user were
|
||||
// to delete the installer.ini, though, and as an example, we won't know the context of the
|
||||
// original install.
|
||||
constexpr auto INSTALLER_KEY_TYPE = "type";
|
||||
constexpr auto INSTALLER_KEY_CAMPAIGN = "campaign";
|
||||
constexpr auto INSTALLER_TYPE_UNKNOWN = "unknown";
|
||||
constexpr auto INSTALLER_TYPE_STEAM = "steam";
|
||||
|
||||
auto typeIt = installerKeyValues.find(INSTALLER_KEY_TYPE);
|
||||
QString installerType = INSTALLER_TYPE_UNKNOWN;
|
||||
if (typeIt == installerKeyValues.end()) {
|
||||
if (property(hifi::properties::STEAM).toBool()) {
|
||||
installerType = INSTALLER_TYPE_STEAM;
|
||||
}
|
||||
} else {
|
||||
installerType = typeIt->second;
|
||||
}
|
||||
|
||||
auto campaignIt = installerKeyValues.find(INSTALLER_KEY_CAMPAIGN);
|
||||
QString installerCampaign = campaignIt != installerKeyValues.end() ? campaignIt->second : "";
|
||||
|
||||
qDebug() << "Detected installer type:" << installerType;
|
||||
qDebug() << "Detected installer campaign:" << installerCampaign;
|
||||
|
||||
// add firstRun flag from settings to launch event
|
||||
Setting::Handle<bool> firstRun { Settings::firstRun, true };
|
||||
|
||||
|
@ -1377,6 +1405,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
userActivityLogger.disable(false);
|
||||
}
|
||||
|
||||
QString machineFingerPrint = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
|
||||
|
||||
if (userActivityLogger.isEnabled()) {
|
||||
// sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
|
||||
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
|
||||
|
@ -1386,6 +1416,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
QJsonObject properties = {
|
||||
{ "version", applicationVersion() },
|
||||
{ "tester", QProcessEnvironment::systemEnvironment().contains(TESTER) },
|
||||
{ "installer_campaign", installerCampaign },
|
||||
{ "installer_type", installerType },
|
||||
{ "previousSessionCrashed", _previousSessionCrashed },
|
||||
{ "previousSessionRuntime", sessionRunTime.get() },
|
||||
{ "cpu_architecture", QSysInfo::currentCpuArchitecture() },
|
||||
|
@ -1424,11 +1456,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
properties["first_run"] = firstRun.get();
|
||||
|
||||
// add the user's machine ID to the launch event
|
||||
properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
|
||||
properties["machine_fingerprint"] = machineFingerPrint;
|
||||
|
||||
userActivityLogger.logAction("launch", properties);
|
||||
}
|
||||
|
||||
setCrashAnnotation("machine_fingerprint", machineFingerPrint.toStdString());
|
||||
|
||||
_entityEditSender.setMyAvatar(myAvatar.get());
|
||||
|
||||
// The entity octree will have to know about MyAvatar for the parentJointName import
|
||||
|
@ -1705,7 +1739,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
const QString HIFI_NO_UPDATER_COMMAND_LINE_KEY = "--no-updater";
|
||||
bool noUpdater = arguments().indexOf(HIFI_NO_UPDATER_COMMAND_LINE_KEY) != -1;
|
||||
if (!noUpdater) {
|
||||
constexpr auto INSTALLER_TYPE_CLIENT_ONLY = "client_only";
|
||||
|
||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||
|
||||
AutoUpdater::InstallerType type = installerType == INSTALLER_TYPE_CLIENT_ONLY
|
||||
? AutoUpdater::InstallerType::CLIENT_ONLY : AutoUpdater::InstallerType::FULL;
|
||||
|
||||
applicationUpdater->setInstallerType(type);
|
||||
applicationUpdater->setInstallerCampaign(installerCampaign);
|
||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||
applicationUpdater->checkForUpdate();
|
||||
}
|
||||
|
@ -2165,6 +2207,46 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
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) {
|
||||
DomainHandler::ConnectionRefusedReason reasonCode = static_cast<DomainHandler::ConnectionRefusedReason>(reasonCodeInt);
|
||||
|
||||
|
@ -3036,7 +3118,6 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
|||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
|
||||
bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll());
|
||||
qDebug() << "HandleSandboxStatus" << sandboxIsRunning;
|
||||
|
||||
enum HandControllerType {
|
||||
Vive,
|
||||
|
|
|
@ -403,6 +403,8 @@ public slots:
|
|||
|
||||
Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); }
|
||||
|
||||
void updateVerboseLogging();
|
||||
|
||||
private slots:
|
||||
void onDesktopRootItemCreated(QQuickItem* qmlContext);
|
||||
void onDesktopRootContextCreated(QQmlContext* qmlContext);
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
#include "Bookmarks.h"
|
||||
|
||||
/**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 {
|
||||
|
@ -27,16 +28,12 @@ public:
|
|||
AvatarBookmarks();
|
||||
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:
|
||||
/**jsdoc
|
||||
* Add the current Avatar to your avatar bookmarks.
|
||||
* @function AvatarBookmarks.addBookMark
|
||||
*/
|
||||
void addBookmark();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -49,7 +49,6 @@ protected:
|
|||
|
||||
protected slots:
|
||||
/**jsdoc
|
||||
* Delete
|
||||
* @function AvatarBookmarks.deleteBookmark
|
||||
*/
|
||||
void deleteBookmark();
|
||||
|
|
|
@ -43,12 +43,10 @@ void ConnectionMonitor::init() {
|
|||
}
|
||||
|
||||
void ConnectionMonitor::startTimer() {
|
||||
qDebug() << "ConnectionMonitor: Starting timer";
|
||||
_timer.start(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS);
|
||||
}
|
||||
|
||||
void ConnectionMonitor::stopTimer() {
|
||||
qDebug() << "ConnectionMonitor: Stopping timer";
|
||||
_timer.stop();
|
||||
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(false);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#if HAS_CRASHPAD
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
|
||||
|
@ -23,8 +25,8 @@
|
|||
#include <client/crashpad_client.h>
|
||||
#include <client/crash_report_database.h>
|
||||
#include <client/settings.h>
|
||||
// #include <client/annotation_list.h>
|
||||
// #include <client/crashpad_info.h>
|
||||
#include <client/annotation_list.h>
|
||||
#include <client/crashpad_info.h>
|
||||
|
||||
using namespace crashpad;
|
||||
|
||||
|
@ -35,32 +37,19 @@ static std::wstring gIPCPipe;
|
|||
|
||||
extern QString qAppFileName();
|
||||
|
||||
// crashpad::AnnotationList* crashpadAnnotations { nullptr };
|
||||
std::mutex annotationMutex;
|
||||
crashpad::SimpleStringDictionary* crashpadAnnotations { nullptr };
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
LONG WINAPI vectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) {
|
||||
static const DWORD EXTERNAL_EXCEPTION_CODE{ 0xe06d7363 };
|
||||
static const DWORD HEAP_CORRUPTION_CODE{ 0xc0000374 };
|
||||
|
||||
auto exceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode;
|
||||
if (exceptionCode == EXTERNAL_EXCEPTION_CODE) {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
if (exceptionCode == HEAP_CORRUPTION_CODE) {
|
||||
qCritical() << "VectoredExceptionHandler: Heap corruption:" << QString::number(exceptionCode, 16);
|
||||
|
||||
if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_HEAP_CORRUPTION ||
|
||||
pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_BUFFER_OVERRUN) {
|
||||
CrashpadClient client;
|
||||
if (gIPCPipe.length()) {
|
||||
bool rc = client.SetHandlerIPCPipe(gIPCPipe);
|
||||
qCritical() << "SetHandlerIPCPipe = " << rc;
|
||||
} else {
|
||||
qCritical() << "No IPC Pipe was previously defined for crash handler.";
|
||||
client.SetHandlerIPCPipe(gIPCPipe);
|
||||
}
|
||||
qCritical() << "Calling DumpAndCrash()";
|
||||
client.DumpAndCrash(pExceptionInfo);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
@ -116,12 +105,14 @@ bool startCrashHandler() {
|
|||
}
|
||||
|
||||
void setCrashAnnotation(std::string name, std::string value) {
|
||||
// if (!crashpadAnnotations) {
|
||||
// crashpadAnnotations = new crashpad::AnnotationList(); // don't free this, let it leak
|
||||
// crashpad::CrashpadInfo* crashpad_info = crashpad::GetCrashpadInfo();
|
||||
// crashpad_info->set_simple_annotations(crashpadAnnotations);
|
||||
// }
|
||||
// crashpadAnnotations->SetKeyValue(name, value);
|
||||
std::lock_guard<std::mutex> guard(annotationMutex);
|
||||
if (!crashpadAnnotations) {
|
||||
crashpadAnnotations = new crashpad::SimpleStringDictionary(); // don't free this, let it leak
|
||||
crashpad::CrashpadInfo* crashpad_info = crashpad::CrashpadInfo::GetCrashpadInfo();
|
||||
crashpad_info->set_simple_annotations(crashpadAnnotations);
|
||||
}
|
||||
std::replace(value.begin(), value.end(), ',', ';');
|
||||
crashpadAnnotations->SetKeyValue(name, value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Crashpad.h"
|
||||
#include "DiscoverabilityManager.h"
|
||||
#include "Menu.h"
|
||||
|
||||
|
@ -127,10 +128,12 @@ void DiscoverabilityManager::updateLocation() {
|
|||
QNetworkAccessManager::PutOperation, callbackParameters);
|
||||
}
|
||||
|
||||
// Update Steam
|
||||
// Update Steam and crash logger
|
||||
QUrl currentAddress = addressManager->currentFacingPublicAddress();
|
||||
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
||||
steamClient->updateLocation(domainHandler.getHostname(), addressManager->currentFacingPublicAddress());
|
||||
steamClient->updateLocation(domainHandler.getHostname(), currentAddress);
|
||||
}
|
||||
setCrashAnnotation("address", currentAddress.toString().toStdString());
|
||||
}
|
||||
|
||||
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {
|
||||
|
|
|
@ -49,21 +49,18 @@ public:
|
|||
* @function LODManager.setAutomaticLODAdjust
|
||||
* @param {boolean} value
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setAutomaticLODAdjust(bool value) { _automaticLODAdjust = value; }
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getAutomaticLODAdjust
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; }
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setDesktopLODDecreaseFPS
|
||||
* @param {float} value
|
||||
* @param {number} value
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -77,28 +74,25 @@ public:
|
|||
* @function LODManager.getDesktopLODIncreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getDesktopLODIncreaseFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setHMDLODDecreaseFPS
|
||||
* @param {number} value
|
||||
*/
|
||||
|
||||
|
||||
Q_INVOKABLE void setHMDLODDecreaseFPS(float value);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getHMDLODDecreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getHMDLODDecreaseFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getHMDLODIncreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getHMDLODIncreaseFPS() const;
|
||||
|
||||
// User Tweakable LOD Items
|
||||
|
@ -106,61 +100,54 @@ public:
|
|||
* @function LODManager.getLODFeedbackText
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE QString getLODFeedbackText();
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setOctreeSizeScale
|
||||
* @param {number} sizeScale
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setOctreeSizeScale(float sizeScale);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getOctreeSizeScale
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getOctreeSizeScale() const { return _octreeSizeScale; }
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.setBoundaryLevelAdjust
|
||||
* @param {number} boundaryLevelAdjust
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getBoundaryLevelAdjust
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getLODDecreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getLODDecreaseFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.getLODIncreaseFPS
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getLODIncreaseFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @namespace LODManager
|
||||
* @property presentTime {number}
|
||||
* @property engineRunTime {number}
|
||||
* @property gpuTime {number}
|
||||
* @property avgRenderTime {number}
|
||||
* @property fps {number}
|
||||
* @property lodLevel {number}
|
||||
* @property lodDecreaseFPS {number}
|
||||
* @property lodIncreaseFPS {number}
|
||||
* @property {number} presentTime <em>Read-only.</em>
|
||||
* @property {number} engineRunTime <em>Read-only.</em>
|
||||
* @property {number} gpuTime <em>Read-only.</em>
|
||||
* @property {number} avgRenderTime <em>Read-only.</em>
|
||||
* @property {number} fps <em>Read-only.</em>
|
||||
* @property {number} lodLevel <em>Read-only.</em>
|
||||
* @property {number} lodDecreaseFPS <em>Read-only.</em>
|
||||
* @property {number} lodIncreaseFPS <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
Q_PROPERTY(float presentTime READ getPresentTime)
|
||||
|
@ -195,14 +182,12 @@ signals:
|
|||
* @function LODManager.LODIncreased
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void LODIncreased();
|
||||
|
||||
/**jsdoc
|
||||
* @function LODManager.LODDecreased
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void LODDecreased();
|
||||
|
||||
private:
|
||||
|
|
|
@ -810,6 +810,9 @@ Menu::Menu() {
|
|||
scriptEngines->loadScript(defaultScriptsLoc.toString());
|
||||
});
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::VerboseLogging, 0, false,
|
||||
qApp, SLOT(updateVerboseLogging()));
|
||||
|
||||
#if 0 /// -------------- REMOVED FOR NOW --------------
|
||||
addDisabledActionAndSeparator(navigateMenu, "History");
|
||||
QAction* backAction = addActionToQMenuAndActionHash(navigateMenu, MenuOption::Back, 0, addressManager.data(), SLOT(goBack()));
|
||||
|
|
|
@ -142,6 +142,7 @@ namespace MenuOption {
|
|||
const QString Pair = "Pair";
|
||||
const QString PhysicsShowHulls = "Draw Collision Shapes";
|
||||
const QString PhysicsShowOwned = "Highlight Simulation Ownership";
|
||||
const QString VerboseLogging = "Verbose Logging";
|
||||
const QString PipelineWarnings = "Log Render Pipeline Warnings";
|
||||
const QString Preferences = "General...";
|
||||
const QString Quit = "Quit";
|
||||
|
|
|
@ -28,12 +28,12 @@ class AudioScope : public QObject, public Dependency {
|
|||
/**jsdoc
|
||||
* The AudioScope API helps control the Audio Scope features in Interface
|
||||
* @namespace AudioScope
|
||||
* @property {int} scopeInput
|
||||
* @property {int} scopeOutputLeft
|
||||
* @property {int} scopeOutputRight
|
||||
* @property {int} triggerInput
|
||||
* @property {int} triggerOutputLeft
|
||||
* @property {int} triggerOutputRight
|
||||
* @property {number} scopeInput <em>Read-only.</em>
|
||||
* @property {number} scopeOutputLeft <em>Read-only.</em>
|
||||
* @property {number} scopeOutputRight <em>Read-only.</em>
|
||||
* @property {number} triggerInput <em>Read-only.</em>
|
||||
* @property {number} triggerOutputLeft <em>Read-only.</em>
|
||||
* @property {number} triggerOutputRight <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
Q_PROPERTY(QVector<int> scopeInput READ getScopeInput)
|
||||
|
@ -55,62 +55,52 @@ public slots:
|
|||
/**jsdoc
|
||||
* @function AudioScope.toggle
|
||||
*/
|
||||
|
||||
void toggle() { setVisible(!_isEnabled); }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.setVisible
|
||||
* @param {boolean} visible
|
||||
*/
|
||||
|
||||
void setVisible(bool visible);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getVisible
|
||||
* @param {boolean} visible
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool getVisible() const { return _isEnabled; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.togglePause
|
||||
*/
|
||||
|
||||
void togglePause() { setPause(!_isPaused); }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.setPause
|
||||
* @param {boolean}
|
||||
* @param {boolean} paused
|
||||
*/
|
||||
|
||||
void setPause(bool paused) { _isPaused = paused; emit pauseChanged(); }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getPause
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool getPause() { return _isPaused; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.toggleTrigger
|
||||
*/
|
||||
|
||||
void toggleTrigger() { _autoTrigger = !_autoTrigger; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getAutoTrigger
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool getAutoTrigger() { return _autoTrigger; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.setAutoTrigger
|
||||
* @param {boolean} autoTrigger
|
||||
*/
|
||||
|
||||
void setAutoTrigger(bool autoTrigger) { _isTriggered = false; _autoTrigger = autoTrigger; }
|
||||
|
||||
/**jsdoc
|
||||
|
@ -118,109 +108,93 @@ public slots:
|
|||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
|
||||
void setTriggerValues(int x, int y) { _triggerValues.x = x; _triggerValues.y = y; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.setTriggered
|
||||
* @param {boolean} triggered
|
||||
*/
|
||||
|
||||
void setTriggered(bool triggered) { _isTriggered = triggered; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getTriggered
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool getTriggered() { return _isTriggered; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getFramesPerSecond
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
float getFramesPerSecond();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getFramesPerScope
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
int getFramesPerScope() { return _framesPerScope; }
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.selectAudioScopeFiveFrames
|
||||
*/
|
||||
|
||||
void selectAudioScopeFiveFrames();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.selectAudioScopeTwentyFrames
|
||||
*/
|
||||
|
||||
void selectAudioScopeTwentyFrames();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.selectAudioScopeFiftyFrames
|
||||
*/
|
||||
|
||||
void selectAudioScopeFiftyFrames();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getScopeInput
|
||||
* @returns {number}
|
||||
* @returns {number[]}
|
||||
*/
|
||||
|
||||
QVector<int> getScopeInput() { return _scopeInputData; };
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getScopeOutputLeft
|
||||
* @returns {number}
|
||||
* @returns {number[]}
|
||||
*/
|
||||
|
||||
QVector<int> getScopeOutputLeft() { return _scopeOutputLeftData; };
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getScopeOutputRight
|
||||
* @returns {number}
|
||||
* @returns {number[]}
|
||||
*/
|
||||
|
||||
QVector<int> getScopeOutputRight() { return _scopeOutputRightData; };
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getTriggerInput
|
||||
* @returns {number}
|
||||
* @returns {number[]}
|
||||
*/
|
||||
|
||||
QVector<int> getTriggerInput() { return _triggerInputData; };
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getTriggerOutputLeft
|
||||
* @returns {number}
|
||||
* @returns {number[]}
|
||||
*/
|
||||
|
||||
QVector<int> getTriggerOutputLeft() { return _triggerOutputLeftData; };
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.getTriggerOutputRight
|
||||
* @returns {number}
|
||||
* @returns {number[]}
|
||||
*/
|
||||
|
||||
QVector<int> getTriggerOutputRight() { return _triggerOutputRightData; };
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.setLocalEcho
|
||||
* @parm {boolean} serverEcho
|
||||
* @parm {boolean} localEcho
|
||||
*/
|
||||
|
||||
void setLocalEcho(bool serverEcho);
|
||||
void setLocalEcho(bool localEcho);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.setServerEcho
|
||||
* @parm {boolean} serverEcho
|
||||
*/
|
||||
|
||||
void setServerEcho(bool serverEcho);
|
||||
|
||||
signals:
|
||||
|
@ -229,14 +203,12 @@ signals:
|
|||
* @function AudioScope.pauseChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void pauseChanged();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioScope.triggered
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void triggered();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -38,75 +38,6 @@ class AvatarManager : public AvatarHashMap {
|
|||
|
||||
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.
|
||||
static void registerMetaTypes(QScriptEngine* engine);
|
||||
|
||||
|
@ -119,10 +50,9 @@ public:
|
|||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.getAvatar
|
||||
* @param {string} avatarID
|
||||
* @returns {}
|
||||
* @param {Uuid} avatarID
|
||||
* @returns {AvatarData}
|
||||
*/
|
||||
|
||||
// Null/Default-constructed QUuids will return MyAvatar
|
||||
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) override { return new ScriptAvatar(getAvatarBySessionID(avatarID)); }
|
||||
|
||||
|
@ -148,16 +78,15 @@ public:
|
|||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.getAvatarDataRate
|
||||
* @param {string} sessionID
|
||||
* @param {Uuid} sessionID
|
||||
* @param {string} [rateName=""]
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float getAvatarDataRate(const QUuid& sessionID, const QString& rateName = QString("")) const;
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.getAvatarUpdateRate
|
||||
* @param {string} sessionID
|
||||
* @param {Uuid} sessionID
|
||||
* @param {string} [rateName=""]
|
||||
* @returns {number}
|
||||
*/
|
||||
|
@ -166,51 +95,47 @@ public:
|
|||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.getAvatarSimulationRate
|
||||
* @param {string} sessionID
|
||||
* @param {Uuid} sessionID
|
||||
* @param {string} [rateName=""]
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
|
||||
Q_INVOKABLE float getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName = QString("")) const;
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.findRayIntersection
|
||||
* @param {PickRay} ray
|
||||
* @param {} avatarIdsToInclude
|
||||
* @param {} avatarIdsToDiscard
|
||||
* @param {Uuid[]} [avatarsToInclude=[]]
|
||||
* @param {Uuid[]} [avatarsToDiscard=[]]
|
||||
* @returns {RayToAvatarIntersectionResult}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray,
|
||||
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
||||
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
||||
/**jsdoc
|
||||
* @function AvatarManager.findRayIntersectionVector
|
||||
* @param {PickRay} ray
|
||||
* @param {} avatarsToInclude
|
||||
* @param {} avatarIdsToDiscard
|
||||
* @param {Uuid[]} avatarsToInclude
|
||||
* @param {Uuid[]} avatarsToDiscard
|
||||
* @returns {RayToAvatarIntersectionResult}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVector(const PickRay& ray,
|
||||
const QVector<EntityItemID>& avatarsToInclude,
|
||||
const QVector<EntityItemID>& avatarsToDiscard);
|
||||
|
||||
// TODO: remove this HACK once we settle on optimal default sort coefficients
|
||||
/**jsdoc
|
||||
* @function AvatarManager.getAvatarSortCoefficient
|
||||
* @param {string} name
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
// TODO: remove this HACK once we settle on optimal default sort coefficients
|
||||
Q_INVOKABLE float getAvatarSortCoefficient(const QString& name);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.setAvatarSortCoefficient
|
||||
* @param {string} name
|
||||
* @param {string} value
|
||||
* @param {number} value
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value);
|
||||
|
||||
float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); }
|
||||
|
@ -221,7 +146,6 @@ public slots:
|
|||
* @function AvatarManager.updateAvatarRenderStatus
|
||||
* @param {boolean} shouldRenderAvatars
|
||||
*/
|
||||
|
||||
void updateAvatarRenderStatus(bool shouldRenderAvatars);
|
||||
|
||||
private:
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* @namespace MyAvatar
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
*
|
||||
* @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,
|
||||
* otherwise it is not rendered for you (but it is still rendered for other users).
|
||||
|
|
|
@ -67,13 +67,11 @@ public slots:
|
|||
* @function FaceTracker.setEnabled
|
||||
* @param {boolean} enabled
|
||||
*/
|
||||
|
||||
void setEnabled(bool enabled) override;
|
||||
|
||||
/**jsdoc
|
||||
* @function FaceTracker.calibrate
|
||||
*/
|
||||
|
||||
void calibrate();
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
*
|
||||
* @typedef {Object} Picks.RayPickResult
|
||||
* @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 {float} distance The distance to the intersection point from the origin of the ray.
|
||||
* @property {Vec3} intersection The intersection point in world-space.
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
*
|
||||
* @typedef {Object} Picks.StylusPickResult
|
||||
* @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 {float} distance The distance to the intersection point from the origin of the ray.
|
||||
* @property {Vec3} intersection The intersection point in world-space.
|
||||
|
|
|
@ -39,10 +39,10 @@ class AccountServicesScriptingInterface : public QObject {
|
|||
* The AccountServices API contains helper functions related to user connectivity
|
||||
*
|
||||
* @namespace AccountServices
|
||||
* @property {string} username
|
||||
* @property {boolean} loggedIn
|
||||
* @property {string} username <em>Read-only.</em>
|
||||
* @property {boolean} loggedIn <em>Read-only.</em>
|
||||
* @property {string} findableBy
|
||||
* @property {string} metaverseServerURL
|
||||
* @property {string} metaverseServerURL <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged)
|
||||
|
@ -63,33 +63,28 @@ public slots:
|
|||
* @function AccountServices.getDownloadInfo
|
||||
* @returns {DownloadInfoResult}
|
||||
*/
|
||||
|
||||
DownloadInfoResult getDownloadInfo();
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.updateDownloadInfo
|
||||
*/
|
||||
|
||||
void updateDownloadInfo();
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.isLoggedIn
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool isLoggedIn();
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.checkAndSignalForAccessToken
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool checkAndSignalForAccessToken();
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.logOut
|
||||
*/
|
||||
|
||||
void logOut();
|
||||
|
||||
private slots:
|
||||
|
@ -108,47 +103,41 @@ signals:
|
|||
* @function AccountServices.connected
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void connected();
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.disconnected
|
||||
* @params {string} reason
|
||||
* @param {string} reason
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void disconnected(const QString& reason);
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.myUsernameChanged
|
||||
* @params {string} username
|
||||
* @param {string} username
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void myUsernameChanged(const QString& username);
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.downloadInfoChanged
|
||||
* @params {} info
|
||||
* @param {} info
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void downloadInfoChanged(DownloadInfoResult info);
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.findableByChanged
|
||||
* @params {string} discoverabilityMode
|
||||
* @param {string} discoverabilityMode
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void findableByChanged(const QString& discoverabilityMode);
|
||||
|
||||
/**jsdoc
|
||||
* @function AccountServices.loggedInChanged
|
||||
* @params {boolean} loggedIn
|
||||
* @param {boolean} loggedIn
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void loggedInChanged(bool loggedIn);
|
||||
|
||||
private:
|
||||
|
|
|
@ -31,10 +31,10 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
|
|||
* @namespace Audio
|
||||
* @property {boolean} muted
|
||||
* @property {boolean} noiseReduction
|
||||
* @property {boolean} inputVolume
|
||||
* @property {boolean} inputLevel
|
||||
* @property {string} context
|
||||
* @property {} devices
|
||||
* @property {number} inputVolume
|
||||
* @property {number} inputLevel <em>Read-only.</em>
|
||||
* @property {string} context <em>Read-only.</em>
|
||||
* @property {} devices <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
|
||||
|
@ -66,7 +66,6 @@ public:
|
|||
* @param {} device
|
||||
* @param {boolean} isHMD
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -74,40 +73,36 @@ public:
|
|||
* @param {} device
|
||||
* @param {boolean} isHMD
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.setReverb
|
||||
* @param {boolean} enable
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setReverb(bool enable);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.setReverbOptions
|
||||
* @param {} options
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setReverbOptions(const AudioEffectOptions* options);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.setReverbOptions
|
||||
* @function Audio.startRecording
|
||||
* @param {string} filename
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE bool startRecording(const QString& filename);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.stopRecording
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void stopRecording();
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.getRecording
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE bool getRecording();
|
||||
|
||||
signals:
|
||||
|
@ -116,39 +111,34 @@ signals:
|
|||
* @function Audio.nop
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void nop();
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.nop
|
||||
* @param {bool} isMuted
|
||||
* @function Audio.mutedChanged
|
||||
* @param {boolean} isMuted
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void mutedChanged(bool isMuted);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.noiseReductionChanged
|
||||
* @param {bool} isEnabled
|
||||
* @param {boolean} isEnabled
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void noiseReductionChanged(bool isEnabled);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.inputVolumeChanged
|
||||
* @param {float} volume
|
||||
* @param {number} volume
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void inputVolumeChanged(float volume);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.inputLevelChanged
|
||||
* @param {float} level
|
||||
* @param {number} level
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void inputLevelChanged(float level);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -156,7 +146,6 @@ signals:
|
|||
* @param {string} context
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void contextChanged(const QString& context);
|
||||
|
||||
public slots:
|
||||
|
@ -165,7 +154,6 @@ public slots:
|
|||
* @function Audio.onContextChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void onContextChanged();
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -108,11 +108,9 @@ AudioDeviceList::~AudioDeviceList() {
|
|||
// store the selected device
|
||||
foreach(std::shared_ptr<AudioDevice> adevice, _devices) {
|
||||
if (adevice->selectedDesktop) {
|
||||
qDebug() << "Saving Desktop for" << _mode << "name" << adevice->info.deviceName();
|
||||
settingDesktop.set(adevice->info.deviceName());
|
||||
}
|
||||
if (adevice->selectedHMD) {
|
||||
qDebug() << "Saving HMD for" << _mode << "name" << 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class ScriptEngine;
|
|||
/**jsdoc
|
||||
* The Controller API provides facilities to interact with computer and controller hardware.
|
||||
*
|
||||
* <h5>Functions:</h5>
|
||||
* <h5>Functions</h5>
|
||||
*
|
||||
* <p>Properties</p>
|
||||
* <ul>
|
||||
|
@ -143,6 +143,61 @@ class ScriptEngine;
|
|||
* <li>{@link Controller.stopInputPlayback|stopInputPlayback}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h5>Entity Methods:</h5>
|
||||
*
|
||||
* <p>The default scripts implement hand controller actions that use {@link Entities.callEntityMethod} to call entity script
|
||||
* methods, if present in the entity being interacted with.</p>
|
||||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Method Name</th><th>Description</th><th>Example</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td><code>startFarTrigger</code><br /><code>continueFarTrigger</code><br /><code>stopFarTrigger</code></td>
|
||||
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is triggerable, and the
|
||||
* user starts, continues, or stops squeezing the trigger.</td>
|
||||
* </td>
|
||||
* <td>A light switch that can be toggled on and off from a distance.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startNearTrigger</code><br /><code>continueNearTrigger</code><br /><code>stopNearTrigger</code></td>
|
||||
* <td>These methods are called when a user is less than 0.3m away from the entity, the entity is triggerable, and the
|
||||
* user starts, continues, or stops squeezing the trigger.</td>
|
||||
* <td>A doorbell that can be rung when a user is near.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startDistanceGrab</code><br /><code>continueDistanceGrab</code><br /></td>
|
||||
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is either cloneable, or
|
||||
* grabbable and not locked, and the user starts or continues to squeeze the trigger.</td>
|
||||
* <td>A comet that emits icy particle trails when a user is dragging it through the sky.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startNearGrab</code><br /><code>continueNearGrab</code><br /></td>
|
||||
* <td>These methods are called when a user is less than 0.3m away from the entity, the entity is either cloneable, or
|
||||
* grabbable and not locked, and the user starts or continues to squeeze the trigger.</td>
|
||||
* <td>A ball that glows when it's being held close.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>releaseGrab</code></td>
|
||||
* <td>This method is called when a user releases the trigger when having been either distance or near grabbing an
|
||||
* entity.</td>
|
||||
* <td>Turn off the ball glow or comet trail with the user finishes grabbing it.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startEquip</code><br /><code>continueEquip</code><br /><code>releaseEquip</code></td>
|
||||
* <td>These methods are called when a user starts, continues, or stops equipping an entity.</td>
|
||||
* <td>A glass that stays in the user's hand after the trigger is clicked.</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* <p>All the entity methods are called with the following two arguments:</p>
|
||||
* <ul>
|
||||
* <li>The entity ID.</li>
|
||||
* <li>A string, <code>"hand,userID"</code> — where "hand" is <code>"left"</code> or <code>"right"</code>, and "userID"
|
||||
* is the user's {@link MyAvatar|MyAvatar.sessionUUID}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @namespace Controller
|
||||
*
|
||||
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
|
||||
|
|
|
@ -32,7 +32,6 @@ public slots:
|
|||
* @function GooglePoly.setAPIKey
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
void setAPIKey(const QString& key);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -42,7 +41,6 @@ public slots:
|
|||
* @param {string} format
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getAssetList(const QString& keyword, const QString& category, const QString& format);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -51,7 +49,6 @@ public slots:
|
|||
* @param {string} category
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getFBX(const QString& keyword, const QString& category);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -60,7 +57,6 @@ public slots:
|
|||
* @param {string} category
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getOBJ(const QString& keyword, const QString& category);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -69,7 +65,6 @@ public slots:
|
|||
* @param {string} category
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getBlocks(const QString& keyword, const QString& category);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -78,7 +73,6 @@ public slots:
|
|||
* @param {string} category
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getGLTF(const QString& keyword, const QString& category);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -87,7 +81,6 @@ public slots:
|
|||
* @param {string} category
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getGLTF2(const QString& keyword, const QString& category);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -96,7 +89,6 @@ public slots:
|
|||
* @param {string} category
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getTilt(const QString& keyword, const QString& category);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -104,7 +96,6 @@ public slots:
|
|||
* @param {string} input
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
QString getModelInfo(const QString& input);
|
||||
|
||||
private:
|
||||
|
|
|
@ -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
|
||||
* waiting for a user response.
|
||||
* @function Window.alert
|
||||
* @param {string} message="" - The message to display.
|
||||
* @param {string} [message=""] - The message to display.
|
||||
* @example <caption>Display a friendly greeting.</caption>
|
||||
* Window.alert("Welcome!");
|
||||
* 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.
|
||||
* responds.
|
||||
* @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>.
|
||||
* @example <caption>Ask the user a question requiring a yes/no answer.</caption>
|
||||
* 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
|
||||
* is emitted if the user cancels the dialog.
|
||||
* @function Window.promptAsync
|
||||
* @param {string} message - The question to display.
|
||||
* @param {string} defaultText - The default answer text.
|
||||
* @param {string} [message=""] - The question to display.
|
||||
* @param {string} [defaultText=""] - The default answer text.
|
||||
* @example <caption>Ask the user a question requiring a text answer without waiting for the answer.</caption>
|
||||
* function onPromptTextChanged(text) {
|
||||
* print("User answer: " + text);
|
||||
|
@ -144,8 +144,8 @@ public slots:
|
|||
/**jsdoc
|
||||
* Prompt the user to choose a directory. Displays a modal dialog that navigates the directory tree.
|
||||
* @function Window.browseDir
|
||||
* @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} [title=""] - The title to display at the top of the dialog.
|
||||
* @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>.
|
||||
* @example <caption>Ask the user to choose a directory.</caption>
|
||||
* 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
|
||||
* the user cancels the dialog.
|
||||
* @function Window.browseDirAsync
|
||||
* @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} [title=""] - The title to display at the top of the dialog.
|
||||
* @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>
|
||||
* function onBrowseDirChanged(directory) {
|
||||
* print("Directory: " + directory);
|
||||
|
@ -174,9 +174,9 @@ public slots:
|
|||
/**jsdoc
|
||||
* Prompt the user to choose a file. Displays a modal dialog that navigates the directory tree.
|
||||
* @function Window.browse
|
||||
* @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} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||
* @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} [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.
|
||||
* @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>
|
||||
|
@ -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
|
||||
* cancels the dialog.
|
||||
* @function Window.browseAsync
|
||||
* @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} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||
* @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} [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.
|
||||
* @example <caption>Ask the user to choose an image file without waiting for the answer.</caption>
|
||||
* 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
|
||||
* tree and allows the user to type in a file name.
|
||||
* @function Window.save
|
||||
* @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} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||
* @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} [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.
|
||||
* @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.
|
||||
|
@ -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
|
||||
* emitted when a file is specified; no signal is emitted if the user cancels the dialog.
|
||||
* @function Window.saveAsync
|
||||
* @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} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||
* @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} [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.
|
||||
* @example <caption>Ask the user to specify a file to save to without waiting for an answer.</caption>
|
||||
* 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
|
||||
* Server.
|
||||
* @function Window.browseAssets
|
||||
* @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} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||
* @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} [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.
|
||||
* @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>
|
||||
|
@ -261,9 +261,9 @@ public slots:
|
|||
* 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.
|
||||
* @function Window.browseAssetsAsync
|
||||
* @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} nameFilter="" - The types of files to display. Examples: <code>"*.json"</code> and
|
||||
* @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} [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.
|
||||
* @example
|
||||
* 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
|
||||
* map the file to on the asset server.
|
||||
* @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>
|
||||
* var filename = Window.browse("Select File to Add to Asset Server", Paths.resources);
|
||||
* print("File: " + filename);
|
||||
|
@ -317,14 +317,14 @@ public slots:
|
|||
* NOTE: to provide a non-default value - all previous parameters must be provided.
|
||||
* General > Snapshots.
|
||||
* @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.
|
||||
* @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.
|
||||
* @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
|
||||
* 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".
|
||||
* 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.
|
||||
* NOTE: to provide a non-default value - all previous parameters must be provided.
|
||||
* @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".
|
||||
* Otherwise, the image will be saved to this filename, with an appended ".jpg".
|
||||
*
|
||||
|
@ -397,7 +397,7 @@ public slots:
|
|||
* has been prepared.
|
||||
* @function Window.shareSnapshot
|
||||
* @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(""));
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ class AvatarInputs : public QObject {
|
|||
/**jsdoc
|
||||
* API to help manage your Avatar's input
|
||||
* @namespace AvatarInputs
|
||||
* @param {boolean} cameraEnabled
|
||||
* @param {boolean} cameraMuted
|
||||
* @param {boolean} isHMD
|
||||
* @param {boolean} showAudioTools
|
||||
* @property {boolean} cameraEnabled <em>Read-only.</em>
|
||||
* @property {boolean} cameraMuted <em>Read-only.</em>
|
||||
* @property {boolean} isHMD <em>Read-only.</em>
|
||||
* @property {boolean} showAudioTools
|
||||
*/
|
||||
|
||||
AI_PROPERTY(bool, cameraEnabled, false)
|
||||
|
@ -46,8 +46,8 @@ public:
|
|||
* @param {number} loudness
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE float loudnessToAudioLevel(float loudness);
|
||||
|
||||
AvatarInputs(QObject* parent = nullptr);
|
||||
void update();
|
||||
bool showAudioTools() const { return _showAudioTools; }
|
||||
|
@ -58,7 +58,6 @@ public slots:
|
|||
* @function AvatarInputs.setShowAudioTools
|
||||
* @param {boolean} showAudioTools
|
||||
*/
|
||||
|
||||
void setShowAudioTools(bool showAudioTools);
|
||||
|
||||
signals:
|
||||
|
@ -67,14 +66,12 @@ signals:
|
|||
* @function AvatarInputs.cameraEnabledChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void cameraEnabledChanged();
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarInputs.cameraMutedChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void cameraMutedChanged();
|
||||
|
||||
/**jsdoc
|
||||
|
@ -89,7 +86,6 @@ signals:
|
|||
* @param {boolean} show
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void showAudioToolsChanged(bool show);
|
||||
|
||||
protected:
|
||||
|
@ -97,13 +93,11 @@ protected:
|
|||
/**jsdoc
|
||||
* @function AvatarInputs.resetSensors
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void resetSensors();
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarInputs.toggleCameraMute
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void toggleCameraMute();
|
||||
|
||||
private:
|
||||
|
|
|
@ -80,7 +80,6 @@ void DialogsManager::showFeed() {
|
|||
}
|
||||
|
||||
void DialogsManager::setDomainConnectionFailureVisibility(bool visible) {
|
||||
qDebug() << "DialogsManager::setDomainConnectionFailureVisibility: visible" << visible;
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
|
||||
|
|
|
@ -588,6 +588,7 @@ void AnimExpression::evalUnaryMinus(const AnimVariantMap& map, std::stack<OpCode
|
|||
PUSH(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::Int:
|
||||
PUSH(-rhs.intVal);
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
#include <FBXReader.h>
|
||||
#include <ResourceCache.h>
|
||||
|
||||
/**jsdoc
|
||||
* API to manage Animation Cache resources
|
||||
* @namespace AnimationCache
|
||||
*/
|
||||
|
||||
class Animation;
|
||||
|
||||
typedef QSharedPointer<Animation> AnimationPointer;
|
||||
|
@ -35,79 +30,67 @@ class AnimationCache : public ResourceCache, public Dependency {
|
|||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
// Copied over from ResourceCache (see ResourceCache.h for reason)
|
||||
|
||||
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* API to manage animation cache resources.
|
||||
* @namespace AnimationCache
|
||||
* @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
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of resources
|
||||
* @function AnimationCache.getNumTotalResources
|
||||
* @returns {number}
|
||||
*/
|
||||
// Functions are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of all resources
|
||||
* @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
|
||||
/**jsdoc
|
||||
* Get the list of all resource URLs.
|
||||
* @function AnimationCache.getResourceList
|
||||
* @returns {string[]}
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
||||
/**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
|
||||
/**jsdoc
|
||||
* @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
|
||||
* Returns animation resource for particular animation
|
||||
* Returns animation resource for particular animation.
|
||||
* @function AnimationCache.getAnimation
|
||||
* @param url {string} url to load
|
||||
* @param {string} url - URL to load.
|
||||
* @returns {Resource} animation
|
||||
*/
|
||||
|
||||
Q_INVOKABLE AnimationPointer getAnimation(const QString& url) { return getAnimation(QUrl(url)); }
|
||||
Q_INVOKABLE AnimationPointer getAnimation(const QUrl& url);
|
||||
|
||||
|
|
|
@ -40,65 +40,135 @@ class AudioStreamStatsInterface : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
/**jsdoc
|
||||
* Audio stats from the Audio Mixer
|
||||
* @namespace AudioStats.mixerStream
|
||||
* @param {number} lossRate
|
||||
* @param {number} lossCount
|
||||
* @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
|
||||
* @class AudioStats.AudioStreamStats
|
||||
* @property {number} lossRate <em>Read-only.</em>
|
||||
* @property {number} lossCount <em>Read-only.</em>
|
||||
* @property {number} lossRateWindow <em>Read-only.</em>
|
||||
* @property {number} lossCountWindow <em>Read-only.</em>
|
||||
* @property {number} framesDesired <em>Read-only.</em>
|
||||
* @property {number} framesAvailable <em>Read-only.</em>
|
||||
* @property {number} framesAvailableAvg <em>Read-only.</em>
|
||||
* @property {number} unplayedMsMax <em>Read-only.</em>
|
||||
* @property {number} starveCount <em>Read-only.</em>
|
||||
* @property {number} lastStarveDurationCount <em>Read-only.</em>
|
||||
* @property {number} dropCount <em>Read-only.</em>
|
||||
* @property {number} overflowCount <em>Read-only.</em>
|
||||
* @property {number} timegapMsMax <em>Read-only.</em>
|
||||
* @property {number} timegapMsAvg <em>Read-only.</em>
|
||||
* @property {number} timegapMsMaxWindow <em>Read-only.</em>
|
||||
* @property {number} timegapMsAvgWindow <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Audio stats from the Client Mixer
|
||||
* @namespace AudioStats.clientMixer
|
||||
* @function AudioStats.AudioStreamStats.lossRateChanged
|
||||
* @param {number} lossRate
|
||||
* @param {number} lossCount
|
||||
* @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
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
AUDIO_PROPERTY(float, lossRate)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.lossCountChanged
|
||||
* @param {number} lossCount
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, lossCount)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.lossRateWindowChanged
|
||||
* @param {number} lossRateWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, lossRateWindow)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.lossCountWindowChanged
|
||||
* @param {number} lossCountWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, lossCountWindow)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.framesDesiredChanged
|
||||
* @param {number} framesDesired
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, framesDesired)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.framesAvailableChanged
|
||||
* @param {number} framesAvailable
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, framesAvailable)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.framesAvailableAvgChanged
|
||||
* @param {number} framesAvailableAvg
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, framesAvailableAvg)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.unplayedMsMaxChanged
|
||||
* @param {number} unplayedMsMax
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, unplayedMsMax)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.starveCountChanged
|
||||
* @param {number} starveCount
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, starveCount)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.lastStarveDurationCountChanged
|
||||
* @param {number} lastStarveDurationCount
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, lastStarveDurationCount)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.dropCountChanged
|
||||
* @param {number} dropCount
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, dropCount)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.overflowCountChanged
|
||||
* @param {number} overflowCount
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(int, overflowCount)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.timegapMsMaxChanged
|
||||
* @param {number} timegapMsMax
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, timegapMsMax)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.timegapMsAvgChanged
|
||||
* @param {number} timegapMsAvg
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, timegapMsAvg)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.timegapMsMaxWindowChanged
|
||||
* @param {number} timegapMsMaxWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, timegapMsMaxWindow)
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.AudioStreamStats.timegapMsAvgWindowChanged
|
||||
* @param {number} timegapMsAvgWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, timegapMsAvgWindow)
|
||||
|
||||
public:
|
||||
|
@ -113,31 +183,82 @@ class AudioStatsInterface : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
/**jsdoc
|
||||
* Audio stats from the client
|
||||
* Audio stats from the client.
|
||||
* @namespace AudioStats
|
||||
* @param {number} pingMs
|
||||
* @param {number} inputReadMsMax
|
||||
* @param {number} inputUnplayedMsMax
|
||||
* @param {number} outputUnplayedMsMax
|
||||
* @param {number} sentTimegapMsMax
|
||||
* @param {number} sentTimegapMsAvg
|
||||
* @param {number} sentTimegapMsMaxWindow
|
||||
* @param {number} sentTimegapMsAvgWindow
|
||||
* @property {number} pingMs <em>Read-only.</em>
|
||||
* @property {number} inputReadMsMax <em>Read-only.</em>
|
||||
* @property {number} inputUnplayedMsMax <em>Read-only.</em>
|
||||
* @property {number} outputUnplayedMsMax <em>Read-only.</em>
|
||||
* @property {number} sentTimegapMsMax <em>Read-only.</em>
|
||||
* @property {number} sentTimegapMsAvg <em>Read-only.</em>
|
||||
* @property {number} sentTimegapMsMaxWindow <em>Read-only.</em>
|
||||
* @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);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.inputReadMsMaxChanged
|
||||
* @param {number} inputReadMsMax
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, inputReadMsMax);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.inputUnplayedMsMaxChanged
|
||||
* @param {number} inputUnplayedMsMax
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, inputUnplayedMsMax);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.outputUnplayedMsMaxChanged
|
||||
* @param {number} outputUnplayedMsMax
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(float, outputUnplayedMsMax);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.sentTimegapMsMaxChanged
|
||||
* @param {number} sentTimegapMsMax
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, sentTimegapMsMax);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.sentTimegapMsAvgChanged
|
||||
* @param {number} sentTimegapMsAvg
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, sentTimegapMsAvg);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.sentTimegapMsMaxWindowChanged
|
||||
* @param {number} sentTimegapMsMaxWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, sentTimegapMsMaxWindow);
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.sentTimegapMsAvgWindowChanged
|
||||
* @param {number} sentTimegapMsAvgWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
AUDIO_PROPERTY(quint64, sentTimegapMsAvgWindow);
|
||||
|
||||
Q_PROPERTY(AudioStreamStatsInterface* mixerStream READ getMixerStream NOTIFY mixerStreamChanged);
|
||||
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);
|
||||
|
||||
public:
|
||||
|
@ -159,21 +280,18 @@ signals:
|
|||
* @function AudioStats.mixerStreamChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void mixerStreamChanged();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.clientStreamChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void clientStreamChanged();
|
||||
|
||||
/**jsdoc
|
||||
* @function AudioStats.injectorStreamsChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void injectorStreamsChanged();
|
||||
|
||||
private:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// Inline functions to implement audio dynamics processing
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
|
@ -16,84 +16,32 @@
|
|||
|
||||
#include "Sound.h"
|
||||
|
||||
/**jsdoc
|
||||
* API to manage Sound Cache resources
|
||||
* @namespace SoundCache
|
||||
*/
|
||||
|
||||
|
||||
/// Scriptable interface for sound loading.
|
||||
class SoundCache : public ResourceCache, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
// Copied over from ResourceCache (see ResourceCache.h for reason)
|
||||
|
||||
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* API to manage sound cache resources.
|
||||
* @namespace SoundCache
|
||||
* @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
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of resources
|
||||
* @function SoundCache.getNumTotalResources
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
// Functions are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of all resources
|
||||
* @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
|
||||
* Get the list of all resource URLs.
|
||||
* @function SoundCache.getResourceList
|
||||
* @returns {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}
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
|
@ -101,12 +49,40 @@ public:
|
|||
* @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
|
||||
* @function SoundCache.getSound
|
||||
* @param {string} url
|
||||
* @returns {}
|
||||
* @returns {object}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url);
|
||||
protected:
|
||||
virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <unordered_map>
|
||||
|
||||
AutoUpdater::AutoUpdater() {
|
||||
#if defined Q_OS_WIN32
|
||||
|
@ -43,63 +44,114 @@ void AutoUpdater::parseLatestVersionData() {
|
|||
QNetworkReply* sender = qobject_cast<QNetworkReply*>(QObject::sender());
|
||||
|
||||
QXmlStreamReader xml(sender);
|
||||
|
||||
struct InstallerURLs {
|
||||
QString full;
|
||||
QString clientOnly;
|
||||
};
|
||||
|
||||
int version;
|
||||
int version { 0 };
|
||||
QString downloadUrl;
|
||||
QString releaseTime;
|
||||
QString releaseNotes;
|
||||
QString commitSha;
|
||||
QString pullRequestNumber;
|
||||
|
||||
while (!xml.atEnd() && !xml.hasError()) {
|
||||
if (xml.name().toString() == "project" &&
|
||||
xml.attributes().hasAttribute("name") &&
|
||||
xml.attributes().value("name").toString() == "interface") {
|
||||
xml.readNext();
|
||||
|
||||
while (!xml.atEnd() && !xml.hasError() && xml.name().toString() != "project") {
|
||||
if (xml.name().toString() == "platform" &&
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name() == "projects") {
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name().toString() == "project" &&
|
||||
xml.attributes().hasAttribute("name") &&
|
||||
xml.attributes().value("name").toString() == _operatingSystem) {
|
||||
xml.readNext();
|
||||
while (!xml.atEnd() && !xml.hasError() &&
|
||||
xml.name().toString() != "platform") {
|
||||
|
||||
if (xml.name().toString() == "build" && xml.tokenType() != QXmlStreamReader::EndElement) {
|
||||
xml.readNext();
|
||||
version = xml.readElementText().toInt();
|
||||
xml.readNext();
|
||||
downloadUrl = xml.readElementText();
|
||||
xml.readNext();
|
||||
releaseTime = xml.readElementText();
|
||||
xml.readNext();
|
||||
if (xml.name().toString() == "notes" && xml.tokenType() != QXmlStreamReader::EndElement) {
|
||||
xml.readNext();
|
||||
while (!xml.atEnd() && !xml.hasError() && xml.name().toString() != "notes") {
|
||||
if (xml.name().toString() == "note" && xml.tokenType() != QXmlStreamReader::EndElement) {
|
||||
releaseNotes = releaseNotes + "\n" + xml.readElementText();
|
||||
xml.attributes().value("name").toString() == "interface") {
|
||||
|
||||
while (xml.readNextStartElement()) {
|
||||
|
||||
if (xml.name().toString() == "platform" &&
|
||||
xml.attributes().hasAttribute("name") &&
|
||||
xml.attributes().value("name").toString() == _operatingSystem) {
|
||||
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name() == "build") {
|
||||
QHash<QString, InstallerURLs> campaignInstallers;
|
||||
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name() == "version") {
|
||||
version = xml.readElementText().toInt();
|
||||
} else if (xml.name() == "url") {
|
||||
downloadUrl = xml.readElementText();
|
||||
} else if (xml.name() == "installers") {
|
||||
while (xml.readNextStartElement()) {
|
||||
QString campaign = xml.name().toString();
|
||||
QString full;
|
||||
QString clientOnly;
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name() == "full") {
|
||||
full = xml.readElementText();
|
||||
} else if (xml.name() == "client_only") {
|
||||
clientOnly = xml.readElementText();
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
campaignInstallers[campaign] = { full, clientOnly };
|
||||
}
|
||||
} else if (xml.name() == "timestamp") {
|
||||
releaseTime = xml.readElementText();
|
||||
} else if (xml.name() == "notes") {
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name() == "note") {
|
||||
releaseNotes = releaseNotes + "\n" + xml.readElementText();
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else if (xml.name() == "sha") {
|
||||
commitSha = xml.readElementText();
|
||||
} else if (xml.name() == "pull_request") {
|
||||
pullRequestNumber = xml.readElementText();
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
xml.readNext();
|
||||
|
||||
static const QString DEFAULT_INSTALLER_CAMPAIGN_NAME = "standard";
|
||||
for (auto& campaign : { _installerCampaign, DEFAULT_INSTALLER_CAMPAIGN_NAME }) {
|
||||
auto it = campaignInstallers.find(campaign);
|
||||
if (it != campaignInstallers.end()) {
|
||||
auto& urls = *it;
|
||||
if (_installerType == InstallerType::CLIENT_ONLY) {
|
||||
if (!urls.clientOnly.isEmpty()) {
|
||||
downloadUrl = urls.clientOnly;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!urls.full.isEmpty()) {
|
||||
downloadUrl = urls.full;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appendBuildData(version, downloadUrl, releaseTime, releaseNotes, pullRequestNumber);
|
||||
releaseNotes = "";
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
xml.readNext();
|
||||
commitSha = xml.readElementText();
|
||||
xml.readNext();
|
||||
pullRequestNumber = xml.readElementText();
|
||||
appendBuildData(version, downloadUrl, releaseTime, releaseNotes, pullRequestNumber);
|
||||
releaseNotes = "";
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
|
||||
xml.readNext();
|
||||
}
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
xml.readNext();
|
||||
}
|
||||
|
||||
} else {
|
||||
xml.readNext();
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
sender->deleteLater();
|
||||
emit latestVersionDataParsed();
|
||||
}
|
||||
|
|
|
@ -36,10 +36,17 @@ class AutoUpdater : public QObject, public Dependency {
|
|||
|
||||
public:
|
||||
AutoUpdater();
|
||||
|
||||
enum class InstallerType {
|
||||
CLIENT_ONLY = 0,
|
||||
FULL
|
||||
};
|
||||
|
||||
void checkForUpdate();
|
||||
const QMap<int, QMap<QString, QString>>& getBuildData() { return _builds; }
|
||||
void performAutoUpdate(int version);
|
||||
void setInstallerType(InstallerType type) { _installerType = type; }
|
||||
void setInstallerCampaign(QString campaign) { _installerCampaign = campaign; }
|
||||
|
||||
signals:
|
||||
void latestVersionDataParsed();
|
||||
|
@ -49,6 +56,8 @@ signals:
|
|||
private:
|
||||
QMap<int, QMap<QString, QString>> _builds;
|
||||
QString _operatingSystem;
|
||||
InstallerType _installerType { InstallerType::FULL };
|
||||
QString _installerCampaign { "" };
|
||||
|
||||
void getLatestVersionData();
|
||||
void downloadUpdateVersion(int version);
|
||||
|
|
|
@ -30,15 +30,6 @@
|
|||
|
||||
#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 {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
@ -51,26 +42,20 @@ public:
|
|||
// Currently, your own avatar will be included as the null avatar id.
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.getAvatarIdentifiers
|
||||
* @function AvatarManager.getAvatarIdentifiers
|
||||
* @returns {Uuid[]}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers();
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.getAvatarsInRange
|
||||
* @function AvatarManager.getAvatarsInRange
|
||||
* @param {Vec3} position
|
||||
* @param {float} rangeMeters
|
||||
* @returns {string[]}
|
||||
* @param {number} range
|
||||
* @returns {Uuid[]}
|
||||
*/
|
||||
|
||||
Q_INVOKABLE QVector<QUuid> getAvatarsInRange(const glm::vec3& position, float rangeMeters) const;
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.getAvatar
|
||||
* @param {string} avatarID
|
||||
* @returns {ScriptAvatarData}
|
||||
*/
|
||||
|
||||
// No JSDod because it's documwented in AvatarManager.
|
||||
// Null/Default-constructed QUuids will return MyAvatar
|
||||
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
|
||||
|
||||
|
@ -80,73 +65,65 @@ public:
|
|||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.avatarAddedEvent
|
||||
* @param {string} sessionUUID
|
||||
* @function AvatarManager.avatarAddedEvent
|
||||
* @param {Uuid} sessionUUID
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void avatarAddedEvent(const QUuid& sessionUUID);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.avatarRemovedEvent
|
||||
* @param {string} sessionUUID
|
||||
* @function AvatarManager.avatarRemovedEvent
|
||||
* @param {Uuid} sessionUUID
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void avatarRemovedEvent(const QUuid& sessionUUID);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.avatarSessionChangedEvent
|
||||
* @param {string} sessionUUID
|
||||
* @param {string} oldUUID
|
||||
* @function AvatarManager.avatarSessionChangedEvent
|
||||
* @param {Uuid} sessionUUID
|
||||
* @param {Uuid} oldSessionUUID
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void avatarSessionChangedEvent(const QUuid& sessionUUID,const QUuid& oldUUID);
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.isAvatarInRange
|
||||
* @function AvatarManager.isAvatarInRange
|
||||
* @param {string} position
|
||||
* @param {string} range
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool isAvatarInRange(const glm::vec3 & position, const float range);
|
||||
|
||||
protected slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.sessionUUIDChanged
|
||||
* @param {string} sessionUUID
|
||||
* @param {string} oldUUID
|
||||
* @function AvatarManager.sessionUUIDChanged
|
||||
* @param {Uuid} sessionUUID
|
||||
* @param {Uuid} oldSessionUUID
|
||||
*/
|
||||
|
||||
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.processAvatarDataPacket
|
||||
* @function AvatarManager.processAvatarDataPacket
|
||||
* @param {} message
|
||||
* @param {} sendingNode
|
||||
*/
|
||||
|
||||
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.processAvatarIdentityPacket
|
||||
* @function AvatarManager.processAvatarIdentityPacket
|
||||
* @param {} message
|
||||
* @param {} sendingNode
|
||||
*/
|
||||
|
||||
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarHashMap.processKillAvatar
|
||||
* @function AvatarManager.processKillAvatar
|
||||
* @param {} message
|
||||
* @param {} sendingNode
|
||||
*/
|
||||
|
||||
void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -39,7 +39,9 @@ class UserInputMapper;
|
|||
* methods.</li>
|
||||
* <li>Use {@link Controller.parseMapping} or {@link Controller.loadMapping} to load a {@link Controller.MappingJSON}.</li>
|
||||
* </ul>
|
||||
* <p>Enable the mapping using {@link MappingObject#enable|enable} or {@link Controller.enableMapping} for it to take effect.
|
||||
*
|
||||
* <p>Enable the mapping using {@link MappingObject#enable|enable} or {@link Controller.enableMapping} for it to take
|
||||
* effect.</p>
|
||||
*
|
||||
* <p>Mappings and their routes are applied according to the following rules:</p>
|
||||
* <ul>
|
||||
|
@ -49,7 +51,7 @@ class UserInputMapper;
|
|||
* output that already has a route the new route is ignored.</li>
|
||||
* <li>New mappings override previous mappings: each output is processed using the route in the most recently enabled
|
||||
* mapping that contains that output.</li>
|
||||
* </p>
|
||||
* </ul>
|
||||
*
|
||||
* @class MappingObject
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,8 @@ class ScriptingInterface;
|
|||
* <p>A route in a {@link MappingObject} used by the {@link Controller} API.</p>
|
||||
*
|
||||
* <p>Create a route using {@link MappingObject} methods and apply this object's methods to process it, terminating with
|
||||
* {@link RouteObject#to} to apply it to a <code>Standard</code> control, action, or script function.</p>
|
||||
* {@link RouteObject#to} to apply it to a <code>Standard</code> control, action, or script function. Note: Loops are not
|
||||
* permitted.</p>
|
||||
*
|
||||
* <p>Some methods apply to routes with number data, some apply routes with {@link Pose} data, and some apply to both route
|
||||
* types.<p>
|
||||
|
|
|
@ -390,17 +390,18 @@ public slots:
|
|||
/**jsdoc
|
||||
* Find all entities of a particular name that intersect a sphere defined by a center point and radius.
|
||||
* @function Entities.findEntitiesByName
|
||||
* @param {Entities.EntityType} entityName - The name of the entity to search for.
|
||||
* @param {string} entityName - The name of the entity to search for.
|
||||
* @param {Vec3} center - The point about which to search.
|
||||
* @param {number} radius - The radius within which to search.
|
||||
* @param {bool} 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
|
||||
* no entities could be found.
|
||||
* @example <caption>Get back a list of entities</caption>
|
||||
* @param {boolean} [caseSensitive=false] - If <code>true</code> then the search is case-sensitive.
|
||||
* @returns {Uuid[]} An array of entity IDs that have the specified name and intersect the search sphere. The array is empty
|
||||
* if no entities could be found.
|
||||
* @example <caption>Report the number of entities with the name, "Light-Target".</caption>
|
||||
* var entityIDs = Entities.findEntitiesByName("Light-Target", MyAvatar.position, 10, false);
|
||||
* print("Number of Entities with the name Light-Target " + entityIDs.length);
|
||||
* print("Number of entities with the name "Light-Target": " + entityIDs.length);
|
||||
*/
|
||||
Q_INVOKABLE QVector<QUuid> findEntitiesByName(const QString entityName, const glm::vec3& center, float radius, bool caseSensitiveSearch = false ) const;
|
||||
Q_INVOKABLE QVector<QUuid> findEntitiesByName(const QString entityName, const glm::vec3& center, float radius,
|
||||
bool caseSensitiveSearch = false ) const;
|
||||
|
||||
/**jsdoc
|
||||
* Find the first entity intersected by a {@link PickRay}. <code>Light</code> and <code>Zone</code> entities are not
|
||||
|
|
|
@ -1180,16 +1180,6 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID)
|
|||
_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) {
|
||||
QUuid nonce = QUuid::createUuid(); //random, 5-hex value, separated by "-"
|
||||
QByteArray nonceBytes = nonce.toByteArray();
|
||||
|
@ -1329,7 +1319,7 @@ void EntityTree::sendChallengeOwnershipRequestPacket(const QByteArray& certID, c
|
|||
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.
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
// First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint.
|
||||
|
@ -1360,30 +1350,13 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt
|
|||
withWriteLock([&] {
|
||||
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 {
|
||||
// Second, challenge ownership of the PoP cert
|
||||
// (ignore pending status; a failure will be cleaned up during DDV)
|
||||
sendChallengeOwnershipPacket(certID,
|
||||
jsonObject["transfer_recipient_key"].toString(),
|
||||
entityItemID,
|
||||
senderNode);
|
||||
|
||||
}
|
||||
} else {
|
||||
qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID
|
||||
|
@ -1627,7 +1600,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
|
|||
// Delete the entity we just added if it doesn't pass static certificate verification
|
||||
deleteEntity(entityItemID, true);
|
||||
} else {
|
||||
validatePop(properties.getCertificateID(), entityItemID, senderNode, false);
|
||||
validatePop(properties.getCertificateID(), entityItemID, senderNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -399,12 +399,11 @@ protected:
|
|||
QHash<EntityItemID, EntityItemPointer> _entitiesToAdd;
|
||||
|
||||
Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID);
|
||||
Q_INVOKABLE void startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode);
|
||||
|
||||
private:
|
||||
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 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 };
|
||||
|
||||
|
|
|
@ -996,14 +996,12 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
QByteArray filepath = filename.replace('\\', '/');
|
||||
filename = fileOnUrl(filepath, url);
|
||||
qDebug() << "Filename" << filepath << filename;
|
||||
_textureFilepaths.insert(getID(object.properties), filepath);
|
||||
_textureFilenames.insert(getID(object.properties), filename);
|
||||
} else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) {
|
||||
// trim the name from the timestamp
|
||||
QString name = QString(subobject.properties.at(0).toByteArray());
|
||||
name = name.left(name.indexOf('['));
|
||||
qDebug() << "Filename" << name;
|
||||
_textureNames.insert(getID(object.properties), name);
|
||||
} 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>());
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
#include "FBXReader.h"
|
||||
#include "TextureCache.h"
|
||||
|
||||
/**jsdoc
|
||||
* API to manage Model Cache resources
|
||||
* @namespace ModelCache
|
||||
*/
|
||||
|
||||
// Alias instead of derive to avoid copying
|
||||
|
||||
class NetworkTexture;
|
||||
|
@ -141,72 +136,62 @@ class ModelCache : public ResourceCache, public Dependency {
|
|||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
* @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
|
||||
*/
|
||||
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of resources
|
||||
* @function ModelCache.getNumTotalResources
|
||||
* @returns {number}
|
||||
*/
|
||||
* API to manage model cache resources.
|
||||
* @namespace ModelCache
|
||||
*
|
||||
* @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
|
||||
* Returns the total size in bytes of all resources
|
||||
* @function ModelCache.getSizeTotalResources
|
||||
* @returns {number}
|
||||
*/
|
||||
* Get the list of all resource URLs.
|
||||
* @function ModelCache.getResourceList
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of cached resources
|
||||
* @function ModelCache.getNumCachedResources
|
||||
* @returns {number}
|
||||
*/
|
||||
* @function ModelCache.dirty
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of cached resources
|
||||
* @function ModelCache.getSizeCachedResources
|
||||
* @returns {number}
|
||||
*/
|
||||
* @function ModelCache.updateTotalSize
|
||||
* @param {number} deltaSize
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns list of all resource urls
|
||||
* @function ModelCache.getResourceList
|
||||
* @returns {string[]}
|
||||
*/
|
||||
* @function ModelCache.prefetch
|
||||
* @param {string} url
|
||||
* @param {object} extra
|
||||
* @returns {object}
|
||||
*/
|
||||
|
||||
/**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 ModelCache.getResource
|
||||
* @returns {Resource}
|
||||
*/
|
||||
* Asynchronously loads a resource from the specified URL and returns it.
|
||||
* @function ModelCache.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.
|
||||
* @param url {string} url of resource to load
|
||||
* @function ModelCache.prefetch
|
||||
* @returns {Resource}
|
||||
*/
|
||||
* Prefetches a resource.
|
||||
* @function ModelCache.prefetch
|
||||
* @param {string} url - URL of the resource to prefetch.
|
||||
* @return {Resource}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* @param {number} deltaSize
|
||||
* @function ModelCache.updateTotalSize
|
||||
* @returns {Resource}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* @function ModelCache.dirty
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
GeometryResource::Pointer getGeometryResource(const QUrl& url,
|
||||
const QVariantHash& mapping = QVariantHash(),
|
||||
|
|
|
@ -137,10 +137,6 @@ using NetworkTexturePointer = QSharedPointer<NetworkTexture>;
|
|||
|
||||
Q_DECLARE_METATYPE(QWeakPointer<NetworkTexture>)
|
||||
|
||||
/**jsdoc
|
||||
* API to manage Texture Cache resources
|
||||
* @namespace TextureCache
|
||||
*/
|
||||
|
||||
/// Stores cached textures, including render-to-texture targets.
|
||||
class TextureCache : public ResourceCache, public Dependency {
|
||||
|
@ -148,78 +144,61 @@ class TextureCache : public ResourceCache, public Dependency {
|
|||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
// Copied over from ResourceCache (see ResourceCache.h for reason)
|
||||
|
||||
// Properties are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* @namespace TextureCache
|
||||
* @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
|
||||
*/
|
||||
* API to manage texture cache resources.
|
||||
* @namespace TextureCache
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of resources
|
||||
* @function TextureCache.getNumTotalResources
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of all resources
|
||||
* @function TextureCache.getSizeTotalResources
|
||||
* @returns {number}
|
||||
*/
|
||||
// Functions are copied over from ResourceCache (see ResourceCache.h for reason).
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of cached resources
|
||||
* @function TextureCache.getNumCachedResources
|
||||
* @returns {number}
|
||||
*/
|
||||
/**jsdoc
|
||||
* Get the list of all resource URLs.
|
||||
* @function TextureCache.getResourceList
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of cached resources
|
||||
* @function TextureCache.getSizeCachedResources
|
||||
* @returns {number}
|
||||
*/
|
||||
/**jsdoc
|
||||
* @function TextureCache.dirty
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns list of all resource urls
|
||||
* @function TextureCache.getResourceList
|
||||
* @returns {string[]}
|
||||
*/
|
||||
/**jsdoc
|
||||
* @function TextureCache.updateTotalSize
|
||||
* @param {number} deltaSize
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Returns animation resource for particular animation
|
||||
* @function TextureCache.getAnimation
|
||||
* @param url {string} url to load
|
||||
* @returns {Resource} animation
|
||||
*/
|
||||
/**jsdoc
|
||||
* @function TextureCache.prefetch
|
||||
* @param {string} url
|
||||
* @param {object} extra
|
||||
* @returns {object}
|
||||
*/
|
||||
|
||||
/**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 TextureCache.getResource
|
||||
* @returns {Resource}
|
||||
*/
|
||||
/**jsdoc
|
||||
* Asynchronously loads a resource from the specified URL and returns it.
|
||||
* @function TextureCache.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.
|
||||
* @param url {string} url of resource to load
|
||||
* @function TextureCache.prefetch
|
||||
* @returns {Resource}
|
||||
*/
|
||||
/**jsdoc
|
||||
* Prefetches a resource.
|
||||
* @function TextureCache.prefetch
|
||||
* @param {string} url - URL of the resource to prefetch.
|
||||
* @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
|
||||
/// 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();
|
||||
|
||||
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
|
||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);
|
||||
|
||||
|
|
|
@ -333,12 +333,14 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static const QString LOCALHOST = "localhost";
|
||||
|
||||
bool isPossiblePlaceName(QString possiblePlaceName) {
|
||||
bool result { false };
|
||||
int length = possiblePlaceName.length();
|
||||
static const int MINIMUM_PLACENAME_LENGTH = 1;
|
||||
static const int MAXIMUM_PLACENAME_LENGTH = 64;
|
||||
if (possiblePlaceName.toLower() != "localhost" &&
|
||||
if (possiblePlaceName.toLower() != LOCALHOST &&
|
||||
length >= MINIMUM_PLACENAME_LENGTH && length <= MAXIMUM_PLACENAME_LENGTH) {
|
||||
const QRegExp PLACE_NAME_REGEX = QRegExp("^[0-9A-Za-z](([0-9A-Za-z]|-(?!-))*[^\\W_]$|$)");
|
||||
result = PLACE_NAME_REGEX.indexIn(possiblePlaceName) == 0;
|
||||
|
@ -358,7 +360,7 @@ void AddressManager::handleLookupString(const QString& lookupString, bool fromSu
|
|||
sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX);
|
||||
|
||||
lookupURL = QUrl(sanitizedString);
|
||||
if (lookupURL.scheme().isEmpty()) {
|
||||
if (lookupURL.scheme().isEmpty() || lookupURL.scheme().toLower() == LOCALHOST) {
|
||||
lookupURL = QUrl("hifi://" + sanitizedString);
|
||||
}
|
||||
} else {
|
||||
|
@ -607,7 +609,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
|
|||
if (ipAddressRegex.indexIn(lookupString) != -1) {
|
||||
QString domainIPString = ipAddressRegex.cap(1);
|
||||
|
||||
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
quint16 domainPort = 0;
|
||||
if (!ipAddressRegex.cap(2).isEmpty()) {
|
||||
domainPort = (quint16) ipAddressRegex.cap(2).toInt();
|
||||
}
|
||||
|
@ -629,7 +631,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
|
|||
if (hostnameRegex.indexIn(lookupString) != -1) {
|
||||
QString domainHostname = hostnameRegex.cap(1);
|
||||
|
||||
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
quint16 domainPort = 0;
|
||||
|
||||
if (!hostnameRegex.cap(2).isEmpty()) {
|
||||
domainPort = (quint16)hostnameRegex.cap(2).toInt();
|
||||
|
|
|
@ -31,12 +31,54 @@ public:
|
|||
BaseAssetScriptingInterface(QObject* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function Assets.isValidPath
|
||||
* @param {string} input
|
||||
* @returns {boolean}
|
||||
*/
|
||||
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); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Assets.getATPUrl
|
||||
* @param {string} input
|
||||
* @returns {string}
|
||||
*/
|
||||
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); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Assets.isValidHash
|
||||
* @param {string} input
|
||||
* @returns {boolean}
|
||||
*/
|
||||
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); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Assets.hashDataHex
|
||||
* @param {} data
|
||||
* @returns {string}
|
||||
*/
|
||||
QString hashDataHex(const QByteArray& data) { return hashData(data).toHex(); }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -166,7 +166,12 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
|
|||
}
|
||||
}
|
||||
|
||||
if (_domainURL != domainURL || _sockAddr.getPort() != domainURL.port()) {
|
||||
auto domainPort = domainURL.port();
|
||||
if (domainPort == -1) {
|
||||
domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
}
|
||||
|
||||
if (_domainURL != domainURL || _sockAddr.getPort() != domainPort) {
|
||||
// re-set the domain info so that auth information is reloaded
|
||||
hardReset();
|
||||
|
||||
|
@ -192,12 +197,10 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
|
|||
|
||||
emit domainURLChanged(_domainURL);
|
||||
|
||||
if (_sockAddr.getPort() != domainURL.port()) {
|
||||
qCDebug(networking) << "Updated domain port to" << domainURL.port();
|
||||
if (_sockAddr.getPort() != domainPort) {
|
||||
qCDebug(networking) << "Updated domain port to" << domainPort;
|
||||
_sockAddr.setPort(domainPort);
|
||||
}
|
||||
|
||||
// grab the port by reading the string after the colon
|
||||
_sockAddr.setPort(domainURL.port());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -192,8 +192,6 @@ void EntityScriptClient::handleNodeClientConnectionReset(SharedNodePointer node)
|
|||
return;
|
||||
}
|
||||
|
||||
//qCDebug(entity_script_client) << "EntityScriptClient detected client connection reset handshake with Asset Server - failing any pending requests";
|
||||
|
||||
forceFailureOfPendingRequests(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -715,10 +715,11 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
|
|||
// insert the new node and release our read lock
|
||||
#if defined(Q_OS_ANDROID) || (defined(__clang__) && defined(Q_OS_LINUX))
|
||||
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer));
|
||||
_localIDMap.insert(std::pair<Node::LocalID, SharedNodePointer>(localID, newNodePointer));
|
||||
#else
|
||||
_nodeHash.emplace(newNode->getUUID(), newNodePointer);
|
||||
#endif
|
||||
_localIDMap.emplace(localID, newNodePointer);
|
||||
#endif
|
||||
readLocker.unlock();
|
||||
|
||||
qCDebug(networking) << "Added" << *newNode;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
Q_DECLARE_LOGGING_CATEGORY(resourceLog)
|
||||
Q_DECLARE_LOGGING_CATEGORY(networking)
|
||||
Q_DECLARE_LOGGING_CATEGORY(asset_client)
|
||||
Q_DECLARE_LOGGING_CATEGORY(entity_script_client)
|
||||
Q_DECLARE_LOGGING_CATEGORY(messages_client)
|
||||
|
||||
#endif // hifi_NetworkLogging_h
|
||||
|
|
|
@ -89,14 +89,13 @@ class ScriptableResource : public QObject {
|
|||
|
||||
/**jsdoc
|
||||
* @constructor Resource
|
||||
* @property url {string} url of this resource
|
||||
* @property state {Resource.State} current loading state
|
||||
* @property {string} url - URL of this resource.
|
||||
* @property {Resource.State} state - Current loading state.
|
||||
*/
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUrl url READ getURL)
|
||||
Q_PROPERTY(int state READ getState NOTIFY stateChanged)
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
@ -104,11 +103,11 @@ public:
|
|||
/**jsdoc
|
||||
* @name Resource.State
|
||||
* @static
|
||||
* @property QUEUED {int} The resource is queued up, waiting to be loaded.
|
||||
* @property LOADING {int} The resource is downloading
|
||||
* @property LOADED {int} The resource has finished downloaded by is not complete
|
||||
* @property FINISHED {int} The resource has completly finished loading and is ready.
|
||||
* @property FAILED {int} Downloading the resource has failed.
|
||||
* @property {number} QUEUED - The resource is queued up, waiting to be loaded.
|
||||
* @property {number} LOADING - The resource is downloading.
|
||||
* @property {number} LOADED - The resource has finished downloaded by is not complete.
|
||||
* @property {number} FINISHED - The resource has completely finished loading and is ready.
|
||||
* @property {number} FAILED - Downloading the resource has failed.
|
||||
*/
|
||||
|
||||
enum State {
|
||||
|
@ -124,7 +123,7 @@ public:
|
|||
virtual ~ScriptableResource() = default;
|
||||
|
||||
/**jsdoc
|
||||
* Release this resource
|
||||
* Release this resource.
|
||||
* @function Resource#release
|
||||
*/
|
||||
Q_INVOKABLE void release();
|
||||
|
@ -139,18 +138,18 @@ public:
|
|||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when download progress for this resource has changed
|
||||
* Triggered when download progress for this resource has changed.
|
||||
* @function Resource#progressChanged
|
||||
* @param bytesReceived {int} bytes downloaded so far
|
||||
* @param bytesTotal {int} total number of bytes in the resource
|
||||
* @param {number} bytesReceived - Byytes downloaded so far.
|
||||
* @param {number} bytesTotal - Total number of bytes in the resource.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void progressChanged(uint64_t bytesReceived, uint64_t bytesTotal);
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when resource loading state has changed
|
||||
* Triggered when resource loading state has changed.
|
||||
* @function Resource#stateChanged
|
||||
* @param bytesReceived {Resource.State} new state
|
||||
* @param {Resource.State} state - New state.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void stateChanged(int state);
|
||||
|
@ -185,14 +184,15 @@ Q_DECLARE_METATYPE(ScriptableResource*);
|
|||
/// Base class for resource caches.
|
||||
class ResourceCache : public QObject {
|
||||
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
|
||||
* @namespace ResourceCache
|
||||
* @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
|
||||
* @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>
|
||||
*/
|
||||
Q_PROPERTY(size_t numTotal READ getNumTotalResources 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)
|
||||
|
||||
public:
|
||||
/**jsdoc
|
||||
* Returns the total number of resources
|
||||
* @function ResourceCache.getNumTotalResources
|
||||
* @return {number}
|
||||
*/
|
||||
|
||||
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; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of cached resources
|
||||
* @function ResourceCache.getNumCachedResources
|
||||
* @return {number}
|
||||
*/
|
||||
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; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns list of all resource urls
|
||||
* Get the list of all resource URLs.
|
||||
* @function ResourceCache.getResourceList
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
@ -257,28 +235,45 @@ public:
|
|||
void clearUnusedResources();
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* @function ResourceCache.dirty
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void dirty();
|
||||
|
||||
protected slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function ResourceCache.updateTotalSize
|
||||
* @param {number} 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.
|
||||
// Left as a protected member so subclasses can overload prefetch
|
||||
// and delegate to it (see TextureCache::prefetch(const QUrl&, int).
|
||||
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.
|
||||
/// If the caller is on a different thread than the ResourceCache,
|
||||
/// returns an empty smart pointer and loads its asynchronously.
|
||||
/// \param fallback a fallback URL to load if the desired one is unavailable
|
||||
/// \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(),
|
||||
void* extra = NULL);
|
||||
|
||||
|
@ -292,8 +287,8 @@ protected:
|
|||
// the QScriptEngine will delete the pointer when it is garbage collected.
|
||||
/**jsdoc
|
||||
* Prefetches a resource.
|
||||
* @param url {string} url of resource to load
|
||||
* @function ResourceCache.prefetch
|
||||
* @param {string} url - URL of the resource to prefetch.
|
||||
* @return {Resource}
|
||||
*/
|
||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url) { return prefetch(url, nullptr); }
|
||||
|
|
|
@ -84,7 +84,8 @@ void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeTy
|
|||
_domainServerTimer.start();
|
||||
|
||||
// start sending stats packet once we connect to the domain
|
||||
connect(&nodeList->getDomainHandler(), SIGNAL(connectedToDomain(const QString&)), &_statsTimer, SLOT(start()));
|
||||
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
|
||||
&_statsTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
|
||||
|
||||
// stop sending stats if we disconnect
|
||||
connect(&nodeList->getDomainHandler(), &DomainHandler::disconnectedFromDomain, &_statsTimer, &QTimer::stop);
|
||||
|
|
|
@ -795,9 +795,10 @@ QString getMarketplaceID(const QString& urlString) {
|
|||
}
|
||||
|
||||
bool Octree::readFromURL(const QString& urlString) {
|
||||
QString marketplaceID = getMarketplaceID(urlString);
|
||||
QString trimmedUrl = urlString.trimmed();
|
||||
QString marketplaceID = getMarketplaceID(trimmedUrl);
|
||||
auto request =
|
||||
std::unique_ptr<ResourceRequest>(DependencyManager::get<ResourceManager>()->createResourceRequest(this, urlString));
|
||||
std::unique_ptr<ResourceRequest>(DependencyManager::get<ResourceManager>()->createResourceRequest(this, trimmedUrl));
|
||||
|
||||
if (!request) {
|
||||
return false;
|
||||
|
|
|
@ -159,6 +159,8 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
// remove the objects (aka MotionStates) from physics
|
||||
_physicsEngine->removeSetOfObjects(_physicalObjects);
|
||||
|
||||
clearOwnershipData();
|
||||
|
||||
// delete the MotionStates
|
||||
for (auto stateItr : _physicalObjects) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr));
|
||||
|
@ -171,7 +173,6 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
_physicalObjects.clear();
|
||||
|
||||
// clear all other lists specific to this derived class
|
||||
clearOwnershipData();
|
||||
_entitiesToRemoveFromPhysics.clear();
|
||||
_entitiesToAddToPhysics.clear();
|
||||
_incomingChanges.clear();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "AbstractViewStateInterface.h"
|
||||
#include "RenderUtilsLogging.h"
|
||||
#include "DebugDraw.h"
|
||||
#include "StencilMaskPass.h"
|
||||
|
||||
#include "animdebugdraw_vert.h"
|
||||
#include "animdebugdraw_frag.h"
|
||||
|
@ -70,7 +71,7 @@ public:
|
|||
typedef render::Payload<AnimDebugDrawData> AnimDebugDrawPayload;
|
||||
|
||||
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 <> void payloadRender(const AnimDebugDrawData::Pointer& data, RenderArgs* args) {
|
||||
data->render(args);
|
||||
|
@ -104,6 +105,7 @@ AnimDebugDraw::AnimDebugDraw() :
|
|||
state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
|
||||
gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA,
|
||||
gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
PrepareStencil::testMaskDrawShape(*state.get());
|
||||
auto vertShader = animdebugdraw_vert::getShader();
|
||||
auto fragShader = animdebugdraw_frag::getShader();
|
||||
auto program = gpu::Shader::createProgram(vertShader, fragShader);
|
||||
|
|
|
@ -198,7 +198,7 @@ Antialiasing::~Antialiasing() {
|
|||
_antialiasingTextures[1].reset();
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
||||
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(const render::RenderContextPointer& renderContext) {
|
||||
|
||||
if (!_antialiasingPipeline) {
|
||||
|
||||
|
@ -207,17 +207,6 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
|||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
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());
|
||||
|
||||
|
@ -225,6 +214,21 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
|||
|
||||
// Good to go add the brand new pipeline
|
||||
_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;
|
||||
|
@ -347,7 +351,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
|
|||
batch.setViewportTransform(args->_viewport);
|
||||
|
||||
// TAA step
|
||||
getAntialiasingPipeline();
|
||||
getAntialiasingPipeline(renderContext);
|
||||
batch.setResourceFramebufferSwapChainTexture(AntialiasingPass_HistoryMapSlot, _antialiasingBuffers, 0);
|
||||
batch.setResourceTexture(AntialiasingPass_SourceMapSlot, sourceBuffer->getRenderBuffer(0));
|
||||
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.setFramebufferSwapChain(_antialiasingBuffers, 1);
|
||||
batch.setPipeline(getAntialiasingPipeline());
|
||||
batch.setPipeline(getAntialiasingPipeline(renderContext));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
// Blend step
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
void configure(const Config& config);
|
||||
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& getDebugBlendPipeline();
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
|
|||
outputs.edit4() = halfNormalTexture;
|
||||
|
||||
auto linearDepthPipeline = getLinearDepthPipeline(renderContext);
|
||||
auto downsamplePipeline = getDownsamplePipeline();
|
||||
auto downsamplePipeline = getDownsamplePipeline(renderContext);
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
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) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = surfaceGeometry_downsampleDepthNormal_frag::getShader();
|
||||
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());
|
||||
PrepareStencil::testShape(*state);
|
||||
|
||||
|
@ -261,6 +254,16 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() {
|
|||
|
||||
// Good to go add the brand new pipeline
|
||||
_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;
|
||||
|
|
|
@ -84,7 +84,7 @@ private:
|
|||
const gpu::PipelinePointer& getLinearDepthPipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _linearDepthPipeline;
|
||||
|
||||
const gpu::PipelinePointer& getDownsamplePipeline();
|
||||
const gpu::PipelinePointer& getDownsamplePipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _downsamplePipeline;
|
||||
|
||||
gpu::RangeTimerPointer _gpuTimer;
|
||||
|
|
|
@ -113,7 +113,7 @@ void VelocityBufferPass::run(const render::RenderContextPointer& renderContext,
|
|||
outputs.edit1() = velocityFBO;
|
||||
outputs.edit2() = velocityTexture;
|
||||
|
||||
auto cameraMotionPipeline = getCameraMotionPipeline();
|
||||
auto cameraMotionPipeline = getCameraMotionPipeline(renderContext);
|
||||
|
||||
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) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = velocityBuffer_cameraMotion_frag::getShader();
|
||||
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());
|
||||
|
||||
// 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
|
||||
_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;
|
||||
|
|
|
@ -79,7 +79,7 @@ private:
|
|||
|
||||
VelocityFramebufferPointer _velocityFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getCameraMotionPipeline();
|
||||
const gpu::PipelinePointer& getCameraMotionPipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _cameraMotionPipeline;
|
||||
|
||||
gpu::RangeTimerPointer _gpuTimer;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <QtNetwork/QNetworkDiskCache>
|
||||
|
||||
/**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
|
||||
*/
|
||||
class AssetScriptingInterface : public BaseAssetScriptingInterface, QScriptable {
|
||||
|
@ -41,14 +41,12 @@ public:
|
|||
* @param data {string} content to upload
|
||||
* @param callback {Assets~uploadDataCallback} called when upload is complete
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when uploadData is complete
|
||||
* @callback Assets~uploadDataCallback
|
||||
* @param {string} url
|
||||
* @param {string} hash
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void uploadData(QString data, QScriptValue callback);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -57,13 +55,11 @@ public:
|
|||
* @param url {string} URL of asset to download, must be ATP scheme URL.
|
||||
* @param callback {Assets~downloadDataCallback}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when downloadData is complete
|
||||
* @callback Assets~downloadDataCallback
|
||||
* @param data {string} content that was downloaded
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -73,13 +69,11 @@ public:
|
|||
* @param hash {string}
|
||||
* @param callback {Assets~setMappingCallback}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when setMapping is complete
|
||||
* @callback Assets~setMappingCallback
|
||||
* @param {string} error
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -88,21 +82,12 @@ public:
|
|||
* @param path {string}
|
||||
* @param callback {Assets~getMappingCallback}
|
||||
*/
|
||||
|
||||
/**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.
|
||||
*/
|
||||
|
||||
/**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);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -111,7 +96,10 @@ public:
|
|||
* @param enabled {boolean}
|
||||
* @param callback {}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when setBakingEnabled is complete.
|
||||
* @callback Assets~setBakingEnabledCallback
|
||||
*/
|
||||
Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback);
|
||||
|
||||
#if (PR_BUILD || DEV_BUILD)
|
||||
|
@ -122,13 +110,14 @@ public:
|
|||
* Request Asset data from the ATP Server
|
||||
* @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 {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
|
||||
* A set of properties that can be passed to {@link Assets.getAsset}.
|
||||
* @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 {boolean} [decompress=false] whether to attempt gunzip decompression on the fetched data
|
||||
* See: {@link Assets.putAsset} and its .compress=true option
|
||||
|
@ -144,7 +133,7 @@ public:
|
|||
/**jsdoc
|
||||
* Result value returned by {@link Assets.getAsset}.
|
||||
* @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|ArrayBuffer|Object} [response] response data (possibly converted per .responseType value)
|
||||
* @property {string} [responseType] response type (text | arraybuffer | json)
|
||||
|
@ -160,6 +149,7 @@ public:
|
|||
* @function Assets.putAsset
|
||||
* @param {Assets.PutOptions} options A PutOptions object with upload parameters
|
||||
* @param {Assets~putAssetCallback} scope[callback] A scoped callback function invoked with (error, results)
|
||||
* @param {function} [callback=undefined]
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
|
@ -180,7 +170,7 @@ public:
|
|||
/**jsdoc
|
||||
* Result value returned by {@link Assets.putAsset}.
|
||||
* @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} [hash] the uploaded asset's resulting ATP hash
|
||||
* @property {boolean} [compressed] flag indicating whether the data was compressed before upload
|
||||
|
@ -243,7 +233,7 @@ public:
|
|||
/**jsdoc
|
||||
* @function Assets.getCacheStatus
|
||||
* @property {} scope
|
||||
* @property {} [callback = ""]
|
||||
* @property {} [callback=undefined]
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void getCacheStatus(QScriptValue scope, QScriptValue callback = QScriptValue()) {
|
||||
|
@ -254,7 +244,7 @@ public:
|
|||
* @function Assets.queryCacheMeta
|
||||
* @property {} options
|
||||
* @property {} scope
|
||||
* @property {} [callback = ""]
|
||||
* @property {} [callback=undefined]
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void queryCacheMeta(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue());
|
||||
|
@ -263,7 +253,7 @@ public:
|
|||
* @function Assets.loadFromCache
|
||||
* @property {} options
|
||||
* @property {} scope
|
||||
* @property {} [callback = ""]
|
||||
* @property {} [callback=undefined]
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void loadFromCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue());
|
||||
|
@ -272,7 +262,7 @@ public:
|
|||
* @function Assets.saveToCache
|
||||
* @property {} options
|
||||
* @property {} scope
|
||||
* @property {} [callback = ""]
|
||||
* @property {} [callback=undefined]
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void saveToCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue());
|
||||
|
@ -283,7 +273,7 @@ public:
|
|||
* @property {} data
|
||||
* @property {} metadata
|
||||
* @property {} scope
|
||||
* @property {} [callback = ""]
|
||||
* @property {} [callback=undefined]
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void saveToCache(const QUrl& url, const QByteArray& data, const QVariantMap& metadata,
|
||||
|
|
|
@ -31,21 +31,88 @@ protected:
|
|||
AudioScriptingInterface() {}
|
||||
|
||||
// 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());
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.playSystemSound
|
||||
* @param {} sound
|
||||
* @param {} position
|
||||
* @returns {object}
|
||||
*/
|
||||
// FIXME: there is no way to play a positionless sound
|
||||
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.setStereoInput
|
||||
* @param {boolean} stereo
|
||||
* @returns {boolean}
|
||||
*/
|
||||
Q_INVOKABLE bool setStereoInput(bool stereo);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.isStereoInput
|
||||
* @returns {boolean}
|
||||
*/
|
||||
Q_INVOKABLE bool isStereoInput();
|
||||
|
||||
signals:
|
||||
void mutedByMixer(); /// the client has been muted by the mixer
|
||||
void environmentMuted(); /// the entire environment has been muted by the mixer
|
||||
void receivedFirstPacket(); /// the client has received its first packet from the audio mixer
|
||||
void disconnected(); /// the client has been disconnected from the audio mixer
|
||||
void noiseGateOpened(); /// the noise gate has opened
|
||||
void noiseGateClosed(); /// the noise gate has closed
|
||||
void inputReceived(const QByteArray& inputSamples); /// a frame of mic input audio has been received and processed
|
||||
|
||||
/**jsdoc
|
||||
* The client has been muted by the mixer.
|
||||
* @function Audio.mutedByMixer
|
||||
* @returns {Signal}
|
||||
*/
|
||||
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:
|
||||
AbstractAudioInterface* _localAudioInterface { nullptr };
|
||||
|
|
|
@ -2161,6 +2161,32 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString&
|
|||
}, forceRedownload);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script starts for a user.
|
||||
* <p>Note: Can only be connected to via <code>this.preload = function (...) { ... }</code> in the entity script.</p>
|
||||
* <table><tr><th>Available in:</th><td>Client Entity Scripts</td><td>Server Entity Scripts</td></tr></table>
|
||||
* @function Entities.preload
|
||||
* @param {Uuid} entityID - The ID of the entity that the script is running in.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
|
||||
* var entityScript = (function () {
|
||||
* this.entityID = Uuid.NULL;
|
||||
*
|
||||
* this.preload = function (entityID) {
|
||||
* this.entityID = entityID;
|
||||
* print("Entity ID: " + this.entityID);
|
||||
* };
|
||||
* );
|
||||
*
|
||||
* var entityID = Entities.addEntity({
|
||||
* type: "Box",
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
||||
* dimensions: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
* color: { red: 255, green: 0, blue: 0 },
|
||||
* script: "(" + entityScript + ")", // Could host the script on a Web server instead.
|
||||
* lifetime: 300 // Delete after 5 minutes.
|
||||
* });
|
||||
*/
|
||||
// since all of these operations can be asynch we will always do the actual work in the response handler
|
||||
// for the download
|
||||
void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success , const QString& status) {
|
||||
|
@ -2345,6 +2371,13 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
|||
processDeferredEntityLoads(entityScript, entityID);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script terminates for a user.
|
||||
* <p>Note: Can only be connected to via <code>this.unoad = function () { ... }</code> in the entity script.</p>
|
||||
* <table><tr><th>Available in:</th><td>Client Entity Scripts</td><td>Server Entity Scripts</td></tr></table>
|
||||
* @function Entities.unload
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
#ifdef THREAD_DEBUGGING
|
||||
|
|
|
@ -273,9 +273,9 @@ QVariantList ScriptEngines::getRunning() {
|
|||
} else {
|
||||
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.
|
||||
resultNode.insert("path", normalizeScriptURL(runningScript).toString());
|
||||
resultNode.insert("path", displayURLString);
|
||||
resultNode.insert("url", normalizeScriptURL(runningScript).toString());
|
||||
resultNode.insert("local", runningScriptURL.isLocalFile());
|
||||
result.append(resultNode);
|
||||
}
|
||||
|
@ -538,7 +538,6 @@ int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) {
|
|||
int ii=0;
|
||||
for (auto initializer : _scriptInitializers) {
|
||||
ii++;
|
||||
qDebug() << "initializer" << ii;
|
||||
initializer(scriptEngine);
|
||||
}
|
||||
return ii;
|
||||
|
|
|
@ -213,7 +213,7 @@ void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectio
|
|||
int byteForSection = (BITS_IN_OCTAL * section / BITS_IN_BYTE);
|
||||
unsigned char* byteAt = octalCode + 1 + byteForSection;
|
||||
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;
|
||||
unsigned char shiftedMask;
|
||||
unsigned char shiftedValue;
|
||||
|
|
|
@ -22,6 +22,5 @@ namespace {
|
|||
}
|
||||
void MiniPromise::registerMetaTypes(QObject* engine) {
|
||||
auto scriptEngine = qobject_cast<QScriptEngine*>(engine);
|
||||
qDebug() << "----------------------- MiniPromise::registerMetaTypes ------------" << scriptEngine;
|
||||
qScriptRegisterMetaType(scriptEngine, promiseToScriptValue, promiseFromScriptValue);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
#include "StorageLogging.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(storagelogging, "hifi.core.storage")
|
||||
|
||||
|
@ -102,4 +102,4 @@ FileStorage::~FileStorage() {
|
|||
if (_file.isOpen()) {
|
||||
_file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
libraries/shared/src/shared/StorageLogging.h
Normal file
18
libraries/shared/src/shared/StorageLogging.h
Normal 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
|
|
@ -64,29 +64,22 @@ signals:
|
|||
* @function FaceTracker.muteToggled
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
||||
void muteToggled();
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function FaceTracker.setEnabled
|
||||
* @param {boolean} enabled
|
||||
*/
|
||||
|
||||
// No JSDoc here because it's overridden in DdeFaceTracker.
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
|
||||
/**jsdoc
|
||||
* @function FaceTracker.toggleMute
|
||||
*/
|
||||
|
||||
void toggleMute();
|
||||
|
||||
/**jsdoc
|
||||
* @function FaceTracker.getMuted
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
bool getMuted() { return _isMuted; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_Controllers_Logging_h
|
||||
#define hifi_Controllers_Logging_h
|
||||
#ifndef hifi_UI_Logging_h
|
||||
#define hifi_UI_Logging_h
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class AudioHandler : public QObject, QRunnable {
|
|||
public:
|
||||
AudioHandler(OffscreenQmlSurface* surface, const QString& deviceName, QObject* parent = nullptr);
|
||||
|
||||
virtual ~AudioHandler() { qDebug() << "Audio Handler Destroyed"; }
|
||||
virtual ~AudioHandler() { }
|
||||
|
||||
void run() override;
|
||||
|
||||
|
|
|
@ -21,40 +21,16 @@
|
|||
|
||||
|
||||
// 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 SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
|
||||
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.
|
||||
|
||||
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;
|
||||
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.selected = selected || false; // not undefined
|
||||
this.selected = false;
|
||||
this.hovering = false;
|
||||
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) };
|
||||
}
|
||||
|
||||
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
|
||||
var lastHoveringId = 0;
|
||||
ExtendedOverlay.prototype.hover = function (hovering) {
|
||||
|
@ -91,9 +63,6 @@
|
|||
lastHoveringId = 0;
|
||||
}
|
||||
this.editOverlay({ color: color(this.selected, hovering) });
|
||||
if (this.model) {
|
||||
this.model.editOverlay({ textures: textures(this.selected, hovering) });
|
||||
}
|
||||
if (hovering) {
|
||||
// un-hover the last hovering overlay
|
||||
if (lastHoveringId && lastHoveringId !== this.key) {
|
||||
|
@ -108,15 +77,12 @@
|
|||
}
|
||||
|
||||
this.editOverlay({ color: color(selected, this.hovering) });
|
||||
if (this.model) {
|
||||
this.model.editOverlay({ textures: textures(selected) });
|
||||
}
|
||||
this.selected = selected;
|
||||
};
|
||||
// Class methods:
|
||||
var selectedIds = [];
|
||||
var selectedId = false;
|
||||
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
|
||||
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) {
|
||||
var selected = ExtendedOverlay.isSelected(id);
|
||||
return new ExtendedOverlay(id, "sphere", {
|
||||
drawInFront: true,
|
||||
solid: true,
|
||||
alpha: 0.8,
|
||||
color: color(selected, false),
|
||||
color: color(false, false),
|
||||
ignoreRayIntersection: false
|
||||
}, selected, !conserveResources);
|
||||
});
|
||||
}
|
||||
|
||||
var pingPong = true;
|
||||
|
@ -236,14 +165,6 @@
|
|||
position: target,
|
||||
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;
|
||||
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)
|
||||
|
@ -251,13 +172,10 @@
|
|||
overlay.deleteOverlay();
|
||||
}
|
||||
});
|
||||
// We could re-populateNearbyUserList if anything added or removed, but not for now.
|
||||
HighlightedEntity.updateOverlays();
|
||||
}
|
||||
function removeOverlays() {
|
||||
selectedIds = [];
|
||||
selectedId = false;
|
||||
lastHoveringId = 0;
|
||||
HighlightedEntity.clearOverlays();
|
||||
ExtendedOverlay.some(function (overlay) {
|
||||
overlay.deleteOverlay();
|
||||
});
|
||||
|
@ -267,7 +185,7 @@
|
|||
// Clicks.
|
||||
//
|
||||
function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
|
||||
if (selectedIds[0] === id) {
|
||||
if (selectedId === id) {
|
||||
var message = {
|
||||
method: 'updateSelectedRecipientUsername',
|
||||
userName: username === "" ? "unknown username" : username
|
||||
|
@ -279,13 +197,13 @@
|
|||
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
||||
var nextSelectedStatus = !overlay.selected;
|
||||
var avatarId = overlay.key;
|
||||
selectedIds = nextSelectedStatus ? [avatarId] : [];
|
||||
selectedId = nextSelectedStatus ? avatarId : false;
|
||||
if (nextSelectedStatus) {
|
||||
Users.requestUsernameFromID(avatarId);
|
||||
}
|
||||
var message = {
|
||||
method: 'selectRecipient',
|
||||
id: [avatarId],
|
||||
id: avatarId,
|
||||
isSelected: nextSelectedStatus,
|
||||
displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"',
|
||||
userName: ''
|
||||
|
@ -298,24 +216,6 @@
|
|||
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;
|
||||
});
|
||||
}
|
||||
|
@ -657,12 +557,14 @@
|
|||
}
|
||||
|
||||
if (onWalletScreen) {
|
||||
if (!isWired) {
|
||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||
triggerMapping.enable();
|
||||
triggerPressMapping.enable();
|
||||
}
|
||||
isWired = true;
|
||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||
triggerMapping.enable();
|
||||
triggerPressMapping.enable();
|
||||
} else {
|
||||
off();
|
||||
}
|
||||
|
|
|
@ -796,7 +796,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
};
|
||||
|
||||
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;
|
||||
}
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
|
|
|
@ -153,40 +153,16 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}
|
||||
|
||||
// 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 SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
|
||||
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.
|
||||
|
||||
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;
|
||||
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.selected = selected || false; // not undefined
|
||||
this.selected = false;
|
||||
this.hovering = false;
|
||||
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) };
|
||||
}
|
||||
|
||||
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
|
||||
var lastHoveringId = 0;
|
||||
ExtendedOverlay.prototype.hover = function (hovering) {
|
||||
|
@ -223,9 +195,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
lastHoveringId = 0;
|
||||
}
|
||||
this.editOverlay({ color: color(this.selected, hovering) });
|
||||
if (this.model) {
|
||||
this.model.editOverlay({ textures: textures(this.selected, hovering) });
|
||||
}
|
||||
if (hovering) {
|
||||
// un-hover the last hovering overlay
|
||||
if (lastHoveringId && lastHoveringId !== this.key) {
|
||||
|
@ -240,15 +209,12 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}
|
||||
|
||||
this.editOverlay({ color: color(selected, this.hovering) });
|
||||
if (this.model) {
|
||||
this.model.editOverlay({ textures: textures(selected) });
|
||||
}
|
||||
this.selected = selected;
|
||||
};
|
||||
// Class methods:
|
||||
var selectedIds = [];
|
||||
var selectedId = false;
|
||||
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
|
||||
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) {
|
||||
var selected = ExtendedOverlay.isSelected(id);
|
||||
return new ExtendedOverlay(id, "sphere", {
|
||||
drawInFront: true,
|
||||
solid: true,
|
||||
alpha: 0.8,
|
||||
color: color(selected, false),
|
||||
color: color(false, false),
|
||||
ignoreRayIntersection: false
|
||||
}, selected, !conserveResources);
|
||||
});
|
||||
}
|
||||
|
||||
var pingPong = true;
|
||||
|
@ -368,14 +297,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
position: target,
|
||||
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;
|
||||
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();
|
||||
}
|
||||
});
|
||||
// We could re-populateNearbyUserList if anything added or removed, but not for now.
|
||||
HighlightedEntity.updateOverlays();
|
||||
}
|
||||
function removeOverlays() {
|
||||
selectedIds = [];
|
||||
selectedId = false;
|
||||
lastHoveringId = 0;
|
||||
HighlightedEntity.clearOverlays();
|
||||
ExtendedOverlay.some(function (overlay) {
|
||||
overlay.deleteOverlay();
|
||||
});
|
||||
|
@ -399,7 +317,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
// Clicks.
|
||||
//
|
||||
function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
|
||||
if (selectedIds[0] === id) {
|
||||
if (selectedId === id) {
|
||||
var message = {
|
||||
method: 'updateSelectedRecipientUsername',
|
||||
userName: username === "" ? "unknown username" : username
|
||||
|
@ -411,13 +329,13 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
||||
var nextSelectedStatus = !overlay.selected;
|
||||
var avatarId = overlay.key;
|
||||
selectedIds = nextSelectedStatus ? [avatarId] : [];
|
||||
selectedId = nextSelectedStatus ? avatarId : false;
|
||||
if (nextSelectedStatus) {
|
||||
Users.requestUsernameFromID(avatarId);
|
||||
}
|
||||
var message = {
|
||||
method: 'selectRecipient',
|
||||
id: [avatarId],
|
||||
id: avatarId,
|
||||
isSelected: nextSelectedStatus,
|
||||
displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"',
|
||||
userName: ''
|
||||
|
@ -430,24 +348,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
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;
|
||||
});
|
||||
}
|
||||
|
@ -1155,12 +1055,14 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}
|
||||
|
||||
if (onCommerceScreen) {
|
||||
if (!isWired) {
|
||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||
triggerMapping.enable();
|
||||
triggerPressMapping.enable();
|
||||
}
|
||||
isWired = true;
|
||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||
triggerMapping.enable();
|
||||
triggerPressMapping.enable();
|
||||
Wallet.refreshWalletStatus();
|
||||
} else {
|
||||
off();
|
||||
|
|
|
@ -321,7 +321,8 @@
|
|||
{
|
||||
id: "alpha",
|
||||
name: "Alpha",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
@ -329,7 +330,8 @@
|
|||
{
|
||||
id: "alphaSpread",
|
||||
name: "Alpha Spread",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
@ -337,7 +339,8 @@
|
|||
{
|
||||
id: "alphaStart",
|
||||
name: "Alpha Start",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
@ -345,7 +348,8 @@
|
|||
{
|
||||
id: "alphaFinish",
|
||||
name: "Alpha Finish",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
|
|
@ -23,5 +23,9 @@ if (WIN32)
|
|||
add_dependency_external_projects(wasapi)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_link_libraries(${TARGET_NAME} atomic)
|
||||
endif()
|
||||
|
||||
package_libraries_for_deployment()
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -27,6 +27,10 @@ if (WIN32)
|
|||
add_dependency_external_projects(wasapi)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_link_libraries(${TARGET_NAME} atomic)
|
||||
endif()
|
||||
|
||||
package_libraries_for_deployment()
|
||||
|
||||
|
||||
|
|
|
@ -9,21 +9,25 @@ function endsWith(path, exts) {
|
|||
}
|
||||
|
||||
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) {
|
||||
const pathTools = require('path');
|
||||
var pathTools = require('path');
|
||||
var rootFolder = pathTools.dirname(e.filename);
|
||||
console.log("Scanning hifi source for jsdoc comments...");
|
||||
|
||||
// directories to scan for jsdoc comments
|
||||
var dirList = [
|
||||
'../../interface/src',
|
||||
'../../interface/src/assets',
|
||||
'../../interface/src/audio',
|
||||
'../../interface/src/assets',
|
||||
'../../interface/src/audio',
|
||||
'../../interface/src/avatar',
|
||||
'../../interface/src/commerce',
|
||||
'../../interface/src/devices',
|
||||
'../../interface/src/java',
|
||||
'../../interface/src/networking',
|
||||
'../../interface/src/commerce',
|
||||
'../../interface/src/devices',
|
||||
'../../interface/src/java',
|
||||
'../../interface/src/networking',
|
||||
'../../interface/src/ui/',
|
||||
'../../interface/src/scripting',
|
||||
'../../interface/src/ui/overlays',
|
||||
|
@ -47,27 +51,96 @@ exports.handlers = {
|
|||
'../../libraries/script-engine/src',
|
||||
'../../libraries/shared/src',
|
||||
'../../libraries/shared/src/shared',
|
||||
'../../libraries/trackers/src/trackers',
|
||||
'../../libraries/ui/src/ui',
|
||||
'../../plugins/oculus/src',
|
||||
'../../plugins/openvr/src',
|
||||
'../../plugins/openvr/src'
|
||||
];
|
||||
|
||||
// only files with this extension will be searched for jsdoc comments.
|
||||
var exts = ['.h', '.cpp'];
|
||||
|
||||
const fs = require('fs');
|
||||
var fs = require('fs');
|
||||
dirList.forEach(function (dir) {
|
||||
var joinedDir = pathTools.join(rootFolder, dir);
|
||||
var files = fs.readdirSync(joinedDir)
|
||||
var files = fs.readdirSync(joinedDir);
|
||||
files.forEach(function (file) {
|
||||
var path = pathTools.join(joinedDir, file);
|
||||
if (fs.lstatSync(path).isFile() && endsWith(path, exts)) {
|
||||
// load entire file into a string
|
||||
var data = fs.readFileSync(path, "utf8");
|
||||
|
||||
// this regex searches for blocks starting with /**jsdoc and end with */
|
||||
var reg = /(\/\*\*jsdoc(.|[\r\n])*?\*\/)/gm;
|
||||
var matches = data.match(reg);
|
||||
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.hifiClientEntity) {
|
||||
rows.push("Client Entity Scripts");
|
||||
}
|
||||
if (e.doclet.hifiServerEntity) {
|
||||
rows.push("Server Entity Scripts");
|
||||
}
|
||||
if (e.doclet.hifiAssignmentClient) {
|
||||
rows.push("Assignment Client Scripts");
|
||||
}
|
||||
|
||||
// Append an Available In: table at the end of the namespace description.
|
||||
if (rows.length > 0) {
|
||||
var table = "<br><br><table><tr><th>Available in:</th><td>" + rows.join("</td><td>") + "</td></tr></table>";
|
||||
e.doclet.description = (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-assignment-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;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue