/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QQMLTYPELOADER_P_H #define QQMLTYPELOADER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class QQmlScriptBlob; class QQmlQmldirData; class QQmlTypeData; class QQmlEngineExtensionInterface; class QQmlExtensionInterface; class QQmlProfiler; class QQmlTypeLoaderThread; class QQmlEngine; class Q_QML_PRIVATE_EXPORT QQmlTypeLoader { Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader) public: enum Mode { PreferSynchronous, Asynchronous, Synchronous }; class Q_QML_PRIVATE_EXPORT Blob : public QQmlDataBlob { public: Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader); ~Blob() override; const QQmlImports &imports() const { return m_importCache; } void setCachedUnitStatus(QQmlMetaType::CachedUnitLookupError status) { m_cachedUnitStatus = status; } struct PendingImport { QV4::CompiledData::Import::ImportType type = QV4::CompiledData::Import::ImportType::ImportLibrary; QString uri; QString qualifier; QTypeRevision version; QV4::CompiledData::Location location; int priority = 0; PendingImport() = default; PendingImport(Blob *blob, const QV4::CompiledData::Import *import); }; using PendingImportPtr = std::shared_ptr; protected: bool addImport(const QV4::CompiledData::Import *import, uint flags, QList *errors); bool addImport(PendingImportPtr import, uint flags, QList *errors); bool fetchQmldir(const QUrl &url, PendingImportPtr import, int priority, QList *errors); bool updateQmldir(const QQmlRefPointer &data, PendingImportPtr import, QList *errors); private: virtual bool qmldirDataAvailable(const QQmlRefPointer &, QList *); virtual void scriptImported(const QQmlRefPointer &, const QV4::CompiledData::Location &, const QString &, const QString &) {} void dependencyComplete(QQmlDataBlob *) override; bool loadImportDependencies(PendingImportPtr currentImport, const QString &qmldirUri, QList *errors); protected: virtual QString stringAt(int) const { return QString(); } bool isDebugging() const; bool diskCacheEnabled() const; QQmlImports m_importCache; QVector m_unresolvedImports; QVector> m_qmldirs; QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus = QQmlMetaType::CachedUnitLookupError::NoError; }; QQmlTypeLoader(QQmlEngine *); ~QQmlTypeLoader(); QQmlImportDatabase *importDatabase() const; static QUrl normalize(const QUrl &unNormalizedUrl); QQmlRefPointer getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous); QQmlRefPointer getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous); QQmlRefPointer getScript(const QUrl &unNormalizedUrl); QQmlRefPointer getQmldir(const QUrl &); QString absoluteFilePath(const QString &path); bool fileExists(const QString &path, const QString &file); bool directoryExists(const QString &path); const QQmlTypeLoaderQmldirContent qmldirContent(const QString &filePath); void setQmldirContent(const QString &filePath, const QString &content); void clearCache(); void trimCache(); bool isTypeLoaded(const QUrl &url) const; bool isScriptLoaded(const QUrl &url) const; void lock() { m_mutex.lock(); } void unlock() { m_mutex.unlock(); } void load(QQmlDataBlob *, Mode = PreferSynchronous); void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous); void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode = PreferSynchronous); QQmlEngine *engine() const; void initializeEngine(QQmlEngineExtensionInterface *, const char *); void initializeEngine(QQmlExtensionInterface *, const char *); void invalidate(); #if !QT_CONFIG(qml_debug) quintptr profiler() const { return 0; } void setProfiler(quintptr) {} #else QQmlProfiler *profiler() const { return m_profiler.data(); } void setProfiler(QQmlProfiler *profiler); #endif // QT_CONFIG(qml_debug) private: friend class QQmlDataBlob; friend class QQmlTypeLoaderThread; #if QT_CONFIG(qml_network) friend class QQmlTypeLoaderNetworkReplyProxy; #endif // qml_network void shutdownThread(); void loadThread(QQmlDataBlob *); void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &); void loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit); #if QT_CONFIG(qml_network) void networkReplyFinished(QNetworkReply *); void networkReplyProgress(QNetworkReply *, qint64, qint64); typedef QHash NetworkReplies; #endif void setData(QQmlDataBlob *, const QByteArray &); void setData(QQmlDataBlob *, const QString &fileName); void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &); void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit); template struct TypedCallback { TypedCallback(T *object, void (T::*func)(QQmlTypeData *)) : o(object), mf(func) {} static void redirect(void *arg, QQmlTypeData *type) { TypedCallback *self = reinterpret_cast *>(arg); ((self->o)->*(self->mf))(type); } private: T *o; void (T::*mf)(QQmlTypeData *); }; typedef QHash TypeCache; typedef QHash ScriptCache; typedef QHash QmldirCache; typedef QCache > ImportDirCache; typedef QStringHash ImportQmlDirCache; QQmlEngine *m_engine; QQmlTypeLoaderThread *m_thread; QMutex &m_mutex; #if QT_CONFIG(qml_debug) QScopedPointer m_profiler; #endif #if QT_CONFIG(qml_network) NetworkReplies m_networkReplies; #endif TypeCache m_typeCache; int m_typeCacheTrimThreshold; ScriptCache m_scriptCache; QmldirCache m_qmldirCache; ImportDirCache m_importDirCache; ImportQmlDirCache m_importQmlDirCache; template void doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode); void updateTypeCacheTrimThreshold(); friend struct PlainLoader; friend struct CachedLoader; friend struct StaticLoader; }; QT_END_NAMESPACE #endif // QQMLTYPELOADER_P_H