From f900a81e7ad282dbad5c7fcfd1be58f081a04826 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 14 Nov 2018 15:33:40 -0800 Subject: [PATCH 01/35] Add ModelLoader --- .../src/model-networking/ModelLoader.cpp | 52 +++++++++++ .../src/model-networking/ModelLoader.h | 87 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 libraries/model-networking/src/model-networking/ModelLoader.cpp create mode 100644 libraries/model-networking/src/model-networking/ModelLoader.h diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp new file mode 100644 index 0000000000..3eb1bec9f0 --- /dev/null +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -0,0 +1,52 @@ +// +// ModelLoader.cpp +// libraries/model-networking/src/model-networking +// +// Created by Sabrina Shanman on 2018/11/14. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ModelLoader.h" + +hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { + // Check file contents + for (auto& supportedFormat : supportedFormats) { + for (auto& fileSignature : supportedFormat.mimeType.fileSignatures) { + auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString(); + if (testBytes == fileSignature.bytes) { + return supportedFormat.loader(data, mapping, url); + } + } + } + + // Check file extension + std::string urlString = url.path().toStdString(); + std::size_t extensionSeparator = urlString.rfind('.'); + if (extensionSeparator != std::string::npos) { + std::string detectedExtension = urlString.substr(extensionSeparator + 1); + for (auto& supportedFormat : supportedFormats) { + for (auto& extension : supportedFormat.mimeType.extensions) { + if (extension == detectedExtension) { + return supportedFormat.loader(data, mapping, url); + } + } + } + } + + // Check web media type + if (webMediaType != "") { + for (auto& supportedFormat : supportedFormats) { + for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) { + if (candidateWebMediaType == webMediaType) { + return supportedFormat.loader(data, mapping, url); + } + } + } + } + + // Supported file type not found. Abort loading. + return hfm::Model::Pointer(); +} diff --git a/libraries/model-networking/src/model-networking/ModelLoader.h b/libraries/model-networking/src/model-networking/ModelLoader.h new file mode 100644 index 0000000000..1a8901e8da --- /dev/null +++ b/libraries/model-networking/src/model-networking/ModelLoader.h @@ -0,0 +1,87 @@ +// +// ModelLoader.h +// libraries/model-networking/src/model-networking +// +// Created by Sabrina Shanman on 2018/11/13. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ModelLoader_h +#define hifi_ModelLoader_h + +#include +#include +#include + +#include +#include + +class ModelLoader { +public: + + // A short sequence of bytes, typically at the beginning of the file, which identifies the file format + class FileSignature { + public: + FileSignature(const std::string& bytes, int byteOffset) : + bytes(bytes), + byteOffset(byteOffset) { + } + + std::string bytes; + int byteOffset; + }; + + // A named file extension with a list of known ways to positively identify the file type + class MIMEType { + public: + MIMEType(const std::string& name) : + name(name) { + } + + std::string name; + std::vector extensions; + std::vector webMediaTypes; + std::vector fileSignatures; + }; + + // T is a subclass of hfm::Serializer + template + void addSupportedFormat(const MIMEType& mimeType) { + supportedFormats.push_back(SupportedFormat(mimeType, SupportedFormat::getLoader())); + } + + // Given the currently stored list of supported file formats, determine how to load a model from the given parameters. + // If successful, return an owned reference to the newly loaded model. + // If failed, return an empty reference. + hfm::Model::Pointer load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; + +protected: + using Loader = std::function; + + class SupportedFormat { + public: + SupportedFormat(const MIMEType& mimeType, const Loader& loader) : + mimeType(mimeType), + loader(loader) { + } + + MIMEType mimeType; + Loader loader; + + template + static Loader getLoader() { + assert(dynamic_cast(&T())); + + return [](const hifi::ByteArray& bytes, const hifi::VariantHash& mapping, const hifi::URL& url) -> hfm::Model::Pointer { + return T().read(bytes, mapping, url); + }; + } + }; + + std::vector supportedFormats; +}; + +#endif // hifi_ModelLoader_h From fc0a31fa0de40879235a8c828598750acda25a06 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 14 Nov 2018 17:21:47 -0800 Subject: [PATCH 02/35] Define ModelLoader instance in ModelCache --- .../src/model-networking/ModelCache.cpp | 16 ++++++++++++++++ .../src/model-networking/ModelCache.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 254f61eba9..53a0ec14a1 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -316,6 +316,22 @@ ModelCache::ModelCache() { const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE; setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE); setObjectName("ModelCache"); + + // Add supported model formats + + ModelLoader::MIMEType fbxMIMEType("fbx"); + fbxMIMEType.extensions.push_back("fbx"); + fbxMIMEType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); + _modelLoader.addSupportedFormat(fbxMIMEType); + + ModelLoader::MIMEType objMIMEType("obj"); + objMIMEType.extensions.push_back("obj"); + _modelLoader.addSupportedFormat(objMIMEType); + + ModelLoader::MIMEType gltfMIMEType("gltf"); + gltfMIMEType.extensions.push_back("gltf"); + gltfMIMEType.webMediaTypes.push_back("model/gltf+json"); + _modelLoader.addSupportedFormat(gltfMIMEType); } QSharedPointer ModelCache::createResource(const QUrl& url, const QSharedPointer& fallback, diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 9d458e7512..1018bdecd5 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -20,6 +20,7 @@ #include "FBXSerializer.h" #include "TextureCache.h" +#include "ModelLoader.h" // Alias instead of derive to avoid copying @@ -158,6 +159,7 @@ protected: private: ModelCache(); virtual ~ModelCache() = default; + ModelLoader _modelLoader; }; class NetworkMaterial : public graphics::Material { From 2387641cbbbb8b264c752a73e98bc97606c996d7 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 15 Nov 2018 14:52:27 -0800 Subject: [PATCH 03/35] Store the MIME type in HTTPResourceRequest::onRequestFinished() --- .../networking/src/HTTPResourceRequest.cpp | 21 ++++++++++++++++++- libraries/networking/src/ResourceRequest.h | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/HTTPResourceRequest.cpp b/libraries/networking/src/HTTPResourceRequest.cpp index e26f27adcf..50221a136a 100644 --- a/libraries/networking/src/HTTPResourceRequest.cpp +++ b/libraries/networking/src/HTTPResourceRequest.cpp @@ -94,7 +94,7 @@ void HTTPResourceRequest::onRequestFinished() { // Content-Range: -/* // Content-Range: */ // - auto parseContentRangeHeader = [](QString contentRangeHeader) -> std::pair { + static auto parseContentRangeHeader = [](QString contentRangeHeader) -> std::pair { auto unitRangeParts = contentRangeHeader.split(' '); if (unitRangeParts.size() != 2) { return { false, 0 }; @@ -115,6 +115,15 @@ void HTTPResourceRequest::onRequestFinished() { } }; + static auto parseMediaType = [](QString contentTypeHeader) -> std::pair { + auto contentTypeParts = contentTypeHeader.split(';'); + if (contentTypeParts.size() < 1) { + return { false, "" }; + } + + return { true, contentTypeParts[0] }; + }; + switch(_reply->error()) { case QNetworkReply::NoError: _data = _reply->readAll(); @@ -141,6 +150,16 @@ void HTTPResourceRequest::onRequestFinished() { } } + { + auto contentTypeHeader = _reply->rawHeader("Content-Type"); + bool success; + QString mediaType; + std::tie(success, mediaType) = parseMediaType(contentTypeHeader); + if (success) { + _webMediaType = mediaType; + } + } + recordBytesDownloadedInStats(STAT_HTTP_RESOURCE_TOTAL_BYTES, _data.size()); break; diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index eb306ca5be..550294d79b 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -84,6 +84,7 @@ public: bool loadedFromCache() const { return _loadedFromCache; } bool getRangeRequestSuccessful() const { return _rangeRequestSuccessful; } bool getTotalSizeOfResource() const { return _totalSizeOfResource; } + QString getWebMediaType() const { return _webMediaType; } void setFailOnRedirect(bool failOnRedirect) { _failOnRedirect = failOnRedirect; } void setCacheEnabled(bool value) { _cacheEnabled = value; } @@ -111,6 +112,7 @@ protected: ByteRange _byteRange; bool _rangeRequestSuccessful { false }; uint64_t _totalSizeOfResource { 0 }; + QString _webMediaType; int64_t _lastRecordedBytesDownloaded { 0 }; bool _isObservable; qint64 _callerId; From b3d5f2fa65689c9155259feeb5cedbba67ca51ea Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 15 Nov 2018 17:25:05 -0800 Subject: [PATCH 04/35] Add MIME type-based Serializer selection --- .../src/model-networking/ModelCache.cpp | 115 +++++++++--------- 1 file changed, 55 insertions(+), 60 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 53a0ec14a1..81188031e1 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -144,9 +144,9 @@ void GeometryMappingResource::onGeometryMappingLoaded(bool success) { class GeometryReader : public QRunnable { public: - GeometryReader(QWeakPointer& resource, const QUrl& url, const QVariantHash& mapping, - const QByteArray& data, bool combineParts) : - _resource(resource), _url(url), _mapping(mapping), _data(data), _combineParts(combineParts) { + GeometryReader(const ModelLoader& modelLoader, QWeakPointer& resource, const QUrl& url, const QVariantHash& mapping, + const QByteArray& data, bool combineParts, const QString& webMediaType) : + _modelLoader(modelLoader), _resource(resource), _url(url), _mapping(mapping), _data(data), _combineParts(combineParts), _webMediaType(webMediaType) { DependencyManager::get()->incrementStat("PendingProcessing"); } @@ -154,11 +154,13 @@ public: virtual void run() override; private: + ModelLoader _modelLoader; QWeakPointer _resource; QUrl _url; QVariantHash _mapping; QByteArray _data; bool _combineParts; + QString _webMediaType; }; void GeometryReader::run() { @@ -183,62 +185,54 @@ void GeometryReader::run() { throw QString("reply is NULL"); } + // Ensure the resource has not been deleted + auto resource = _resource.toStrongRef(); + if (!resource) { + qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref"; + return; + } + QString urlname = _url.path().toLower(); - if (!urlname.isEmpty() && !_url.path().isEmpty() && - - (_url.path().toLower().endsWith(".fbx") || - _url.path().toLower().endsWith(".obj") || - _url.path().toLower().endsWith(".obj.gz") || - _url.path().toLower().endsWith(".gltf"))) { - - HFMModel::Pointer hfmModel; - - QVariantHash serializerMapping = _mapping; - serializerMapping["combineParts"] = _combineParts; - - if (_url.path().toLower().endsWith(".fbx")) { - hfmModel = FBXSerializer().read(_data, serializerMapping, _url); - if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { - throw QString("empty geometry, possibly due to an unsupported FBX version"); - } - } else if (_url.path().toLower().endsWith(".obj")) { - hfmModel = OBJSerializer().read(_data, serializerMapping, _url); - } else if (_url.path().toLower().endsWith(".obj.gz")) { - QByteArray uncompressedData; - if (gunzip(_data, uncompressedData)){ - hfmModel = OBJSerializer().read(uncompressedData, serializerMapping, _url); - } else { - throw QString("failed to decompress .obj.gz"); - } - - } else if (_url.path().toLower().endsWith(".gltf")) { - hfmModel = GLTFSerializer().read(_data, serializerMapping, _url); - if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { - throw QString("empty geometry, possibly due to an unsupported GLTF version"); - } - } else { - throw QString("unsupported format"); - } - - // Add scripts to hfmModel - if (!_mapping.value(SCRIPT_FIELD).isNull()) { - QVariantList scripts = _mapping.values(SCRIPT_FIELD); - for (auto &script : scripts) { - hfmModel->scripts.push_back(script.toString()); - } - } - - // Ensure the resource has not been deleted - auto resource = _resource.toStrongRef(); - if (!resource) { - qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref"; - } else { - QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition", - Q_ARG(HFMModel::Pointer, hfmModel)); - } - } else { + if (urlname.isEmpty() || _url.path().isEmpty()) { throw QString("url is invalid"); } + + HFMModel::Pointer hfmModel; + QVariantHash serializerMapping = _mapping; + serializerMapping["combineParts"] = _combineParts; + + if (_url.path().toLower().endsWith(".gz")) { + QByteArray uncompressedData; + if (!gunzip(_data, uncompressedData)) { + throw QString("failed to decompress .gz model"); + } + // Strip the compression extension from the path, so the loader can infer the file type from what remains. + // This is okay because we don't expect the serializer to be able to read the contents of a compressed model file. + auto strippedUrl = _url; + strippedUrl.setPath(_url.path().left(_url.path().size() - 3)); + hfmModel = _modelLoader.load(uncompressedData, serializerMapping, strippedUrl, ""); + } else { + hfmModel = _modelLoader.load(_data, serializerMapping, _url, _webMediaType.toStdString()); + } + + if (!hfmModel) { + throw QString("unsupported format"); + } + + if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { + throw QString("empty geometry, possibly due to an unsupported model version"); + } + + // Add scripts to hfmModel + if (!_mapping.value(SCRIPT_FIELD).isNull()) { + QVariantList scripts = _mapping.values(SCRIPT_FIELD); + for (auto &script : scripts) { + hfmModel->scripts.push_back(script.toString()); + } + } + + QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition", + Q_ARG(HFMModel::Pointer, hfmModel)); } catch (const std::exception&) { auto resource = _resource.toStrongRef(); if (resource) { @@ -258,8 +252,8 @@ void GeometryReader::run() { class GeometryDefinitionResource : public GeometryResource { Q_OBJECT public: - GeometryDefinitionResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl, bool combineParts) : - GeometryResource(url, resolveTextureBaseUrl(url, textureBaseUrl)), _mapping(mapping), _combineParts(combineParts) {} + GeometryDefinitionResource(const ModelLoader& modelLoader, const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl, bool combineParts) : + GeometryResource(url, resolveTextureBaseUrl(url, textureBaseUrl)), _modelLoader(modelLoader), _mapping(mapping), _combineParts(combineParts) {} QString getType() const override { return "GeometryDefinition"; } @@ -269,6 +263,7 @@ protected: Q_INVOKABLE void setGeometryDefinition(HFMModel::Pointer hfmModel); private: + ModelLoader _modelLoader; QVariantHash _mapping; bool _combineParts; }; @@ -278,7 +273,7 @@ void GeometryDefinitionResource::downloadFinished(const QByteArray& data) { _url = _effectiveBaseURL; _textureBaseUrl = _effectiveBaseURL; } - QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts)); + QThreadPool::globalInstance()->start(new GeometryReader(_modelLoader, _self, _effectiveBaseURL, _mapping, data, _combineParts, _request->getWebMediaType())); } void GeometryDefinitionResource::setGeometryDefinition(HFMModel::Pointer hfmModel) { @@ -344,7 +339,7 @@ QSharedPointer ModelCache::createResource(const QUrl& url, const QShar auto mapping = geometryExtra ? geometryExtra->mapping : QVariantHash(); auto textureBaseUrl = geometryExtra ? geometryExtra->textureBaseUrl : QUrl(); bool combineParts = geometryExtra ? geometryExtra->combineParts : true; - resource = new GeometryDefinitionResource(url, mapping, textureBaseUrl, combineParts); + resource = new GeometryDefinitionResource(_modelLoader, url, mapping, textureBaseUrl, combineParts); } return QSharedPointer(resource, &Resource::deleter); From 98853b5d1d97d9c3f1d31db581dd8d93251c5f91 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 26 Nov 2018 14:31:57 -0800 Subject: [PATCH 05/35] Move FBXSerializer import by AnimationCache to source file --- libraries/animation/src/AnimationCache.cpp | 1 + libraries/animation/src/AnimationCache.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index ec26782d0e..f7a7dd861a 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -20,6 +20,7 @@ #include #include "AnimationLogging.h" +#include int animationPointerMetaTypeId = qRegisterMetaType(); diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index d4574d9d3b..2f8168625e 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -17,7 +17,7 @@ #include #include -#include +#include #include class Animation; From d1f8bfe48bee695b70cb25ef8fccbd5089dc9dda Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 26 Nov 2018 17:45:55 -0800 Subject: [PATCH 06/35] Move definition of supported file types into ModelLoader --- .../src/model-networking/ModelCache.cpp | 19 ---------------- .../src/model-networking/ModelLoader.cpp | 22 +++++++++++++++++++ .../src/model-networking/ModelLoader.h | 2 ++ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 81188031e1..22835de59d 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -12,9 +12,6 @@ #include "ModelCache.h" #include #include -#include "FBXSerializer.h" -#include "OBJSerializer.h" -#include "GLTFSerializer.h" #include #include @@ -311,22 +308,6 @@ ModelCache::ModelCache() { const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE; setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE); setObjectName("ModelCache"); - - // Add supported model formats - - ModelLoader::MIMEType fbxMIMEType("fbx"); - fbxMIMEType.extensions.push_back("fbx"); - fbxMIMEType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); - _modelLoader.addSupportedFormat(fbxMIMEType); - - ModelLoader::MIMEType objMIMEType("obj"); - objMIMEType.extensions.push_back("obj"); - _modelLoader.addSupportedFormat(objMIMEType); - - ModelLoader::MIMEType gltfMIMEType("gltf"); - gltfMIMEType.extensions.push_back("gltf"); - gltfMIMEType.webMediaTypes.push_back("model/gltf+json"); - _modelLoader.addSupportedFormat(gltfMIMEType); } QSharedPointer ModelCache::createResource(const QUrl& url, const QSharedPointer& fallback, diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp index 3eb1bec9f0..04384acd39 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.cpp +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -11,6 +11,28 @@ #include "ModelLoader.h" +#include "FBXSerializer.h" +#include "OBJSerializer.h" +#include "GLTFSerializer.h" + +ModelLoader::ModelLoader() { + // Add supported model formats + + MIMEType fbxMIMEType("fbx"); + fbxMIMEType.extensions.push_back("fbx"); + fbxMIMEType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); + addSupportedFormat(fbxMIMEType); + + MIMEType objMIMEType("obj"); + objMIMEType.extensions.push_back("obj"); + addSupportedFormat(objMIMEType); + + MIMEType gltfMIMEType("gltf"); + gltfMIMEType.extensions.push_back("gltf"); + gltfMIMEType.webMediaTypes.push_back("model/gltf+json"); + addSupportedFormat(gltfMIMEType); +} + hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { // Check file contents for (auto& supportedFormat : supportedFormats) { diff --git a/libraries/model-networking/src/model-networking/ModelLoader.h b/libraries/model-networking/src/model-networking/ModelLoader.h index 1a8901e8da..2cd5460f84 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.h +++ b/libraries/model-networking/src/model-networking/ModelLoader.h @@ -47,6 +47,8 @@ public: std::vector fileSignatures; }; + ModelLoader(); + // T is a subclass of hfm::Serializer template void addSupportedFormat(const MIMEType& mimeType) { From fd83ae231b752ca1c30108555812a1d0b2f80609 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Tue, 27 Nov 2018 09:49:55 -0800 Subject: [PATCH 07/35] Fix case for ModelLoader import --- libraries/model-networking/src/model-networking/ModelLoader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelLoader.h b/libraries/model-networking/src/model-networking/ModelLoader.h index 2cd5460f84..92d93a040e 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.h +++ b/libraries/model-networking/src/model-networking/ModelLoader.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include class ModelLoader { From df1083970f00e50e7aee8e4b269b16371c7e8ce9 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Tue, 27 Nov 2018 10:24:45 -0800 Subject: [PATCH 08/35] Fix assert in ModelLoader.h --- .../model-networking/src/model-networking/ModelLoader.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelLoader.h b/libraries/model-networking/src/model-networking/ModelLoader.h index 92d93a040e..0deb339f15 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.h +++ b/libraries/model-networking/src/model-networking/ModelLoader.h @@ -18,6 +18,7 @@ #include #include +#include class ModelLoader { public: @@ -75,7 +76,10 @@ protected: template static Loader getLoader() { - assert(dynamic_cast(&T())); + assert([](){ + T t; + return dynamic_cast(&t) != nullptr; + }()); return [](const hifi::ByteArray& bytes, const hifi::VariantHash& mapping, const hifi::URL& url) -> hfm::Model::Pointer { return T().read(bytes, mapping, url); From 2919097f29719a5ad72211d395344ff53e43cadc Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 28 Nov 2018 15:56:56 -0800 Subject: [PATCH 09/35] Complain about empty HFMModel when EITHER meshes or joints are empty --- libraries/model-networking/src/model-networking/ModelCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 22835de59d..8dc483e43b 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -216,7 +216,7 @@ void GeometryReader::run() { throw QString("unsupported format"); } - if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) { + if (hfmModel->meshes.empty() || hfmModel->joints.empty()) { throw QString("empty geometry, possibly due to an unsupported model version"); } From 142e787a9cdc585453e38eda26da7388ecfbec7f Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 29 Nov 2018 16:46:08 -0800 Subject: [PATCH 10/35] Create MIMETypeLibrary for general MIME type detection --- .../shared/src/shared/MIMETypeLibrary.cpp | 85 +++++++++++++++++ libraries/shared/src/shared/MIMETypeLibrary.h | 91 +++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 libraries/shared/src/shared/MIMETypeLibrary.cpp create mode 100644 libraries/shared/src/shared/MIMETypeLibrary.h diff --git a/libraries/shared/src/shared/MIMETypeLibrary.cpp b/libraries/shared/src/shared/MIMETypeLibrary.cpp new file mode 100644 index 0000000000..4f12f373fe --- /dev/null +++ b/libraries/shared/src/shared/MIMETypeLibrary.cpp @@ -0,0 +1,85 @@ +// +// MIMETypeLibrary.cpp +// libraries/shared/src/shared +// +// Created by Sabrina Shanman on 2018/11/29. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "MIMETypeLibrary.h" + +MIMETypeLibrary::ID MIMETypeLibrary::registerMIMEType(const MIMEType& mimeType) { + ID id; + withWriteLock([&](){ + id = nextID++; + _mimeTypes.emplace_back(id, mimeType); + }); + return id; +} + +void MIMETypeLibrary::unregisterMIMEType(const MIMETypeLibrary::ID& id) { + withWriteLock([&](){ + for (auto it = _mimeTypes.begin(); it != _mimeTypes.end(); it++) { + if ((*it).id == id) { + _mimeTypes.erase(it); + break; + } + } + }); +} + +MIMEType MIMETypeLibrary::getMIMEType(const MIMETypeLibrary::ID& id) const { + return resultWithReadLock([&](){ + for (auto& supportedFormat : _mimeTypes) { + if (supportedFormat.id == id) { + return supportedFormat.mimeType; + } + } + return MIMEType::NONE; + }); +} + +MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { + return resultWithReadLock([&](){ + // Check file contents + for (auto& mimeType : _mimeTypes) { + for (auto& fileSignature : mimeType.mimeType.fileSignatures) { + auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString(); + if (testBytes == fileSignature.bytes) { + return mimeType.id; + } + } + } + + // Check file extension + std::string urlString = url.path().toStdString(); + std::size_t extensionSeparator = urlString.rfind('.'); + if (extensionSeparator != std::string::npos) { + std::string detectedExtension = urlString.substr(extensionSeparator + 1); + for (auto& supportedFormat : _mimeTypes) { + for (auto& extension : supportedFormat.mimeType.extensions) { + if (extension == detectedExtension) { + return supportedFormat.id; + } + } + } + } + + // Check web media type + if (webMediaType != "") { + for (auto& supportedFormat : _mimeTypes) { + for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) { + if (candidateWebMediaType == webMediaType) { + return supportedFormat.id; + } + } + } + } + + // Supported file type not found. + return INVALID_ID; + }); +} diff --git a/libraries/shared/src/shared/MIMETypeLibrary.h b/libraries/shared/src/shared/MIMETypeLibrary.h new file mode 100644 index 0000000000..62bc28cdad --- /dev/null +++ b/libraries/shared/src/shared/MIMETypeLibrary.h @@ -0,0 +1,91 @@ +// +// MIMETypeLibrary.h +// libraries/shared/src/shared +// +// Created by Sabrina Shanman on 2018/11/28. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_MIMETypeLibrary_h +#define hifi_MIMETypeLibrary_h + +#include +#include +#include +#include + +#include "HifiTypes.h" + +#include "ReadWriteLockable.h" + +// A short sequence of bytes, typically at the beginning of the file, which identifies the file format +class FileSignature { +public: + FileSignature(const std::string& bytes, int byteOffset) : + bytes(bytes), + byteOffset(byteOffset) { + } + FileSignature(const FileSignature& fileSignature) : + bytes(fileSignature.bytes), + byteOffset(fileSignature.byteOffset) { + } + + std::string bytes; + int byteOffset; +}; + +// A named file extension with a list of known ways to positively identify the file type +class MIMEType { +public: + MIMEType(const std::string& name) : + name(name) { + } + MIMEType() {}; + MIMEType(const MIMEType& mimeType) : + name(mimeType.name), + extensions(mimeType.extensions), + webMediaTypes(mimeType.webMediaTypes), + fileSignatures(mimeType.fileSignatures) { + } + + static MIMEType NONE; + + std::string name; + std::vector extensions; + std::vector webMediaTypes; + std::vector fileSignatures; +}; + +MIMEType MIMEType::NONE = MIMEType(""); + +class MIMETypeLibrary : ReadWriteLockable { +public: + using ID = unsigned int; + static const ID INVALID_ID { 0 }; + + ID registerMIMEType(const MIMEType& mimeType); + void unregisterMIMEType(const ID& id); + + MIMEType getMIMEType(const ID& id) const; + ID findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; + +protected: + ID nextID { 1 }; + + class Entry { + public: + Entry(const ID& id, const MIMEType& mimeType) : + id(id), + mimeType(mimeType) { + } + ID id; + MIMEType mimeType; + }; + + std::vector _mimeTypes; +}; + +#endif // hifi_MIMETypeLibrary_h From d1ac50196742e3a58152258373483b922798b58e Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 29 Nov 2018 16:51:56 -0800 Subject: [PATCH 11/35] Create hfm::FormatRegistry, for more general model format definition --- libraries/hfm/src/hfm/HFMFormat.h | 25 ++++++++++ libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 52 +++++++++++++++++++++ libraries/hfm/src/hfm/HFMFormatRegistry.h | 48 +++++++++++++++++++ libraries/hfm/src/hfm/HFMSerializer.h | 6 +++ 4 files changed, 131 insertions(+) create mode 100644 libraries/hfm/src/hfm/HFMFormat.h create mode 100644 libraries/hfm/src/hfm/HFMFormatRegistry.cpp create mode 100644 libraries/hfm/src/hfm/HFMFormatRegistry.h diff --git a/libraries/hfm/src/hfm/HFMFormat.h b/libraries/hfm/src/hfm/HFMFormat.h new file mode 100644 index 0000000000..4430bca3f4 --- /dev/null +++ b/libraries/hfm/src/hfm/HFMFormat.h @@ -0,0 +1,25 @@ +// +// HFMFormat.h +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HFMFormat_h +#define hifi_HFMFormat_h + +#include "HFMFormatRegistry.h" + +namespace hfm { + class Format { + public: + virtual void registerFormat(FormatRegistry& registry) = 0; + virtual void unregisterFormat(FormatRegistry& registry) = 0; + }; +}; + +#endif // hifi_HFMFormat_h diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp new file mode 100644 index 0000000000..08f13c414a --- /dev/null +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -0,0 +1,52 @@ +// +// HFMFormatRegistry.cpp +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/29. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "HFMFormatRegistry.h" + +namespace hfm { + +FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, const std::shared_ptr& supportedFactory) { + MIMETypeID id = _mimeTypeLibrary.registerMIMEType(mimeType); + withWriteLock([&](){ + _supportedFormats.emplace_back(id, supportedFactory); + }); + return id; +} + +void FormatRegistry::unregisterMIMEType(const MIMETypeID& mimeTypeID) { + withWriteLock([&](){ + for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { + if ((*it).mimeTypeID == mimeTypeID) { + _supportedFormats.erase(it); + break; + } + } + }); + _mimeTypeLibrary.unregisterMIMEType(mimeTypeID); +} + +std::shared_ptr FormatRegistry::getFactoryForMIMETypeID(FormatRegistry::MIMETypeID mimeTypeID) const { + return resultWithReadLock>([&](){ + for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { + if ((*it).mimeTypeID == mimeTypeID) { + return (*it).factory; + } + } + return std::shared_ptr(); + }); +} + +std::shared_ptr FormatRegistry::getFactoryForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { + MIMETypeID id = _mimeTypeLibrary.findMatchingMIMEType(data, mapping, url, webMediaType); + return getFactoryForMIMETypeID(id); +} + +}; diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h new file mode 100644 index 0000000000..e807d98c46 --- /dev/null +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -0,0 +1,48 @@ +// +// HFMFormatRegistry.h +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/28. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HFMFormatRegistry_h +#define hifi_HFMFormatRegistry_h + +#include "HFMSerializer.h" +#include +#include + +namespace hfm { + +class FormatRegistry : public ReadWriteLockable { +public: + using MIMETypeID = MIMETypeLibrary::ID; + static const MIMETypeID INVALID_MIME_TYPE_ID { MIMETypeLibrary::INVALID_ID }; + + MIMETypeID registerMIMEType(const MIMEType& mimeType, const std::shared_ptr& supportedFactory); + void unregisterMIMEType(const MIMETypeID& id); + + std::shared_ptr getFactoryForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; + std::shared_ptr getFactoryForMIMETypeID(MIMETypeID id) const; + +protected: + MIMETypeLibrary _mimeTypeLibrary; + class SupportedFormat { + public: + SupportedFormat(const MIMETypeID& mimeTypeID, const std::shared_ptr& factory) : + mimeTypeID(mimeTypeID), + factory(factory) { + } + MIMETypeID mimeTypeID; + std::shared_ptr factory; + }; + std::vector _supportedFormats; +}; + +}; + +#endif // hifi_HFMFormatRegistry_h diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index db18f21e06..a8ff4a3fa0 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -19,6 +19,12 @@ namespace hfm { class Serializer { +public: + class Factory { + public: + virtual std::shared_ptr get() = 0; + }; + virtual Model::Pointer read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url = hifi::URL()) = 0; }; From 74015a1a5ed961aa8d5e84472bf36a8c436afde7 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 30 Nov 2018 11:19:27 -0800 Subject: [PATCH 12/35] Implement hfm::Format/hfm::Factory for model serializers --- libraries/fbx/src/FBXSerializer.cpp | 16 ++++++++++++++++ libraries/fbx/src/FBXSerializer.h | 13 +++++++++++++ libraries/fbx/src/GLTFSerializer.cpp | 16 ++++++++++++++++ libraries/fbx/src/GLTFSerializer.h | 12 ++++++++++++ libraries/fbx/src/OBJSerializer.cpp | 14 ++++++++++++++ libraries/fbx/src/OBJSerializer.h | 12 ++++++++++++ 6 files changed, 83 insertions(+) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index a9887cde15..dc39143f6b 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1833,6 +1833,22 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } +void FBXFormat::registerFormat(hfm::FormatRegistry& registry) { + MIMEType mimeType("fbx"); + mimeType.extensions.push_back("fbx"); + mimeType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); + mimeTypeID = registry.registerMIMEType(mimeType, std::make_shared()); +} + +void FBXFormat::unregisterFormat(hfm::FormatRegistry& registry) { + registry.unregisterMIMEType(mimeTypeID); + mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; +} + +std::shared_ptr FBXSerializer::Factory::get() { + return std::make_shared(); +} + HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); buffer.open(QIODevice::ReadOnly); diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index c69f75cc5c..231fc5316c 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -28,6 +28,7 @@ #include "FBX.h" #include +#include #include #include @@ -94,8 +95,20 @@ public: class ExtractedMesh; +class FBXFormat : public hfm::Format { +public: + virtual void registerFormat(hfm::FormatRegistry& registry) override; + virtual void unregisterFormat(hfm::FormatRegistry& registry) override; +protected: + hfm::FormatRegistry::MIMETypeID mimeTypeID { hfm::FormatRegistry::INVALID_MIME_TYPE_ID }; +}; + class FBXSerializer : public HFMSerializer { public: + class Factory : public HFMSerializer::Factory { + std::shared_ptr get() override; + }; + HFMModel* _hfmModel; /// Reads HFMModel from the supplied model and mapping data. /// \exception QString if an error occurs in parsing diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 28d377c605..801adf6bc5 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -910,6 +910,22 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } +void GLTFFormat::registerFormat(hfm::FormatRegistry& registry) { + MIMEType mimeType("gltf"); + mimeType.extensions.push_back("gltf"); + mimeType.webMediaTypes.push_back("model/gltf+json"); + mimeTypeID = registry.registerMIMEType(mimeType, std::make_shared()); +} + +void GLTFFormat::unregisterFormat(hfm::FormatRegistry& registry) { + registry.unregisterMIMEType(mimeTypeID); + mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; +} + +std::shared_ptr GLTFSerializer::Factory::get() { + return std::make_shared(); +} + HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { _url = url; diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 1ec1183e36..154ba08e9d 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "FBXSerializer.h" @@ -700,9 +701,20 @@ struct GLTFFile { } }; +class GLTFFormat : public hfm::Format { +public: + virtual void registerFormat(hfm::FormatRegistry& registry) override; + virtual void unregisterFormat(hfm::FormatRegistry& registry) override; +protected: + hfm::FormatRegistry::MIMETypeID mimeTypeID; +}; + class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: + class Factory : public HFMSerializer::Factory { + std::shared_ptr get() override; + }; GLTFSerializer(); HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index af8dfb5562..ae279bf0a7 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -651,6 +651,20 @@ done: return result; } +void OBJFormat::registerFormat(hfm::FormatRegistry& registry) { + MIMEType mimeType("obj"); + mimeType.extensions.push_back("obj"); + mimeTypeID = registry.registerMIMEType(mimeType, std::make_shared()); +} + +void OBJFormat::unregisterFormat(hfm::FormatRegistry& registry) { + registry.unregisterMIMEType(mimeTypeID); + mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; +} + +std::shared_ptr OBJSerializer::Factory::get() { + return std::make_shared(); +} HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index a6fe3817ca..0a3f4c93ac 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -14,6 +14,7 @@ #include #include +#include #include "FBXSerializer.h" class OBJTokenizer { @@ -89,9 +90,20 @@ public: OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), illuminationModel(-1) {} }; +class OBJFormat : public hfm::Format { +public: + virtual void registerFormat(hfm::FormatRegistry& registry) override; + virtual void unregisterFormat(hfm::FormatRegistry& registry) override; +protected: + hfm::FormatRegistry::MIMETypeID mimeTypeID; +}; + class OBJSerializer: public QObject, public HFMSerializer { // QObject so we can make network requests. Q_OBJECT public: + class Factory : public HFMSerializer::Factory { + std::shared_ptr get() override; + }; typedef QVector FaceGroup; QVector vertices; QVector vertexColors; From 243a1d6598e69b50a59bdc5f2e571d6a1f498f7a Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 30 Nov 2018 14:34:44 -0800 Subject: [PATCH 13/35] Add ModelFormatRegistry for handling model loading on the application side --- interface/src/Application.cpp | 3 ++ .../model-networking/ModelFormatRegistry.cpp | 40 +++++++++++++++++++ .../model-networking/ModelFormatRegistry.h | 29 ++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp create mode 100644 libraries/model-networking/src/model-networking/ModelFormatRegistry.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 21af28ffcb..6ff8618918 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include @@ -883,6 +884,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(NodeType::Agent, listenPort); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -2745,6 +2747,7 @@ Application::~Application() { DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp new file mode 100644 index 0000000000..26f5b66b48 --- /dev/null +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp @@ -0,0 +1,40 @@ +// +// ModelFormatRegistry.cpp +// libraries/model-networking/src/model-networking +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ModelFormatRegistry.h" + +#include "FBXSerializer.h" +#include "OBJSerializer.h" +#include "GLTFSerializer.h" + +ModelFormatRegistry::ModelFormatRegistry() : hfm::FormatRegistry() { + addDefaultFormats(); +} + +void ModelFormatRegistry::addDefaultFormats() { + addFormat(std::make_shared()); + addFormat(std::make_shared()); + addFormat(std::make_shared()); +} + +void ModelFormatRegistry::addFormat(const std::shared_ptr& format) { + format->registerFormat(*this); + withWriteLock([&](){ + formats.push_back(format); + }); +} + +ModelFormatRegistry::~ModelFormatRegistry() { + for (auto& format : formats) { + format->unregisterFormat(*this); + } + formats.clear(); +} diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h new file mode 100644 index 0000000000..becc53fc1b --- /dev/null +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h @@ -0,0 +1,29 @@ +// +// ModelFormatRegistry.h +// libraries/model-networking/src/model-networking +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ModelFormatRegistry_h +#define hifi_ModelFormatRegistry_h + +#include +#include + +class ModelFormatRegistry : public hfm::FormatRegistry { +public: + ModelFormatRegistry(); + ~ModelFormatRegistry(); + void addFormat(const std::shared_ptr& format); + +protected: + void addDefaultFormats(); + std::vector> formats; +}; + +#endif // hifi_ModelFormatRegistry_h From 39d1a2be6fab230de00e51b7518cc9eb1de764d0 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 30 Nov 2018 16:14:14 -0800 Subject: [PATCH 14/35] Simplify ModelLoader to utilize new model format registry --- .../src/model-networking/ModelLoader.cpp | 62 ++--------------- .../src/model-networking/ModelLoader.h | 67 ------------------- 2 files changed, 6 insertions(+), 123 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp index 04384acd39..ff32c3a999 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.cpp +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -11,64 +11,14 @@ #include "ModelLoader.h" -#include "FBXSerializer.h" -#include "OBJSerializer.h" -#include "GLTFSerializer.h" +#include +#include "ModelFormatRegistry.h" -ModelLoader::ModelLoader() { - // Add supported model formats - - MIMEType fbxMIMEType("fbx"); - fbxMIMEType.extensions.push_back("fbx"); - fbxMIMEType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); - addSupportedFormat(fbxMIMEType); - - MIMEType objMIMEType("obj"); - objMIMEType.extensions.push_back("obj"); - addSupportedFormat(objMIMEType); - - MIMEType gltfMIMEType("gltf"); - gltfMIMEType.extensions.push_back("gltf"); - gltfMIMEType.webMediaTypes.push_back("model/gltf+json"); - addSupportedFormat(gltfMIMEType); -} hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { - // Check file contents - for (auto& supportedFormat : supportedFormats) { - for (auto& fileSignature : supportedFormat.mimeType.fileSignatures) { - auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString(); - if (testBytes == fileSignature.bytes) { - return supportedFormat.loader(data, mapping, url); - } - } + auto factory = DependencyManager::get()->getFactoryForMIMEType(data, mapping, url, webMediaType); + if (!factory) { + return hfm::Model::Pointer(); } - - // Check file extension - std::string urlString = url.path().toStdString(); - std::size_t extensionSeparator = urlString.rfind('.'); - if (extensionSeparator != std::string::npos) { - std::string detectedExtension = urlString.substr(extensionSeparator + 1); - for (auto& supportedFormat : supportedFormats) { - for (auto& extension : supportedFormat.mimeType.extensions) { - if (extension == detectedExtension) { - return supportedFormat.loader(data, mapping, url); - } - } - } - } - - // Check web media type - if (webMediaType != "") { - for (auto& supportedFormat : supportedFormats) { - for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) { - if (candidateWebMediaType == webMediaType) { - return supportedFormat.loader(data, mapping, url); - } - } - } - } - - // Supported file type not found. Abort loading. - return hfm::Model::Pointer(); + return factory->get()->read(data, mapping, url); } diff --git a/libraries/model-networking/src/model-networking/ModelLoader.h b/libraries/model-networking/src/model-networking/ModelLoader.h index 0deb339f15..5fbab4fb65 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.h +++ b/libraries/model-networking/src/model-networking/ModelLoader.h @@ -12,82 +12,15 @@ #ifndef hifi_ModelLoader_h #define hifi_ModelLoader_h -#include -#include -#include - #include #include -#include class ModelLoader { public: - - // A short sequence of bytes, typically at the beginning of the file, which identifies the file format - class FileSignature { - public: - FileSignature(const std::string& bytes, int byteOffset) : - bytes(bytes), - byteOffset(byteOffset) { - } - - std::string bytes; - int byteOffset; - }; - - // A named file extension with a list of known ways to positively identify the file type - class MIMEType { - public: - MIMEType(const std::string& name) : - name(name) { - } - - std::string name; - std::vector extensions; - std::vector webMediaTypes; - std::vector fileSignatures; - }; - - ModelLoader(); - - // T is a subclass of hfm::Serializer - template - void addSupportedFormat(const MIMEType& mimeType) { - supportedFormats.push_back(SupportedFormat(mimeType, SupportedFormat::getLoader())); - } - // Given the currently stored list of supported file formats, determine how to load a model from the given parameters. // If successful, return an owned reference to the newly loaded model. // If failed, return an empty reference. hfm::Model::Pointer load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; - -protected: - using Loader = std::function; - - class SupportedFormat { - public: - SupportedFormat(const MIMEType& mimeType, const Loader& loader) : - mimeType(mimeType), - loader(loader) { - } - - MIMEType mimeType; - Loader loader; - - template - static Loader getLoader() { - assert([](){ - T t; - return dynamic_cast(&t) != nullptr; - }()); - - return [](const hifi::ByteArray& bytes, const hifi::VariantHash& mapping, const hifi::URL& url) -> hfm::Model::Pointer { - return T().read(bytes, mapping, url); - }; - } - }; - - std::vector supportedFormats; }; #endif // hifi_ModelLoader_h From 2178baf1a8b0691b8a42683dc43365134b5137f9 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 30 Nov 2018 16:49:28 -0800 Subject: [PATCH 15/35] Create SimpleFormat --- libraries/hfm/src/hfm/HFMSimpleFormat.cpp | 35 +++++++++++++++++ libraries/hfm/src/hfm/HFMSimpleFormat.h | 47 +++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 libraries/hfm/src/hfm/HFMSimpleFormat.cpp create mode 100644 libraries/hfm/src/hfm/HFMSimpleFormat.h diff --git a/libraries/hfm/src/hfm/HFMSimpleFormat.cpp b/libraries/hfm/src/hfm/HFMSimpleFormat.cpp new file mode 100644 index 0000000000..2881945400 --- /dev/null +++ b/libraries/hfm/src/hfm/HFMSimpleFormat.cpp @@ -0,0 +1,35 @@ +// +// HFMSimpleFormat.cpp +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "HFMSimpleFormat.h" + +namespace hfm { + template + std::shared_ptr SimpleFactory::get() { + return std::make_shared(); + } + + template + SimpleFormat::SimpleFormat(const MIMEType& mimeType) : Format(), + _mimeType(mimeType) { + } + + template + void SimpleFormat::registerFormat(FormatRegistry& registry) { + _mimeTypeID = registry.registerMIMEType(_mimeType, std::make_shared>()); + } + + template + void SimpleFormat::unregisterFormat(FormatRegistry& registry) { + registry.unregisterMIMEType(_mimeTypeID); + _mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; + } +}; diff --git a/libraries/hfm/src/hfm/HFMSimpleFormat.h b/libraries/hfm/src/hfm/HFMSimpleFormat.h new file mode 100644 index 0000000000..c12a7233bf --- /dev/null +++ b/libraries/hfm/src/hfm/HFMSimpleFormat.h @@ -0,0 +1,47 @@ +// +// HFMSimpleFormat.h +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HFMSimpleFormat_h +#define hifi_HFMSimpleFormat_h + +#include "HFMFormat.h" +#include "HFMSerializer.h" + +namespace hfm { + template + class SimpleFactory : public Serializer::Factory { + std::shared_ptr get() override { + return std::make_shared(); + } + }; + + template // T is an implementation of hfm::Serializer + class SimpleFormat : public Format { + public: + SimpleFormat(const MIMEType& mimeType) : Format(), + _mimeType(mimeType) { + } + + void registerFormat(FormatRegistry& registry) override { + _mimeTypeID = registry.registerMIMEType(_mimeType, std::make_unique>()); + } + + void unregisterFormat(FormatRegistry& registry) override { + registry.unregisterMIMEType(_mimeTypeID); + _mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; + } + protected: + MIMEType _mimeType; + hfm::FormatRegistry::MIMETypeID _mimeTypeID; + }; +}; + +#endif // hifi_HFMSimpleFormat_h From 30c4830bd8192582461a68bb0ad6e22b3b4a8fdb Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 30 Nov 2018 17:20:16 -0800 Subject: [PATCH 16/35] Make Serializers use SimpleFormat --- libraries/fbx/src/FBXSerializer.cpp | 14 ++++---------- libraries/fbx/src/FBXSerializer.h | 12 +----------- libraries/fbx/src/GLTFSerializer.cpp | 14 ++++---------- libraries/fbx/src/GLTFSerializer.h | 14 +++----------- libraries/fbx/src/OBJSerializer.cpp | 14 ++++---------- libraries/fbx/src/OBJSerializer.h | 13 ++----------- .../src/model-networking/ModelFormatRegistry.cpp | 6 +++--- 7 files changed, 21 insertions(+), 66 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index dc39143f6b..b57ff183a0 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -33,6 +33,7 @@ #include #include +#include #include // TOOL: Uncomment the following line to enable the filtering of all the unkwnon fields of a node so we can break point easily while loading a model with problems... @@ -1833,21 +1834,14 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -void FBXFormat::registerFormat(hfm::FormatRegistry& registry) { +MIMEType getFBXMIMEType() { MIMEType mimeType("fbx"); mimeType.extensions.push_back("fbx"); mimeType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); - mimeTypeID = registry.registerMIMEType(mimeType, std::make_shared()); + return mimeType; } -void FBXFormat::unregisterFormat(hfm::FormatRegistry& registry) { - registry.unregisterMIMEType(mimeTypeID); - mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; -} - -std::shared_ptr FBXSerializer::Factory::get() { - return std::make_shared(); -} +std::shared_ptr FBXSerializer::FORMAT = std::make_shared>(getFBXMIMEType()); HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index 231fc5316c..e66a6b911a 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -95,19 +95,9 @@ public: class ExtractedMesh; -class FBXFormat : public hfm::Format { -public: - virtual void registerFormat(hfm::FormatRegistry& registry) override; - virtual void unregisterFormat(hfm::FormatRegistry& registry) override; -protected: - hfm::FormatRegistry::MIMETypeID mimeTypeID { hfm::FormatRegistry::INVALID_MIME_TYPE_ID }; -}; - class FBXSerializer : public HFMSerializer { public: - class Factory : public HFMSerializer::Factory { - std::shared_ptr get() override; - }; + static std::shared_ptr FORMAT; HFMModel* _hfmModel; /// Reads HFMModel from the supplied model and mapping data. diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 801adf6bc5..2cad08984f 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -34,6 +34,7 @@ #include #include "FBXSerializer.h" +#include GLTFSerializer::GLTFSerializer() { @@ -910,21 +911,14 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -void GLTFFormat::registerFormat(hfm::FormatRegistry& registry) { +MIMEType getGLTFMIMEType() { MIMEType mimeType("gltf"); mimeType.extensions.push_back("gltf"); mimeType.webMediaTypes.push_back("model/gltf+json"); - mimeTypeID = registry.registerMIMEType(mimeType, std::make_shared()); + return mimeType; } -void GLTFFormat::unregisterFormat(hfm::FormatRegistry& registry) { - registry.unregisterMIMEType(mimeTypeID); - mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; -} - -std::shared_ptr GLTFSerializer::Factory::get() { - return std::make_shared(); -} +std::shared_ptr GLTFSerializer::FORMAT = std::make_shared>(getGLTFMIMEType()); HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 154ba08e9d..626e6c0995 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -701,21 +701,13 @@ struct GLTFFile { } }; -class GLTFFormat : public hfm::Format { -public: - virtual void registerFormat(hfm::FormatRegistry& registry) override; - virtual void unregisterFormat(hfm::FormatRegistry& registry) override; -protected: - hfm::FormatRegistry::MIMETypeID mimeTypeID; -}; - class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: - class Factory : public HFMSerializer::Factory { - std::shared_ptr get() override; - }; GLTFSerializer(); + + static std::shared_ptr FORMAT; + HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: GLTFFile _file; diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index ae279bf0a7..62b33e3690 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -28,6 +28,7 @@ #include #include "FBXSerializer.h" +#include #include #include @@ -651,20 +652,13 @@ done: return result; } -void OBJFormat::registerFormat(hfm::FormatRegistry& registry) { +MIMEType getOBJMIMEType() { MIMEType mimeType("obj"); mimeType.extensions.push_back("obj"); - mimeTypeID = registry.registerMIMEType(mimeType, std::make_shared()); + return mimeType; } -void OBJFormat::unregisterFormat(hfm::FormatRegistry& registry) { - registry.unregisterMIMEType(mimeTypeID); - mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; -} - -std::shared_ptr OBJSerializer::Factory::get() { - return std::make_shared(); -} +std::shared_ptr OBJSerializer::FORMAT = std::make_shared>(getOBJMIMEType()); HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index 0a3f4c93ac..cbf6ee3ce2 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -90,20 +90,11 @@ public: OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), illuminationModel(-1) {} }; -class OBJFormat : public hfm::Format { -public: - virtual void registerFormat(hfm::FormatRegistry& registry) override; - virtual void unregisterFormat(hfm::FormatRegistry& registry) override; -protected: - hfm::FormatRegistry::MIMETypeID mimeTypeID; -}; - class OBJSerializer: public QObject, public HFMSerializer { // QObject so we can make network requests. Q_OBJECT public: - class Factory : public HFMSerializer::Factory { - std::shared_ptr get() override; - }; + static std::shared_ptr FORMAT; + typedef QVector FaceGroup; QVector vertices; QVector vertexColors; diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp index 26f5b66b48..ccc89eb402 100644 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp @@ -20,9 +20,9 @@ ModelFormatRegistry::ModelFormatRegistry() : hfm::FormatRegistry() { } void ModelFormatRegistry::addDefaultFormats() { - addFormat(std::make_shared()); - addFormat(std::make_shared()); - addFormat(std::make_shared()); + addFormat(FBXSerializer::FORMAT); + addFormat(OBJSerializer::FORMAT); + addFormat(GLTFSerializer::FORMAT); } void ModelFormatRegistry::addFormat(const std::shared_ptr& format) { From bf1c5f2fa5b1d1e78531279e08c1e6eb00a2fef5 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 10:48:50 -0800 Subject: [PATCH 17/35] Make Serializer::Factory stored by HFMFormatRegistry unique_ptr --- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 14 +++++++------- libraries/hfm/src/hfm/HFMFormatRegistry.h | 12 ++++++------ libraries/hfm/src/hfm/HFMSimpleFormat.cpp | 2 +- .../src/model-networking/ModelLoader.cpp | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index 08f13c414a..1be05e99d9 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -13,7 +13,7 @@ namespace hfm { -FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, const std::shared_ptr& supportedFactory) { +FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, std::unique_ptr& supportedFactory) { MIMETypeID id = _mimeTypeLibrary.registerMIMEType(mimeType); withWriteLock([&](){ _supportedFormats.emplace_back(id, supportedFactory); @@ -33,20 +33,20 @@ void FormatRegistry::unregisterMIMEType(const MIMETypeID& mimeTypeID) { _mimeTypeLibrary.unregisterMIMEType(mimeTypeID); } -std::shared_ptr FormatRegistry::getFactoryForMIMETypeID(FormatRegistry::MIMETypeID mimeTypeID) const { - return resultWithReadLock>([&](){ +std::shared_ptr FormatRegistry::getSerializerForMIMETypeID(FormatRegistry::MIMETypeID mimeTypeID) const { + return resultWithReadLock>([&](){ for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { if ((*it).mimeTypeID == mimeTypeID) { - return (*it).factory; + return (*it).factory->get(); } } - return std::shared_ptr(); + return std::shared_ptr(); }); } -std::shared_ptr FormatRegistry::getFactoryForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { +std::shared_ptr FormatRegistry::getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { MIMETypeID id = _mimeTypeLibrary.findMatchingMIMEType(data, mapping, url, webMediaType); - return getFactoryForMIMETypeID(id); + return getSerializerForMIMETypeID(id); } }; diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h index e807d98c46..6e0bd5c66c 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.h +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -23,22 +23,22 @@ public: using MIMETypeID = MIMETypeLibrary::ID; static const MIMETypeID INVALID_MIME_TYPE_ID { MIMETypeLibrary::INVALID_ID }; - MIMETypeID registerMIMEType(const MIMEType& mimeType, const std::shared_ptr& supportedFactory); + MIMETypeID registerMIMEType(const MIMEType& mimeType, std::unique_ptr& supportedFactory); void unregisterMIMEType(const MIMETypeID& id); - std::shared_ptr getFactoryForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; - std::shared_ptr getFactoryForMIMETypeID(MIMETypeID id) const; + std::shared_ptr getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; + std::shared_ptr getSerializerForMIMETypeID(MIMETypeID id) const; protected: MIMETypeLibrary _mimeTypeLibrary; class SupportedFormat { public: - SupportedFormat(const MIMETypeID& mimeTypeID, const std::shared_ptr& factory) : + SupportedFormat(const MIMETypeID& mimeTypeID, std::unique_ptr& factory) : mimeTypeID(mimeTypeID), - factory(factory) { + factory(std::move(factory)) { } MIMETypeID mimeTypeID; - std::shared_ptr factory; + std::unique_ptr factory; }; std::vector _supportedFormats; }; diff --git a/libraries/hfm/src/hfm/HFMSimpleFormat.cpp b/libraries/hfm/src/hfm/HFMSimpleFormat.cpp index 2881945400..0388268de8 100644 --- a/libraries/hfm/src/hfm/HFMSimpleFormat.cpp +++ b/libraries/hfm/src/hfm/HFMSimpleFormat.cpp @@ -24,7 +24,7 @@ namespace hfm { template void SimpleFormat::registerFormat(FormatRegistry& registry) { - _mimeTypeID = registry.registerMIMEType(_mimeType, std::make_shared>()); + _mimeTypeID = registry.registerMIMEType(_mimeType, std::make_unique>()); } template diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp index ff32c3a999..51d2c96ee3 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.cpp +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -16,9 +16,9 @@ hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { - auto factory = DependencyManager::get()->getFactoryForMIMEType(data, mapping, url, webMediaType); - if (!factory) { + auto serializer = DependencyManager::get()->getSerializerForMIMEType(data, mapping, url, webMediaType); + if (!serializer) { return hfm::Model::Pointer(); } - return factory->get()->read(data, mapping, url); + return serializer->read(data, mapping, url); } From 6ec0e42ded733c1d98267fde56b5f725005f43d3 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 11:04:29 -0800 Subject: [PATCH 18/35] Remove locks from MIMETypeLibrary --- .../shared/src/shared/MIMETypeLibrary.cpp | 91 +++++++++---------- libraries/shared/src/shared/MIMETypeLibrary.h | 4 +- 2 files changed, 42 insertions(+), 53 deletions(-) diff --git a/libraries/shared/src/shared/MIMETypeLibrary.cpp b/libraries/shared/src/shared/MIMETypeLibrary.cpp index 4f12f373fe..3532876b67 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.cpp +++ b/libraries/shared/src/shared/MIMETypeLibrary.cpp @@ -12,74 +12,65 @@ #include "MIMETypeLibrary.h" MIMETypeLibrary::ID MIMETypeLibrary::registerMIMEType(const MIMEType& mimeType) { - ID id; - withWriteLock([&](){ - id = nextID++; - _mimeTypes.emplace_back(id, mimeType); - }); + ID id = nextID++; + _mimeTypes.emplace_back(id, mimeType); return id; } void MIMETypeLibrary::unregisterMIMEType(const MIMETypeLibrary::ID& id) { - withWriteLock([&](){ - for (auto it = _mimeTypes.begin(); it != _mimeTypes.end(); it++) { - if ((*it).id == id) { - _mimeTypes.erase(it); - break; - } + for (auto it = _mimeTypes.begin(); it != _mimeTypes.end(); it++) { + if ((*it).id == id) { + _mimeTypes.erase(it); + break; } - }); + } } MIMEType MIMETypeLibrary::getMIMEType(const MIMETypeLibrary::ID& id) const { - return resultWithReadLock([&](){ - for (auto& supportedFormat : _mimeTypes) { - if (supportedFormat.id == id) { - return supportedFormat.mimeType; - } + for (auto& supportedFormat : _mimeTypes) { + if (supportedFormat.id == id) { + return supportedFormat.mimeType; } - return MIMEType::NONE; - }); + } + return MIMEType::NONE; } MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { - return resultWithReadLock([&](){ - // Check file contents - for (auto& mimeType : _mimeTypes) { - for (auto& fileSignature : mimeType.mimeType.fileSignatures) { - auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString(); - if (testBytes == fileSignature.bytes) { - return mimeType.id; + // Check file contents + for (auto& mimeType : _mimeTypes) { + for (auto& fileSignature : mimeType.mimeType.fileSignatures) { + auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString(); + if (testBytes == fileSignature.bytes) { + return mimeType.id; + } + } + } + + // Check file extension + std::string urlString = url.path().toStdString(); + std::size_t extensionSeparator = urlString.rfind('.'); + if (extensionSeparator != std::string::npos) { + std::string detectedExtension = urlString.substr(extensionSeparator + 1); + for (auto& supportedFormat : _mimeTypes) { + for (auto& extension : supportedFormat.mimeType.extensions) { + if (extension == detectedExtension) { + return supportedFormat.id; } } } + } - // Check file extension - std::string urlString = url.path().toStdString(); - std::size_t extensionSeparator = urlString.rfind('.'); - if (extensionSeparator != std::string::npos) { - std::string detectedExtension = urlString.substr(extensionSeparator + 1); - for (auto& supportedFormat : _mimeTypes) { - for (auto& extension : supportedFormat.mimeType.extensions) { - if (extension == detectedExtension) { - return supportedFormat.id; - } + // Check web media type + if (webMediaType != "") { + for (auto& supportedFormat : _mimeTypes) { + for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) { + if (candidateWebMediaType == webMediaType) { + return supportedFormat.id; } } } + } - // Check web media type - if (webMediaType != "") { - for (auto& supportedFormat : _mimeTypes) { - for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) { - if (candidateWebMediaType == webMediaType) { - return supportedFormat.id; - } - } - } - } - - // Supported file type not found. - return INVALID_ID; - }); + // Supported file type not found. + return INVALID_ID; } diff --git a/libraries/shared/src/shared/MIMETypeLibrary.h b/libraries/shared/src/shared/MIMETypeLibrary.h index 62bc28cdad..354192dd48 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.h +++ b/libraries/shared/src/shared/MIMETypeLibrary.h @@ -19,8 +19,6 @@ #include "HifiTypes.h" -#include "ReadWriteLockable.h" - // A short sequence of bytes, typically at the beginning of the file, which identifies the file format class FileSignature { public: @@ -61,7 +59,7 @@ public: MIMEType MIMEType::NONE = MIMEType(""); -class MIMETypeLibrary : ReadWriteLockable { +class MIMETypeLibrary { public: using ID = unsigned int; static const ID INVALID_ID { 0 }; From 0da4669370ac272f87777617f7cb8310b1b0e4a0 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 11:24:31 -0800 Subject: [PATCH 19/35] Replace ReadWriteLockable with std::lock_guard in HFMFormatRegistry/ModelFormatRegistry --- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 42 +++++++++++-------- libraries/hfm/src/hfm/HFMFormatRegistry.h | 3 +- .../model-networking/ModelFormatRegistry.cpp | 5 ++- .../model-networking/ModelFormatRegistry.h | 1 + 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index 1be05e99d9..2a537af151 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -14,38 +14,44 @@ namespace hfm { FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, std::unique_ptr& supportedFactory) { + std::lock_guard lock(_libraryLock); + MIMETypeID id = _mimeTypeLibrary.registerMIMEType(mimeType); - withWriteLock([&](){ - _supportedFormats.emplace_back(id, supportedFactory); - }); + _supportedFormats.emplace_back(id, supportedFactory); return id; } void FormatRegistry::unregisterMIMEType(const MIMETypeID& mimeTypeID) { - withWriteLock([&](){ - for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { - if ((*it).mimeTypeID == mimeTypeID) { - _supportedFormats.erase(it); - break; - } + std::lock_guard lock(_libraryLock); + + for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { + if ((*it).mimeTypeID == mimeTypeID) { + _supportedFormats.erase(it); + break; } - }); + } _mimeTypeLibrary.unregisterMIMEType(mimeTypeID); } std::shared_ptr FormatRegistry::getSerializerForMIMETypeID(FormatRegistry::MIMETypeID mimeTypeID) const { - return resultWithReadLock>([&](){ - for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { - if ((*it).mimeTypeID == mimeTypeID) { - return (*it).factory->get(); - } + // TODO: shared_lock in C++14 + std::lock_guard lock(*const_cast(&_libraryLock)); + + for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { + if ((*it).mimeTypeID == mimeTypeID) { + return (*it).factory->get(); } - return std::shared_ptr(); - }); + } + return std::shared_ptr(); } std::shared_ptr FormatRegistry::getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { - MIMETypeID id = _mimeTypeLibrary.findMatchingMIMEType(data, mapping, url, webMediaType); + MIMETypeID id; + { + // TODO: shared_lock in C++14 + std::lock_guard lock(*const_cast(&_libraryLock)); + id = _mimeTypeLibrary.findMatchingMIMEType(data, mapping, url, webMediaType); + } return getSerializerForMIMETypeID(id); } diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h index 6e0bd5c66c..6a16dce0b9 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.h +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -18,7 +18,7 @@ namespace hfm { -class FormatRegistry : public ReadWriteLockable { +class FormatRegistry { public: using MIMETypeID = MIMETypeLibrary::ID; static const MIMETypeID INVALID_MIME_TYPE_ID { MIMETypeLibrary::INVALID_ID }; @@ -31,6 +31,7 @@ public: protected: MIMETypeLibrary _mimeTypeLibrary; + std::mutex _libraryLock; class SupportedFormat { public: SupportedFormat(const MIMETypeID& mimeTypeID, std::unique_ptr& factory) : diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp index ccc89eb402..8adc4ea5d9 100644 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp @@ -27,9 +27,10 @@ void ModelFormatRegistry::addDefaultFormats() { void ModelFormatRegistry::addFormat(const std::shared_ptr& format) { format->registerFormat(*this); - withWriteLock([&](){ + { + std::lock_guard lock(_formatsLock); formats.push_back(format); - }); + } } ModelFormatRegistry::~ModelFormatRegistry() { diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h index becc53fc1b..c88873eaca 100644 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h @@ -24,6 +24,7 @@ public: protected: void addDefaultFormats(); std::vector> formats; + std::mutex _formatsLock; }; #endif // hifi_ModelFormatRegistry_h From 660d8c4e92633afb5596ef469c17af806bcc0183 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 11:30:29 -0800 Subject: [PATCH 20/35] Remove unused mapping parameter from MIME type detection --- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 4 ++-- libraries/hfm/src/hfm/HFMFormatRegistry.h | 2 +- .../model-networking/src/model-networking/ModelLoader.cpp | 2 +- libraries/shared/src/shared/MIMETypeLibrary.cpp | 2 +- libraries/shared/src/shared/MIMETypeLibrary.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index 2a537af151..1125486f5e 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -45,12 +45,12 @@ std::shared_ptr FormatRegistry::getSerializerForMIMETypeID(FormatReg return std::shared_ptr(); } -std::shared_ptr FormatRegistry::getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { +std::shared_ptr FormatRegistry::getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { MIMETypeID id; { // TODO: shared_lock in C++14 std::lock_guard lock(*const_cast(&_libraryLock)); - id = _mimeTypeLibrary.findMatchingMIMEType(data, mapping, url, webMediaType); + id = _mimeTypeLibrary.findMatchingMIMEType(data, url, webMediaType); } return getSerializerForMIMETypeID(id); } diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h index 6a16dce0b9..bf67254c39 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.h +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -26,7 +26,7 @@ public: MIMETypeID registerMIMEType(const MIMEType& mimeType, std::unique_ptr& supportedFactory); void unregisterMIMEType(const MIMETypeID& id); - std::shared_ptr getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; + std::shared_ptr getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; std::shared_ptr getSerializerForMIMETypeID(MIMETypeID id) const; protected: diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp index 51d2c96ee3..a69559ad38 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.cpp +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -16,7 +16,7 @@ hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { - auto serializer = DependencyManager::get()->getSerializerForMIMEType(data, mapping, url, webMediaType); + auto serializer = DependencyManager::get()->getSerializerForMIMEType(data, url, webMediaType); if (!serializer) { return hfm::Model::Pointer(); } diff --git a/libraries/shared/src/shared/MIMETypeLibrary.cpp b/libraries/shared/src/shared/MIMETypeLibrary.cpp index 3532876b67..7bc9defab6 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.cpp +++ b/libraries/shared/src/shared/MIMETypeLibrary.cpp @@ -35,7 +35,7 @@ MIMEType MIMETypeLibrary::getMIMEType(const MIMETypeLibrary::ID& id) const { return MIMEType::NONE; } -MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { +MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { // Check file contents for (auto& mimeType : _mimeTypes) { for (auto& fileSignature : mimeType.mimeType.fileSignatures) { diff --git a/libraries/shared/src/shared/MIMETypeLibrary.h b/libraries/shared/src/shared/MIMETypeLibrary.h index 354192dd48..94dba0b3c8 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.h +++ b/libraries/shared/src/shared/MIMETypeLibrary.h @@ -68,7 +68,7 @@ public: void unregisterMIMEType(const ID& id); MIMEType getMIMEType(const ID& id) const; - ID findMatchingMIMEType(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const; + ID findMatchingMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; protected: ID nextID { 1 }; From 19459c15a54a2eebe7b08895c0e07e5aed5adfa9 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 11:50:50 -0800 Subject: [PATCH 21/35] Split MIMETypeLibrary file type detection into three separate functions --- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 9 ++++++++- libraries/shared/src/shared/MIMETypeLibrary.cpp | 11 +++++++++-- libraries/shared/src/shared/MIMETypeLibrary.h | 5 ++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index 1125486f5e..b96662bdcc 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -50,7 +50,14 @@ std::shared_ptr FormatRegistry::getSerializerForMIMEType(const hifi: { // TODO: shared_lock in C++14 std::lock_guard lock(*const_cast(&_libraryLock)); - id = _mimeTypeLibrary.findMatchingMIMEType(data, url, webMediaType); + + id = _mimeTypeLibrary.findMIMETypeForData(data); + if (id == INVALID_MIME_TYPE_ID) { + id = _mimeTypeLibrary.findMIMETypeForURL(url); + } + if (id == INVALID_MIME_TYPE_ID) { + id = _mimeTypeLibrary.findMIMETypeForMediaType(webMediaType); + } } return getSerializerForMIMETypeID(id); } diff --git a/libraries/shared/src/shared/MIMETypeLibrary.cpp b/libraries/shared/src/shared/MIMETypeLibrary.cpp index 7bc9defab6..f3874012b1 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.cpp +++ b/libraries/shared/src/shared/MIMETypeLibrary.cpp @@ -35,7 +35,7 @@ MIMEType MIMETypeLibrary::getMIMEType(const MIMETypeLibrary::ID& id) const { return MIMEType::NONE; } -MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { +MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForData(const hifi::ByteArray& data) const { // Check file contents for (auto& mimeType : _mimeTypes) { for (auto& fileSignature : mimeType.mimeType.fileSignatures) { @@ -46,6 +46,10 @@ MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& } } + return INVALID_ID; +} + +MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForURL(const hifi::URL& url) const { // Check file extension std::string urlString = url.path().toStdString(); std::size_t extensionSeparator = urlString.rfind('.'); @@ -60,6 +64,10 @@ MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& } } + return INVALID_ID; +} + +MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForMediaType(const std::string& webMediaType) const { // Check web media type if (webMediaType != "") { for (auto& supportedFormat : _mimeTypes) { @@ -71,6 +79,5 @@ MIMETypeLibrary::ID MIMETypeLibrary::findMatchingMIMEType(const hifi::ByteArray& } } - // Supported file type not found. return INVALID_ID; } diff --git a/libraries/shared/src/shared/MIMETypeLibrary.h b/libraries/shared/src/shared/MIMETypeLibrary.h index 94dba0b3c8..33e415a86c 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.h +++ b/libraries/shared/src/shared/MIMETypeLibrary.h @@ -68,7 +68,10 @@ public: void unregisterMIMEType(const ID& id); MIMEType getMIMEType(const ID& id) const; - ID findMatchingMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; + + ID findMIMETypeForData(const hifi::ByteArray& data) const; + ID findMIMETypeForURL(const hifi::URL& url) const; + ID findMIMETypeForMediaType(const std::string& webMediaType) const; protected: ID nextID { 1 }; From da9f37bb3986e6c8e7332bf5de45dd615957dbc0 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 14:13:33 -0800 Subject: [PATCH 22/35] Fix up HFMFormatRegistry to accept subclass factory unique pointers --- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 2 +- libraries/hfm/src/hfm/HFMFormatRegistry.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index b96662bdcc..8ff11d851d 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -13,7 +13,7 @@ namespace hfm { -FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, std::unique_ptr& supportedFactory) { +FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, std::unique_ptr supportedFactory) { std::lock_guard lock(_libraryLock); MIMETypeID id = _mimeTypeLibrary.registerMIMEType(mimeType); diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h index bf67254c39..92076e814c 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.h +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -23,7 +23,7 @@ public: using MIMETypeID = MIMETypeLibrary::ID; static const MIMETypeID INVALID_MIME_TYPE_ID { MIMETypeLibrary::INVALID_ID }; - MIMETypeID registerMIMEType(const MIMEType& mimeType, std::unique_ptr& supportedFactory); + MIMETypeID registerMIMEType(const MIMEType& mimeType, std::unique_ptr supportedFactory); void unregisterMIMEType(const MIMETypeID& id); std::shared_ptr getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; From a04c822ef0f44acd56dcfefda2c8948d14d64378 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 14:25:55 -0800 Subject: [PATCH 23/35] Oops, ModelFormatRegistry needs to be defined as a Dependency before it can be used by DependencyManager --- .../src/model-networking/ModelFormatRegistry.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h index c88873eaca..88681a01d7 100644 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h @@ -15,7 +15,9 @@ #include #include -class ModelFormatRegistry : public hfm::FormatRegistry { +#include + +class ModelFormatRegistry : public hfm::FormatRegistry, Dependency { public: ModelFormatRegistry(); ~ModelFormatRegistry(); From a63888cac8aa96a90e6d6987b7c6d11fedff4f48 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 14:26:37 -0800 Subject: [PATCH 24/35] Remove unused default constructor for GLTFSerializer --- libraries/fbx/src/GLTFSerializer.cpp | 5 ----- libraries/fbx/src/GLTFSerializer.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 2cad08984f..b841226a9e 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -36,11 +36,6 @@ #include "FBXSerializer.h" #include - -GLTFSerializer::GLTFSerializer() { - -} - bool GLTFSerializer::getStringVal(const QJsonObject& object, const QString& fieldname, QString& value, QMap& defined) { bool _defined = (object.contains(fieldname) && object[fieldname].isString()); diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 626e6c0995..fffb192b5b 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -704,8 +704,6 @@ struct GLTFFile { class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: - GLTFSerializer(); - static std::shared_ptr FORMAT; HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; From 3c38b43a6516ceef302dfd3bbc6a20b871b3eab6 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 15:26:34 -0800 Subject: [PATCH 25/35] Fix compilation error due to static variable definition in MIMETypeLibrary header file --- libraries/shared/src/shared/MIMETypeLibrary.cpp | 2 ++ libraries/shared/src/shared/MIMETypeLibrary.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/shared/MIMETypeLibrary.cpp b/libraries/shared/src/shared/MIMETypeLibrary.cpp index f3874012b1..5ae4016c54 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.cpp +++ b/libraries/shared/src/shared/MIMETypeLibrary.cpp @@ -11,6 +11,8 @@ #include "MIMETypeLibrary.h" +MIMEType MIMEType::NONE = MIMEType(""); + MIMETypeLibrary::ID MIMETypeLibrary::registerMIMEType(const MIMEType& mimeType) { ID id = nextID++; _mimeTypes.emplace_back(id, mimeType); diff --git a/libraries/shared/src/shared/MIMETypeLibrary.h b/libraries/shared/src/shared/MIMETypeLibrary.h index 33e415a86c..5066e859fb 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.h +++ b/libraries/shared/src/shared/MIMETypeLibrary.h @@ -57,8 +57,6 @@ public: std::vector fileSignatures; }; -MIMEType MIMEType::NONE = MIMEType(""); - class MIMETypeLibrary { public: using ID = unsigned int; From 1c9beed44fb96238bdb2109f31cf0dbdb473cdde Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 3 Dec 2018 15:28:18 -0800 Subject: [PATCH 26/35] Fix ModelFormatRegistry Dependency inheritance being private --- .../model-networking/src/model-networking/ModelFormatRegistry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h index 88681a01d7..ec1ce79b43 100644 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h +++ b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h @@ -17,7 +17,7 @@ #include -class ModelFormatRegistry : public hfm::FormatRegistry, Dependency { +class ModelFormatRegistry : public hfm::FormatRegistry, public Dependency { public: ModelFormatRegistry(); ~ModelFormatRegistry(); From ed1684967f7bcc41a174f1c338d82833d31facdb Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Tue, 4 Dec 2018 10:07:31 -0800 Subject: [PATCH 27/35] Remove straggler HFMSimpleFormat.cpp --- libraries/hfm/src/hfm/HFMSimpleFormat.cpp | 35 ----------------------- 1 file changed, 35 deletions(-) delete mode 100644 libraries/hfm/src/hfm/HFMSimpleFormat.cpp diff --git a/libraries/hfm/src/hfm/HFMSimpleFormat.cpp b/libraries/hfm/src/hfm/HFMSimpleFormat.cpp deleted file mode 100644 index 0388268de8..0000000000 --- a/libraries/hfm/src/hfm/HFMSimpleFormat.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// HFMSimpleFormat.cpp -// libraries/hfm/src/hfm -// -// Created by Sabrina Shanman on 2018/11/30. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "HFMSimpleFormat.h" - -namespace hfm { - template - std::shared_ptr SimpleFactory::get() { - return std::make_shared(); - } - - template - SimpleFormat::SimpleFormat(const MIMEType& mimeType) : Format(), - _mimeType(mimeType) { - } - - template - void SimpleFormat::registerFormat(FormatRegistry& registry) { - _mimeTypeID = registry.registerMIMEType(_mimeType, std::make_unique>()); - } - - template - void SimpleFormat::unregisterFormat(FormatRegistry& registry) { - registry.unregisterMIMEType(_mimeTypeID); - _mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; - } -}; From 6ea4769173d2000f92a0d9a1962a89d1591434dc Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 6 Dec 2018 13:38:57 -0800 Subject: [PATCH 28/35] Re-name MIMETypeLibrary to MediaTypeLibrary and update related references --- libraries/fbx/src/FBXSerializer.cpp | 12 ++--- libraries/fbx/src/GLTFSerializer.cpp | 12 ++--- libraries/fbx/src/OBJSerializer.cpp | 10 ++-- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 30 ++++++------ libraries/hfm/src/hfm/HFMFormatRegistry.h | 22 ++++----- libraries/hfm/src/hfm/HFMSimpleFormat.h | 14 +++--- .../src/model-networking/ModelLoader.cpp | 2 +- ...METypeLibrary.cpp => MediaTypeLibrary.cpp} | 44 ++++++++--------- .../{MIMETypeLibrary.h => MediaTypeLibrary.h} | 48 +++++++++---------- 9 files changed, 97 insertions(+), 97 deletions(-) rename libraries/shared/src/shared/{MIMETypeLibrary.cpp => MediaTypeLibrary.cpp} (53%) rename libraries/shared/src/shared/{MIMETypeLibrary.h => MediaTypeLibrary.h} (57%) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index b57ff183a0..ccbda9af33 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1834,14 +1834,14 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -MIMEType getFBXMIMEType() { - MIMEType mimeType("fbx"); - mimeType.extensions.push_back("fbx"); - mimeType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); - return mimeType; +MediaType getFBXMediaType() { + MediaType mediaType("fbx"); + mediaType.extensions.push_back("fbx"); + mediaType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); + return mediaType; } -std::shared_ptr FBXSerializer::FORMAT = std::make_shared>(getFBXMIMEType()); +std::shared_ptr FBXSerializer::FORMAT = std::make_shared>(getFBXMediaType()); HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index b841226a9e..cfa2124c5d 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -906,14 +906,14 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -MIMEType getGLTFMIMEType() { - MIMEType mimeType("gltf"); - mimeType.extensions.push_back("gltf"); - mimeType.webMediaTypes.push_back("model/gltf+json"); - return mimeType; +MediaType getGLTFMediaType() { + MediaType mediaType("gltf"); + mediaType.extensions.push_back("gltf"); + mediaType.webMediaTypes.push_back("model/gltf+json"); + return mediaType; } -std::shared_ptr GLTFSerializer::FORMAT = std::make_shared>(getGLTFMIMEType()); +std::shared_ptr GLTFSerializer::FORMAT = std::make_shared>(getGLTFMediaType()); HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index 62b33e3690..b85ca7ebca 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -652,13 +652,13 @@ done: return result; } -MIMEType getOBJMIMEType() { - MIMEType mimeType("obj"); - mimeType.extensions.push_back("obj"); - return mimeType; +MediaType getOBJMediaType() { + MediaType mediaType("obj"); + mediaType.extensions.push_back("obj"); + return mediaType; } -std::shared_ptr OBJSerializer::FORMAT = std::make_shared>(getOBJMIMEType()); +std::shared_ptr OBJSerializer::FORMAT = std::make_shared>(getOBJMediaType()); HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index 8ff11d851d..60606bc018 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -13,53 +13,53 @@ namespace hfm { -FormatRegistry::MIMETypeID FormatRegistry::registerMIMEType(const MIMEType& mimeType, std::unique_ptr supportedFactory) { +FormatRegistry::MediaTypeID FormatRegistry::registerMediaType(const MediaType& mediaType, std::unique_ptr supportedFactory) { std::lock_guard lock(_libraryLock); - MIMETypeID id = _mimeTypeLibrary.registerMIMEType(mimeType); + MediaTypeID id = _mediaTypeLibrary.registerMediaType(mediaType); _supportedFormats.emplace_back(id, supportedFactory); return id; } -void FormatRegistry::unregisterMIMEType(const MIMETypeID& mimeTypeID) { +void FormatRegistry::unregisterMediaType(const MediaTypeID& mediaTypeID) { std::lock_guard lock(_libraryLock); for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { - if ((*it).mimeTypeID == mimeTypeID) { + if ((*it).mediaTypeID == mediaTypeID) { _supportedFormats.erase(it); break; } } - _mimeTypeLibrary.unregisterMIMEType(mimeTypeID); + _mediaTypeLibrary.unregisterMediaType(mediaTypeID); } -std::shared_ptr FormatRegistry::getSerializerForMIMETypeID(FormatRegistry::MIMETypeID mimeTypeID) const { +std::shared_ptr FormatRegistry::getSerializerForMediaTypeID(FormatRegistry::MediaTypeID mediaTypeID) const { // TODO: shared_lock in C++14 std::lock_guard lock(*const_cast(&_libraryLock)); for (auto it = _supportedFormats.begin(); it != _supportedFormats.end(); it++) { - if ((*it).mimeTypeID == mimeTypeID) { + if ((*it).mediaTypeID == mediaTypeID) { return (*it).factory->get(); } } return std::shared_ptr(); } -std::shared_ptr FormatRegistry::getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { - MIMETypeID id; +std::shared_ptr FormatRegistry::getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { + MediaTypeID id; { // TODO: shared_lock in C++14 std::lock_guard lock(*const_cast(&_libraryLock)); - id = _mimeTypeLibrary.findMIMETypeForData(data); - if (id == INVALID_MIME_TYPE_ID) { - id = _mimeTypeLibrary.findMIMETypeForURL(url); + id = _mediaTypeLibrary.findMediaTypeForData(data); + if (id == INVALID_MEDIA_TYPE_ID) { + id = _mediaTypeLibrary.findMediaTypeForURL(url); } - if (id == INVALID_MIME_TYPE_ID) { - id = _mimeTypeLibrary.findMIMETypeForMediaType(webMediaType); + if (id == INVALID_MEDIA_TYPE_ID) { + id = _mediaTypeLibrary.findMediaTypeForWebID(webMediaType); } } - return getSerializerForMIMETypeID(id); + return getSerializerForMediaTypeID(id); } }; diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h index 92076e814c..203c5f5743 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.h +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -13,32 +13,32 @@ #define hifi_HFMFormatRegistry_h #include "HFMSerializer.h" -#include +#include #include namespace hfm { class FormatRegistry { public: - using MIMETypeID = MIMETypeLibrary::ID; - static const MIMETypeID INVALID_MIME_TYPE_ID { MIMETypeLibrary::INVALID_ID }; + using MediaTypeID = MediaTypeLibrary::ID; + static const MediaTypeID INVALID_MEDIA_TYPE_ID { MediaTypeLibrary::INVALID_ID }; - MIMETypeID registerMIMEType(const MIMEType& mimeType, std::unique_ptr supportedFactory); - void unregisterMIMEType(const MIMETypeID& id); + MediaTypeID registerMediaType(const MediaType& mediaType, std::unique_ptr supportedFactory); + void unregisterMediaType(const MediaTypeID& id); - std::shared_ptr getSerializerForMIMEType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; - std::shared_ptr getSerializerForMIMETypeID(MIMETypeID id) const; + std::shared_ptr getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; + std::shared_ptr getSerializerForMediaTypeID(MediaTypeID id) const; protected: - MIMETypeLibrary _mimeTypeLibrary; + MediaTypeLibrary _mediaTypeLibrary; std::mutex _libraryLock; class SupportedFormat { public: - SupportedFormat(const MIMETypeID& mimeTypeID, std::unique_ptr& factory) : - mimeTypeID(mimeTypeID), + SupportedFormat(const MediaTypeID& mediaTypeID, std::unique_ptr& factory) : + mediaTypeID(mediaTypeID), factory(std::move(factory)) { } - MIMETypeID mimeTypeID; + MediaTypeID mediaTypeID; std::unique_ptr factory; }; std::vector _supportedFormats; diff --git a/libraries/hfm/src/hfm/HFMSimpleFormat.h b/libraries/hfm/src/hfm/HFMSimpleFormat.h index c12a7233bf..0ab6636e7d 100644 --- a/libraries/hfm/src/hfm/HFMSimpleFormat.h +++ b/libraries/hfm/src/hfm/HFMSimpleFormat.h @@ -26,21 +26,21 @@ namespace hfm { template // T is an implementation of hfm::Serializer class SimpleFormat : public Format { public: - SimpleFormat(const MIMEType& mimeType) : Format(), - _mimeType(mimeType) { + SimpleFormat(const MediaType& mediaType) : Format(), + _mediaType(mediaType) { } void registerFormat(FormatRegistry& registry) override { - _mimeTypeID = registry.registerMIMEType(_mimeType, std::make_unique>()); + _mediaTypeID = registry.registerMediaType(_mediaType, std::make_unique>()); } void unregisterFormat(FormatRegistry& registry) override { - registry.unregisterMIMEType(_mimeTypeID); - _mimeTypeID = hfm::FormatRegistry::INVALID_MIME_TYPE_ID; + registry.unregisterMediaType(_mediaTypeID); + _mediaTypeID = hfm::FormatRegistry::INVALID_MEDIA_TYPE_ID; } protected: - MIMEType _mimeType; - hfm::FormatRegistry::MIMETypeID _mimeTypeID; + MediaType _mediaType; + hfm::FormatRegistry::MediaTypeID _mediaTypeID; }; }; diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp index a69559ad38..1ef8e8ae85 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.cpp +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -16,7 +16,7 @@ hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { - auto serializer = DependencyManager::get()->getSerializerForMIMEType(data, url, webMediaType); + auto serializer = DependencyManager::get()->getSerializerForMediaType(data, url, webMediaType); if (!serializer) { return hfm::Model::Pointer(); } diff --git a/libraries/shared/src/shared/MIMETypeLibrary.cpp b/libraries/shared/src/shared/MediaTypeLibrary.cpp similarity index 53% rename from libraries/shared/src/shared/MIMETypeLibrary.cpp rename to libraries/shared/src/shared/MediaTypeLibrary.cpp index 5ae4016c54..790897c3e2 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.cpp +++ b/libraries/shared/src/shared/MediaTypeLibrary.cpp @@ -1,5 +1,5 @@ // -// MIMETypeLibrary.cpp +// MediaTypeLibrary.cpp // libraries/shared/src/shared // // Created by Sabrina Shanman on 2018/11/29. @@ -9,41 +9,41 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "MIMETypeLibrary.h" +#include "MediaTypeLibrary.h" -MIMEType MIMEType::NONE = MIMEType(""); +MediaType MediaType::NONE = MediaType(""); -MIMETypeLibrary::ID MIMETypeLibrary::registerMIMEType(const MIMEType& mimeType) { +MediaTypeLibrary::ID MediaTypeLibrary::registerMediaType(const MediaType& mediaType) { ID id = nextID++; - _mimeTypes.emplace_back(id, mimeType); + _mediaTypes.emplace_back(id, mediaType); return id; } -void MIMETypeLibrary::unregisterMIMEType(const MIMETypeLibrary::ID& id) { - for (auto it = _mimeTypes.begin(); it != _mimeTypes.end(); it++) { +void MediaTypeLibrary::unregisterMediaType(const MediaTypeLibrary::ID& id) { + for (auto it = _mediaTypes.begin(); it != _mediaTypes.end(); it++) { if ((*it).id == id) { - _mimeTypes.erase(it); + _mediaTypes.erase(it); break; } } } -MIMEType MIMETypeLibrary::getMIMEType(const MIMETypeLibrary::ID& id) const { - for (auto& supportedFormat : _mimeTypes) { +MediaType MediaTypeLibrary::getMediaType(const MediaTypeLibrary::ID& id) const { + for (auto& supportedFormat : _mediaTypes) { if (supportedFormat.id == id) { - return supportedFormat.mimeType; + return supportedFormat.mediaType; } } - return MIMEType::NONE; + return MediaType::NONE; } -MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForData(const hifi::ByteArray& data) const { +MediaTypeLibrary::ID MediaTypeLibrary::findMediaTypeForData(const hifi::ByteArray& data) const { // Check file contents - for (auto& mimeType : _mimeTypes) { - for (auto& fileSignature : mimeType.mimeType.fileSignatures) { + for (auto& mediaType : _mediaTypes) { + for (auto& fileSignature : mediaType.mediaType.fileSignatures) { auto testBytes = data.mid(fileSignature.byteOffset, (int)fileSignature.bytes.size()).toStdString(); if (testBytes == fileSignature.bytes) { - return mimeType.id; + return mediaType.id; } } } @@ -51,14 +51,14 @@ MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForData(const hifi::ByteArray& return INVALID_ID; } -MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForURL(const hifi::URL& url) const { +MediaTypeLibrary::ID MediaTypeLibrary::findMediaTypeForURL(const hifi::URL& url) const { // Check file extension std::string urlString = url.path().toStdString(); std::size_t extensionSeparator = urlString.rfind('.'); if (extensionSeparator != std::string::npos) { std::string detectedExtension = urlString.substr(extensionSeparator + 1); - for (auto& supportedFormat : _mimeTypes) { - for (auto& extension : supportedFormat.mimeType.extensions) { + for (auto& supportedFormat : _mediaTypes) { + for (auto& extension : supportedFormat.mediaType.extensions) { if (extension == detectedExtension) { return supportedFormat.id; } @@ -69,11 +69,11 @@ MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForURL(const hifi::URL& url) co return INVALID_ID; } -MIMETypeLibrary::ID MIMETypeLibrary::findMIMETypeForMediaType(const std::string& webMediaType) const { +MediaTypeLibrary::ID MediaTypeLibrary::findMediaTypeForWebID(const std::string& webMediaType) const { // Check web media type if (webMediaType != "") { - for (auto& supportedFormat : _mimeTypes) { - for (auto& candidateWebMediaType : supportedFormat.mimeType.webMediaTypes) { + for (auto& supportedFormat : _mediaTypes) { + for (auto& candidateWebMediaType : supportedFormat.mediaType.webMediaTypes) { if (candidateWebMediaType == webMediaType) { return supportedFormat.id; } diff --git a/libraries/shared/src/shared/MIMETypeLibrary.h b/libraries/shared/src/shared/MediaTypeLibrary.h similarity index 57% rename from libraries/shared/src/shared/MIMETypeLibrary.h rename to libraries/shared/src/shared/MediaTypeLibrary.h index 5066e859fb..c87da01fa1 100644 --- a/libraries/shared/src/shared/MIMETypeLibrary.h +++ b/libraries/shared/src/shared/MediaTypeLibrary.h @@ -1,5 +1,5 @@ // -// MIMETypeLibrary.h +// MediaTypeLibrary.h // libraries/shared/src/shared // // Created by Sabrina Shanman on 2018/11/28. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_MIMETypeLibrary_h -#define hifi_MIMETypeLibrary_h +#ifndef hifi_MediaTypeLibrary_h +#define hifi_MediaTypeLibrary_h #include #include @@ -36,20 +36,20 @@ public: }; // A named file extension with a list of known ways to positively identify the file type -class MIMEType { +class MediaType { public: - MIMEType(const std::string& name) : + MediaType(const std::string& name) : name(name) { } - MIMEType() {}; - MIMEType(const MIMEType& mimeType) : - name(mimeType.name), - extensions(mimeType.extensions), - webMediaTypes(mimeType.webMediaTypes), - fileSignatures(mimeType.fileSignatures) { + MediaType() {}; + MediaType(const MediaType& mediaType) : + name(mediaType.name), + extensions(mediaType.extensions), + webMediaTypes(mediaType.webMediaTypes), + fileSignatures(mediaType.fileSignatures) { } - static MIMEType NONE; + static MediaType NONE; std::string name; std::vector extensions; @@ -57,34 +57,34 @@ public: std::vector fileSignatures; }; -class MIMETypeLibrary { +class MediaTypeLibrary { public: using ID = unsigned int; static const ID INVALID_ID { 0 }; - ID registerMIMEType(const MIMEType& mimeType); - void unregisterMIMEType(const ID& id); + ID registerMediaType(const MediaType& mediaType); + void unregisterMediaType(const ID& id); - MIMEType getMIMEType(const ID& id) const; + MediaType getMediaType(const ID& id) const; - ID findMIMETypeForData(const hifi::ByteArray& data) const; - ID findMIMETypeForURL(const hifi::URL& url) const; - ID findMIMETypeForMediaType(const std::string& webMediaType) const; + ID findMediaTypeForData(const hifi::ByteArray& data) const; + ID findMediaTypeForURL(const hifi::URL& url) const; + ID findMediaTypeForWebID(const std::string& webMediaType) const; protected: ID nextID { 1 }; class Entry { public: - Entry(const ID& id, const MIMEType& mimeType) : + Entry(const ID& id, const MediaType& mediaType) : id(id), - mimeType(mimeType) { + mediaType(mediaType) { } ID id; - MIMEType mimeType; + MediaType mediaType; }; - std::vector _mimeTypes; + std::vector _mediaTypes; }; -#endif // hifi_MIMETypeLibrary_h +#endif // hifi_MeidaTypeLibrary_h From 7cbe3776f5b6e58793840bcecf16fc5354ecbd72 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 7 Dec 2018 11:47:32 -0800 Subject: [PATCH 29/35] Simplify serializer registration process --- interface/src/Application.cpp | 6 +-- libraries/fbx/src/FBXSerializer.cpp | 7 ++-- libraries/fbx/src/FBXSerializer.h | 4 +- libraries/fbx/src/GLTFSerializer.cpp | 7 ++-- libraries/fbx/src/GLTFSerializer.h | 5 +-- libraries/fbx/src/OBJSerializer.cpp | 7 ++-- libraries/fbx/src/OBJSerializer.h | 5 +-- .../hfm/src/hfm/FormatSerializerRegister.cpp | 29 +++++++++++++ .../hfm/src/hfm/FormatSerializerRegister.h | 35 ++++++++++++++++ libraries/hfm/src/hfm/HFMFormat.h | 25 ----------- libraries/hfm/src/hfm/HFMFormatRegistry.h | 3 +- libraries/hfm/src/hfm/HFMSerializer.h | 11 +++++ libraries/hfm/src/hfm/ModelFormatRegistry.cpp | 20 +++++++++ libraries/hfm/src/hfm/ModelFormatRegistry.h | 30 ++++++++++++++ .../src/model-networking/ModelCache.cpp | 9 ++++ .../src/model-networking/ModelCache.h | 1 + .../model-networking/ModelFormatRegistry.cpp | 41 ------------------- .../model-networking/ModelFormatRegistry.h | 32 --------------- .../src/model-networking/ModelLoader.cpp | 2 +- 19 files changed, 159 insertions(+), 120 deletions(-) create mode 100644 libraries/hfm/src/hfm/FormatSerializerRegister.cpp create mode 100644 libraries/hfm/src/hfm/FormatSerializerRegister.h delete mode 100644 libraries/hfm/src/hfm/HFMFormat.h create mode 100644 libraries/hfm/src/hfm/ModelFormatRegistry.cpp create mode 100644 libraries/hfm/src/hfm/ModelFormatRegistry.h delete mode 100644 libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp delete mode 100644 libraries/model-networking/src/model-networking/ModelFormatRegistry.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6ff8618918..1570b6fe95 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -101,7 +101,7 @@ #include #include #include -#include +#include #include #include #include @@ -884,7 +884,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(NodeType::Agent, listenPort); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); + DependencyManager::set(); // ModelFormatRegistry must be defined before ModelCache. See the ModelCache constructor. DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -2747,9 +2747,9 @@ Application::~Application() { DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index ccbda9af33..ac338407f4 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -33,7 +33,6 @@ #include #include -#include #include // TOOL: Uncomment the following line to enable the filtering of all the unkwnon fields of a node so we can break point easily while loading a model with problems... @@ -1834,14 +1833,16 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr return hfmModelPtr; } -MediaType getFBXMediaType() { +MediaType FBXSerializer::getMediaType() const { MediaType mediaType("fbx"); mediaType.extensions.push_back("fbx"); mediaType.fileSignatures.emplace_back("Kaydara FBX Binary \x00", 0); return mediaType; } -std::shared_ptr FBXSerializer::FORMAT = std::make_shared>(getFBXMediaType()); +std::unique_ptr FBXSerializer::getFactory() const { + return std::make_unique>(); +} HFMModel::Pointer FBXSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { QBuffer buffer(const_cast(&data)); diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index e66a6b911a..a76fb8f9bf 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -28,7 +28,6 @@ #include "FBX.h" #include -#include #include #include @@ -97,7 +96,8 @@ class ExtractedMesh; class FBXSerializer : public HFMSerializer { public: - static std::shared_ptr FORMAT; + MediaType getMediaType() const override; + std::unique_ptr getFactory() const override; HFMModel* _hfmModel; /// Reads HFMModel from the supplied model and mapping data. diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index cfa2124c5d..e254a91eb0 100644 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -34,7 +34,6 @@ #include #include "FBXSerializer.h" -#include bool GLTFSerializer::getStringVal(const QJsonObject& object, const QString& fieldname, QString& value, QMap& defined) { @@ -906,14 +905,16 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const QUrl& url) { return true; } -MediaType getGLTFMediaType() { +MediaType GLTFSerializer::getMediaType() const { MediaType mediaType("gltf"); mediaType.extensions.push_back("gltf"); mediaType.webMediaTypes.push_back("model/gltf+json"); return mediaType; } -std::shared_ptr GLTFSerializer::FORMAT = std::make_shared>(getGLTFMediaType()); +std::unique_ptr GLTFSerializer::getFactory() const { + return std::make_unique>(); +} HFMModel::Pointer GLTFSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index fffb192b5b..5fca77c4fd 100644 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -16,8 +16,6 @@ #include #include #include -#include -#include "FBXSerializer.h" struct GLTFAsset { @@ -704,7 +702,8 @@ struct GLTFFile { class GLTFSerializer : public QObject, public HFMSerializer { Q_OBJECT public: - static std::shared_ptr FORMAT; + MediaType getMediaType() const override; + std::unique_ptr getFactory() const override; HFMModel::Pointer read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url = QUrl()) override; private: diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index b85ca7ebca..9c92466565 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -28,7 +28,6 @@ #include #include "FBXSerializer.h" -#include #include #include @@ -652,13 +651,15 @@ done: return result; } -MediaType getOBJMediaType() { +MediaType OBJSerializer::getMediaType() const { MediaType mediaType("obj"); mediaType.extensions.push_back("obj"); return mediaType; } -std::shared_ptr OBJSerializer::FORMAT = std::make_shared>(getOBJMediaType()); +std::unique_ptr OBJSerializer::getFactory() const { + return std::make_unique>(); +} HFMModel::Pointer OBJSerializer::read(const QByteArray& data, const QVariantHash& mapping, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index cbf6ee3ce2..3723b0e569 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -14,8 +14,6 @@ #include #include -#include -#include "FBXSerializer.h" class OBJTokenizer { public: @@ -93,7 +91,8 @@ public: class OBJSerializer: public QObject, public HFMSerializer { // QObject so we can make network requests. Q_OBJECT public: - static std::shared_ptr FORMAT; + MediaType getMediaType() const override; + std::unique_ptr getFactory() const; typedef QVector FaceGroup; QVector vertices; diff --git a/libraries/hfm/src/hfm/FormatSerializerRegister.cpp b/libraries/hfm/src/hfm/FormatSerializerRegister.cpp new file mode 100644 index 0000000000..09c858b79d --- /dev/null +++ b/libraries/hfm/src/hfm/FormatSerializerRegister.cpp @@ -0,0 +1,29 @@ +// +// FormatSerializerRegister.cpp +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/12/07. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "FormatSerializerRegister.h" + +#include "ModelFormatRegistry.h" + +namespace hfm { + +DoFormatSerializerRegister::DoFormatSerializerRegister(const MediaType& mediaType, std::unique_ptr factory) { + auto registry = DependencyManager::get(); + _mediaTypeID = registry->_hfmFormatRegistry.registerMediaType(mediaType, std::move(factory)); +} + +void DoFormatSerializerRegister::unregisterFormat() { + auto registry = DependencyManager::get(); + registry->_hfmFormatRegistry.unregisterMediaType(_mediaTypeID); + _mediaTypeID = hfm::FormatRegistry::INVALID_MEDIA_TYPE_ID; +} + +}; diff --git a/libraries/hfm/src/hfm/FormatSerializerRegister.h b/libraries/hfm/src/hfm/FormatSerializerRegister.h new file mode 100644 index 0000000000..5971d678c8 --- /dev/null +++ b/libraries/hfm/src/hfm/FormatSerializerRegister.h @@ -0,0 +1,35 @@ +// +// FormatSerializerRegister.h +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HFMFormat_h +#define hifi_HFMFormat_h + +#include "HFMFormatRegistry.h" +#include "HFMSerializer.h" + +namespace hfm { + // A helper class which allows early de-registration of a Serializer from ModelFormatRegistry + class FormatSerializerRegister { + public: + virtual void unregisterFormat() = 0; + }; + + class DoFormatSerializerRegister : public FormatSerializerRegister { + public: + DoFormatSerializerRegister(const MediaType& mediaType, std::unique_ptr factory); + + void unregisterFormat() override; + protected: + FormatRegistry::MediaTypeID _mediaTypeID { FormatRegistry::INVALID_MEDIA_TYPE_ID }; + }; +}; + +#endif // hifi_HFMFormat_h diff --git a/libraries/hfm/src/hfm/HFMFormat.h b/libraries/hfm/src/hfm/HFMFormat.h deleted file mode 100644 index 4430bca3f4..0000000000 --- a/libraries/hfm/src/hfm/HFMFormat.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// HFMFormat.h -// libraries/hfm/src/hfm -// -// Created by Sabrina Shanman on 2018/11/30. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_HFMFormat_h -#define hifi_HFMFormat_h - -#include "HFMFormatRegistry.h" - -namespace hfm { - class Format { - public: - virtual void registerFormat(FormatRegistry& registry) = 0; - virtual void unregisterFormat(FormatRegistry& registry) = 0; - }; -}; - -#endif // hifi_HFMFormat_h diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.h b/libraries/hfm/src/hfm/HFMFormatRegistry.h index 203c5f5743..a437e9ac37 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.h +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.h @@ -27,9 +27,10 @@ public: void unregisterMediaType(const MediaTypeID& id); std::shared_ptr getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; - std::shared_ptr getSerializerForMediaTypeID(MediaTypeID id) const; protected: + std::shared_ptr getSerializerForMediaTypeID(MediaTypeID id) const; + MediaTypeLibrary _mediaTypeLibrary; std::mutex _libraryLock; class SupportedFormat { diff --git a/libraries/hfm/src/hfm/HFMSerializer.h b/libraries/hfm/src/hfm/HFMSerializer.h index a8ff4a3fa0..868ec3dd45 100644 --- a/libraries/hfm/src/hfm/HFMSerializer.h +++ b/libraries/hfm/src/hfm/HFMSerializer.h @@ -15,6 +15,7 @@ #include #include "HFM.h" +#include namespace hfm { @@ -25,6 +26,16 @@ public: virtual std::shared_ptr get() = 0; }; + template + class SimpleFactory : public Factory { + std::shared_ptr get() override { + return std::make_shared(); + } + }; + + virtual MediaType getMediaType() const = 0; + virtual std::unique_ptr getFactory() const = 0; + virtual Model::Pointer read(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url = hifi::URL()) = 0; }; diff --git a/libraries/hfm/src/hfm/ModelFormatRegistry.cpp b/libraries/hfm/src/hfm/ModelFormatRegistry.cpp new file mode 100644 index 0000000000..5520307a9b --- /dev/null +++ b/libraries/hfm/src/hfm/ModelFormatRegistry.cpp @@ -0,0 +1,20 @@ +// +// ModelFormatRegistry.cpp +// libraries/model-networking/src/model-networking +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ModelFormatRegistry.h" + +std::unique_ptr ModelFormatRegistry::addFormat(const hfm::Serializer& serializer) { + return std::make_unique(serializer.getMediaType(), serializer.getFactory()); +} + +std::shared_ptr ModelFormatRegistry::getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { + return _hfmFormatRegistry.getSerializerForMediaType(data, url, webMediaType); +} diff --git a/libraries/hfm/src/hfm/ModelFormatRegistry.h b/libraries/hfm/src/hfm/ModelFormatRegistry.h new file mode 100644 index 0000000000..4116869390 --- /dev/null +++ b/libraries/hfm/src/hfm/ModelFormatRegistry.h @@ -0,0 +1,30 @@ +// +// ModelFormatRegistry.h +// libraries/hfm/src/hfm +// +// Created by Sabrina Shanman on 2018/11/30. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ModelFormatRegistry_h +#define hifi_ModelFormatRegistry_h + +#include "FormatSerializerRegister.h" +#include "HFMFormatRegistry.h" + +#include + +class ModelFormatRegistry : public Dependency { +public: + std::unique_ptr addFormat(const hfm::Serializer& serializer); + std::shared_ptr getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; + +protected: + friend class hfm::DoFormatSerializerRegister; + hfm::FormatRegistry _hfmFormatRegistry; +}; + +#endif // hifi_ModelFormatRegistry_h diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 8dc483e43b..2c82401ad0 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -23,6 +23,10 @@ #include "ModelNetworkingLogging.h" #include #include +#include +#include +#include +#include Q_LOGGING_CATEGORY(trace_resource_parse_geometry, "trace.resource.parse.geometry") @@ -308,6 +312,11 @@ ModelCache::ModelCache() { const qint64 GEOMETRY_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE; setUnusedResourceCacheSize(GEOMETRY_DEFAULT_UNUSED_MAX_SIZE); setObjectName("ModelCache"); + + auto modelFormatRegistry = DependencyManager::get(); + modelFormatRegistry->addFormat(FBXSerializer()); + modelFormatRegistry->addFormat(OBJSerializer()); + modelFormatRegistry->addFormat(GLTFSerializer()); } QSharedPointer ModelCache::createResource(const QUrl& url, const QSharedPointer& fallback, diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 1018bdecd5..5f583d82d9 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -21,6 +21,7 @@ #include "FBXSerializer.h" #include "TextureCache.h" #include "ModelLoader.h" +#include "hfm/FormatSerializerRegister.h" // Alias instead of derive to avoid copying diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp b/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp deleted file mode 100644 index 8adc4ea5d9..0000000000 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// ModelFormatRegistry.cpp -// libraries/model-networking/src/model-networking -// -// Created by Sabrina Shanman on 2018/11/30. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "ModelFormatRegistry.h" - -#include "FBXSerializer.h" -#include "OBJSerializer.h" -#include "GLTFSerializer.h" - -ModelFormatRegistry::ModelFormatRegistry() : hfm::FormatRegistry() { - addDefaultFormats(); -} - -void ModelFormatRegistry::addDefaultFormats() { - addFormat(FBXSerializer::FORMAT); - addFormat(OBJSerializer::FORMAT); - addFormat(GLTFSerializer::FORMAT); -} - -void ModelFormatRegistry::addFormat(const std::shared_ptr& format) { - format->registerFormat(*this); - { - std::lock_guard lock(_formatsLock); - formats.push_back(format); - } -} - -ModelFormatRegistry::~ModelFormatRegistry() { - for (auto& format : formats) { - format->unregisterFormat(*this); - } - formats.clear(); -} diff --git a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h b/libraries/model-networking/src/model-networking/ModelFormatRegistry.h deleted file mode 100644 index ec1ce79b43..0000000000 --- a/libraries/model-networking/src/model-networking/ModelFormatRegistry.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// ModelFormatRegistry.h -// libraries/model-networking/src/model-networking -// -// Created by Sabrina Shanman on 2018/11/30. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_ModelFormatRegistry_h -#define hifi_ModelFormatRegistry_h - -#include -#include - -#include - -class ModelFormatRegistry : public hfm::FormatRegistry, public Dependency { -public: - ModelFormatRegistry(); - ~ModelFormatRegistry(); - void addFormat(const std::shared_ptr& format); - -protected: - void addDefaultFormats(); - std::vector> formats; - std::mutex _formatsLock; -}; - -#endif // hifi_ModelFormatRegistry_h diff --git a/libraries/model-networking/src/model-networking/ModelLoader.cpp b/libraries/model-networking/src/model-networking/ModelLoader.cpp index 1ef8e8ae85..65314633c9 100644 --- a/libraries/model-networking/src/model-networking/ModelLoader.cpp +++ b/libraries/model-networking/src/model-networking/ModelLoader.cpp @@ -12,7 +12,7 @@ #include "ModelLoader.h" #include -#include "ModelFormatRegistry.h" +#include hfm::Model::Pointer ModelLoader::load(const hifi::ByteArray& data, const hifi::VariantHash& mapping, const hifi::URL& url, const std::string& webMediaType) const { From f2e69aec5ea22e0927652cd4c7ff5db8e58e6754 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 7 Dec 2018 13:41:33 -0800 Subject: [PATCH 30/35] Fix mac warning for OBJSerializer::getFactory not marked with override --- libraries/fbx/src/OBJSerializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/OBJSerializer.h b/libraries/fbx/src/OBJSerializer.h index 3723b0e569..c4f8025e66 100644 --- a/libraries/fbx/src/OBJSerializer.h +++ b/libraries/fbx/src/OBJSerializer.h @@ -92,7 +92,7 @@ class OBJSerializer: public QObject, public HFMSerializer { // QObject so we can Q_OBJECT public: MediaType getMediaType() const override; - std::unique_ptr getFactory() const; + std::unique_ptr getFactory() const override; typedef QVector FaceGroup; QVector vertices; From 031085b3843700ee01ac42dc2eab9962ddfea6ec Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 7 Dec 2018 16:17:33 -0800 Subject: [PATCH 31/35] Remove now unused HFMSimpleFormat --- libraries/hfm/src/hfm/HFMSimpleFormat.h | 47 ------------------------- 1 file changed, 47 deletions(-) delete mode 100644 libraries/hfm/src/hfm/HFMSimpleFormat.h diff --git a/libraries/hfm/src/hfm/HFMSimpleFormat.h b/libraries/hfm/src/hfm/HFMSimpleFormat.h deleted file mode 100644 index 0ab6636e7d..0000000000 --- a/libraries/hfm/src/hfm/HFMSimpleFormat.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// HFMSimpleFormat.h -// libraries/hfm/src/hfm -// -// Created by Sabrina Shanman on 2018/11/30. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_HFMSimpleFormat_h -#define hifi_HFMSimpleFormat_h - -#include "HFMFormat.h" -#include "HFMSerializer.h" - -namespace hfm { - template - class SimpleFactory : public Serializer::Factory { - std::shared_ptr get() override { - return std::make_shared(); - } - }; - - template // T is an implementation of hfm::Serializer - class SimpleFormat : public Format { - public: - SimpleFormat(const MediaType& mediaType) : Format(), - _mediaType(mediaType) { - } - - void registerFormat(FormatRegistry& registry) override { - _mediaTypeID = registry.registerMediaType(_mediaType, std::make_unique>()); - } - - void unregisterFormat(FormatRegistry& registry) override { - registry.unregisterMediaType(_mediaTypeID); - _mediaTypeID = hfm::FormatRegistry::INVALID_MEDIA_TYPE_ID; - } - protected: - MediaType _mediaType; - hfm::FormatRegistry::MediaTypeID _mediaTypeID; - }; -}; - -#endif // hifi_HFMSimpleFormat_h From 8792824960aa9fc8774c4f85735d1296a8a6d0aa Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 10 Dec 2018 09:58:59 -0800 Subject: [PATCH 32/35] Remove FormatSerializerRegister as it is unused --- .../hfm/src/hfm/FormatSerializerRegister.cpp | 29 --------------- .../hfm/src/hfm/FormatSerializerRegister.h | 35 ------------------- libraries/hfm/src/hfm/ModelFormatRegistry.cpp | 4 +-- libraries/hfm/src/hfm/ModelFormatRegistry.h | 4 +-- .../src/model-networking/ModelCache.h | 1 - 5 files changed, 3 insertions(+), 70 deletions(-) delete mode 100644 libraries/hfm/src/hfm/FormatSerializerRegister.cpp delete mode 100644 libraries/hfm/src/hfm/FormatSerializerRegister.h diff --git a/libraries/hfm/src/hfm/FormatSerializerRegister.cpp b/libraries/hfm/src/hfm/FormatSerializerRegister.cpp deleted file mode 100644 index 09c858b79d..0000000000 --- a/libraries/hfm/src/hfm/FormatSerializerRegister.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// FormatSerializerRegister.cpp -// libraries/hfm/src/hfm -// -// Created by Sabrina Shanman on 2018/12/07. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "FormatSerializerRegister.h" - -#include "ModelFormatRegistry.h" - -namespace hfm { - -DoFormatSerializerRegister::DoFormatSerializerRegister(const MediaType& mediaType, std::unique_ptr factory) { - auto registry = DependencyManager::get(); - _mediaTypeID = registry->_hfmFormatRegistry.registerMediaType(mediaType, std::move(factory)); -} - -void DoFormatSerializerRegister::unregisterFormat() { - auto registry = DependencyManager::get(); - registry->_hfmFormatRegistry.unregisterMediaType(_mediaTypeID); - _mediaTypeID = hfm::FormatRegistry::INVALID_MEDIA_TYPE_ID; -} - -}; diff --git a/libraries/hfm/src/hfm/FormatSerializerRegister.h b/libraries/hfm/src/hfm/FormatSerializerRegister.h deleted file mode 100644 index 5971d678c8..0000000000 --- a/libraries/hfm/src/hfm/FormatSerializerRegister.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// FormatSerializerRegister.h -// libraries/hfm/src/hfm -// -// Created by Sabrina Shanman on 2018/11/30. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_HFMFormat_h -#define hifi_HFMFormat_h - -#include "HFMFormatRegistry.h" -#include "HFMSerializer.h" - -namespace hfm { - // A helper class which allows early de-registration of a Serializer from ModelFormatRegistry - class FormatSerializerRegister { - public: - virtual void unregisterFormat() = 0; - }; - - class DoFormatSerializerRegister : public FormatSerializerRegister { - public: - DoFormatSerializerRegister(const MediaType& mediaType, std::unique_ptr factory); - - void unregisterFormat() override; - protected: - FormatRegistry::MediaTypeID _mediaTypeID { FormatRegistry::INVALID_MEDIA_TYPE_ID }; - }; -}; - -#endif // hifi_HFMFormat_h diff --git a/libraries/hfm/src/hfm/ModelFormatRegistry.cpp b/libraries/hfm/src/hfm/ModelFormatRegistry.cpp index 5520307a9b..b4d7c5849f 100644 --- a/libraries/hfm/src/hfm/ModelFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/ModelFormatRegistry.cpp @@ -11,8 +11,8 @@ #include "ModelFormatRegistry.h" -std::unique_ptr ModelFormatRegistry::addFormat(const hfm::Serializer& serializer) { - return std::make_unique(serializer.getMediaType(), serializer.getFactory()); +void ModelFormatRegistry::addFormat(const hfm::Serializer& serializer) { + _hfmFormatRegistry.registerMediaType(serializer.getMediaType(), std::move(serializer.getFactory())); } std::shared_ptr ModelFormatRegistry::getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { diff --git a/libraries/hfm/src/hfm/ModelFormatRegistry.h b/libraries/hfm/src/hfm/ModelFormatRegistry.h index 4116869390..1228465298 100644 --- a/libraries/hfm/src/hfm/ModelFormatRegistry.h +++ b/libraries/hfm/src/hfm/ModelFormatRegistry.h @@ -12,18 +12,16 @@ #ifndef hifi_ModelFormatRegistry_h #define hifi_ModelFormatRegistry_h -#include "FormatSerializerRegister.h" #include "HFMFormatRegistry.h" #include class ModelFormatRegistry : public Dependency { public: - std::unique_ptr addFormat(const hfm::Serializer& serializer); + void addFormat(const hfm::Serializer& serializer); std::shared_ptr getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const; protected: - friend class hfm::DoFormatSerializerRegister; hfm::FormatRegistry _hfmFormatRegistry; }; diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 5f583d82d9..1018bdecd5 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -21,7 +21,6 @@ #include "FBXSerializer.h" #include "TextureCache.h" #include "ModelLoader.h" -#include "hfm/FormatSerializerRegister.h" // Alias instead of derive to avoid copying From b960b66542d6c5faf55bf2296dbf1febe8c2dc8f Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 10 Dec 2018 11:10:29 -0800 Subject: [PATCH 33/35] Fix mac warning for std::move on temporary object --- libraries/hfm/src/hfm/ModelFormatRegistry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/hfm/src/hfm/ModelFormatRegistry.cpp b/libraries/hfm/src/hfm/ModelFormatRegistry.cpp index b4d7c5849f..d95453161a 100644 --- a/libraries/hfm/src/hfm/ModelFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/ModelFormatRegistry.cpp @@ -12,7 +12,7 @@ #include "ModelFormatRegistry.h" void ModelFormatRegistry::addFormat(const hfm::Serializer& serializer) { - _hfmFormatRegistry.registerMediaType(serializer.getMediaType(), std::move(serializer.getFactory())); + _hfmFormatRegistry.registerMediaType(serializer.getMediaType(), serializer.getFactory()); } std::shared_ptr ModelFormatRegistry::getSerializerForMediaType(const hifi::ByteArray& data, const hifi::URL& url, const std::string& webMediaType) const { From 31d15127013b38e887e8ca3b912027ecab9c9b06 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 10 Dec 2018 16:12:23 -0800 Subject: [PATCH 34/35] Simplify url empty check in GeometryReader::run --- libraries/model-networking/src/model-networking/ModelCache.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 2c82401ad0..dfee4750f5 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -193,8 +193,7 @@ void GeometryReader::run() { return; } - QString urlname = _url.path().toLower(); - if (urlname.isEmpty() || _url.path().isEmpty()) { + if (_url.path().isEmpty()) { throw QString("url is invalid"); } From 79e9bff225f8af6db38a72d0aa833adb43b9f9ba Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 10 Dec 2018 16:18:11 -0800 Subject: [PATCH 35/35] Nest if statement for invalid id checking in hfm::FormatRegistry::getSerializerForMediaType --- libraries/hfm/src/hfm/HFMFormatRegistry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp index 60606bc018..1328369cff 100644 --- a/libraries/hfm/src/hfm/HFMFormatRegistry.cpp +++ b/libraries/hfm/src/hfm/HFMFormatRegistry.cpp @@ -54,9 +54,9 @@ std::shared_ptr FormatRegistry::getSerializerForMediaType(const hifi id = _mediaTypeLibrary.findMediaTypeForData(data); if (id == INVALID_MEDIA_TYPE_ID) { id = _mediaTypeLibrary.findMediaTypeForURL(url); - } - if (id == INVALID_MEDIA_TYPE_ID) { - id = _mediaTypeLibrary.findMediaTypeForWebID(webMediaType); + if (id == INVALID_MEDIA_TYPE_ID) { + id = _mediaTypeLibrary.findMediaTypeForWebID(webMediaType); + } } } return getSerializerForMediaTypeID(id);