From 906459d9bf08b03b585854ce47ed29548ff41d76 Mon Sep 17 00:00:00 2001
From: Elliu <elliu@hashi.re>
Date: Fri, 22 Jul 2022 21:02:53 +0200
Subject: [PATCH] Give easy access to rootVivyDocument[View] from various views

Inherit from AbstractVivyDocumentNeeder for classes needing
easy access to their rootVivyDocument[Const] and
rootVivyDocumentView[Const].
Make the change for AudioVisualizer and TimingScene for now
---
 src/UI/AbstractVivyDocumentNeeder.hh          | 28 ++++++++++
 src/UI/DocumentViews/AudioVisualizer.cc       | 16 +++---
 src/UI/DocumentViews/AudioVisualizer.hh       |  5 +-
 .../AudioVisualizer/TimingScene.cc            | 54 +++++++------------
 .../AudioVisualizer/TimingScene.hh            |  9 ++--
 src/UI/VivyDocumentView.cc                    |  2 +-
 src/UI/VivyDocumentView.hh                    |  3 +-
 7 files changed, 63 insertions(+), 54 deletions(-)
 create mode 100644 src/UI/AbstractVivyDocumentNeeder.hh

diff --git a/src/UI/AbstractVivyDocumentNeeder.hh b/src/UI/AbstractVivyDocumentNeeder.hh
new file mode 100644
index 00000000..555a5ac3
--- /dev/null
+++ b/src/UI/AbstractVivyDocumentNeeder.hh
@@ -0,0 +1,28 @@
+#pragma once
+
+#ifndef __cplusplus
+#error "This is a C++ header"
+#endif
+
+#include "../Lib/Document/VivyDocument.hh"
+#include "VivyDocumentView.hh"
+
+namespace Vivy
+{
+class AbstractVivyDocumentNeeder {
+protected:
+    explicit AbstractVivyDocumentNeeder(VivyDocumentView &view)
+        : rootVivyDocumentView(view)
+        , rootVivyDocumentViewConst(rootVivyDocumentView)
+        , rootVivyDocument(*rootVivyDocumentView.getDocument())
+        , rootVivyDocumentConst(rootVivyDocument)
+    {
+    }
+
+    VivyDocumentView &rootVivyDocumentView;
+    const VivyDocumentView &rootVivyDocumentViewConst;
+
+    VivyDocument &rootVivyDocument;
+    const VivyDocument &rootVivyDocumentConst;
+};
+}
diff --git a/src/UI/DocumentViews/AudioVisualizer.cc b/src/UI/DocumentViews/AudioVisualizer.cc
index 6e6dabd0..62582f54 100644
--- a/src/UI/DocumentViews/AudioVisualizer.cc
+++ b/src/UI/DocumentViews/AudioVisualizer.cc
@@ -5,10 +5,10 @@ using namespace Vivy;
 
 #define MAXPIXVALUE 7 // Some magix AV magic stuff
 
-AudioVisualizer::AudioVisualizer(AudioContext::StreamPtr stream,
-                                 std::weak_ptr<VivyDocumentView> rootView_, QWidget *parent)
+AudioVisualizer::AudioVisualizer(AudioContext::StreamPtr stream, VivyDocumentView &rootView,
+                                 QWidget *parent)
     : QWidget(parent)
