From 348be788f77885d157300a7a95dca0f21b19ce3f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Aug 2017 11:14:09 -0700 Subject: [PATCH] Add BakingEnabled protocol --- assignment-client/src/assets/AssetServer.cpp | 54 +++++++++++++------ assignment-client/src/assets/AssetServer.h | 3 ++ assignment-client/src/assets/AutoBaker.cpp | 10 ++-- assignment-client/src/assets/AutoBaker.h | 2 +- interface/resources/qml/AssetServer.qml | 11 ++-- interface/resources/qml/controls-uit/Tree.qml | 20 ++++++- libraries/networking/src/AssetClient.cpp | 40 ++++++++++++++ libraries/networking/src/AssetClient.h | 4 ++ libraries/networking/src/AssetUtils.cpp | 4 ++ libraries/networking/src/AssetUtils.h | 7 ++- libraries/networking/src/MappingRequest.cpp | 43 +++++++++++++++ libraries/networking/src/MappingRequest.h | 15 ++++++ .../networking/src/udt/PacketHeaders.cpp | 4 +- libraries/networking/src/udt/PacketHeaders.h | 4 ++ .../src/AssetScriptingInterface.cpp | 14 +++++ .../src/AssetScriptingInterface.h | 2 + 16 files changed, 205 insertions(+), 32 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index ea0010cb26..c5de1005f5 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -334,11 +334,10 @@ void AssetServer::completeSetup() { QRegExp hashFileRegex { "^[a-f0-9]{" + QString::number(SHA256_HASH_HEX_LENGTH) + "}" }; auto files = _filesDirectory.entryInfoList(QDir::Files); - auto mappedHashes = _fileMappings.values(); - for (const auto& fileInfo : files) { - AssetHash hash = fileInfo.fileName(); - bool isAsset = hashFileRegex.exactMatch(hash); - if (isAsset && _baker.assetNeedsBaking(hash)) { + for (auto& it = _fileMappings.cbegin(); it != _fileMappings.cend(); ++it) { + AssetPath path = it.key(); + AssetHash hash = it.value().toString(); + if (_baker.assetNeedsBaking(path, hash)) { _baker.addPendingBake(hash); } } @@ -381,26 +380,24 @@ void AssetServer::handleAssetMappingOperation(QSharedPointer me replyPacket->writePrimitive(messageID); switch (operationType) { - case AssetMappingOperationType::Get: { + case AssetMappingOperationType::Get: handleGetMappingOperation(*message, senderNode, *replyPacket); break; - } - case AssetMappingOperationType::GetAll: { + case AssetMappingOperationType::GetAll: handleGetAllMappingOperation(*message, senderNode, *replyPacket); break; - } - case AssetMappingOperationType::Set: { + case AssetMappingOperationType::Set: handleSetMappingOperation(*message, senderNode, *replyPacket); break; - } - case AssetMappingOperationType::Delete: { + case AssetMappingOperationType::Delete: handleDeleteMappingsOperation(*message, senderNode, *replyPacket); break; - } - case AssetMappingOperationType::Rename: { + case AssetMappingOperationType::Rename: handleRenameMappingOperation(*message, senderNode, *replyPacket); break; - } + case AssetMappingOperationType::SetBakingEnabled: + handleSetBakingEnabledOperation(*message, senderNode, *replyPacket); + break; } auto nodeList = DependencyManager::get(); @@ -545,6 +542,30 @@ void AssetServer::handleRenameMappingOperation(ReceivedMessage& message, SharedN } } +void AssetServer::handleSetBakingEnabledOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { + if (senderNode->getCanWriteToAssetServer()) { + bool enabled { true }; + message.readPrimitive(&enabled); + + int numberOfMappings{ 0 }; + message.readPrimitive(&numberOfMappings); + + QStringList mappings; + + for (int i = 0; i < numberOfMappings; ++i) { + mappings << message.readString(); + } + + if (setBakingEnabled(mappings, enabled)) { + replyPacket.writePrimitive(AssetServerError::NoError); + } else { + replyPacket.writePrimitive(AssetServerError::MappingOperationFailed); + } + } else { + replyPacket.writePrimitive(AssetServerError::PermissionDenied); + } +} + void AssetServer::handleAssetGetInfo(QSharedPointer message, SharedNodePointer senderNode) { QByteArray assetHash; MessageID messageID; @@ -1100,4 +1121,7 @@ bool AssetServer::createMetaFile(AssetHash originalAssetHash) { } else { return false; } + +bool AssetServer::setBakingEnabled(AssetPathList& paths, bool enabled) { + return "test"; } diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index 2ce223760f..4d2b8da877 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -64,6 +64,7 @@ private: void handleSetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); void handleDeleteMappingsOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); void handleRenameMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); + void handleSetBakingEnabledOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); // Mapping file operations must be called from main assignment thread only bool loadMappingsFromFile(); @@ -78,6 +79,8 @@ private: /// Rename mapping from `oldPath` to `newPath`. Returns true if successful bool renameMapping(AssetPath oldPath, AssetPath newPath); + bool setBakingEnabled(AssetPathList& paths, bool enabled); + /// Delete any unmapped files from the local asset directory void cleanupUnmappedFiles(); diff --git a/assignment-client/src/assets/AutoBaker.cpp b/assignment-client/src/assets/AutoBaker.cpp index fae895e635..38c564425b 100644 --- a/assignment-client/src/assets/AutoBaker.cpp +++ b/assignment-client/src/assets/AutoBaker.cpp @@ -20,8 +20,8 @@ void AutoBaker::addPendingBake(AssetHash hash) { // Maybe start baking it right away } -bool AutoBaker::assetNeedsBaking(AssetHash hash) { - return true; +bool AutoBaker::assetNeedsBaking(AssetPath path, AssetHash hash) { + return path.endsWith(".fbx"); } BakingStatus AutoBaker::getAssetStatus(AssetHash hash) { @@ -33,9 +33,5 @@ BakingStatus AutoBaker::getAssetStatus(AssetHash hash) { return Baking; } - if (assetNeedsBaking(hash)) { - return NotBaked; - } else { - return Baked; - } + return NotBaked; } diff --git a/assignment-client/src/assets/AutoBaker.h b/assignment-client/src/assets/AutoBaker.h index 805130bf52..258fb15931 100644 --- a/assignment-client/src/assets/AutoBaker.h +++ b/assignment-client/src/assets/AutoBaker.h @@ -20,7 +20,7 @@ class AutoBaker { public: void addPendingBake(AssetHash hash); - bool assetNeedsBaking(AssetHash hash); + bool assetNeedsBaking(AssetPath path, AssetHash hash); BakingStatus getAssetStatus(AssetHash hash); diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 0b307bbc3b..a34de72270 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -542,7 +542,7 @@ ScrollingWindow { id: bakedColumn title: "Use Baked?" role: "baked" - width: 120 + width: 140 } MouseArea { @@ -596,14 +596,17 @@ ScrollingWindow { anchors.bottomMargin: hifi.dimensions.contentSpacing.y spacing: hifi.dimensions.contentSpacing.x - HifiControls.Label { - text: treeView.selection.selectedIndexes.length + " ITEMS SELECTED" - colorScheme: root.colorScheme + RalewayRegular { + size: hifi.fontSizes.sectionName + font.capitalization: Font.AllUppercase + text: selectedItems + " items selected" + color: hifi.colors.lightGrayText } HifiControls.CheckBox { text: "Use baked (optimized) versions" colorScheme: root.colorScheme + enabled: selectedItems > 0 } } diff --git a/interface/resources/qml/controls-uit/Tree.qml b/interface/resources/qml/controls-uit/Tree.qml index 711c6b4e5f..b7d9558cb6 100644 --- a/interface/resources/qml/controls-uit/Tree.qml +++ b/interface/resources/qml/controls-uit/Tree.qml @@ -212,12 +212,16 @@ TreeView { if (treeView.canEdit && styleData.selected) { return textFieldComponent; } else { - return labelComponent; + if (styleData.value.startsWith("HifiGlyphs#")) { + return glyphComponent; + } else { + return labelComponent; + } } } sourceComponent: getComponent() - + Component { id: labelComponent FiraSansSemiBold { @@ -231,6 +235,18 @@ TreeView { elide: Text.ElideRight } } + Component { + id: glyphComponent + HiFiGlyphs { + text: styleData.value.replace("HifiGlyphs#", "") + size: hifi.fontSizes.tableText + color: colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + + elide: Text.ElideRight + } + } Component { id: textFieldComponent diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index cb0b620a54..0d4e7c8388 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -185,6 +185,14 @@ RenameMappingRequest* AssetClient::createRenameMappingRequest(const AssetPath& o return request; } +SetBakingEnabledRequest* AssetClient::createSetBakingEnabledRequest(const AssetPathList& path, bool enabled) { + auto bakingEnabledRequest = new SetBakingEnabledRequest(path, enabled); + + bakingEnabledRequest->moveToThread(thread()); + + return bakingEnabledRequest; +} + AssetRequest* AssetClient::createRequest(const AssetHash& hash, const ByteRange& byteRange) { auto request = new AssetRequest(hash, byteRange); @@ -585,6 +593,38 @@ MessageID AssetClient::renameAssetMapping(const AssetPath& oldPath, const AssetP return INVALID_MESSAGE_ID; } +MessageID AssetClient::setBakingEnabled(const AssetPathList& paths, bool enabled, MappingOperationCallback callback) { + auto nodeList = DependencyManager::get(); + SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer); + + if (assetServer) { + auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true); + + auto messageID = ++_currentID; + packetList->writePrimitive(messageID); + + packetList->writePrimitive(AssetMappingOperationType::SetBakingEnabled); + + packetList->writePrimitive(enabled); + + packetList->writePrimitive(int(paths.size())); + + for (auto& path : paths) { + packetList->writeString(path); + } + + if (nodeList->sendPacketList(std::move(packetList), *assetServer) != -1) { + _pendingMappingRequests[assetServer][messageID] = callback; + + return messageID; + + } + } + + callback(false, AssetServerError::NoError, QSharedPointer()); + return INVALID_MESSAGE_ID; +} + bool AssetClient::cancelMappingRequest(MessageID id) { Q_ASSERT(QThread::currentThread() == thread()); diff --git a/libraries/networking/src/AssetClient.h b/libraries/networking/src/AssetClient.h index 3f6602b76b..8035aa886e 100644 --- a/libraries/networking/src/AssetClient.h +++ b/libraries/networking/src/AssetClient.h @@ -32,6 +32,7 @@ class SetMappingRequest; class GetAllMappingsRequest; class DeleteMappingsRequest; class RenameMappingRequest; +class SetBakingEnabledRequest; class AssetRequest; class AssetUpload; @@ -56,6 +57,7 @@ public: Q_INVOKABLE DeleteMappingsRequest* createDeleteMappingsRequest(const AssetPathList& paths); Q_INVOKABLE SetMappingRequest* createSetMappingRequest(const AssetPath& path, const AssetHash& hash); Q_INVOKABLE RenameMappingRequest* createRenameMappingRequest(const AssetPath& oldPath, const AssetPath& newPath); + Q_INVOKABLE SetBakingEnabledRequest* createSetBakingEnabledRequest(const AssetPathList& path, bool enabled); Q_INVOKABLE AssetRequest* createRequest(const AssetHash& hash, const ByteRange& byteRange = ByteRange()); Q_INVOKABLE AssetUpload* createUpload(const QString& filename); Q_INVOKABLE AssetUpload* createUpload(const QByteArray& data); @@ -81,6 +83,7 @@ private: MessageID setAssetMapping(const QString& path, const AssetHash& hash, MappingOperationCallback callback); MessageID deleteAssetMappings(const AssetPathList& paths, MappingOperationCallback callback); MessageID renameAssetMapping(const AssetPath& oldPath, const AssetPath& newPath, MappingOperationCallback callback); + MessageID setBakingEnabled(const AssetPathList& paths, bool enabled, MappingOperationCallback callback); MessageID getAssetInfo(const QString& hash, GetInfoCallback callback); MessageID getAsset(const QString& hash, DataOffset start, DataOffset end, @@ -119,6 +122,7 @@ private: friend class SetMappingRequest; friend class DeleteMappingsRequest; friend class RenameMappingRequest; + friend class SetBakingEnabledRequest; }; #endif diff --git a/libraries/networking/src/AssetUtils.cpp b/libraries/networking/src/AssetUtils.cpp index 7c8ffd6746..af085d6463 100644 --- a/libraries/networking/src/AssetUtils.cpp +++ b/libraries/networking/src/AssetUtils.cpp @@ -87,6 +87,8 @@ bool isValidHash(const AssetHash& hash) { QString bakingStatusToString(BakingStatus status) { switch (status) { + case Unrelevant: + return "--"; case NotBaked: return "Not Baked"; case Pending: @@ -95,5 +97,7 @@ QString bakingStatusToString(BakingStatus status) { return "Baking"; case Baked: return "Baked"; + case Error: + return "Error"; } } diff --git a/libraries/networking/src/AssetUtils.h b/libraries/networking/src/AssetUtils.h index 4b78d8aaaf..f8f0171a5d 100644 --- a/libraries/networking/src/AssetUtils.h +++ b/libraries/networking/src/AssetUtils.h @@ -48,14 +48,17 @@ enum AssetMappingOperationType : uint8_t { GetAll, Set, Delete, - Rename + Rename, + SetBakingEnabled }; enum BakingStatus { + Unrelevant, NotBaked, Pending, Baking, - Baked + Baked, + Error }; struct MappingInfo { diff --git a/libraries/networking/src/MappingRequest.cpp b/libraries/networking/src/MappingRequest.cpp index 5ad1a83d2e..258b7c6359 100644 --- a/libraries/networking/src/MappingRequest.cpp +++ b/libraries/networking/src/MappingRequest.cpp @@ -273,3 +273,46 @@ void RenameMappingRequest::doStart() { emit finished(this); }); } + +SetBakingEnabledRequest::SetBakingEnabledRequest(const AssetPathList& paths, bool enabled) : _paths(paths), _enabled(enabled) { + for (auto& path : _paths) { + path = path.trimmed(); + } +}; + +void SetBakingEnabledRequest::doStart() { + + // short circuit the request if any of the paths are invalid + for (auto& path : _paths) { + if (!isValidPath(path)) { + _error = MappingRequest::InvalidPath; + emit finished(this); + return; + } + } + + auto assetClient = DependencyManager::get(); + + _mappingRequestID = assetClient->setBakingEnabled(_paths, _enabled, + [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer message) { + + _mappingRequestID = INVALID_MESSAGE_ID; + if (!responseReceived) { + _error = NetworkError; + } else { + switch (error) { + case AssetServerError::NoError: + _error = NoError; + break; + case AssetServerError::PermissionDenied: + _error = PermissionDenied; + break; + default: + _error = UnknownError; + break; + } + } + + emit finished(this); + }); +}; \ No newline at end of file diff --git a/libraries/networking/src/MappingRequest.h b/libraries/networking/src/MappingRequest.h index 3875915721..fc43375469 100644 --- a/libraries/networking/src/MappingRequest.h +++ b/libraries/networking/src/MappingRequest.h @@ -133,5 +133,20 @@ private: AssetMapping _mappings; }; +class SetBakingEnabledRequest : public MappingRequest { + Q_OBJECT +public: + SetBakingEnabledRequest(const AssetPathList& path, bool enabled); + +signals: + void finished(SetBakingEnabledRequest* thisRequest); + +private: + virtual void doStart() override; + + AssetPathList _paths; + bool _enabled; +}; + #endif // hifi_MappingRequest_h diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index f453d096b6..74d3c46eb3 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -67,7 +67,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::MicrophoneAudioWithEcho: case PacketType::AudioStreamStats: return static_cast(AudioVersion::HighDynamicRangeVolume); - + case PacketType::AssetMappingOperation: + case PacketType::AssetMappingOperationReply: + return static_cast(AssetMappingOperationVersion::SetBakingEnabledOperation); default: return 17; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 6b57c8a3cb..d71470383b 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -336,4 +336,8 @@ enum class MessageDataVersion : PacketVersion { TextOrBinaryData = 18 }; +enum class AssetMappingOperationVersion : PacketVersion { + SetBakingEnabledOperation = 18 +}; + #endif // hifi_PacketHeaders_h diff --git a/libraries/script-engine/src/AssetScriptingInterface.cpp b/libraries/script-engine/src/AssetScriptingInterface.cpp index 51b3d7ffbe..25e8c0dcf3 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.cpp +++ b/libraries/script-engine/src/AssetScriptingInterface.cpp @@ -88,6 +88,20 @@ void AssetScriptingInterface::downloadData(QString urlString, QScriptValue callb assetRequest->start(); } +void AssetScriptingInterface::setBakingEnabled(QString path, bool enabled, QScriptValue callback) { + auto setBakingEnabledRequest = DependencyManager::get()->createSetBakingEnabledRequest({ path }, enabled); + + QObject::connect(setBakingEnabledRequest, &SetBakingEnabledRequest::finished, this, [this, callback](SetBakingEnabledRequest* request) mutable { + if (callback.isFunction()) { + QString error = request->getErrorString(); + QScriptValueList args{ error }; + callback.call(_engine->currentContext()->thisObject(), args); + } + request->deleteLater(); + }); + setBakingEnabledRequest->start(); +} + #if (PR_BUILD || DEV_BUILD) void AssetScriptingInterface::sendFakedHandshake() { auto nodeList = DependencyManager::get(); diff --git a/libraries/script-engine/src/AssetScriptingInterface.h b/libraries/script-engine/src/AssetScriptingInterface.h index 0238329b73..2812be65f9 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.h +++ b/libraries/script-engine/src/AssetScriptingInterface.h @@ -75,6 +75,8 @@ public: * @param {string} error */ Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback); + + Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback); #if (PR_BUILD || DEV_BUILD) Q_INVOKABLE void sendFakedHandshake();