Sélectionner une révision Git
PreCompiledHeaders.cmake
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 };
};
}