Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • c5dcabdd5da9b920f7eea981beb078bedd2531be
  • master par défaut
  • script
  • new-devel
  • devel
  • timingView-edit
  • fix-mpv
7 résultats

PreCompiledHeaders.cmake

Blame
  • CRTPSubDocument.hh 5,60 Kio
    #pragma once
    
    #ifndef __cplusplus
    #error "This is a C++ header"
    #endif
    
    #include "PreCompiledHeaders.hh"
    #include "VivyApplication.hh"
    #include "Lib/Log.hh"
    #include "Lib/Utils.hh"
    #include "Lib/Audio.hh"
    #include "Lib/Video.hh"
    #include "Lib/Ass/Ass.hh"
    
    #define VIVY_ENABLE_IF_TYPE(Type) \
        template <typename = typename std::enable_if<!std::is_same<Type, void>::value>>
    
    namespace Vivy
    {
    // The Big CRTP class for all common things to all the subdocuments
    template <class CRTPSubDocumentType, class Document, class Context = void> class CRTPSubDocument {
    protected:
        VIVY_APP_LOGGABLE_OBJECT(CRTPSubDocument, logger)
        friend std::unique_ptr<Document>;
    
    public:
        using Type = CRTPSubDocumentType;
    
    protected:
        QString filePath;
        Type fileType;
    
        explicit CRTPSubDocument() = default;
    
        bool isFileValid(const QString &path) const noexcept
        {
            QFileInfo file(path);
            return Document::suffixList.contains(file.suffix());
        }
    
    public:
        static std::unique_ptr<Document> fromFile(const QString &path) noexcept
        {
            auto ret = std::unique_ptr<Document>(new Document());
            ret->logDebug() << "Init document from file " << VIVY_LOG_QUOTED(path);
            ret->filePath = path;
    
            try {
                ret->initFromPath(path); // May throw
            } catch (const std::runtime_error &e) {
                ret->logDebug() << "Failed to init document from file " << VIVY_LOG_QUOTED(path) << ": "
                                << e.what();
                ret.reset();
            }
    
            return ret;
        }
    
        // Get the default stream index or -1 if not possible.
        VIVY_ENABLE_IF_TYPE(Context)
        int getDefaultStreamIndex() const noexcept
        {
            if (auto ptr = getDefaultStream())
                return ptr->getStreamIndex();
            return -1;
        }
    
        // Get a pointer to the default stream, nullptr if not possible
        VIVY_ENABLE_IF_TYPE(Context)
        auto getDefaultStream() const
        {
            const Document *const self = static_cast<const Document *const>(this);
            auto weakPtr               = self->contextPtr->getDefaultStream();
            if (auto ptr = weakPtr.lock())
                return ptr;
            throw std::runtime_error("SubDocument has been deleted");
        }
    
        // Get the stream asked for, nullptr if no stream or if the index is invalid
        VIVY_ENABLE_IF_TYPE(Context)
        auto getStream(int index) const
        {
            const Document *const self = static_cast<const Document *const>(this);
            auto weakPtr               = self->contextPtr->getStream(index);
            if (auto ptr = weakPtr.lock())
                return ptr;
            throw std::runtime_error("SubDocument has been deleted");
        }
    
        inline Type getType() const noexcept { return fileType; }
        inline QString getFilePath() const noexcept { return filePath; }
    };
    
    // Audio document
    class AudioSubDocument final
        : public CRTPSubDocument<AudioDocumentType, AudioSubDocument, AudioContext> {
        const QStringList &suffixList = Vivy::Utils::audioFileSuffix;
        std::unique_ptr<AudioContext> contextPtr{ nullptr };
    
        void initFromPath(const QString &);
    
        explicit AudioSubDocument() = default;
        friend CRTPSubDocument<AudioDocumentType, AudioSubDocument, AudioContext>;
    
    public:
        QString getElementName() const noexcept;
        QJsonDocument getProperties() const noexcept;
    };
    
    // Video document
    class VideoSubDocument final
        : public CRTPSubDocument<VideoDocumentType, VideoSubDocument, VideoContext> {
        static constexpr inline bool hasContext = true;
        const QStringList &suffixList           = Vivy::Utils::videoFileSuffix;
        std::unique_ptr<VideoContext> contextPtr{ nullptr };
    
        void initFromPath(const QString &);
    
        explicit VideoSubDocument() noexcept = default;
        friend CRTPSubDocument<VideoDocumentType, VideoSubDocument, VideoContext>;
    
    public:
        QString getElementName() const noexcept;
        QJsonDocument getProperties() const noexcept;
    };
    
    // ASS document
    class AssSubDocument final : public CRTPSubDocument<AssDocumentType, AssSubDocument> {
        static constexpr inline bool hasContext = false;
        const QStringList &suffixList           = Vivy::Utils::assFileSuffix;
    
    public:
        static std::unique_ptr<AssSubDocument> fromInternal(const QJsonValue &internal,
                                                            const QString &baseAss) noexcept
        {
            auto ret = std::unique_ptr<AssSubDocument>(new AssSubDocument());
            ret->logDebug() << "Init ASS subdocument from internal";
            ret->filePath = baseAss;
    
            try {
                ret->initFromInternal(internal); // May throw
            } catch (const std::runtime_error &e) {
                ret->logDebug() << "Failed to init ASS subdocument from internal: " << e.what();
                ret.reset();
                // FIXME: currently terminate, but should be changed to stop the loading of the document
                throw e;
            }
    
            return ret;
        }
    
    private:
        void initFromPath(const QString &);
        void initFromInternal(const QJsonValue &);
    
        explicit AssSubDocument() noexcept = default;
        friend CRTPSubDocument<AssDocumentType, AssSubDocument, void>;
    
    public:
        QString getElementName() const noexcept;
        QJsonDocument getProperties() const noexcept;
        Ass::AssFactory *getFactory() noexcept;
        QJsonArray getInternalAss() noexcept;
    
        const QVector<Ass::LinePtr> &getLines() const noexcept;
        const QVector<Ass::StylePtr> &getStyles() const noexcept;
    
        void setFilePath(QString filepath) noexcept;
        void setInternalAss(bool b) noexcept;
        bool haveInternalAss() const noexcept;
    
    private:
        QVector<Ass::StylePtr> styles;
        QVector<Ass::LinePtr> lines;
        Ass::AssFactory *assFactory;
        bool internalAss{ false };
    };
    }