From 162573bc634c722650c58827269ed0f4d800d638 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 20 Feb 2019 16:50:26 -0800 Subject: [PATCH] enable js baking from non-local file --- libraries/baking/src/JSBaker.cpp | 78 ++++++++++++++++++++++---- libraries/baking/src/JSBaker.h | 12 +++- tools/oven/src/DomainBaker.cpp | 11 ++-- tools/oven/src/DomainBaker.h | 3 +- tools/oven/src/ui/DomainBakeWidget.cpp | 7 +-- tools/oven/src/ui/DomainBakeWidget.h | 1 - 6 files changed, 87 insertions(+), 25 deletions(-) diff --git a/libraries/baking/src/JSBaker.cpp b/libraries/baking/src/JSBaker.cpp index b19336f4ca..82d482967b 100644 --- a/libraries/baking/src/JSBaker.cpp +++ b/libraries/baking/src/JSBaker.cpp @@ -11,9 +11,11 @@ #include "JSBaker.h" -#include +#include -#include "Baker.h" +#include +#include +#include const int ASCII_CHARACTERS_UPPER_LIMIT = 126; @@ -21,25 +23,79 @@ JSBaker::JSBaker(const QUrl& jsURL, const QString& bakedOutputDir) : _jsURL(jsURL), _bakedOutputDir(bakedOutputDir) { - } void JSBaker::bake() { qCDebug(js_baking) << "JS Baker " << _jsURL << "bake starting"; - // Import file to start baking - QFile jsFile(_jsURL.toLocalFile()); - if (!jsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - handleError("Error opening " + _jsURL.fileName() + " for reading"); - return; - } + // once our texture is loaded, kick off a the processing + connect(this, &JSBaker::originalScriptLoaded, this, &JSBaker::processScript); + if (_jsURL.isEmpty()) { + // first load the texture (either locally or remotely) + loadScript(); + } else { + // we already have a texture passed to us, use that + emit originalScriptLoaded(); + } +} + +void JSBaker::loadScript() { + // check if the texture is local or first needs to be downloaded + if (_jsURL.isLocalFile()) { + // load up the local file + QFile localScript(_jsURL.toLocalFile()); + if (!localScript.open(QIODevice::ReadOnly | QIODevice::Text)) { + handleError("Error opening " + _jsURL.fileName() + " for reading"); + return; + } + + _originalScript = localScript.readAll(); + + emit originalScriptLoaded(); + } else { + // remote file, kick off a download + auto& networkAccessManager = NetworkAccessManager::getInstance(); + + QNetworkRequest networkRequest; + + // setup the request to follow re-directs and always hit the network + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); + + networkRequest.setUrl(_jsURL); + + qCDebug(js_baking) << "Downloading" << _jsURL; + + // kickoff the download, wait for slot to tell us it is done + auto networkReply = networkAccessManager.get(networkRequest); + connect(networkReply, &QNetworkReply::finished, this, &JSBaker::handleScriptNetworkReply); + } +} + +void JSBaker::handleScriptNetworkReply() { + auto requestReply = qobject_cast(sender()); + + if (requestReply->error() == QNetworkReply::NoError) { + qCDebug(js_baking) << "Downloaded texture" << _jsURL; + + // store the original texture so it can be passed along for the bake + _originalScript = requestReply->readAll(); + + emit originalScriptLoaded(); + } else { + // add an error to our list stating that this texture could not be downloaded + handleError("Error downloading " + _jsURL.toString() + " - " + requestReply->errorString()); + } +} + +void JSBaker::processScript() { // Read file into an array - QByteArray inputJS = jsFile.readAll(); QByteArray outputJS; // Call baking on inputJS and store result in outputJS - bool success = bakeJS(inputJS, outputJS); + bool success = bakeJS(_originalScript, outputJS); if (!success) { qCDebug(js_baking) << "Bake Failed"; handleError("Unterminated multi-line comment"); diff --git a/libraries/baking/src/JSBaker.h b/libraries/baking/src/JSBaker.h index 764681c71e..7eda85fa6d 100644 --- a/libraries/baking/src/JSBaker.h +++ b/libraries/baking/src/JSBaker.h @@ -25,14 +25,24 @@ public: JSBaker(const QUrl& jsURL, const QString& bakedOutputDir); static bool bakeJS(const QByteArray& inputFile, QByteArray& outputFile); - QString getJSPath() const { return _jsURL.fileName(); } + QString getJSPath() const { return _jsURL.toDisplayString(); } QString getBakedJSFilePath() const { return _bakedJSFilePath; } public slots: virtual void bake() override; +signals: + void originalScriptLoaded(); + +private slots: + void processScript(); + private: + void loadScript(); + void handleScriptNetworkReply(); + QUrl _jsURL; + QByteArray _originalScript; QString _bakedOutputDir; QString _bakedJSFilePath; diff --git a/tools/oven/src/DomainBaker.cpp b/tools/oven/src/DomainBaker.cpp index 3c2f1d77bb..6f94b455d9 100644 --- a/tools/oven/src/DomainBaker.cpp +++ b/tools/oven/src/DomainBaker.cpp @@ -23,8 +23,7 @@ #include "baking/BakerLibrary.h" DomainBaker::DomainBaker(const QUrl& localModelFileURL, const QString& domainName, - const QString& baseOutputPath, const QUrl& destinationPath, - bool shouldRebakeOriginals) : + const QString& baseOutputPath, const QUrl& destinationPath) : _localEntitiesFileURL(localModelFileURL), _domainName(domainName), _baseOutputPath(baseOutputPath) @@ -178,7 +177,8 @@ void DomainBaker::addModelBaker(const QString& property, const QString& url, QJs } void DomainBaker::addTextureBaker(const QString& property, const QString& url, image::TextureUsage::Type type, QJsonValueRef& jsonRef) { - auto idx = url.lastIndexOf('.'); + QString cleanURL = QUrl(url).adjusted(QUrl::RemoveQuery | QUrl::RemoveFragment).toDisplayString(); + auto idx = cleanURL.lastIndexOf('.'); auto extension = idx >= 0 ? url.mid(idx + 1).toLower() : ""; if (QImageReader::supportedImageFormats().contains(extension.toLatin1())) { @@ -211,6 +211,8 @@ void DomainBaker::addTextureBaker(const QString& property, const QString& url, i // add this QJsonValueRef to our multi hash so that it can re-write the texture URL // to the baked version once the baker is complete _entitiesNeedingRewrite.insert(textureURL, { property, jsonRef }); + } else { + qDebug() << "Texture extension not supported: " << extension; } } @@ -551,6 +553,7 @@ void DomainBaker::handleFinishedScriptBaker() { } // remove the baked URL from the multi hash of entities needing a re-write + _entitiesNeedingRewrite.remove(baker->getJSPath()); // drop our shared pointer to this baker so that it gets cleaned up @@ -611,5 +614,5 @@ void DomainBaker::writeNewEntitiesFile() { return; } - qDebug() << "Exported entities file with baked model URLs to" << bakedEntitiesFilePath; + qDebug() << "Exported baked entities file to" << bakedEntitiesFilePath; } diff --git a/tools/oven/src/DomainBaker.h b/tools/oven/src/DomainBaker.h index 2a5abb4ca6..2a9522143e 100644 --- a/tools/oven/src/DomainBaker.h +++ b/tools/oven/src/DomainBaker.h @@ -29,8 +29,7 @@ public: // This means that we need to put all of the FBX importing/exporting from the same process on the same thread. // That means you must pass a usable running QThread when constructing a domain baker. DomainBaker(const QUrl& localEntitiesFileURL, const QString& domainName, - const QString& baseOutputPath, const QUrl& destinationPath, - bool shouldRebakeOriginals = false); + const QString& baseOutputPath, const QUrl& destinationPath); signals: void allModelsFinished(); diff --git a/tools/oven/src/ui/DomainBakeWidget.cpp b/tools/oven/src/ui/DomainBakeWidget.cpp index 1121041e39..23074e775e 100644 --- a/tools/oven/src/ui/DomainBakeWidget.cpp +++ b/tools/oven/src/ui/DomainBakeWidget.cpp @@ -126,10 +126,6 @@ void DomainBakeWidget::setupUI() { // start a new row for the next component ++rowIndex; - // setup a checkbox to allow re-baking of original assets - _rebakeOriginalsCheckBox = new QCheckBox("Re-bake originals"); - gridLayout->addWidget(_rebakeOriginalsCheckBox, rowIndex, 0); - // add a button that will kickoff the bake QPushButton* bakeButton = new QPushButton("Bake"); connect(bakeButton, &QPushButton::clicked, this, &DomainBakeWidget::bakeButtonClicked); @@ -211,8 +207,7 @@ void DomainBakeWidget::bakeButtonClicked() { auto fileToBakeURL = QUrl::fromLocalFile(_entitiesFileLineEdit->text()); auto domainBaker = std::unique_ptr { new DomainBaker(fileToBakeURL, _domainNameLineEdit->text(), - outputDirectory.absolutePath(), _destinationPathLineEdit->text(), - _rebakeOriginalsCheckBox->isChecked()) + outputDirectory.absolutePath(), _destinationPathLineEdit->text()) }; // make sure we hear from the baker when it is done diff --git a/tools/oven/src/ui/DomainBakeWidget.h b/tools/oven/src/ui/DomainBakeWidget.h index a6f26b3731..0a1d613912 100644 --- a/tools/oven/src/ui/DomainBakeWidget.h +++ b/tools/oven/src/ui/DomainBakeWidget.h @@ -45,7 +45,6 @@ private: QLineEdit* _entitiesFileLineEdit; QLineEdit* _outputDirLineEdit; QLineEdit* _destinationPathLineEdit; - QCheckBox* _rebakeOriginalsCheckBox; Setting::Handle _domainNameSetting; Setting::Handle _exportDirectory;