From 0641a598e7ef3d1d6935bf7ca703207e2c31de3d Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 30 Jul 2021 14:21:25 +0200
Subject: [PATCH] LIB: Will remove duplicate code with CRTP on the Store object
 (store for documents and scripts!)

---
 src/Lib/CRTPStore.hh                  | 61 +++++++++++++++++++++++++++
 src/Lib/Document/VivyDocumentStore.cc | 23 ----------
 src/Lib/Document/VivyDocumentStore.hh | 30 ++++---------
 3 files changed, 69 insertions(+), 45 deletions(-)
 create mode 100644 src/Lib/CRTPStore.hh

diff --git a/src/Lib/CRTPStore.hh b/src/Lib/CRTPStore.hh
new file mode 100644
index 00000000..278e8e2b
--- /dev/null
+++ b/src/Lib/CRTPStore.hh
@@ -0,0 +1,61 @@
+#pragma once
+
+#ifndef __cplusplus
+#error "This is a C++ header"
+#endif
+
+#include "Utils.hh"
+#include <QString>
+
+#define VIVY_STORAGE_CLASS(theClassName, theDocumentName)                                          \
+    VIVY_UNMOVABLE_OBJECT(theClassName)                                                            \
+    friend CRTPStore<theClassName, theDocumentName>;
+
+namespace Vivy
+{
+// For example:
+// VivyDocumentStore final : public
+//      CRTPStore<VivyDocumentStore,    <- Child class
+//                VivyDocument>         <- Document type to hold
+template <class Store, class Document> class CRTPStore {
+    VIVY_UNMOVABLE_OBJECT(CRTPStore)
+    using Uuid = typename Document::Uuid;
+
+protected:
+    QMap<Uuid, std::shared_ptr<Document>> documents{};
+    uint newDocumentNumber{ 1 };
+    static inline const QString newDocumentBaseName = QStringLiteral("Untitled ");
+
+protected:
+    explicit CRTPStore() noexcept = default;
+
+public:
+    // Close a document, please be sure to not used any of the dangling
+    // references to the closed document...
+    void closeDocument(const Uuid &uuid) noexcept
+    {
+        auto *self = static_cast<Store *>(this);
+        self->documents.remove(uuid);
+    }
+
+    // Get stored documents
+    std::shared_ptr<Document> getDocument(const Uuid &uuid) const
+    {
+        auto *self = static_cast<Store *>(this);
+
+        if (!self->documents.contains(uuid)) {
+            qCritical() << "Couldn't find the document " << uuid;
+            throw std::runtime_error("Can't find the document");
+        }
+
+        return self->documents.value(uuid);
+    }
+
+    // Get to see if a document is already present or not
+    [[nodiscard("handle-it")]] bool isDocumentPresent(const Uuid &uuid) noexcept
+    {
+        auto *self = static_cast<Store *>(this);
+        return self->documents.count(uuid) >= 1;
+    }
+};
+}
diff --git a/src/Lib/Document/VivyDocumentStore.cc b/src/Lib/Document/VivyDocumentStore.cc
index bdf6674d..68939f04 100644
--- a/src/Lib/Document/VivyDocumentStore.cc
+++ b/src/Lib/Document/VivyDocumentStore.cc
@@ -22,12 +22,6 @@ VivyDocumentStore::loadDocument(const QString &file)
     }
 }
 
-bool
-VivyDocumentStore::isDocumentPresent(const VivyDocument::Uuid &uuid) noexcept
-{
-    return documents.count(uuid) >= 1;
-}
-
 std::shared_ptr<VivyDocument>
 VivyDocumentStore::newDocument(VivyDocument::Options opt)
 {
@@ -43,20 +37,3 @@ VivyDocumentStore::newDocument(VivyDocument::Options opt)
         throw std::runtime_error("Failed to create the document");
     }
 }
-
-void
-VivyDocumentStore::closeDocument(const VivyDocument::Uuid &uuid) noexcept
-{
-    qDebug() << "Store is closing the document " << uuid;
-    documents.remove(uuid);
-}
-
-std::shared_ptr<VivyDocument>
-VivyDocumentStore::getDocument(const VivyDocument::Uuid &uuid) const
-{
-    if (!documents.contains(uuid)) {
-        qCritical() << "Couldn't find the document " << uuid;
-        throw std::runtime_error("Can't find the document");
-    }
-    return documents.value(uuid);
-}
diff --git a/src/Lib/Document/VivyDocumentStore.hh b/src/Lib/Document/VivyDocumentStore.hh
index f25fd3f7..b319ef7d 100644
--- a/src/Lib/Document/VivyDocumentStore.hh
+++ b/src/Lib/Document/VivyDocumentStore.hh
@@ -1,8 +1,12 @@
-#ifndef VIVY_DOCUMENTSTORE_H
-#define VIVY_DOCUMENTSTORE_H
+#pragma once
+
+#ifndef __cplusplus
+#error "This is a C++ header"
+#endif
 
 #include "VivyDocument.hh"
 #include "../Utils.hh"
+#include "../CRTPStore.hh"
 
 #include <QMap>
 #include <QString>
@@ -10,33 +14,15 @@
 
 namespace Vivy
 {
-class VivyDocumentStore final {
-    VIVY_UNMOVABLE_OBJECT(VivyDocumentStore)
+class VivyDocumentStore final : public CRTPStore<VivyDocumentStore, VivyDocument> {
+    VIVY_STORAGE_CLASS(VivyDocumentStore, VivyDocument)
 
 public:
     explicit VivyDocumentStore() noexcept = default;
-    ~VivyDocumentStore() noexcept         = default;
 
     /* Create/load documents */
     std::shared_ptr<VivyDocument> loadDocument(const QString &file);
     std::shared_ptr<VivyDocument> newDocument(VivyDocument::Options opt = VivyDocument::NoOption);
-
-    /* Get to see if a document is already present or not */
-    [[nodiscard("handle-it")]] bool isDocumentPresent(const VivyDocument::Uuid &) noexcept;
-
-    /* Close a document, please be sure to not used any of the dangling
-     * references to the closed document... */
-    void closeDocument(const VivyDocument::Uuid &uuid) noexcept;
-
-    /* Get stored documents */
-    std::shared_ptr<VivyDocument> getDocument(const VivyDocument::Uuid &uuid) const;
-
-private:
-    QMap<VivyDocument::Uuid, std::shared_ptr<VivyDocument>> documents;
-    uint newDocumentNumber{ 1 };
-    static inline const QString newDocumentBaseName = "Untitled ";
 };
 
 }
-
-#endif // VIVY_DOCUMENTSTORE_H
-- 
GitLab