From dc9121433d4ac09e3b783181a5613c93feb96b26 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 13 Jun 2016 16:37:34 -0700 Subject: [PATCH 01/28] trying to fix skeleton switching bug --- interface/src/main.cpp | 4 ++-- libraries/avatars/src/AvatarData.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8fc0384aee..f0c7938b2a 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -90,11 +90,11 @@ int main(int argc, const char* argv[]) { qDebug() << "Interface instance appears to be running, exiting"; - return EXIT_SUCCESS; + //return EXIT_SUCCESS; } #ifdef Q_OS_WIN - return EXIT_SUCCESS; + //return EXIT_SUCCESS; #endif } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ff7438bb17..26bf0fb2a2 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1052,6 +1052,8 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } + sendIdentityPacket(); + networkReply->deleteLater(); } @@ -1094,6 +1096,7 @@ void AvatarData::sendIdentityPacket() { void AvatarData::updateJointMappings() { _jointIndices.clear(); _jointNames.clear(); + _jointData.clear(); if (_skeletonModelURL.fileName().toLower().endsWith(".fst")) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); From 59b785a33bbfcc818a8597b262dec15749b83847 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 15 Jun 2016 16:55:34 -0700 Subject: [PATCH 02/28] trying to debug --- libraries/animation/src/Rig.cpp | 4 +--- libraries/avatars/src/AvatarData.cpp | 27 ++++++++++++++++++--------- libraries/avatars/src/AvatarData.h | 2 +- libraries/render-utils/src/Model.cpp | 3 +++ 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index b21f5a0e84..8f0bd3fd87 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -163,7 +163,6 @@ void Rig::destroyAnimGraph() { } void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) { - _geometryOffset = AnimPose(geometry.offset); _invGeometryOffset = _geometryOffset.inverse(); setModelOffset(modelOffset); @@ -1224,8 +1223,7 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { } void Rig::copyJointsFromJointData(const QVector& jointDataVec) { - - if (_animSkeleton) { + if (_animSkeleton && jointDataVec.size() == _internalPoseSet._overrideFlags.size()) { // transform all the default poses into rig space. const AnimPose geometryToRigPose(_geometryToRigTransform); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 26bf0fb2a2..0ae58ca1de 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -261,7 +261,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { unsigned char validity = 0; int validityBit = 0; - #ifdef WANT_DEBUG + #if 1 int rotationSentCount = 0; unsigned char* beforeRotations = destinationBuffer; #endif @@ -276,7 +276,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { if (data.rotationSet) { validity |= (1 << validityBit); - #ifdef WANT_DEBUG + #if 1 rotationSentCount++; #endif } @@ -310,7 +310,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validity = 0; validityBit = 0; - #ifdef WANT_DEBUG + #if 1 int translationSentCount = 0; unsigned char* beforeTranslations = destinationBuffer; #endif @@ -324,7 +324,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { if (data.translationSet) { validity |= (1 << validityBit); - #ifdef WANT_DEBUG + #if 1 translationSentCount++; #endif maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); @@ -359,7 +359,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } } - #ifdef WANT_DEBUG + #if 1 if (sendAll) { qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll << "rotations:" << rotationSentCount << "translations:" << translationSentCount @@ -584,6 +584,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackOrientationQuatFromSixBytes(sourceBuffer, data.rotation); _hasNewJointRotations = true; data.rotationSet = true; + } else if (numValidJointRotations == numJoints) { + _hasNewJointRotations = true; + data.rotationSet = false; } } @@ -620,10 +623,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); _hasNewJointTranslations = true; data.translationSet = true; + } else if (numValidJointRotations == numJoints) { + _hasNewJointTranslations = true; + data.translationSet = false; } } - #ifdef WANT_DEBUG + #if 1 if (numValidJointRotations > 15) { qDebug() << "RECEIVING -- rotations:" << numValidJointRotations << "translations:" << numValidJointTranslations @@ -1052,17 +1058,20 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } - sendIdentityPacket(); + //sendIdentityPacket(); + //sendAvatarDataPacket(true); + qDebug() << "set joint mapping froms network reply, num joints: " << _jointIndices.size(); networkReply->deleteLater(); } -void AvatarData::sendAvatarDataPacket() { +void AvatarData::sendAvatarDataPacket(bool sendFull) { auto nodeList = DependencyManager::get(); // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. - bool sendFullUpdate = randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO; + bool sendFullUpdate = sendFull || (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); + if (sendFullUpdate) qDebug() << sendFullUpdate; QByteArray avatarByteArray = toByteArray(true, sendFullUpdate); doneEncoding(true); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 61ee649273..7fe339c2b9 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -352,7 +352,7 @@ public: AvatarEntityIDs getAndClearRecentlyDetachedIDs(); public slots: - void sendAvatarDataPacket(); + void sendAvatarDataPacket(bool sendFull = false); void sendIdentityPacket(); void setJointMappingsFromNetworkReply(); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ded1184c24..2112e64a39 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -254,6 +254,7 @@ bool Model::updateGeometry() { _needsReload = false; if (_rig->jointStatesEmpty() && getFBXGeometry().joints.size() > 0) { + qDebug() << "initJointStates, num joints: " << getFBXGeometry().joints.size(); initJointStates(); const FBXGeometry& fbxGeometry = getFBXGeometry(); @@ -817,7 +818,9 @@ void Model::setURL(const QUrl& url) { invalidCalculatedMeshBoxes(); deleteGeometry(); + if (_geometry && _geometry->getGeometry()) qDebug() << "geometry1: " << _geometry->getGeometry()->getGeometry().joints.size(); _geometry = DependencyManager::get()->getGeometry(url); + if (_geometry && _geometry->getGeometry()) qDebug() << "geometry2: " << _geometry->getGeometry()->getGeometry().joints.size(); onInvalidate(); } From f02ffa92fdb03b8a6afd85e95761c62843b113f9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 15 Jun 2016 18:00:08 -0700 Subject: [PATCH 03/28] undo debugging --- libraries/avatars/src/AvatarData.cpp | 33 ++++++++++++++-------------- libraries/avatars/src/AvatarData.h | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0ae58ca1de..c98fec0d7d 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -261,7 +261,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { unsigned char validity = 0; int validityBit = 0; - #if 1 + #ifdef WANT_DEBUG int rotationSentCount = 0; unsigned char* beforeRotations = destinationBuffer; #endif @@ -276,7 +276,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { if (data.rotationSet) { validity |= (1 << validityBit); - #if 1 + #ifdef WANT_DEBUG rotationSentCount++; #endif } @@ -310,7 +310,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validity = 0; validityBit = 0; - #if 1 + #ifdef WANT_DEBUG int translationSentCount = 0; unsigned char* beforeTranslations = destinationBuffer; #endif @@ -324,7 +324,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { if (data.translationSet) { validity |= (1 << validityBit); - #if 1 + #ifdef WANT_DEBUG translationSentCount++; #endif maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); @@ -359,7 +359,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } } - #if 1 + #ifdef WANT_DEBUG if (sendAll) { qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll << "rotations:" << rotationSentCount << "translations:" << translationSentCount @@ -575,6 +575,14 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } } + // If all the rotations were sent, this is a full packet + bool fullPacket = numValidJointRotations == numJoints; + + if (fullPacket) { + _hasNewJointRotations = true; + _hasNewJointTranslations = true; + } + // each joint rotation is stored in 6 bytes. const int COMPRESSED_QUATERNION_SIZE = 6; PACKET_READ_CHECK(JointRotations, numValidJointRotations * COMPRESSED_QUATERNION_SIZE); @@ -584,9 +592,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackOrientationQuatFromSixBytes(sourceBuffer, data.rotation); _hasNewJointRotations = true; data.rotationSet = true; - } else if (numValidJointRotations == numJoints) { - _hasNewJointRotations = true; - data.rotationSet = false; } } @@ -623,13 +628,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); _hasNewJointTranslations = true; data.translationSet = true; - } else if (numValidJointRotations == numJoints) { - _hasNewJointTranslations = true; - data.translationSet = false; } } - #if 1 + #ifdef WANT_DEBUG if (numValidJointRotations > 15) { qDebug() << "RECEIVING -- rotations:" << numValidJointRotations << "translations:" << numValidJointTranslations @@ -1058,20 +1060,17 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } - //sendIdentityPacket(); - //sendAvatarDataPacket(true); qDebug() << "set joint mapping froms network reply, num joints: " << _jointIndices.size(); networkReply->deleteLater(); } -void AvatarData::sendAvatarDataPacket(bool sendFull) { +void AvatarData::sendAvatarDataPacket() { auto nodeList = DependencyManager::get(); // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. - bool sendFullUpdate = sendFull || (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); - if (sendFullUpdate) qDebug() << sendFullUpdate; + bool sendFullUpdate = randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO; QByteArray avatarByteArray = toByteArray(true, sendFullUpdate); doneEncoding(true); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 7fe339c2b9..61ee649273 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -352,7 +352,7 @@ public: AvatarEntityIDs getAndClearRecentlyDetachedIDs(); public slots: - void sendAvatarDataPacket(bool sendFull = false); + void sendAvatarDataPacket(); void sendIdentityPacket(); void setJointMappingsFromNetworkReply(); From 1ce9e96cba6427ed98d8ff0235004752fe56a43b Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 16 Jun 2016 01:20:28 -0700 Subject: [PATCH 04/28] Send domain metadata for authed domains --- domain-server/src/DomainServer.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 7c596bb187..1f666455c6 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -108,6 +108,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : connect(&_settingsManager, &DomainServerSettingsManager::updateNodePermissions, &_gatekeeper, &DomainGatekeeper::updateNodePermissions); + // update the metadata with current descriptors + _metadata.setDescriptors(_settingsManager.getSettingsMap()); + if (optionallyReadX509KeyAndCertificate() && optionallySetupOAuth()) { // we either read a certificate and private key or were not passed one // and completed login or did not need to @@ -122,10 +125,17 @@ DomainServer::DomainServer(int argc, char* argv[]) : _gatekeeper.preloadAllowedUserPublicKeys(); optionallyGetTemporaryName(args); - } - // update the metadata with current descriptors - _metadata.setDescriptors(_settingsManager.getSettingsMap()); + // send metadata descriptors + QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(_metadata.getDescriptors()).toJson(QJsonDocument::Compact))); + const QUuid& domainID = DependencyManager::get()->getSessionUUID(); + static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; + DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + AccountManagerAuth::Required, + QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), + domainUpdateJSON.toUtf8()); + } } DomainServer::~DomainServer() { From 0f9c637c5a490dd43da16ca74dbfde34e80fd843 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 16 Jun 2016 01:32:38 -0700 Subject: [PATCH 05/28] Wireframe a metadata overlay tutorial --- scripts/tutorials/getDomainMetadata.js | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 scripts/tutorials/getDomainMetadata.js diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js new file mode 100644 index 0000000000..1c78d640e8 --- /dev/null +++ b/scripts/tutorials/getDomainMetadata.js @@ -0,0 +1,28 @@ +// +// Created by Zach Pomerantz on June 16, 2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// Avoid polluting the namespace +// !function() { + var MetadataNotification = null; + + // Every time you enter a domain, display the domain's metadata + SomeEvent.connect(function() { + // Fetch the domain metadata from the directory + + // Display the fetched metadata in an overlay + + }); + + // Remove the overlay if the script is stopped + Script.scriptEnding.connect(teardown); + + function teardown() { + // Close the overlay, if it exists + + } +// }(); From aca3d4d90b0acd3522eeabad214152a48406ac0b Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 16 Jun 2016 15:22:34 -0700 Subject: [PATCH 06/28] add example script for metadata from metaverse --- scripts/tutorials/getDomainMetadata.js | 118 ++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 13 deletions(-) diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 1c78d640e8..0a6f742823 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -6,23 +6,115 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// Avoid polluting the namespace -// !function() { - var MetadataNotification = null; +var SERVER = 'https://metaverse.highfidelity.com/api/v1'; - // Every time you enter a domain, display the domain's metadata - SomeEvent.connect(function() { - // Fetch the domain metadata from the directory +var OVERLAY = null; - // Display the fetched metadata in an overlay +// Every time you enter a domain, display the domain's metadata +location.hostChanged.connect(function(host) { + print('Detected host change:', host); - }); + // Fetch the domain ID from the metaverse + var placeData = request(SERVER + '/places/' + host); + if (!placeData) { return; } + var domainID = placeData.data.place.domain.id; + print('Domain ID:', domainID); - // Remove the overlay if the script is stopped - Script.scriptEnding.connect(teardown); + // Fetch the domain metadata from the metaverse + var domainData = request(SERVER + '/domains/' + domainID); + print(SERVER + '/domains/' + domainID); + if (!domainData) { return; } + var metadata = domainData.domain; + print('Domain metadata:', JSON.stringify(metadata)); - function teardown() { - // Close the overlay, if it exists + // Display the fetched metadata in an overlay + displayMetadata(host, metadata); +}); +Script.scriptEnding.connect(clearMetadata); + +function displayMetadata(place, metadata) { + clearMetadata(); + + var COLOR_TEXT = { red: 255, green: 255, blue: 255 }; + var COLOR_BACKGROUND = { red: 0, green: 0, blue: 0 }; + var MARGIN = 200; + var STARTING_OPACITY = 0.8; + var FADE_AFTER_SEC = 2; + var FADE_FOR_SEC = 4; + + var fade_per_sec = STARTING_OPACITY / FADE_FOR_SEC; + var properties = { + color: COLOR_TEXT, + alpha: STARTING_OPACITY, + backgroundColor: COLOR_BACKGROUND, + backgroundAlpha: STARTING_OPACITY, + font: { size: 24 }, + x: MARGIN, + y: MARGIN + }; + + // Center the overlay on the screen + properties.width = Window.innerWidth - MARGIN*2; + properties.height = Window.innerHeight - MARGIN*2; + + // Parse the metadata into text + parsed = [ 'Welcome to ' + place + '!',, ]; + if (metadata.description) { + parsed.push(description); } -// }(); + if (metadata.tags && metadata.tags.length) { + parsed.push('Tags: ' + metadata.tags.join(',')); + } + if (metadata.capacity) { + parsed.push('Capacity (max users): ' + metadata.capacity); + } + if (metadata.maturity) { + parsed.push('Maturity: ' + metadata.maturity); + } + if (metadata.hosts && metadata.hosts.length) { + parsed.push('Hosts: ' + metadata.tags.join(',')); + } + if (metadata.online_users) { + parsed.push('Users online: ' + metadata.online_users); + } + + properties.text = parsed.join('\n\n'); + + // Display the overlay + OVERLAY = Overlays.addOverlay('text', properties); + + // Fade out the overlay over 10 seconds + !function() { + var overlay = OVERLAY; + var alpha = STARTING_OPACITY; + + var fade = function() { + // Only fade so long as the same overlay is up + if (overlay == OVERLAY) { + alpha -= fade_per_sec / 10; + if (alpha <= 0) { + clearMetadata(); + } else { + Overlays.editOverlay(overlay, { alpha: alpha, backgroundAlpha: alpha }); + Script.setTimeout(fade, 100); + } + } + }; + Script.setTimeout(fade, FADE_AFTER_SEC * 1000); + }(); +} + +function clearMetadata() { + if (OVERLAY) { Overlays.deleteOverlay(OVERLAY); } +} + +// Request JSON from a url, synchronously +function request(url) { + var req = new XMLHttpRequest(); + req.responseType = 'json'; + req.open('GET', url, false); + req.send(); + return req.status == 200 ? req.response : null; +} + From 5f7e49b0870f72239e07ad5d7c575e9461c04768 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 11:50:56 -0700 Subject: [PATCH 07/28] possible fix, needs testing --- libraries/avatars/src/AvatarData.cpp | 25 ++++++++----------------- libraries/render-utils/src/Model.cpp | 3 --- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c98fec0d7d..33a6d1305f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -269,7 +269,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { _lastSentJointData.resize(_jointData.size()); for (int i=0; i < _jointData.size(); i++) { - const JointData& data = _jointData.at(i); + const JointData& data = _jointData[i]; if (sendAll || _lastSentJointData[i].rotation != data.rotation) { if (sendAll || !cullSmallChanges || @@ -294,7 +294,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validityBit = 0; validity = *validityPosition++; for (int i = 0; i < _jointData.size(); i ++) { - const JointData& data = _jointData[ i ]; + const JointData& data = _jointData[i]; if (validity & (1 << validityBit)) { destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); } @@ -317,7 +317,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { float maxTranslationDimension = 0.0; for (int i=0; i < _jointData.size(); i++) { - const JointData& data = _jointData.at(i); + const JointData& data = _jointData[i]; if (sendAll || _lastSentJointData[i].translation != data.translation) { if (sendAll || !cullSmallChanges || @@ -348,7 +348,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { validityBit = 0; validity = *validityPosition++; for (int i = 0; i < _jointData.size(); i ++) { - const JointData& data = _jointData[ i ]; + const JointData& data = _jointData[i]; if (validity & (1 << validityBit)) { destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); @@ -425,7 +425,6 @@ bool AvatarData::shouldLogError(const quint64& now) { // read data in packet starting at byte offset and return number of bytes parsed int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { - // lazily allocate memory for HeadData in case we're not an Avatar instance if (!_headData) { _headData = new HeadData(this); @@ -575,14 +574,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } } - // If all the rotations were sent, this is a full packet - bool fullPacket = numValidJointRotations == numJoints; - - if (fullPacket) { - _hasNewJointRotations = true; - _hasNewJointTranslations = true; - } - // each joint rotation is stored in 6 bytes. const int COMPRESSED_QUATERNION_SIZE = 6; PACKET_READ_CHECK(JointRotations, numValidJointRotations * COMPRESSED_QUATERNION_SIZE); @@ -677,7 +668,9 @@ void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::v } JointData& data = _jointData[index]; data.rotation = rotation; + data.rotationSet = true; data.translation = translation; + data.translationSet = true; } void AvatarData::clearJointData(int index) { @@ -782,6 +775,7 @@ void AvatarData::setJointRotation(int index, const glm::quat& rotation) { } JointData& data = _jointData[index]; data.rotation = rotation; + data.rotationSet = true; } void AvatarData::setJointTranslation(int index, const glm::vec3& translation) { @@ -797,6 +791,7 @@ void AvatarData::setJointTranslation(int index, const glm::vec3& translation) { } JointData& data = _jointData[index]; data.translation = translation; + data.translationSet = true; } void AvatarData::clearJointData(const QString& name) { @@ -866,7 +861,6 @@ void AvatarData::setJointTranslations(QVector jointTranslations) { "setJointTranslations", Qt::BlockingQueuedConnection, Q_ARG(QVector, jointTranslations)); } - if (_jointData.size() < jointTranslations.size()) { _jointData.resize(jointTranslations.size()); } @@ -1060,8 +1054,6 @@ void AvatarData::setJointMappingsFromNetworkReply() { _jointIndices.insert(_jointNames.at(i), i + 1); } - qDebug() << "set joint mapping froms network reply, num joints: " << _jointIndices.size(); - networkReply->deleteLater(); } @@ -1460,7 +1452,6 @@ void AvatarData::fromJson(const QJsonObject& json) { auto joint = jointDataFromJsonValue(jointJson); jointArray.push_back(joint); setJointData(i, joint.rotation, joint.translation); - _jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose i++; } setRawJointData(jointArray); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2112e64a39..ded1184c24 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -254,7 +254,6 @@ bool Model::updateGeometry() { _needsReload = false; if (_rig->jointStatesEmpty() && getFBXGeometry().joints.size() > 0) { - qDebug() << "initJointStates, num joints: " << getFBXGeometry().joints.size(); initJointStates(); const FBXGeometry& fbxGeometry = getFBXGeometry(); @@ -818,9 +817,7 @@ void Model::setURL(const QUrl& url) { invalidCalculatedMeshBoxes(); deleteGeometry(); - if (_geometry && _geometry->getGeometry()) qDebug() << "geometry1: " << _geometry->getGeometry()->getGeometry().joints.size(); _geometry = DependencyManager::get()->getGeometry(url); - if (_geometry && _geometry->getGeometry()) qDebug() << "geometry2: " << _geometry->getGeometry()->getGeometry().joints.size(); onInvalidate(); } From 7d602986cdd9688172cc739901096aa5ed4febe9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 12:01:02 -0700 Subject: [PATCH 08/28] removed multiple interface instances hack which you should never do anyways because it breaks everything --- interface/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index f0c7938b2a..8fc0384aee 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -90,11 +90,11 @@ int main(int argc, const char* argv[]) { qDebug() << "Interface instance appears to be running, exiting"; - //return EXIT_SUCCESS; + return EXIT_SUCCESS; } #ifdef Q_OS_WIN - //return EXIT_SUCCESS; + return EXIT_SUCCESS; #endif } From caf4a9fa34f0a52b9f4e89293f1106af248f1bb7 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 14:17:32 -0700 Subject: [PATCH 09/28] got rid of comparison warning --- libraries/animation/src/Rig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8f0bd3fd87..8aee2245c0 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1223,7 +1223,7 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { } void Rig::copyJointsFromJointData(const QVector& jointDataVec) { - if (_animSkeleton && jointDataVec.size() == _internalPoseSet._overrideFlags.size()) { + if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._overrideFlags.size()) { // transform all the default poses into rig space. const AnimPose geometryToRigPose(_geometryToRigTransform); From c30c2b64b21bec14f3acf65f0d73fcb006e48259 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 17 Jun 2016 17:49:27 -0700 Subject: [PATCH 10/28] first pass at preventing repeated compileShader error prints --- libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp | 7 +++++++ libraries/gpu/src/gpu/Shader.h | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp index 19cf798b19..fa54e7c8fe 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp @@ -24,8 +24,15 @@ GLPipeline* GLPipeline::sync(const Pipeline& pipeline) { // No object allocated yet, let's see if it's worth it... ShaderPointer shader = pipeline.getProgram(); + + // If this pipeline's shader has already failed to compile, don't try again + if (shader->compilationHasFailed()) { + return nullptr; + } + GLShader* programObject = GLShader::sync(*shader); if (programObject == nullptr) { + shader->setCompilationHasFailed(true); return nullptr; } diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index 59c6401150..ec712bfa78 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -120,6 +120,9 @@ public: bool isProgram() const { return getType() > NUM_DOMAINS; } bool isDomain() const { return getType() < NUM_DOMAINS; } + void setCompilationHasFailed(bool compilationHasFailed) { _compilationHasFailed = compilationHasFailed; } + bool compilationHasFailed() const { return _compilationHasFailed; } + const Source& getSource() const { return _source; } const Shaders& getShaders() const { return _shaders; } @@ -180,6 +183,9 @@ protected: // The type of the shader, the master key Type _type; + + // Whether or not the shader compilation failed + mutable bool _compilationHasFailed { false }; }; typedef Shader::Pointer ShaderPointer; From e65e6dc9ce10d10522eab5ca6c9023cc81315fac Mon Sep 17 00:00:00 2001 From: humbletim Date: Sun, 19 Jun 2016 13:40:03 -0400 Subject: [PATCH 11/28] Fix entity lifetime guards (re: canRez/canRezTmp) --- libraries/entities/src/EntityTree.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 77a0c6d6fe..ec1f8a50bc 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -150,8 +150,10 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI if (!canRezPermanentEntities && (entity->getLifetime() != properties.getLifetime())) { // we don't allow a Node that can't create permanent entities to adjust lifetimes on existing ones - qCDebug(entities) << "Refusing disallowed entity lifetime adjustment."; - return false; + if (properties.lifetimeChanged()) { + qCDebug(entities) << "Refusing disallowed entity lifetime adjustment."; + return false; + } } // enforce support for locked entities. If an entity is currently locked, then the only @@ -322,8 +324,8 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI bool EntityTree::permissionsAllowRez(const EntityItemProperties& properties, bool canRez, bool canRezTmp) { float lifeTime = properties.getLifetime(); - if (lifeTime == 0.0f || lifeTime > _maxTmpEntityLifetime) { - // this is an attempt to rez a permanent entity. + if (lifeTime == ENTITY_ITEM_IMMORTAL_LIFETIME || lifeTime > _maxTmpEntityLifetime) { + // this is an attempt to rez a permanent or non-temporary entity. if (!canRez) { return false; } From 34d18da4e4ecd18f330c7ae5294003628e893dfa Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 20 Jun 2016 11:11:54 -0700 Subject: [PATCH 12/28] remove mutable --- libraries/gpu/src/gpu/Shader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index ec712bfa78..e4643f2b7c 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -185,7 +185,7 @@ protected: Type _type; // Whether or not the shader compilation failed - mutable bool _compilationHasFailed { false }; + bool _compilationHasFailed { false }; }; typedef Shader::Pointer ShaderPointer; From 40f2d364877c7566cf04f4530ae8f137362cf746 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 11:38:38 -0700 Subject: [PATCH 13/28] fix hosts/tags in domain-server settings --- domain-server/resources/describe-settings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index bad24dd3a1..dce6c3449f 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -116,6 +116,7 @@ "name": "hosts", "label": "Hosts", "type": "table", + "can_add_new_rows": true, "help": "Usernames of hosts who can reliably show your domain to new visitors.", "numbered": false, "columns": [ @@ -130,6 +131,7 @@ "name": "tags", "label": "Tags", "type": "table", + "can_add_new_rows": true, "help": "Common categories under which your domain falls.", "numbered": false, "columns": [ From 25b21dacda246e7ff691bdf4db9cf67d8b57cbd0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 12:57:32 -0700 Subject: [PATCH 14/28] clean domain metadata and update acl --- domain-server/src/DomainMetadata.cpp | 156 +++++++++++++++++++-------- domain-server/src/DomainMetadata.h | 60 ++++++----- domain-server/src/DomainServer.cpp | 30 ++---- domain-server/src/DomainServer.h | 8 +- 4 files changed, 154 insertions(+), 100 deletions(-) diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index 26d2bb87ce..d3eb7a97b0 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -10,16 +10,18 @@ #include "DomainMetadata.h" -#include +#include #include +#include #include +#include "DomainServer.h" #include "DomainServerNodeData.h" const QString DomainMetadata::USERS = "users"; -const QString DomainMetadata::USERS_NUM_TOTAL = "num_users"; -const QString DomainMetadata::USERS_NUM_ANON = "num_anon_users"; -const QString DomainMetadata::USERS_HOSTNAMES = "user_hostnames"; +const QString DomainMetadata::Users::NUM_TOTAL = "num_users"; +const QString DomainMetadata::Users::NUM_ANON = "num_anon_users"; +const QString DomainMetadata::Users::HOSTNAMES = "user_hostnames"; // users metadata will appear as (JSON): // { "num_users": Number, // "num_anon_users": Number, @@ -27,25 +29,20 @@ const QString DomainMetadata::USERS_HOSTNAMES = "user_hostnames"; // } const QString DomainMetadata::DESCRIPTORS = "descriptors"; -const QString DomainMetadata::DESCRIPTORS_DESCRIPTION = "description"; -const QString DomainMetadata::DESCRIPTORS_CAPACITY = "capacity"; // parsed from security -const QString DomainMetadata::DESCRIPTORS_RESTRICTION = "restriction"; // parsed from ACL -const QString DomainMetadata::DESCRIPTORS_MATURITY = "maturity"; -const QString DomainMetadata::DESCRIPTORS_HOSTS = "hosts"; -const QString DomainMetadata::DESCRIPTORS_TAGS = "tags"; +const QString DomainMetadata::Descriptors::DESCRIPTION = "description"; +const QString DomainMetadata::Descriptors::CAPACITY = "capacity"; // parsed from security +const QString DomainMetadata::Descriptors::HOURS = "hours"; +const QString DomainMetadata::Descriptors::RESTRICTION = "restriction"; // parsed from ACL +const QString DomainMetadata::Descriptors::MATURITY = "maturity"; +const QString DomainMetadata::Descriptors::HOSTS = "hosts"; +const QString DomainMetadata::Descriptors::TAGS = "tags"; // descriptors metadata will appear as (JSON): -// { "capacity": Number, -// TODO: "hours": String, // UTF-8 representation of the week, split into 15" segments +// { "description": String, // capped description +// "capacity": Number, +// "hours": String, // UTF-8 representation of the week, split into 15" segments // "restriction": String, // enum of either open, hifi, or acl // "maturity": String, // enum corresponding to ESRB ratings // "hosts": [ String ], // capped list of usernames -// "description": String, // capped description -// TODO: "img": { -// "src": String, -// "type": String, -// "size": Number, -// "updated_at": Number, -// }, // "tags": [ String ], // capped list of tags // } @@ -54,36 +51,103 @@ const QString DomainMetadata::DESCRIPTORS_TAGS = "tags"; // // it is meant to be sent to and consumed by an external API -DomainMetadata::DomainMetadata() { +DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { _metadata[USERS] = {}; _metadata[DESCRIPTORS] = {}; + + assert(dynamic_cast(domainServer)); + DomainServer* server = static_cast(domainServer); + + // update the metadata when a user (dis)connects + connect(server, &DomainServer::userConnected, this, &DomainMetadata::usersChanged); + connect(server, &DomainServer::userDisconnected, this, &DomainMetadata::usersChanged); + + // update the metadata when security changes + connect(&server->_settingsManager, &DomainServerSettingsManager::updateNodePermissions, + this, static_cast(&DomainMetadata::securityChanged)); + + // initialize the descriptors + descriptorsChanged(); } -void DomainMetadata::setDescriptors(QVariantMap& settings) { +QJsonObject DomainMetadata::get() { + maybeUpdateUsers(); + return QJsonObject::fromVariantMap(_metadata); +} + +QJsonObject DomainMetadata::get(const QString& group) { + maybeUpdateUsers(); + return QJsonObject::fromVariantMap(_metadata[group].toMap()); +} + +void DomainMetadata::descriptorsChanged() { const QString CAPACITY = "security.maximum_user_capacity"; + auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY); unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0; - // TODO: Keep parity with ACL development. - const QString RESTRICTION = "security.restricted_access"; - const QString RESTRICTION_OPEN = "open"; - // const QString RESTRICTION_HIFI = "hifi"; - const QString RESTRICTION_ACL = "acl"; - const QVariant* isRestrictedVariant = valueForKeyPath(settings, RESTRICTION); - bool isRestricted = isRestrictedVariant ? isRestrictedVariant->toBool() : false; - QString restriction = isRestricted ? RESTRICTION_ACL : RESTRICTION_OPEN; + auto descriptors = settings[DESCRIPTORS].toMap(); + descriptors[Descriptors::CAPACITY] = capacity; + _metadata[DESCRIPTORS] = descriptors; - QVariantMap descriptors = settings[DESCRIPTORS].toMap(); - descriptors[DESCRIPTORS_CAPACITY] = capacity; - descriptors[DESCRIPTORS_RESTRICTION] = restriction; + // update overwritten fields + securityChanged(false); + +#if DEV_BUILD || PR_BUILD + qDebug() << "Domain metadata descriptors set:" << _metadata[DESCRIPTORS]; +#endif + + sendDescriptors(); +} + +void DomainMetadata::securityChanged(bool send) { + const QString RESTRICTION_OPEN = "open"; + const QString RESTRICTION_ANON = "anon"; + const QString RESTRICTION_HIFI = "hifi"; + const QString RESTRICTION_ACL = "acl"; + + QString restriction; + + const auto& settingsManager = static_cast(parent())->_settingsManager; + bool hasAnonymousAccess = + settingsManager.getStandardPermissionsForName(NodePermissions::standardNameAnonymous).canConnectToDomain; + bool hasHifiAccess = + settingsManager.getStandardPermissionsForName(NodePermissions::standardNameLoggedIn).canConnectToDomain; + if (hasAnonymousAccess) { + restriction = hasHifiAccess ? RESTRICTION_OPEN : RESTRICTION_ANON; + } else if (hasHifiAccess) { + restriction = RESTRICTION_HIFI; + } else { + restriction = RESTRICTION_ACL; + } + + auto descriptors = _metadata[DESCRIPTORS].toMap(); + descriptors[Descriptors::RESTRICTION] = restriction; _metadata[DESCRIPTORS] = descriptors; #if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata descriptors set:" << descriptors; + qDebug() << "Domain metadata restriction set:" << restriction; +#endif + + if (send) { + sendDescriptors(); + } +} + +void DomainMetadata::usersChanged() { + ++_tic; + +#if DEV_BUILD || PR_BUILD + qDebug() << "Domain metadata users change detected"; #endif } -void DomainMetadata::updateUsers() { +void DomainMetadata::maybeUpdateUsers() { + if (_lastTic == _tic) { + return; + } + _lastTic = _tic; + static const QString DEFAULT_HOSTNAME = "*"; auto nodeList = DependencyManager::get(); @@ -113,20 +177,26 @@ void DomainMetadata::updateUsers() { }); QVariantMap users = { - { USERS_NUM_TOTAL, numConnected }, - { USERS_NUM_ANON, numConnectedAnonymously }, - { USERS_HOSTNAMES, userHostnames }}; + { Users::NUM_TOTAL, numConnected }, + { Users::NUM_ANON, numConnectedAnonymously }, + { Users::HOSTNAMES, userHostnames }}; _metadata[USERS] = users; + ++_tic; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata users updated:" << users; #endif } -void DomainMetadata::usersChanged() { - ++_tic; - -#if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata users change detected"; -#endif +void DomainMetadata::sendDescriptors() { + QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(get(DESCRIPTORS)).toJson(QJsonDocument::Compact))); + const QUuid& domainID = DependencyManager::get()->getSessionUUID(); + if (!domainID.isNull()) { + static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; + DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + AccountManagerAuth::Required, + QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), + domainUpdateJSON.toUtf8()); + } } diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 7d58d43182..86918f5c78 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -19,46 +19,48 @@ class DomainMetadata : public QObject { Q_OBJECT +public: + using Tic = uint32_t; + static const QString USERS; - static const QString USERS_NUM_TOTAL; - static const QString USERS_NUM_ANON; - static const QString USERS_HOSTNAMES; + class Users { + public: + static const QString NUM_TOTAL; + static const QString NUM_ANON; + static const QString HOSTNAMES; + }; static const QString DESCRIPTORS; - static const QString DESCRIPTORS_DESCRIPTION; - static const QString DESCRIPTORS_CAPACITY; - static const QString DESCRIPTORS_HOURS; - static const QString DESCRIPTORS_RESTRICTION; - static const QString DESCRIPTORS_MATURITY; - static const QString DESCRIPTORS_HOSTS; - static const QString DESCRIPTORS_TAGS; - static const QString DESCRIPTORS_IMG; - static const QString DESCRIPTORS_IMG_SRC; - static const QString DESCRIPTORS_IMG_TYPE; - static const QString DESCRIPTORS_IMG_SIZE; - static const QString DESCRIPTORS_IMG_UPDATED_AT; + class Descriptors { + public: + static const QString DESCRIPTION; + static const QString CAPACITY; + static const QString HOURS; + static const QString RESTRICTION; + static const QString MATURITY; + static const QString HOSTS; + static const QString TAGS; + }; -public: - DomainMetadata(); + DomainMetadata(QObject* domainServer); + DomainMetadata() = delete; - // Returns the last set metadata - // If connected users have changed, metadata may need to be updated - // this should be checked by storing tic = getTic() between calls - // and testing it for equality before the next get (tic == getTic()) - QJsonObject get() { return QJsonObject::fromVariantMap(_metadata); } - QJsonObject getUsers() { return QJsonObject::fromVariantMap(_metadata[USERS].toMap()); } - QJsonObject getDescriptors() { return QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); } - - uint32_t getTic() { return _tic; } - - void setDescriptors(QVariantMap& settings); - void updateUsers(); + // Get cached metadata + QJsonObject get(); + QJsonObject get(const QString& group); public slots: + void descriptorsChanged(); + void securityChanged(bool send); + void securityChanged() { securityChanged(true); } void usersChanged(); protected: + void maybeUpdateUsers(); + void sendDescriptors(); + QVariantMap _metadata; + uint32_t _lastTic{ -1 }; uint32_t _tic{ 0 }; }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 1f666455c6..223cab61da 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -94,10 +94,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : qRegisterMetaType("DomainServerWebSessionData"); qRegisterMetaTypeStreamOperators("DomainServerWebSessionData"); - // update the metadata when a user (dis)connects - connect(this, &DomainServer::userConnected, &_metadata, &DomainMetadata::usersChanged); - connect(this, &DomainServer::userDisconnected, &_metadata, &DomainMetadata::usersChanged); - // make sure we hear about newly connected nodes from our gatekeeper connect(&_gatekeeper, &DomainGatekeeper::connectedNode, this, &DomainServer::handleConnectedNode); @@ -108,9 +104,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : connect(&_settingsManager, &DomainServerSettingsManager::updateNodePermissions, &_gatekeeper, &DomainGatekeeper::updateNodePermissions); - // update the metadata with current descriptors - _metadata.setDescriptors(_settingsManager.getSettingsMap()); - if (optionallyReadX509KeyAndCertificate() && optionallySetupOAuth()) { // we either read a certificate and private key or were not passed one // and completed login or did not need to @@ -125,17 +118,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : _gatekeeper.preloadAllowedUserPublicKeys(); optionallyGetTemporaryName(args); - - // send metadata descriptors - QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(_metadata.getDescriptors()).toJson(QJsonDocument::Compact))); - const QUuid& domainID = DependencyManager::get()->getSessionUUID(); - static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; - DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), - AccountManagerAuth::Required, - QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), - domainUpdateJSON.toUtf8()); } + + _metadata = new DomainMetadata(this); } DomainServer::~DomainServer() { @@ -1111,14 +1096,11 @@ void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) { NodePermissions anonymousPermissions = _settingsManager.getPermissionsForName(NodePermissions::standardNameAnonymous); domainObject[RESTRICTED_ACCESS_FLAG] = !anonymousPermissions.canConnectToDomain; - // Add the metadata to the heartbeat - static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; - auto tic = _metadata.getTic(); - if (_metadataTic != tic) { - _metadataTic = tic; - _metadata.updateUsers(); + if (_metadata) { + // Add the metadata to the heartbeat + static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; + domainObject[DOMAIN_HEARTBEAT_KEY] = _metadata->get(DomainMetadata::USERS); } - domainObject[DOMAIN_HEARTBEAT_KEY] = _metadata.getUsers(); QString domainUpdateJSON = QString("{\"domain\":%1}").arg(QString(QJsonDocument(domainObject).toJson(QJsonDocument::Compact))); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index bdcc36c1ac..c742dbc9b3 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -172,13 +172,12 @@ private: DomainServerSettingsManager _settingsManager; - DomainMetadata _metadata; - uint32_t _metadataTic{ 0 }; - HifiSockAddr _iceServerSocket; std::unique_ptr _iceServerHeartbeatPacket; - QTimer* _iceHeartbeatTimer { nullptr }; // this looks like it dangles when created but it's parented to the DomainServer + // These will be parented to this, they are not dangling + DomainMetadata* _metadata { nullptr }; + QTimer* _iceHeartbeatTimer { nullptr }; QList _iceServerAddresses; QSet _failedIceServerAddresses; @@ -190,6 +189,7 @@ private: bool _hasAccessToken { false }; friend class DomainGatekeeper; + friend class DomainMetadata; }; From cfe9ac32d4ff761fe07817959e9f89a19a0c4535 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 14:46:20 -0700 Subject: [PATCH 15/28] fix narrowing warning by casting -1 --- domain-server/src/DomainMetadata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 86918f5c78..0bfd6c611b 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -60,7 +60,7 @@ protected: void sendDescriptors(); QVariantMap _metadata; - uint32_t _lastTic{ -1 }; + uint32_t _lastTic{ (uint32_t)-1 }; uint32_t _tic{ 0 }; }; From 4e0aeea2b8715f33f0c15914e4751d38f7bc3a7b Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 16:19:19 -0700 Subject: [PATCH 16/28] add time offset to domain-server UI --- .../resources/describe-settings.json | 164 ++++++++++++++++++ domain-server/src/DomainMetadata.cpp | 7 +- 2 files changed, 170 insertions(+), 1 deletion(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index dce6c3449f..3633685365 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -141,6 +141,170 @@ "can_set": true } ] + }, + { + "name": "utc_offset", + "label": "Time Zone", + "help": "This server's time zone, used for searching open servers", + "type": "select", + "options": [ + { + "value": "-12", + "label": "UTC-12:00" + }, + { + "value": "-11", + "label": "UTC-11:00" + }, + { + "value": "-10", + "label": "UTC-10:00" + }, + { + "value": "-9.5", + "label": "UTC-09:30" + }, + { + "value": "-9", + "label": "UTC-09:00" + }, + { + "value": "-8", + "label": "UTC-08:00" + }, + { + "value": "-7", + "label": "UTC-07:00" + }, + { + "value": "-6", + "label": "UTC-06:00" + }, + { + "value": "-5", + "label": "UTC-05:00" + }, + { + "value": "-4", + "label": "UTC-04:00" + }, + { + "value": "-3.5", + "label": "UTC-03:30" + }, + { + "value": "-3", + "label": "UTC-03:00" + }, + { + "value": "-2", + "label": "UTC-02:00" + }, + { + "value": "-1", + "label": "UTC-01:00" + }, + { + "value": "", + "label": "UTC±00:00" + }, + { + "value": "1", + "label": "UTC+01:00" + }, + { + "value": "2", + "label": "UTC+02:00" + }, + { + "value": "3", + "label": "UTC+03:00" + }, + { + "value": "3.5", + "label": "UTC+03:30" + }, + { + "value": "4", + "label": "UTC+04:00" + }, + { + "value": "4.5", + "label": "UTC+04:30" + }, + { + "value": "5", + "label": "UTC+05:00" + }, + { + "value": "5.5", + "label": "UTC+05:30" + }, + { + "value": "5.75", + "label": "UTC+05:45" + }, + { + "value": "6", + "label": "UTC+06:00" + }, + { + "value": "6.5", + "label": "UTC+06:30" + }, + { + "value": "7", + "label": "UTC+07:00" + }, + { + "value": "8", + "label": "UTC+08:00" + }, + { + "value": "8.5", + "label": "UTC+08:30" + }, + { + "value": "8.75", + "label": "UTC+08:45" + }, + { + "value": "9", + "label": "UTC+09:00" + }, + { + "value": "9.5", + "label": "UTC+09:30" + }, + { + "value": "10", + "label": "UTC+10:00" + }, + { + "value": "10.5", + "label": "UTC+10:30" + }, + { + "value": "11", + "label": "UTC+11:00" + }, + { + "value": "12", + "label": "UTC+12:00" + }, + { + "value": "12.75", + "label": "UTC+12:45" + }, + { + "value": "13", + "label": "UTC+13:00" + }, + { + "value": "14", + "label": "UTC+14:00" + } + ] } ] }, diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index d3eb7a97b0..bdf24c000a 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -39,7 +39,11 @@ const QString DomainMetadata::Descriptors::TAGS = "tags"; // descriptors metadata will appear as (JSON): // { "description": String, // capped description // "capacity": Number, -// "hours": String, // UTF-8 representation of the week, split into 15" segments +// "hours": { +// "utc_offset": Number, +// "weekday": [ Number, Number ], +// "weekend": [ Number, Number ] +// } // "restriction": String, // enum of either open, hifi, or acl // "maturity": String, // enum corresponding to ESRB ratings // "hosts": [ String ], // capped list of usernames @@ -50,6 +54,7 @@ const QString DomainMetadata::Descriptors::TAGS = "tags"; // { users: , descriptors: } // // it is meant to be sent to and consumed by an external API +// NOTE: metadata may not appear as documented, as parts are generated by describe-settings.js DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { _metadata[USERS] = {}; From 7fa7abdb1df8c650e538d33d425ac60757174bdb Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 20 Jun 2016 22:43:28 -0700 Subject: [PATCH 17/28] add operating hours to domain-server settings/UI --- .../resources/describe-settings.json | 54 +++++++++++++++++- .../resources/web/settings/js/settings.js | 14 ++++- domain-server/src/DomainMetadata.cpp | 56 ++++++++++++++----- domain-server/src/DomainMetadata.h | 8 ++- .../src/DomainServerSettingsManager.cpp | 27 ++++++++- 5 files changed, 139 insertions(+), 20 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 3633685365..59fa9c4f3d 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1,5 +1,5 @@ { - "version": 1.4, + "version": 1.5, "settings": [ { "name": "metaverse", @@ -143,9 +143,57 @@ ] }, { - "name": "utc_offset", + "label": "Operating Hours", + "help": "\"Open\" domains can be searched using their operating hours. Hours are entered in the local timezone, selected below.", + + "name": "weekday_hours", + "caption": "Weekday Hours (Monday-Friday)", + "type": "table", + "can_add_new_rows": false, + "columns": [ + { + "name": "open", + "label": "Opening Time", + "type": "time", + "default": "00:00", + "editable": true + }, + { + "name": "close", + "label": "Closing Time", + "type": "time", + "default": "23:59", + "editable": true + } + ] + }, + { + "name": "weekend_hours", + "label": "Weekend Hours (Saturday/Sunday)", + "type": "table", + "can_add_new_rows": false, + "columns": [ + { + "name": "open", + "label": "Opening Time", + "type": "time", + "default": "00:00", + "editable": true + }, + { + "name": "close", + "label": "Closing Time", + "type": "time", + "default": "23:59", + "editable": true + } + ] + }, + { "label": "Time Zone", - "help": "This server's time zone, used for searching open servers", + "name": "utc_offset", + "caption": "Time Zone", + "help": "This server's time zone. Used to define your server's operating hours.", "type": "select", "options": [ { diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index aecc48b31f..709e0e05ce 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -987,7 +987,7 @@ function makeTable(setting, keypath, setting_value, isLocked) { html += "" + rowIndexOrName + "" } - var isNonDeletableRow = false; + var isNonDeletableRow = !setting.can_add_new_rows; _.each(setting.columns, function(col) { @@ -1007,6 +1007,10 @@ function makeTable(setting, keypath, setting_value, isLocked) { html += "" + ""; + } else if (isArray && col.type === "time" && col.editable) { + html += "" + + ""; } else { // Use a hidden input so that the values are posted. html += "" @@ -1196,15 +1200,21 @@ function addTableRow(add_glyphicon) { // Hide inputs var input = $(element).find("input") var isCheckbox = false; + var isTime = false; if (input.hasClass("table-checkbox")) { input = $(input).parent(); isCheckbox = true; + } else if (input.hasClass("table-time")) { + input = $(input).parent(); + isTime = true; } var val = input.val(); if (isCheckbox) { - val = $(input).find("input").is(':checked'); // don't hide the checkbox + val = $(input).find("input").is(':checked'); + } else if (isTime) { + // don't hide the time } else { input.attr("type", "hidden") } diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index bdf24c000a..c1656af5b7 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -31,30 +31,32 @@ const QString DomainMetadata::Users::HOSTNAMES = "user_hostnames"; const QString DomainMetadata::DESCRIPTORS = "descriptors"; const QString DomainMetadata::Descriptors::DESCRIPTION = "description"; const QString DomainMetadata::Descriptors::CAPACITY = "capacity"; // parsed from security -const QString DomainMetadata::Descriptors::HOURS = "hours"; const QString DomainMetadata::Descriptors::RESTRICTION = "restriction"; // parsed from ACL const QString DomainMetadata::Descriptors::MATURITY = "maturity"; const QString DomainMetadata::Descriptors::HOSTS = "hosts"; const QString DomainMetadata::Descriptors::TAGS = "tags"; +const QString DomainMetadata::Descriptors::HOURS = "hours"; +const QString DomainMetadata::Descriptors::Hours::WEEKDAY = "weekday"; +const QString DomainMetadata::Descriptors::Hours::WEEKEND = "weekend"; +const QString DomainMetadata::Descriptors::Hours::UTC_OFFSET = "utc_offset"; // descriptors metadata will appear as (JSON): // { "description": String, // capped description // "capacity": Number, -// "hours": { -// "utc_offset": Number, -// "weekday": [ Number, Number ], -// "weekend": [ Number, Number ] -// } // "restriction": String, // enum of either open, hifi, or acl // "maturity": String, // enum corresponding to ESRB ratings // "hosts": [ String ], // capped list of usernames // "tags": [ String ], // capped list of tags +// "hours": { +// "utc_offset": Number, +// "weekday": [ { "open": Time, "close": Time } ], +// "weekend": [ { "open": Time, "close": Time } ], +// } // } // metadata will appear as (JSON): // { users: , descriptors: } // // it is meant to be sent to and consumed by an external API -// NOTE: metadata may not appear as documented, as parts are generated by describe-settings.js DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { _metadata[USERS] = {}; @@ -86,20 +88,42 @@ QJsonObject DomainMetadata::get(const QString& group) { } void DomainMetadata::descriptorsChanged() { - const QString CAPACITY = "security.maximum_user_capacity"; + // get descriptors auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); + auto descriptors = settings[DESCRIPTORS].toMap(); + + // parse capacity + const QString CAPACITY = "security.maximum_user_capacity"; const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY); unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0; - - auto descriptors = settings[DESCRIPTORS].toMap(); descriptors[Descriptors::CAPACITY] = capacity; + + // parse operating hours + const QString WEEKDAY_HOURS = "weekday_hours"; + const QString WEEKEND_HOURS = "weekday_hours"; + const QString UTC_OFFSET = "utc_offset"; + auto weekdayHours = descriptors[WEEKDAY_HOURS]; + auto weekendHours = descriptors[WEEKEND_HOURS]; + auto utcOffset = descriptors[UTC_OFFSET]; + descriptors.remove(WEEKDAY_HOURS); + descriptors.remove(WEEKEND_HOURS); + descriptors.remove(UTC_OFFSET); + QVariantMap hours { + { Descriptors::Hours::UTC_OFFSET, utcOffset }, + { Descriptors::Hours::WEEKDAY, weekdayHours }, + { Descriptors::Hours::WEEKEND, weekendHours } + }; + descriptors[Descriptors::HOURS] = hours; + + // update metadata _metadata[DESCRIPTORS] = descriptors; // update overwritten fields + // this further overwrites metadata, so it must be done after commiting descriptors securityChanged(false); #if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata descriptors set:" << _metadata[DESCRIPTORS]; + qDebug() << "Domain metadata descriptors set:" << QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); #endif sendDescriptors(); @@ -189,7 +213,7 @@ void DomainMetadata::maybeUpdateUsers() { ++_tic; #if DEV_BUILD || PR_BUILD - qDebug() << "Domain metadata users updated:" << users; + qDebug() << "Domain metadata users set:" << QJsonObject::fromVariantMap(_metadata[USERS].toMap()); #endif } @@ -198,10 +222,16 @@ void DomainMetadata::sendDescriptors() { const QUuid& domainID = DependencyManager::get()->getSessionUUID(); if (!domainID.isNull()) { static const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; - DependencyManager::get()->sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + QString path { DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)) }; + DependencyManager::get()->sendRequest(path, AccountManagerAuth::Required, QNetworkAccessManager::PutOperation, JSONCallbackParameters(), domainUpdateJSON.toUtf8()); + +#if DEV_BUILD || PR_BUILD + qDebug() << "Domain metadata sent to" << path; + qDebug() << "Domain metadata update:" << domainUpdateJSON; +#endif } } diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 0bfd6c611b..6573a9076c 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -35,11 +35,17 @@ public: public: static const QString DESCRIPTION; static const QString CAPACITY; - static const QString HOURS; static const QString RESTRICTION; static const QString MATURITY; static const QString HOSTS; static const QString TAGS; + static const QString HOURS; + class Hours { + public: + static const QString WEEKDAY; + static const QString WEEKEND; + static const QString UTC_OFFSET; + }; }; DomainMetadata(QObject* domainServer); diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index b03d2c07ae..f5ff479cd3 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -69,7 +71,7 @@ DomainServerSettingsManager::DomainServerSettingsManager() : } static const QString MISSING_SETTINGS_DESC_MSG = - QString("Did not find settings decription in JSON at %1 - Unable to continue. domain-server will quit.\n%2 at %3") + QString("Did not find settings description in JSON at %1 - Unable to continue. domain-server will quit.\n%2 at %3") .arg(SETTINGS_DESCRIPTION_RELATIVE_PATH).arg(parseError.errorString()).arg(parseError.offset); static const int MISSING_SETTINGS_DESC_ERROR_CODE = 6; @@ -258,6 +260,29 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList _standardAgentPermissions.clear(); _agentPermissions.clear(); } + + if (oldVersion < 1.5) { + // This was prior to operating hours, so add default hours + static const QString WEEKDAY_HOURS{ "descriptors.weekday_hours" }; + static const QString WEEKEND_HOURS{ "descriptors.weekend_hours" }; + static const QString UTC_OFFSET{ "descriptors.utc_offset" }; + + QVariant* weekdayHours = valueForKeyPath(_configMap.getUserConfig(), WEEKDAY_HOURS, true); + QVariant* weekendHours = valueForKeyPath(_configMap.getUserConfig(), WEEKEND_HOURS, true); + QVariant* utcOffset = valueForKeyPath(_configMap.getUserConfig(), UTC_OFFSET, true); + + + QVariantList allHours { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; + *weekdayHours = allHours; + *weekendHours = allHours; + *utcOffset = QVariant(QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / (float)3600); + + // write the new settings to file + persistToFile(); + + // reload the master and user config so the merged config is correct + _configMap.loadMasterAndUserConfig(_argumentList); + } } unpackPermissions(); From 807596596f2923241f57f1349cafc7d0261aca5a Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 00:18:38 -0700 Subject: [PATCH 18/28] fix badging, parsing of operating hours --- .../resources/web/settings/js/settings.js | 12 +++- domain-server/src/DomainMetadata.cpp | 55 +++++++++++++++---- domain-server/src/DomainMetadata.h | 2 + .../src/DomainServerSettingsManager.cpp | 6 +- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 709e0e05ce..c2cb2ecb80 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -243,6 +243,16 @@ $(document).ready(function(){ } }); + $('#' + Settings.FORM_ID).on('change', 'input.table-time', function() { + // Bootstrap switches in table: set the changed data attribute for all rows in table. + var row = $(this).closest('tr'); + if (row.hasClass("value-row")) { // Don't set attribute on input row switches prior to it being added to table. + row.find('td.' + Settings.DATA_COL_CLASS + ' input').attr('data-changed', true); + updateDataChangedForSiblingRows(row, true); + badgeSidebarForDifferences($(this)); + } + }); + $('.advanced-toggle').click(function(){ Settings.showAdvanced = !Settings.showAdvanced var advancedSelector = $('.' + Settings.ADVANCED_CLASS) @@ -1009,7 +1019,7 @@ function makeTable(setting, keypath, setting_value, isLocked) { + "name='" + colName + "'" + (colValue ? " checked" : "") + " />"; } else if (isArray && col.type === "time" && col.editable) { html += "" - + ""; } else { // Use a hidden input so that the values are posted. diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index c1656af5b7..cfb48e6c49 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -39,6 +39,8 @@ const QString DomainMetadata::Descriptors::HOURS = "hours"; const QString DomainMetadata::Descriptors::Hours::WEEKDAY = "weekday"; const QString DomainMetadata::Descriptors::Hours::WEEKEND = "weekend"; const QString DomainMetadata::Descriptors::Hours::UTC_OFFSET = "utc_offset"; +const QString DomainMetadata::Descriptors::Hours::OPEN = "open"; +const QString DomainMetadata::Descriptors::Hours::CLOSE = "close"; // descriptors metadata will appear as (JSON): // { "description": String, // capped description // "capacity": Number, @@ -59,8 +61,13 @@ const QString DomainMetadata::Descriptors::Hours::UTC_OFFSET = "utc_offset"; // it is meant to be sent to and consumed by an external API DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { - _metadata[USERS] = {}; - _metadata[DESCRIPTORS] = {}; + _metadata[USERS] = QVariantMap {}; + _metadata[DESCRIPTORS] = QVariantMap { + { Descriptors::HOURS, QVariantMap { + { Descriptors::Hours::WEEKDAY, QVariantList() }, + { Descriptors::Hours::WEEKEND, QVariantList() } + } } + }; assert(dynamic_cast(domainServer)); DomainServer* server = static_cast(domainServer); @@ -87,10 +94,38 @@ QJsonObject DomainMetadata::get(const QString& group) { return QJsonObject::fromVariantMap(_metadata[group].toMap()); } +QVariant parseHours(QVariant base, QVariant delta) { + using Hours = DomainMetadata::Descriptors::Hours; + + auto& baseList = base.toList(); + auto& deltaList = delta.toList(); + if (baseList.isEmpty() || !baseList.length()) { + return delta; + } else if (deltaList.isEmpty() || !deltaList.length()) { + return base; + } + + auto& baseMap = baseList[0].toMap(); + auto& deltaMap = deltaList[0].toMap(); + if (baseMap.isEmpty()) { + return delta; + } else if (deltaMap.isEmpty()) { + return base; + } + + // merge delta into base + // hours should be of the form [ { open: Time, close: Time } ], so one level is sufficient + foreach(auto key, baseMap.keys()) { + deltaMap[key] = baseMap[key]; + } + + return base; +} + void DomainMetadata::descriptorsChanged() { // get descriptors auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); - auto descriptors = settings[DESCRIPTORS].toMap(); + auto& descriptors = settings[DESCRIPTORS].toMap(); // parse capacity const QString CAPACITY = "security.maximum_user_capacity"; @@ -100,20 +135,21 @@ void DomainMetadata::descriptorsChanged() { // parse operating hours const QString WEEKDAY_HOURS = "weekday_hours"; - const QString WEEKEND_HOURS = "weekday_hours"; + const QString WEEKEND_HOURS = "weekend_hours"; const QString UTC_OFFSET = "utc_offset"; - auto weekdayHours = descriptors[WEEKDAY_HOURS]; - auto weekendHours = descriptors[WEEKEND_HOURS]; + auto& hours = _metadata[DESCRIPTORS].toMap()[Descriptors::HOURS].toMap(); + assert(!hours.isEmpty()); + auto weekdayHours = parseHours(hours[Descriptors::Hours::WEEKDAY], descriptors[WEEKDAY_HOURS]); + auto weekendHours = parseHours(hours[Descriptors::Hours::WEEKEND], descriptors[WEEKEND_HOURS]); auto utcOffset = descriptors[UTC_OFFSET]; descriptors.remove(WEEKDAY_HOURS); descriptors.remove(WEEKEND_HOURS); descriptors.remove(UTC_OFFSET); - QVariantMap hours { + descriptors[Descriptors::HOURS] = QVariantMap { { Descriptors::Hours::UTC_OFFSET, utcOffset }, { Descriptors::Hours::WEEKDAY, weekdayHours }, { Descriptors::Hours::WEEKEND, weekendHours } }; - descriptors[Descriptors::HOURS] = hours; // update metadata _metadata[DESCRIPTORS] = descriptors; @@ -150,9 +186,8 @@ void DomainMetadata::securityChanged(bool send) { restriction = RESTRICTION_ACL; } - auto descriptors = _metadata[DESCRIPTORS].toMap(); + auto& descriptors = _metadata[DESCRIPTORS].toMap(); descriptors[Descriptors::RESTRICTION] = restriction; - _metadata[DESCRIPTORS] = descriptors; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata restriction set:" << restriction; diff --git a/domain-server/src/DomainMetadata.h b/domain-server/src/DomainMetadata.h index 6573a9076c..41f3a60832 100644 --- a/domain-server/src/DomainMetadata.h +++ b/domain-server/src/DomainMetadata.h @@ -45,6 +45,8 @@ public: static const QString WEEKDAY; static const QString WEEKEND; static const QString UTC_OFFSET; + static const QString OPEN; + static const QString CLOSE; }; }; diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index f5ff479cd3..543e61f485 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -271,10 +271,8 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList QVariant* weekendHours = valueForKeyPath(_configMap.getUserConfig(), WEEKEND_HOURS, true); QVariant* utcOffset = valueForKeyPath(_configMap.getUserConfig(), UTC_OFFSET, true); - - QVariantList allHours { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; - *weekdayHours = allHours; - *weekendHours = allHours; + *weekdayHours = QVariantList { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; + *weekendHours = QVariantList { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } }; *utcOffset = QVariant(QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / (float)3600); // write the new settings to file From 31706a39093c88b87b5a58884d18a1d306b7ddfd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 21 Jun 2016 10:38:44 -0700 Subject: [PATCH 19/28] force activate kinmatic objects when necessary --- libraries/physics/src/EntityMotionState.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 8f22c576f0..dc57a82fd3 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -135,7 +135,14 @@ void EntityMotionState::handleEasyChanges(uint32_t& flags) { _nextOwnershipBid = 0; } if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { - _body->activate(); + if (_body->isKinematicObject()) { + // only force activate kinematic bodies (dynamic shouldn't need force and + // active static bodies are special (see PhysicsEngine::_activeStaticBodies)) + _body->activate(true); + _lastKinematicStep = ObjectMotionState::getWorldSimulationStep(); + } else { + _body->activate(); + } } } From 52170eb12e3a1bd4b12bc66b49a15043407a0a48 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 11:16:08 -0700 Subject: [PATCH 20/28] use refs for domain metadata parsing --- domain-server/src/DomainMetadata.cpp | 102 +++++++++++++-------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/domain-server/src/DomainMetadata.cpp b/domain-server/src/DomainMetadata.cpp index cfb48e6c49..f18aa8c71b 100644 --- a/domain-server/src/DomainMetadata.cpp +++ b/domain-server/src/DomainMetadata.cpp @@ -61,11 +61,12 @@ const QString DomainMetadata::Descriptors::Hours::CLOSE = "close"; // it is meant to be sent to and consumed by an external API DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { + // set up the structure necessary for casting during parsing (see parseHours, esp.) _metadata[USERS] = QVariantMap {}; _metadata[DESCRIPTORS] = QVariantMap { { Descriptors::HOURS, QVariantMap { - { Descriptors::Hours::WEEKDAY, QVariantList() }, - { Descriptors::Hours::WEEKEND, QVariantList() } + { Descriptors::Hours::WEEKDAY, QVariantList { QVariantMap{} } }, + { Descriptors::Hours::WEEKEND, QVariantList { QVariantMap{} } } } } }; @@ -81,6 +82,7 @@ DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) { this, static_cast(&DomainMetadata::securityChanged)); // initialize the descriptors + securityChanged(false); descriptorsChanged(); } @@ -94,69 +96,65 @@ QJsonObject DomainMetadata::get(const QString& group) { return QJsonObject::fromVariantMap(_metadata[group].toMap()); } -QVariant parseHours(QVariant base, QVariant delta) { +void parseHours(QVariant delta, QVariant& target) { using Hours = DomainMetadata::Descriptors::Hours; - auto& baseList = base.toList(); - auto& deltaList = delta.toList(); - if (baseList.isEmpty() || !baseList.length()) { - return delta; - } else if (deltaList.isEmpty() || !deltaList.length()) { - return base; - } + // hours should be of the form [ { open: Time, close: Time } ] + assert(target.canConvert()); + auto& targetList = *static_cast(target.data()); - auto& baseMap = baseList[0].toMap(); - auto& deltaMap = deltaList[0].toMap(); - if (baseMap.isEmpty()) { - return delta; - } else if (deltaMap.isEmpty()) { - return base; + // if/when multiple ranges are allowed, this list will need to be iterated + assert(targetList[0].canConvert()); + auto& targetMap = *static_cast(targetList[0].data()); + + auto deltaMap = delta.toList()[0].toMap(); + if (deltaMap.isEmpty()) { + return; } // merge delta into base - // hours should be of the form [ { open: Time, close: Time } ], so one level is sufficient - foreach(auto key, baseMap.keys()) { - deltaMap[key] = baseMap[key]; + auto open = deltaMap.find(Hours::OPEN); + if (open != deltaMap.end()) { + targetMap[Hours::OPEN] = open.value(); } - - return base; + assert(targetMap[Hours::OPEN].canConvert()); + auto close = deltaMap.find(Hours::CLOSE); + if (close != deltaMap.end()) { + targetMap[Hours::CLOSE] = close.value(); + } + assert(targetMap[Hours::CLOSE].canConvert()); } void DomainMetadata::descriptorsChanged() { // get descriptors + assert(_metadata[DESCRIPTORS].canConvert()); + auto& state = *static_cast(_metadata[DESCRIPTORS].data()); auto settings = static_cast(parent())->_settingsManager.getSettingsMap(); - auto& descriptors = settings[DESCRIPTORS].toMap(); + auto descriptors = settings[DESCRIPTORS].toMap(); + + // copy simple descriptors (description/maturity) + state[Descriptors::DESCRIPTION] = descriptors[Descriptors::DESCRIPTION]; + state[Descriptors::MATURITY] = descriptors[Descriptors::MATURITY]; + + // copy array descriptors (hosts/tags) + state[Descriptors::HOSTS] = descriptors[Descriptors::HOSTS].toList(); + state[Descriptors::TAGS] = descriptors[Descriptors::TAGS].toList(); // parse capacity const QString CAPACITY = "security.maximum_user_capacity"; const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY); unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0; - descriptors[Descriptors::CAPACITY] = capacity; + state[Descriptors::CAPACITY] = capacity; // parse operating hours const QString WEEKDAY_HOURS = "weekday_hours"; const QString WEEKEND_HOURS = "weekend_hours"; const QString UTC_OFFSET = "utc_offset"; - auto& hours = _metadata[DESCRIPTORS].toMap()[Descriptors::HOURS].toMap(); - assert(!hours.isEmpty()); - auto weekdayHours = parseHours(hours[Descriptors::Hours::WEEKDAY], descriptors[WEEKDAY_HOURS]); - auto weekendHours = parseHours(hours[Descriptors::Hours::WEEKEND], descriptors[WEEKEND_HOURS]); - auto utcOffset = descriptors[UTC_OFFSET]; - descriptors.remove(WEEKDAY_HOURS); - descriptors.remove(WEEKEND_HOURS); - descriptors.remove(UTC_OFFSET); - descriptors[Descriptors::HOURS] = QVariantMap { - { Descriptors::Hours::UTC_OFFSET, utcOffset }, - { Descriptors::Hours::WEEKDAY, weekdayHours }, - { Descriptors::Hours::WEEKEND, weekendHours } - }; - - // update metadata - _metadata[DESCRIPTORS] = descriptors; - - // update overwritten fields - // this further overwrites metadata, so it must be done after commiting descriptors - securityChanged(false); + assert(state[Descriptors::HOURS].canConvert()); + auto& hours = *static_cast(state[Descriptors::HOURS].data()); + parseHours(descriptors.take(WEEKDAY_HOURS), hours[Descriptors::Hours::WEEKDAY]); + parseHours(descriptors.take(WEEKEND_HOURS), hours[Descriptors::Hours::WEEKEND]); + hours[Descriptors::Hours::UTC_OFFSET] = descriptors.take(UTC_OFFSET); #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata descriptors set:" << QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap()); @@ -166,6 +164,10 @@ void DomainMetadata::descriptorsChanged() { } void DomainMetadata::securityChanged(bool send) { + // get descriptors + assert(_metadata[DESCRIPTORS].canConvert()); + auto& state = *static_cast(_metadata[DESCRIPTORS].data()); + const QString RESTRICTION_OPEN = "open"; const QString RESTRICTION_ANON = "anon"; const QString RESTRICTION_HIFI = "hifi"; @@ -186,8 +188,7 @@ void DomainMetadata::securityChanged(bool send) { restriction = RESTRICTION_ACL; } - auto& descriptors = _metadata[DESCRIPTORS].toMap(); - descriptors[Descriptors::RESTRICTION] = restriction; + state[Descriptors::RESTRICTION] = restriction; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata restriction set:" << restriction; @@ -240,12 +241,11 @@ void DomainMetadata::maybeUpdateUsers() { } }); - QVariantMap users = { - { Users::NUM_TOTAL, numConnected }, - { Users::NUM_ANON, numConnectedAnonymously }, - { Users::HOSTNAMES, userHostnames }}; - _metadata[USERS] = users; - ++_tic; + assert(_metadata[USERS].canConvert()); + auto& users = *static_cast(_metadata[USERS].data()); + users[Users::NUM_TOTAL] = numConnected; + users[Users::NUM_ANON] = numConnectedAnonymously; + users[Users::HOSTNAMES] = userHostnames; #if DEV_BUILD || PR_BUILD qDebug() << "Domain metadata users set:" << QJsonObject::fromVariantMap(_metadata[USERS].toMap()); From c784fa42e99e6b2862ddf73f80a7ae9a040dc9c6 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 11:34:23 -0700 Subject: [PATCH 21/28] log failure to fetch metadata --- scripts/tutorials/getDomainMetadata.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 0a6f742823..8c347a09ae 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -16,14 +16,21 @@ location.hostChanged.connect(function(host) { // Fetch the domain ID from the metaverse var placeData = request(SERVER + '/places/' + host); - if (!placeData) { return; } + if (!placeData) { + print('Cannot find place name - abandoning metadata request for', host); + return; + + } var domainID = placeData.data.place.domain.id; print('Domain ID:', domainID); // Fetch the domain metadata from the metaverse var domainData = request(SERVER + '/domains/' + domainID); print(SERVER + '/domains/' + domainID); - if (!domainData) { return; } + if (!domainData) { + print('Cannot find domain data - abandoning metadata request for', domainID); + return; + } var metadata = domainData.domain; print('Domain metadata:', JSON.stringify(metadata)); From c3223178783c8418bc8e468578d4393c03463abf Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 21 Jun 2016 12:07:05 -0700 Subject: [PATCH 22/28] rework plugins to not depend on PluginContainer unless they want to --- interface/CMakeLists.txt | 2 +- interface/src/Application.cpp | 63 +++++++++++++-- interface/src/Application.h | 26 +++++-- interface/src/PluginContainerProxy.cpp | 78 ------------------- interface/src/PluginContainerProxy.h | 33 -------- libraries/display-plugins/CMakeLists.txt | 2 +- .../AbstractHMDScriptingInterface.cpp | 2 +- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 2 - .../src/display-plugins/NullDisplayPlugin.cpp | 1 - .../src/display-plugins/NullDisplayPlugin.h | 2 + .../display-plugins/OpenGLDisplayPlugin.cpp | 25 ++++-- .../src/display-plugins/OpenGLDisplayPlugin.h | 7 ++ .../display-plugins/hmd/HmdDisplayPlugin.cpp | 1 - .../display-plugins/hmd/HmdDisplayPlugin.h | 2 + .../stereo/SideBySideStereoDisplayPlugin.cpp | 1 - .../stereo/StereoDisplayPlugin.cpp | 1 - libraries/input-plugins/CMakeLists.txt | 2 +- .../plugins/src/plugins/DisplayPlugin.cpp | 22 ------ libraries/plugins/src/plugins/DisplayPlugin.h | 2 - libraries/plugins/src/plugins/Plugin.cpp | 4 - libraries/plugins/src/plugins/Plugin.h | 11 ++- .../plugins/src/plugins/PluginManager.cpp | 11 +-- libraries/plugins/src/plugins/PluginManager.h | 3 + libraries/ui-plugins/CMakeLists.txt | 3 + .../src/ui-plugins}/PluginContainer.cpp | 0 .../src/ui-plugins}/PluginContainer.h | 17 +++- plugins/hifiSixense/CMakeLists.txt | 2 +- plugins/hifiSixense/src/SixenseManager.cpp | 1 - plugins/hifiSixense/src/SixenseManager.h | 2 + plugins/oculus/CMakeLists.txt | 2 +- .../oculus/src/OculusControllerManager.cpp | 2 +- plugins/oculusLegacy/CMakeLists.txt | 2 +- .../src/OculusLegacyDisplayPlugin.cpp | 1 - plugins/openvr/CMakeLists.txt | 2 +- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 1 - plugins/openvr/src/ViveControllerManager.cpp | 1 - plugins/openvr/src/ViveControllerManager.h | 4 +- tests/controllers/CMakeLists.txt | 2 +- tests/controllers/src/main.cpp | 6 +- 39 files changed, 159 insertions(+), 192 deletions(-) delete mode 100644 interface/src/PluginContainerProxy.cpp delete mode 100644 interface/src/PluginContainerProxy.h create mode 100644 libraries/ui-plugins/CMakeLists.txt rename libraries/{plugins/src/plugins => ui-plugins/src/ui-plugins}/PluginContainer.cpp (100%) rename libraries/{plugins/src/plugins => ui-plugins/src/ui-plugins}/PluginContainer.h (77%) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index ae84705da3..cf5a2b60ad 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -139,7 +139,7 @@ link_hifi_libraries(shared octree gpu gl gpu-gl procedural model render recording fbx networking model-networking entities avatars audio audio-client animation script-engine physics render-utils entities-renderer ui auto-updater - controllers plugins display-plugins input-plugins steamworks-wrapper) + controllers plugins ui-plugins display-plugins input-plugins steamworks-wrapper) # include the binary directory of render-utils for shader includes target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils") diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9bcd85fd02..babcd877c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -83,7 +83,6 @@ #include #include #include -#include #include #include #include @@ -119,7 +118,6 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" -#include "PluginContainerProxy.h" #include "scripting/AccountScriptingInterface.h" #include "scripting/AssetMappingsScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" @@ -464,7 +462,6 @@ bool setupEssentials(int& argc, char** argv) { // continuing to overburden Application.cpp Cube3DOverlay* _keyboardFocusHighlight{ nullptr }; int _keyboardFocusHighlightID{ -1 }; -PluginContainer* _pluginContainer; // FIXME hack access to the internal share context for the Chromium helper @@ -504,6 +501,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _maxOctreePPS(maxOctreePacketsPerSecond.get()), _lastFaceTrackerUpdate(0) { + + + PluginContainer* pluginContainer = dynamic_cast(this); // set the container for any plugins that care + PluginManager::getInstance()->setContainer(pluginContainer); + // FIXME this may be excessively conservative. On the other hand // maybe I'm used to having an 8-core machine // Perhaps find the ideal thread count and subtract 2 or 3 @@ -521,7 +523,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _entityClipboard->createRootElement(); - _pluginContainer = new PluginContainerProxy(); #ifdef Q_OS_WIN installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif @@ -2035,9 +2036,9 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Return: if (isOption) { if (_window->isFullScreen()) { - _pluginContainer->unsetFullscreen(); + unsetFullscreen(); } else { - _pluginContainer->setFullscreen(nullptr); + setFullscreen(nullptr); } } else { Menu::getInstance()->triggerOption(MenuOption::AddressBar); @@ -2951,9 +2952,10 @@ void Application::loadSettings() { //DependencyManager::get()->setAutomaticLODAdjust(false); Menu::getInstance()->loadSettings(); - // If there is a preferred plugin, we probably messed it up with the menu settings, so fix it. auto pluginManager = PluginManager::getInstance(); + + auto plugins = pluginManager->getPreferredDisplayPlugins(); for (auto plugin : plugins) { auto menu = Menu::getInstance(); @@ -5190,6 +5192,7 @@ void Application::updateDisplayMode() { // FIXME probably excessive and useless context switching _offscreenContext->makeCurrent(); + qDebug() << "Application::updateDisplayMode()... line:" << __LINE__ << "about to call newDisplayPlugin->activate()"; bool active = newDisplayPlugin->activate(); if (!active) { @@ -5308,3 +5311,49 @@ void Application::showDesktop() { CompositorHelper& Application::getApplicationCompositor() const { return *DependencyManager::get(); } + + +// virtual functions required for PluginContainer +ui::Menu* Application::getPrimaryMenu() { + auto appMenu = _window->menuBar(); + auto uiMenu = dynamic_cast(appMenu); + return uiMenu; +} + +void Application::showDisplayPluginsTools(bool show) { + DependencyManager::get()->hmdTools(show); +} + +GLWidget* Application::getPrimaryWidget() { + return _glWidget; +} + +MainWindow* Application::getPrimaryWindow() { + return getWindow(); +} + +QOpenGLContext* Application::getPrimaryContext() { + return _glWidget->context()->contextHandle(); +} + +bool Application::makeRenderingContextCurrent() { + return _offscreenContext->makeCurrent(); +} + +void Application::releaseSceneTexture(const gpu::TexturePointer& texture) { + Q_ASSERT(QThread::currentThread() == thread()); + auto& framebufferMap = _lockedFramebufferMap; + Q_ASSERT(framebufferMap.contains(texture)); + auto framebufferPointer = framebufferMap[texture]; + framebufferMap.remove(texture); + auto framebufferCache = DependencyManager::get(); + framebufferCache->releaseFramebuffer(framebufferPointer); +} + +void Application::releaseOverlayTexture(const gpu::TexturePointer& texture) { + _applicationOverlay.releaseOverlay(texture); +} + +bool Application::isForeground() const { + return _isForeground && !_window->isMinimized(); +} diff --git a/interface/src/Application.h b/interface/src/Application.h index 6b6148be32..114ce27144 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -86,14 +87,32 @@ class Application; #endif #define qApp (static_cast(QCoreApplication::instance())) -class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, public AbstractUriHandler { +class Application : public QApplication, + public AbstractViewStateInterface, + public AbstractScriptingServicesInterface, + public AbstractUriHandler, + public PluginContainer { Q_OBJECT // TODO? Get rid of those friend class OctreePacketProcessor; - friend class PluginContainerProxy; public: + + // virtual functions required for PluginContainer + virtual ui::Menu* getPrimaryMenu() override; + virtual void requestReset() override { resetSensors(true); } + virtual void showDisplayPluginsTools(bool show) override; + virtual GLWidget* getPrimaryWidget() override; + virtual MainWindow* getPrimaryWindow() override; + virtual QOpenGLContext* getPrimaryContext() override; + virtual bool makeRenderingContextCurrent() override; + virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override; + virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override; + virtual bool isForeground() const override; + + virtual DisplayPluginPointer getActiveDisplayPlugin() const override; + enum Event { Present = DisplayPlugin::Present, Paint = Present + 1, @@ -163,7 +182,6 @@ public: Overlays& getOverlays() { return _overlays; } - bool isForeground() const { return _isForeground; } size_t getFrameCount() const { return _frameCount; } float getFps() const { return _frameCounter.rate(); } @@ -185,8 +203,6 @@ public: void setActiveDisplayPlugin(const QString& pluginName); - DisplayPluginPointer getActiveDisplayPlugin() const; - FileLogger* getLogger() const { return _logger; } glm::vec2 getViewportDimensions() const; diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp deleted file mode 100644 index b651a1520d..0000000000 --- a/interface/src/PluginContainerProxy.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "PluginContainerProxy.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "Application.h" -#include "MainWindow.h" -#include "GLCanvas.h" -#include "ui/DialogsManager.h" - -#include -#include - -PluginContainerProxy::PluginContainerProxy() { -} - -PluginContainerProxy::~PluginContainerProxy() { -} - -ui::Menu* PluginContainerProxy::getPrimaryMenu() { - auto appMenu = qApp->_window->menuBar(); - auto uiMenu = dynamic_cast(appMenu); - return uiMenu; -} - -bool PluginContainerProxy::isForeground() { - return qApp->isForeground() && !qApp->getWindow()->isMinimized(); -} - -void PluginContainerProxy::requestReset() { - // We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway. - qApp->resetSensors(true); -} - -void PluginContainerProxy::showDisplayPluginsTools(bool show) { - DependencyManager::get()->hmdTools(show); -} - -GLWidget* PluginContainerProxy::getPrimaryWidget() { - return qApp->_glWidget; -} - -MainWindow* PluginContainerProxy::getPrimaryWindow() { - return qApp->getWindow(); -} - -QOpenGLContext* PluginContainerProxy::getPrimaryContext() { - return qApp->_glWidget->context()->contextHandle(); -} - -const DisplayPluginPointer PluginContainerProxy::getActiveDisplayPlugin() const { - return qApp->getActiveDisplayPlugin(); -} - -bool PluginContainerProxy::makeRenderingContextCurrent() { - return qApp->_offscreenContext->makeCurrent(); -} - -void PluginContainerProxy::releaseSceneTexture(const gpu::TexturePointer& texture) { - Q_ASSERT(QThread::currentThread() == qApp->thread()); - auto& framebufferMap = qApp->_lockedFramebufferMap; - Q_ASSERT(framebufferMap.contains(texture)); - auto framebufferPointer = framebufferMap[texture]; - framebufferMap.remove(texture); - auto framebufferCache = DependencyManager::get(); - framebufferCache->releaseFramebuffer(framebufferPointer); -} - -void PluginContainerProxy::releaseOverlayTexture(const gpu::TexturePointer& texture) { - qApp->_applicationOverlay.releaseOverlay(texture); -} - diff --git a/interface/src/PluginContainerProxy.h b/interface/src/PluginContainerProxy.h deleted file mode 100644 index a04a1b2977..0000000000 --- a/interface/src/PluginContainerProxy.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#ifndef hifi_PluginContainerProxy_h -#define hifi_PluginContainerProxy_h - -#include -#include - -#include -#include - -class QActionGroup; - -class PluginContainerProxy : public QObject, PluginContainer { - Q_OBJECT - PluginContainerProxy(); - virtual ~PluginContainerProxy(); - virtual void showDisplayPluginsTools(bool show = true) override; - virtual void requestReset() override; - virtual bool makeRenderingContextCurrent() override; - virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override; - virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override; - virtual GLWidget* getPrimaryWidget() override; - virtual MainWindow* getPrimaryWindow() override; - virtual ui::Menu* getPrimaryMenu() override; - virtual QOpenGLContext* getPrimaryContext() override; - virtual bool isForeground() override; - virtual const DisplayPluginPointer getActiveDisplayPlugin() const override; - - friend class Application; - -}; - -#endif diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index f2d58d825e..fe08647074 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME display-plugins) setup_hifi_library(OpenGL) -link_hifi_libraries(shared plugins gl gpu-gl ui) +link_hifi_libraries(shared plugins ui-plugins gl gpu-gl ui) target_opengl() diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp index 4b8d957e5f..d068bef3b0 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp @@ -11,7 +11,7 @@ #include #include "DisplayPlugin.h" -#include +#include static Setting::Handle IPD_SCALE_HANDLE("hmd.ipdScale", 1.0f); diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 48dda1f73d..3bdb96bde3 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -13,8 +13,6 @@ #include #include -#include - const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop"); static const QString FULLSCREEN = "Fullscreen"; diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 3f642072a0..8ebbf4d74b 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -10,7 +10,6 @@ #include "NullDisplayPlugin.h" #include -#include const QString NullDisplayPlugin::NAME("NullDisplayPlugin"); diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index dfa4232a86..c8770393c0 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -7,9 +7,11 @@ // #pragma once +#include #include "DisplayPlugin.h" class NullDisplayPlugin : public DisplayPlugin { + ACCESS_PLUGIN_CONTAINER_MIXIN public: virtual ~NullDisplayPlugin() final {} diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index d34b698410..2128488718 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -22,12 +22,12 @@ #include #include #include -#include #include #include #include #include #include "CompositorHelper.h" +#include #if THREADED_PRESENT @@ -202,6 +202,7 @@ private: #endif + OpenGLDisplayPlugin::OpenGLDisplayPlugin() { _sceneTextureEscrow.setRecycler([this](const gpu::TexturePointer& texture){ cleanupForSceneTexture(texture); @@ -233,10 +234,11 @@ bool OpenGLDisplayPlugin::activate() { cursorData.hotSpot = vec2(0.5f); } } - + if (!_container) { + return false; + } _vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported(); - #if THREADED_PRESENT // Start the present thread if necessary QSharedPointer presentThread; @@ -272,7 +274,11 @@ bool OpenGLDisplayPlugin::activate() { _container->makeRenderingContextCurrent(); #endif - return DisplayPlugin::activate(); + if (isHmd() && (getHmdScreen() >= 0)) { + _container->showDisplayPluginsTools(); + } + + return Parent::activate(); } void OpenGLDisplayPlugin::deactivate() { @@ -288,7 +294,16 @@ void OpenGLDisplayPlugin::deactivate() { _container->makeRenderingContextCurrent(); #endif internalDeactivate(); - DisplayPlugin::deactivate(); + + _container->showDisplayPluginsTools(false); + if (!_container->currentDisplayActions().isEmpty()) { + auto menu = _container->getPrimaryMenu(); + foreach(auto itemInfo, _container->currentDisplayActions()) { + menu->removeMenuItem(itemInfo.first, itemInfo.second); + } + _container->currentDisplayActions().clear(); + } + Parent::deactivate(); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index c87ff1bc93..10362b8181 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -21,9 +21,14 @@ #include #include +#include + #define THREADED_PRESENT 1 class OpenGLDisplayPlugin : public DisplayPlugin { + + ACCESS_PLUGIN_CONTAINER_MIXIN + protected: using Mutex = std::mutex; using Lock = std::unique_lock; @@ -135,7 +140,9 @@ protected: BasicFramebufferWrapperPtr _compositeFramebuffer; bool _lockCurrentTexture { false }; + private: + using Parent = DisplayPlugin; ProgramPtr _activeProgram; }; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 4e594d89ed..b7739a7fb6 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index e6ceb7e376..b87f68231c 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -13,6 +13,8 @@ #include "../OpenGLDisplayPlugin.h" +#include + class HmdDisplayPlugin : public OpenGLDisplayPlugin { using Parent = OpenGLDisplayPlugin; public: diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp index 5f55841be1..be095ecd39 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp @@ -9,7 +9,6 @@ #include "SideBySideStereoDisplayPlugin.h" #include #include -#include #include #include "../CompositorHelper.h" diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index 6c6716c8fa..afb99e3174 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include "../CompositorHelper.h" diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index b81554511d..b0ea13843b 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers) +link_hifi_libraries(shared plugins ui-plugins controllers) GroupSources("src/input-plugins") diff --git a/libraries/plugins/src/plugins/DisplayPlugin.cpp b/libraries/plugins/src/plugins/DisplayPlugin.cpp index a217041f4e..747c72c08e 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.cpp +++ b/libraries/plugins/src/plugins/DisplayPlugin.cpp @@ -1,28 +1,6 @@ #include "DisplayPlugin.h" #include -#include - -#include "PluginContainer.h" - -bool DisplayPlugin::activate() { - if (isHmd() && (getHmdScreen() >= 0)) { - _container->showDisplayPluginsTools(); - } - return Parent::activate(); -} - -void DisplayPlugin::deactivate() { - _container->showDisplayPluginsTools(false); - if (!_container->currentDisplayActions().isEmpty()) { - auto menu = _container->getPrimaryMenu(); - foreach(auto itemInfo, _container->currentDisplayActions()) { - menu->removeMenuItem(itemInfo.first, itemInfo.second); - } - _container->currentDisplayActions().clear(); - } - Parent::deactivate(); -} int64_t DisplayPlugin::getPaintDelayUsecs() const { std::lock_guard lock(_paintDelayMutex); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 19f803e11e..837694372a 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -64,8 +64,6 @@ public: Present = QEvent::User + 1 }; - bool activate() override; - void deactivate() override; virtual bool isHmd() const { return false; } virtual int getHmdScreen() const { return -1; } /// By default, all HMDs are stereo diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 7c30f252c9..54f76b3482 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -9,10 +9,6 @@ QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); -void Plugin::setContainer(PluginContainer* container) { - _container = container; -} - bool Plugin::isSupported() const { return true; } void Plugin::init() {} diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index fb5bf0ba55..cb03f67bd6 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -14,6 +14,8 @@ #include "Forward.h" +#include + class Plugin : public QObject { public: /// \return human-readable name @@ -28,8 +30,11 @@ public: virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } virtual bool isSupported() const; - - void setContainer(PluginContainer* container); + + /// Some plugins may need access to the PluginContainer, if the individual plugin + /// needs access to this, they should override these methods and store their own + /// type safe version of the pointer to the container. + virtual void setContainer(void* container) { } /// Called when plugin is initially loaded, typically at application start virtual void init(); @@ -65,7 +70,5 @@ public: protected: bool _active { false }; - PluginContainer* _container { nullptr }; static QString UNKNOWN_PLUGIN_ID; - }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 7161132c5e..2692de931f 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -17,7 +17,6 @@ #include "RuntimePlugin.h" #include "DisplayPlugin.h" #include "InputPlugin.h" -#include "PluginContainer.h" PluginManager* PluginManager::getInstance() { @@ -133,10 +132,11 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } } } - auto& container = PluginContainer::getInstance(); for (auto plugin : displayPlugins) { - plugin->setContainer(&container); plugin->init(); + if (_container) { + plugin->setContainer(_container); + } } }); @@ -171,10 +171,11 @@ const InputPluginList& PluginManager::getInputPlugins() { } } - auto& container = PluginContainer::getInstance(); for (auto plugin : inputPlugins) { - plugin->setContainer(&container); plugin->init(); + if (_container) { + plugin->setContainer(_container); + } } }); return inputPlugins; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 2a94e6490b..b0aa13d2d0 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -26,4 +26,7 @@ public: void disableDisplays(const QStringList& displays); void disableInputs(const QStringList& inputs); void saveSettings(); + void setContainer(void* container) { _container = container; } +private: + void* _container { nullptr }; }; diff --git a/libraries/ui-plugins/CMakeLists.txt b/libraries/ui-plugins/CMakeLists.txt new file mode 100644 index 0000000000..9ce189b117 --- /dev/null +++ b/libraries/ui-plugins/CMakeLists.txt @@ -0,0 +1,3 @@ +set(TARGET_NAME ui-plugins) +setup_hifi_library(OpenGL) +link_hifi_libraries(shared plugins ui) diff --git a/libraries/plugins/src/plugins/PluginContainer.cpp b/libraries/ui-plugins/src/ui-plugins/PluginContainer.cpp similarity index 100% rename from libraries/plugins/src/plugins/PluginContainer.cpp rename to libraries/ui-plugins/src/ui-plugins/PluginContainer.cpp diff --git a/libraries/plugins/src/plugins/PluginContainer.h b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h similarity index 77% rename from libraries/plugins/src/plugins/PluginContainer.h rename to libraries/ui-plugins/src/ui-plugins/PluginContainer.h index e1d1a212e2..57c3c62704 100644 --- a/libraries/plugins/src/plugins/PluginContainer.h +++ b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h @@ -7,16 +7,18 @@ // #pragma once +#include #include #include #include +#include #include #include #include #include -#include "Forward.h" +#include class QAction; class GLWidget; @@ -63,8 +65,8 @@ public: virtual GLWidget* getPrimaryWidget() = 0; virtual MainWindow* getPrimaryWindow() = 0; virtual QOpenGLContext* getPrimaryContext() = 0; - virtual bool isForeground() = 0; - virtual const DisplayPluginPointer getActiveDisplayPlugin() const = 0; + virtual bool isForeground() const = 0; + virtual DisplayPluginPointer getActiveDisplayPlugin() const = 0; /// settings interface bool getBoolSetting(const QString& settingName, bool defaultValue); @@ -84,3 +86,12 @@ protected: std::map _exclusiveGroups; QRect _savedGeometry { 10, 120, 800, 600 }; }; + +/// Mixin this class to your class to get easy access to the PluginContainer +#define ACCESS_PLUGIN_CONTAINER_MIXIN \ +public: \ + virtual void setContainer(void* container) override { \ + _container = static_cast(container); \ + } \ +protected: \ + PluginContainer* _container { nullptr }; diff --git a/plugins/hifiSixense/CMakeLists.txt b/plugins/hifiSixense/CMakeLists.txt index 589b5b8964..f907d7865f 100644 --- a/plugins/hifiSixense/CMakeLists.txt +++ b/plugins/hifiSixense/CMakeLists.txt @@ -8,5 +8,5 @@ set(TARGET_NAME hifiSixense) setup_hifi_plugin(Script Qml Widgets) -link_hifi_libraries(shared controllers ui plugins input-plugins) +link_hifi_libraries(shared controllers ui plugins ui-plugins input-plugins) target_sixense() diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 9ea79a8b96..4faec959ea 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index 6aec9fd4ad..c9e8f5d4ad 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -17,6 +17,7 @@ #include #include +#include #include struct _sixenseControllerData; @@ -24,6 +25,7 @@ using SixenseControllerData = _sixenseControllerData; // Handles interaction with the Sixense SDK (e.g., Razer Hydra). class SixenseManager : public InputPlugin { + ACCESS_PLUGIN_CONTAINER_MIXIN Q_OBJECT public: // Plugin functions diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt index a91690ecdd..778be08dcf 100644 --- a/plugins/oculus/CMakeLists.txt +++ b/plugins/oculus/CMakeLists.txt @@ -13,7 +13,7 @@ if (WIN32) set(TARGET_NAME oculus) setup_hifi_plugin(Multimedia) - link_hifi_libraries(shared gl gpu controllers ui plugins display-plugins input-plugins audio-client networking) + link_hifi_libraries(shared gl gpu controllers ui plugins ui-plugins display-plugins input-plugins audio-client networking) include_hifi_library_headers(octree) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 9f0e76363b..128b980558 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include diff --git a/plugins/oculusLegacy/CMakeLists.txt b/plugins/oculusLegacy/CMakeLists.txt index a4e00013f1..c1f2c6249f 100644 --- a/plugins/oculusLegacy/CMakeLists.txt +++ b/plugins/oculusLegacy/CMakeLists.txt @@ -12,7 +12,7 @@ if (APPLE) set(TARGET_NAME oculusLegacy) setup_hifi_plugin() - link_hifi_libraries(shared gl gpu plugins ui display-plugins input-plugins) + link_hifi_libraries(shared gl gpu plugins ui ui-plugins display-plugins input-plugins) include_hifi_library_headers(octree) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 8e044fbc16..3b2c9808ab 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -26,7 +26,6 @@ #include #include -#include "plugins/PluginContainer.h" #include "OculusHelpers.h" using namespace oglplus; diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt index 1ba8d05b92..8263e87767 100644 --- a/plugins/openvr/CMakeLists.txt +++ b/plugins/openvr/CMakeLists.txt @@ -12,7 +12,7 @@ if (WIN32) set(TARGET_NAME openvr) setup_hifi_plugin(OpenGL Script Qml Widgets) link_hifi_libraries(shared gl networking controllers ui - plugins display-plugins input-plugins script-engine + plugins display-plugins ui-plugins input-plugins script-engine render-utils model gpu render model-networking fbx) include_hifi_library_headers(octree) diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 3e7e5abbf3..552a62514d 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include "OpenVrHelpers.h" diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index b862aacb06..88c76a97b8 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 3a2ef1573f..f3cd2b4a93 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -23,12 +23,14 @@ #include #include #include +#include namespace vr { class IVRSystem; } -class ViveControllerManager : public InputPlugin { +class ViveControllerManager : public InputPlugin { + ACCESS_PLUGIN_CONTAINER_MIXIN Q_OBJECT public: // Plugin functions diff --git a/tests/controllers/CMakeLists.txt b/tests/controllers/CMakeLists.txt index cf1152da02..3aac4db0a8 100644 --- a/tests/controllers/CMakeLists.txt +++ b/tests/controllers/CMakeLists.txt @@ -6,7 +6,7 @@ setup_hifi_project(Script Qml) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared gl script-engine plugins render-utils input-plugins display-plugins controllers) +link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers) if (WIN32) diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index 36ed566ea7..15b768bb36 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include #include @@ -90,8 +90,8 @@ public: virtual MainWindow* getPrimaryWindow() override { return nullptr; } virtual QOpenGLContext* getPrimaryContext() override { return nullptr; } virtual ui::Menu* getPrimaryMenu() override { return nullptr; } - virtual bool isForeground() override { return true; } - virtual const DisplayPluginPointer getActiveDisplayPlugin() const override { return DisplayPluginPointer(); } + virtual bool isForeground() const override { return true; } + virtual DisplayPluginPointer getActiveDisplayPlugin() const override { return DisplayPluginPointer(); } }; class MyControllerScriptingInterface : public controller::ScriptingInterface { From 160a5de271ccf15d1dd708611c1dc12f2211a912 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 21 Jun 2016 12:34:42 -0700 Subject: [PATCH 23/28] CR feedback --- interface/src/Application.cpp | 3 --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 2 ++ .../src/display-plugins/NullDisplayPlugin.cpp | 1 + .../src/display-plugins/NullDisplayPlugin.h | 2 -- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 1 + .../src/display-plugins/OpenGLDisplayPlugin.h | 4 ---- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 1 + .../src/display-plugins/hmd/HmdDisplayPlugin.h | 2 -- .../stereo/SideBySideStereoDisplayPlugin.cpp | 1 + .../display-plugins/stereo/StereoDisplayPlugin.cpp | 1 + libraries/plugins/src/plugins/Plugin.cpp | 4 ++++ libraries/plugins/src/plugins/Plugin.h | 11 ++++------- libraries/plugins/src/plugins/PluginManager.cpp | 8 ++------ libraries/plugins/src/plugins/PluginManager.h | 4 ++-- libraries/ui-plugins/src/ui-plugins/PluginContainer.h | 10 ---------- plugins/hifiSixense/src/SixenseManager.cpp | 1 + plugins/hifiSixense/src/SixenseManager.h | 2 -- .../oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 1 + plugins/openvr/src/OpenVrDisplayPlugin.cpp | 1 + plugins/openvr/src/ViveControllerManager.cpp | 1 + plugins/openvr/src/ViveControllerManager.h | 4 +--- 21 files changed, 24 insertions(+), 41 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index babcd877c4..f553b4bbdf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2954,8 +2954,6 @@ void Application::loadSettings() { Menu::getInstance()->loadSettings(); // If there is a preferred plugin, we probably messed it up with the menu settings, so fix it. auto pluginManager = PluginManager::getInstance(); - - auto plugins = pluginManager->getPreferredDisplayPlugins(); for (auto plugin : plugins) { auto menu = Menu::getInstance(); @@ -5192,7 +5190,6 @@ void Application::updateDisplayMode() { // FIXME probably excessive and useless context switching _offscreenContext->makeCurrent(); - qDebug() << "Application::updateDisplayMode()... line:" << __LINE__ << "about to call newDisplayPlugin->activate()"; bool active = newDisplayPlugin->activate(); if (!active) { diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 3bdb96bde3..f488a805c6 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -13,6 +13,8 @@ #include #include +#include + const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop"); static const QString FULLSCREEN = "Fullscreen"; diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 8ebbf4d74b..4fadbdb94b 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -10,6 +10,7 @@ #include "NullDisplayPlugin.h" #include +#include const QString NullDisplayPlugin::NAME("NullDisplayPlugin"); diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index c8770393c0..dfa4232a86 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -7,11 +7,9 @@ // #pragma once -#include #include "DisplayPlugin.h" class NullDisplayPlugin : public DisplayPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN public: virtual ~NullDisplayPlugin() final {} diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 2128488718..4bca48aeb0 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 10362b8181..aa3699584a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -21,14 +21,10 @@ #include #include -#include - #define THREADED_PRESENT 1 class OpenGLDisplayPlugin : public DisplayPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN - protected: using Mutex = std::mutex; using Lock = std::unique_lock; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index b7739a7fb6..b29348f646 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index b87f68231c..e6ceb7e376 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -13,8 +13,6 @@ #include "../OpenGLDisplayPlugin.h" -#include - class HmdDisplayPlugin : public OpenGLDisplayPlugin { using Parent = OpenGLDisplayPlugin; public: diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp index be095ecd39..5d9f812edf 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.cpp @@ -9,6 +9,7 @@ #include "SideBySideStereoDisplayPlugin.h" #include #include +#include #include #include "../CompositorHelper.h" diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index afb99e3174..cfdfb1fc21 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include "../CompositorHelper.h" diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 54f76b3482..7c30f252c9 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -9,6 +9,10 @@ QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); +void Plugin::setContainer(PluginContainer* container) { + _container = container; +} + bool Plugin::isSupported() const { return true; } void Plugin::init() {} diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index cb03f67bd6..fb5bf0ba55 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -14,8 +14,6 @@ #include "Forward.h" -#include - class Plugin : public QObject { public: /// \return human-readable name @@ -30,11 +28,8 @@ public: virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } virtual bool isSupported() const; - - /// Some plugins may need access to the PluginContainer, if the individual plugin - /// needs access to this, they should override these methods and store their own - /// type safe version of the pointer to the container. - virtual void setContainer(void* container) { } + + void setContainer(PluginContainer* container); /// Called when plugin is initially loaded, typically at application start virtual void init(); @@ -70,5 +65,7 @@ public: protected: bool _active { false }; + PluginContainer* _container { nullptr }; static QString UNKNOWN_PLUGIN_ID; + }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 2692de931f..d5c860200a 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -133,10 +133,8 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() { } } for (auto plugin : displayPlugins) { + plugin->setContainer(_container); plugin->init(); - if (_container) { - plugin->setContainer(_container); - } } }); @@ -172,10 +170,8 @@ const InputPluginList& PluginManager::getInputPlugins() { } for (auto plugin : inputPlugins) { + plugin->setContainer(_container); plugin->init(); - if (_container) { - plugin->setContainer(_container); - } } }); return inputPlugins; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index b0aa13d2d0..7903bdd724 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -26,7 +26,7 @@ public: void disableDisplays(const QStringList& displays); void disableInputs(const QStringList& inputs); void saveSettings(); - void setContainer(void* container) { _container = container; } + void setContainer(PluginContainer* container) { _container = container; } private: - void* _container { nullptr }; + PluginContainer* _container { nullptr }; }; diff --git a/libraries/ui-plugins/src/ui-plugins/PluginContainer.h b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h index 57c3c62704..74ac834057 100644 --- a/libraries/ui-plugins/src/ui-plugins/PluginContainer.h +++ b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h @@ -7,12 +7,10 @@ // #pragma once -#include #include #include #include -#include #include #include #include @@ -87,11 +85,3 @@ protected: QRect _savedGeometry { 10, 120, 800, 600 }; }; -/// Mixin this class to your class to get easy access to the PluginContainer -#define ACCESS_PLUGIN_CONTAINER_MIXIN \ -public: \ - virtual void setContainer(void* container) override { \ - _container = static_cast(container); \ - } \ -protected: \ - PluginContainer* _container { nullptr }; diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 4faec959ea..566f879f69 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index c9e8f5d4ad..6aec9fd4ad 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -17,7 +17,6 @@ #include #include -#include #include struct _sixenseControllerData; @@ -25,7 +24,6 @@ using SixenseControllerData = _sixenseControllerData; // Handles interaction with the Sixense SDK (e.g., Razer Hydra). class SixenseManager : public InputPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN Q_OBJECT public: // Plugin functions diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 3b2c9808ab..4aadb890d5 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -26,6 +26,7 @@ #include #include +#include #include "OculusHelpers.h" using namespace oglplus; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 552a62514d..c5d3be25b2 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include "OpenVrHelpers.h" diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 88c76a97b8..12813dae93 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index f3cd2b4a93..3a2ef1573f 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -23,14 +23,12 @@ #include #include #include -#include namespace vr { class IVRSystem; } -class ViveControllerManager : public InputPlugin { - ACCESS_PLUGIN_CONTAINER_MIXIN +class ViveControllerManager : public InputPlugin { Q_OBJECT public: // Plugin functions From c8ead2ad048845e46f5d127c132c7239e7c4d011 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 21 Jun 2016 13:28:15 -0700 Subject: [PATCH 24/28] conform to coding braces standard --- scripts/tutorials/getDomainMetadata.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 8c347a09ae..54c356ae7b 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -113,7 +113,9 @@ function displayMetadata(place, metadata) { } function clearMetadata() { - if (OVERLAY) { Overlays.deleteOverlay(OVERLAY); } + if (OVERLAY) { + Overlays.deleteOverlay(OVERLAY); + } } // Request JSON from a url, synchronously From 9a17f5b439a49498377d48c77d069c5283331103 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 21 Jun 2016 14:12:27 -0700 Subject: [PATCH 25/28] update homebrew instructions --- BUILD_OSX.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 44f27d3d02..ab84bc4711 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -13,11 +13,11 @@ We no longer require install of qt5 via our [homebrew formulas repository](https Assuming you've installed OpenSSL or Qt 5 using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR and QT_CMAKE_PREFIX_PATH so CMake can find your installations. For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR: - export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2d_1 + export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2h_1/ For Qt 5.5.1 installed via homebrew, set QT_CMAKE_PREFIX_PATH as follows. - export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.5.1_2/lib/cmake + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt55/5.5.1/lib/cmake Not that these use the versions from homebrew formulae at the time of this writing, and the version in the path will likely change. From f2f7e21eaf3b56b777a2819f0c2499b039b97bf8 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 21 Jun 2016 16:17:43 -0700 Subject: [PATCH 26/28] remove dead refereince to PluginContainer.h from space mouse --- plugins/hifiSpacemouse/src/SpacemouseManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp index 3d9b93ff44..0c29ced6f9 100644 --- a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp @@ -18,7 +18,6 @@ #include #include -#include #include const QString SpacemouseManager::NAME { "Spacemouse" }; From db8190ad4985fd43162119d5b97819f3d93c9440 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 21 Jun 2016 16:56:00 -0700 Subject: [PATCH 27/28] fix typo --- BUILD_OSX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD_OSX.md b/BUILD_OSX.md index ab84bc4711..1c9c5a9796 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -19,7 +19,7 @@ For Qt 5.5.1 installed via homebrew, set QT_CMAKE_PREFIX_PATH as follows. export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt55/5.5.1/lib/cmake -Not that these use the versions from homebrew formulae at the time of this writing, and the version in the path will likely change. +Note that these use the versions from homebrew formulae at the time of this writing, and the version in the path will likely change. ###Xcode If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. From 89c50ab3df3585094c8752e341305c82b8d11dd7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 21 Jun 2016 16:46:10 -0700 Subject: [PATCH 28/28] Update neuron archive in cmakelists --- cmake/externals/neuron/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/neuron/CMakeLists.txt b/cmake/externals/neuron/CMakeLists.txt index 6936725571..76dda8f8c5 100644 --- a/cmake/externals/neuron/CMakeLists.txt +++ b/cmake/externals/neuron/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME neuron) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(NEURON_URL "https://s3.amazonaws.com/hifi-public/dependencies/neuron_datareader_b.12.zip") -set(NEURON_URL_MD5 "0ab54ca04c9cc8094e0fa046c226e574") +set(NEURON_URL "https://s3.amazonaws.com/hifi-public/dependencies/neuron_datareader_b.12.2.zip") +set(NEURON_URL_MD5 "84273ad2200bf86a9279d1f412a822ca") ExternalProject_Add(${EXTERNAL_NAME} URL ${NEURON_URL}