From c4e327b9953faec56d80f4816ca23924243822cd Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 27 Aug 2021 15:04:59 +0200
Subject: [PATCH] LIB: Enable the get streams functions in subdocuments only if
 it has a context!

Spoiler alert: ugly C++ here.
---
 src/Lib/Document/CRTPSubDocument.hh           | 70 +++++++++++++------
 .../CRTPSubDocument/AudioSubDocument.cc       | 34 ---------
 .../CRTPSubDocument/VideoSubDocument.cc       | 34 ---------
 3 files changed, 48 insertions(+), 90 deletions(-)

diff --git a/src/Lib/Document/CRTPSubDocument.hh b/src/Lib/Document/CRTPSubDocument.hh
index 5963b9c0..c89f25c5 100644
--- a/src/Lib/Document/CRTPSubDocument.hh
+++ b/src/Lib/Document/CRTPSubDocument.hh
@@ -1,5 +1,4 @@
-#ifndef VIVY_CRTP_DOCUMENT_H
-#define VIVY_CRTP_DOCUMENT_H
+#pragma once
 
 #ifndef __cplusplus
 #error "This is a C++ header"
@@ -10,10 +9,13 @@
 #include "../Video.hh"
 #include "../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 CRTPSubDocument {
+template <class CRTPSubDocumentType, class Document, class Context> class CRTPSubDocument {
 public:
     using Type = CRTPSubDocumentType;
     friend std::unique_ptr<Document>;
@@ -47,56 +49,83 @@ public:
         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> {
+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>;
+    friend CRTPSubDocument<AudioDocumentType, AudioSubDocument, AudioContext>;
 
 public:
-    int getDefaultStreamIndex() const noexcept;
-    AudioContext::StreamPtr getDefaultStream() const noexcept;
-    AudioContext::StreamPtr getStream(int index) const noexcept;
-
     QString getElementName() const noexcept;
     QJsonDocument getProperties() const noexcept;
 };
 
 // Video document
-class VideoSubDocument final : public CRTPSubDocument<VideoDocumentType, VideoSubDocument> {
-    const QStringList &suffixList = Vivy::Utils::videoFileSuffix;
+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>;
+    friend CRTPSubDocument<VideoDocumentType, VideoSubDocument, VideoContext>;
 
 public:
-    int getDefaultStreamIndex() const noexcept;
-    VideoContext::StreamPtr getDefaultStream() const noexcept;
-    VideoContext::StreamPtr getStream(int index) const noexcept;
-
     QString getElementName() const noexcept;
     QJsonDocument getProperties() const noexcept;
 };
 
 // ASS document
-class AssSubDocument final : public CRTPSubDocument<AssDocumentType, AssSubDocument> {
-    const QStringList &suffixList = Vivy::Utils::assFileSuffix;
+class AssSubDocument final : public CRTPSubDocument<AssDocumentType, AssSubDocument, void> {
+    static constexpr inline bool hasContext = false;
+    const QStringList &suffixList           = Vivy::Utils::assFileSuffix;
 
     void initFromPath(const QString &);
 
     explicit AssSubDocument() noexcept = default;
-    friend CRTPSubDocument<AssDocumentType, AssSubDocument>;
+    friend CRTPSubDocument<AssDocumentType, AssSubDocument, void>;
 
 public:
     QString getElementName() const noexcept;
@@ -109,7 +138,4 @@ private:
     QVector<Ass::StylePtr> styles;
     QVector<Ass::LinePtr> lines;
 };
-
 }
-
-#endif // VIVY_CRTP_DOCUMENT_H
diff --git a/src/Lib/Document/CRTPSubDocument/AudioSubDocument.cc b/src/Lib/Document/CRTPSubDocument/AudioSubDocument.cc
index d1e68c08..c26b99e4 100644
--- a/src/Lib/Document/CRTPSubDocument/AudioSubDocument.cc
+++ b/src/Lib/Document/CRTPSubDocument/AudioSubDocument.cc
@@ -2,40 +2,6 @@
 
 using namespace Vivy;
 
-// Get the default stream index or -1 if not possible
-int
-AudioSubDocument::getDefaultStreamIndex() const noexcept
-{
-    if (auto ptr = getDefaultStream()) {
-        return ptr->getStreamIndex();
-    } else {
-        return -1;
-    }
-}
-
-// Get a pointer to the default stream, nullptr if not possible
-AudioContext::StreamPtr
-AudioSubDocument::getDefaultStream() const noexcept
-{
-    if (auto ptr = contextPtr->getDefaultStream().lock()) {
-        return ptr;
-    } else {
-        qCritical() << "Document deleted!";
-        return nullptr;
-    }
-}
-
-// Get the stream asked for, nullptr if no stream or if the index is invalid
-AudioContext::StreamPtr
-AudioSubDocument::getStream(int index) const noexcept
-{
-    if (auto ptr = contextPtr->getStream(index).lock()) {
-        return ptr;
-    } else {
-        return nullptr;
-    }
-}
-
 // Init an audio sub-document from a file
 void
 AudioSubDocument::initFromPath(const QString &path)
diff --git a/src/Lib/Document/CRTPSubDocument/VideoSubDocument.cc b/src/Lib/Document/CRTPSubDocument/VideoSubDocument.cc
index eaa2a7ed..085131ab 100644
--- a/src/Lib/Document/CRTPSubDocument/VideoSubDocument.cc
+++ b/src/Lib/Document/CRTPSubDocument/VideoSubDocument.cc
@@ -2,40 +2,6 @@
 
 using namespace Vivy;
 
-// Get the default stream index or -1 if not possible
-int
-VideoSubDocument::getDefaultStreamIndex() const noexcept
-{
-    if (auto ptr = getDefaultStream()) {
-        return ptr->getStreamIndex();
-    } else {
-        return -1;
-    }
-}
-
-// Get a pointer to the default stream, nullptr if not possible
-VideoContext::StreamPtr
-VideoSubDocument::getDefaultStream() const noexcept
-{
-    if (auto ptr = contextPtr->getDefaultStream().lock()) {
-        return ptr;
-    } else {
-        qCritical() << "Document deleted!";
-        return nullptr;
-    }
-}
-
-// Get the stream asked for, nullptr if no stream or if the index is invalid
-VideoContext::StreamPtr
-VideoSubDocument::getStream(int index) const noexcept
-{
-    if (auto ptr = contextPtr->getStream(index).lock()) {
-        return ptr;
-    } else {
-        return nullptr;
-    }
-}
-
 // Init a video sub-document from a file
 void
 VideoSubDocument::initFromPath(const QString &path)
-- 
GitLab