-    , rootView(rootView_)
+    , AbstractVivyDocumentNeeder(rootView)
     , audioStream(stream)
 {
     if (!audioStream->isDecoded()) {
@@ -69,7 +69,7 @@ AudioVisualizer::AudioVisualizer(AudioContext::StreamPtr stream,
 void
 AudioVisualizer::printSpectrum(QImage pixmap, AudioContext::StreamPtr stream) noexcept
 {
-    TimingScene *timingScene = new TimingScene(pixmap, stream, rootView, this);
+    TimingScene *timingScene = new TimingScene(pixmap, stream, rootVivyDocumentView, this);
     TimingView *timingView   = new TimingView(timingScene, pixmap, stream, this);
     TimingParams *params     = new TimingParams(this);
 
@@ -85,10 +85,6 @@ AudioVisualizer::printSpectrum(QImage pixmap, AudioContext::StreamPtr stream) no
             &TimingAxis::refreshTicks);
     connect(params->getRebuildSceneButton(), &QPushButton::released, timingScene,
             &TimingScene::rebuildScene);
-    // FIXME: should we replace rootView with a shared_ptr
-    // or is this expected weak_ptr usage?
-    if (auto p = rootView.lock())
-        if (auto sp = p.get())
-            connect(sp, &VivyDocumentView::assSubDocumentChanged, timingScene,
-                    &TimingScene::rebuildScene);
+    connect(&rootVivyDocumentView, &VivyDocumentView::assSubDocumentChanged, timingScene,
+            &TimingScene::rebuildScene);
 }
diff --git a/src/UI/DocumentViews/AudioVisualizer.hh b/src/UI/DocumentViews/AudioVisualizer.hh
index 3c169ac9..ca1cd3a2 100644
--- a/src/UI/DocumentViews/AudioVisualizer.hh
+++ b/src/UI/DocumentViews/AudioVisualizer.hh
@@ -13,11 +13,10 @@
 
 namespace Vivy
 {
-class AudioVisualizer final : public QWidget {
+class AudioVisualizer final : public QWidget, public AbstractVivyDocumentNeeder {
     Q_OBJECT
 
 private:
-    std::weak_ptr<VivyDocumentView> rootView;
     AudioContext::StreamPtr audioStream;
 
 private:
@@ -37,7 +36,7 @@ private:
     using RDFTContextPtr = std::unique_ptr<RDFTContext, decltype(rdftContextDeleter)>;
 
 public:
-    explicit AudioVisualizer(AudioContext::StreamPtr, std::weak_ptr<VivyDocumentView> rootView,
+    explicit AudioVisualizer(AudioContext::StreamPtr, VivyDocumentView &rootView,
                              QWidget *parent = nullptr);
     ~AudioVisualizer() noexcept override = default;
 
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc b/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
index dcca1fb1..1f492d67 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
@@ -25,15 +25,15 @@
 
 using namespace Vivy;
 
-TimingScene::TimingScene(QWidget *parent) noexcept
-    : QGraphicsScene(parent)
-{
-}
+//TimingScene::TimingScene(QWidget *parent) noexcept
+//    : QGraphicsScene(parent)
+//{
+//}
 
-TimingScene::TimingScene(QImage img_, AudioContext::StreamPtr stream,
-                         std::weak_ptr<VivyDocumentView> rootView_, QWidget *parent) noexcept
+TimingScene::TimingScene(QImage img_, AudioContext::StreamPtr stream, VivyDocumentView &rootView,
+                         QWidget *parent) noexcept
     : QGraphicsScene(parent)
-    , rootView(rootView_)
+    , AbstractVivyDocumentNeeder(rootView)
     , img(img_)
     , audioStream(stream)
 {
@@ -81,38 +81,24 @@ TimingScene::rebuildScene()
     addItem(cursor);
     cursor->setPos(0, TimingUtils::axisHeight());
 
-    // FIXME: bruh
-    if (auto p = rootView.lock()) {
-        if (auto v = p.get()) {
-            if (auto d = v->getDocument()) {
-                if (auto assDocument = d->getAssSubDocument()) {
-                    QVector<Ass::LinePtr> lines = assDocument->getLines();
-                    for (int i = 0; i < lines.size(); ++i) {
-                        if (auto line = lines.at(i).get()) {
-                            TimingLine *l = new TimingLine(line, i);
-                            l->setVisible(false);
-                            addItem(l);
-                            timingLines.append(l);
-                            if (auto p = rootView.lock()) {
-                                if (auto assLinesModel = p->getAssLinesModel()) {
-                                    connect(l, &TimingLine::lineChanged, assLinesModel,
-                                            &AssLinesModel::updateLine);
-                                }
-                            }
-                        }
-                    }
+    if (auto assDocument = rootVivyDocument.getAssSubDocument()) {
+        QVector<Ass::LinePtr> lines = assDocument->getLines();
+        for (int i = 0; i < lines.size(); ++i) {
+            if (auto line = lines.at(i).get()) {
+                TimingLine *l = new TimingLine(line, i);
+                l->setVisible(false);
+                addItem(l);
+                timingLines.append(l);
+                if (auto assLinesModel = rootVivyDocumentView.getAssLinesModel()) {
+                    connect(l, &TimingLine::lineChanged, assLinesModel, &AssLinesModel::updateLine);
                 }
             }
         }
     }
 
-    // FIXME: do we need to "disconnect" it when assLinesView or *this is destroyed,
-    // or is this taken care of by Qt alone?
-    if (auto p = rootView.lock()) {
-        if (auto assLinesView = p->getAssLinesView()) {
-            connect(assLinesView, &AssLinesView::updateSelectedLines, this,
-                    &TimingScene::updateSelectedLines);
-        }
+    if (auto assLinesView = rootVivyDocumentView.getAssLinesView()) {
+        connect(assLinesView, &AssLinesView::updateSelectedLines, this,
+                &TimingScene::updateSelectedLines);
     }
 }
 
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingScene.hh b/src/UI/DocumentViews/AudioVisualizer/TimingScene.hh
index df331c07..a6d8ea5d 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingScene.hh
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingScene.hh
@@ -9,11 +9,13 @@
 #include "../../VivyDocumentView.hh"
 #include "../AssLinesView.hh"
 
+#include "../../AbstractVivyDocumentNeeder.hh"
+
 #include "TimingLine.hh"
 
 namespace Vivy
 {
-class TimingScene final : public QGraphicsScene {
+class TimingScene final : public QGraphicsScene, public AbstractVivyDocumentNeeder {
     Q_OBJECT
 
 public:
@@ -24,12 +26,11 @@ public:
     static inline constexpr QColor startColour = QColor(127, 0, 127);
     static inline constexpr QColor endColour   = QColor(0, 127, 0);
 
-    explicit TimingScene(QWidget *parent = nullptr) noexcept;
-    explicit TimingScene(QImage, AudioContext::StreamPtr, std::weak_ptr<VivyDocumentView>,
+    //explicit TimingScene(QWidget *parent = nullptr) noexcept;
+    explicit TimingScene(QImage, AudioContext::StreamPtr, VivyDocumentView &,
                          QWidget * = nullptr) noexcept;
 
 private:
-    std::weak_ptr<VivyDocumentView> rootView;
     QGraphicsPixmapItem *backgroundImg{ nullptr };
     QImage img;
     TimingCursor *cursor;
diff --git a/src/UI/VivyDocumentView.cc b/src/UI/VivyDocumentView.cc
index 94f2213a..94dafc29 100644
--- a/src/UI/VivyDocumentView.cc
+++ b/src/UI/VivyDocumentView.cc
@@ -156,7 +156,7 @@ VivyDocumentView::loadAudioView() noexcept
 
     // Kubat: don't check, may throw an error but don't think we can
     // recover from it.
-    AudioVisualizer *visualizerInner = new AudioVisualizer(stream, shared_from_this(), visualizer);
+    AudioVisualizer *visualizerInner = new AudioVisualizer(stream, *this, visualizer);
     Utils::deleteInternalWidget(visualizer);
     visualizer->setWidget(visualizerInner);
     visualizer->layout()->setAlignment(visualizerInner, Qt::AlignTop);
diff --git a/src/UI/VivyDocumentView.hh b/src/UI/VivyDocumentView.hh
index 54adc495..b07c3ccf 100644
--- a/src/UI/VivyDocumentView.hh
+++ b/src/UI/VivyDocumentView.hh
@@ -16,8 +16,7 @@
 
 namespace Vivy
 {
-class VivyDocumentView final : public AbstractDocumentView,
-                               public std::enable_shared_from_this<VivyDocumentView> {
+class VivyDocumentView final : public AbstractDocumentView {
     Q_OBJECT
     VIVY_UNMOVABLE_OBJECT(VivyDocumentView)
     VIVY_APP_LOGGABLE_OBJECT(VivyDocumentView, logger)
-- 
GitLab