File indexing completed on 2024-05-05 04:38:10

0001 /*
0002     SPDX-FileCopyrightText: 2008 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef REPOSITORYMANAGER_H
0008 #define REPOSITORYMANAGER_H
0009 
0010 #include "abstractitemrepository.h"
0011 #include "itemrepositoryregistry.h"
0012 
0013 #include <QMutexLocker>
0014 
0015 #include <type_traits>
0016 #include <utility>
0017 
0018 namespace KDevelop {
0019 /// This class helps managing the lifetime of a global item repository, and protecting the consistency.
0020 /// Especially it helps doing thread-safe lazy repository-creation.
0021 template <class ItemRepositoryType, bool unloadingEnabled = true, bool lazy = true>
0022 struct RepositoryManager
0023 {
0024 public:
0025     using Mutex = std::decay_t<decltype(*std::declval<ItemRepositoryType>().mutex())>;
0026     explicit RepositoryManager(const QString& name, Mutex* mutex, int version = 1,
0027                                ItemRepositoryRegistry& registry = globalItemRepositoryRegistry())
0028         : m_name(name)
0029         , m_version(version)
0030         , m_registry(registry)
0031         , m_mutex(mutex)
0032     {
0033         if (!lazy) {
0034             createRepository();
0035         }
0036     }
0037 
0038     Q_DISABLE_COPY(RepositoryManager)
0039 
0040     ItemRepositoryType * repository() const
0041     {
0042         if (!m_repository) {
0043             createRepository();
0044         }
0045 
0046         return static_cast<ItemRepositoryType*>(m_repository);
0047     }
0048 
0049     inline ItemRepositoryType* operator->() const
0050     {
0051         return repository();
0052     }
0053 
0054 private:
0055     void createRepository() const
0056     {
0057         if (!m_repository) {
0058             QMutexLocker lock(&m_registry.mutex());
0059             if (!m_repository) {
0060                 m_repository = new ItemRepositoryType(m_name, m_mutex, &m_registry, m_version);
0061                 (*this)->setUnloadingEnabled(unloadingEnabled);
0062             }
0063         }
0064     }
0065 
0066     QString m_name;
0067     int m_version;
0068     ItemRepositoryRegistry& m_registry;
0069     Mutex* m_mutex;
0070     mutable AbstractItemRepository* m_repository = nullptr;
0071 };
0072 }
0073 
0074 #endif // REPOSITORYMANAGER_H