Albert
Loading...
Searching...
No Matches
plugindependency.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2024 Manuel Schneider
2// SPDX-License-Identifier: MIT
3
4#pragma once
5#include <QCoreApplication>
6#include <albert/albert.h>
7#include <albert/export.h>
9#include <albert/logging.h>
10
11namespace albert::util
12{
13
14template<class T>
16{
17public:
18
19 inline operator T() const { return dependency_; }
20 inline operator bool() const { return dependency_ != nullptr; }
21 const T* operator->() const { return dependency_; }
22 T* operator->() { return dependency_; }
23 const T* get() const { return dependency_; }
24 T* get() { return dependency_; }
25
26protected:
27
28 Dependency() = default;
29 ~Dependency() = default;
30
31 T *dependency_ = nullptr;
32};
33
43template<class T>
44class ALBERT_EXPORT StrongDependency final : public Dependency<T>
45{
46public:
47
53 StrongDependency(QString id)
54 {
55 try
56 {
57 this->dependency_ = dynamic_cast<T*>(extensionRegistry().extensions().at(id));
58
59 if (!this->dependency_)
60 throw std::runtime_error(
61 QCoreApplication::translate(
62 "Dependency",
63 "Extension '%1' is available, but it is not of the expected type."
64 ).arg(id).toStdString());
65 }
66 catch (const std::out_of_range &)
67 {
68 throw std::runtime_error(
69 QCoreApplication::translate(
70 "Dependency",
71 "The required extension '%1' is not available."
72 ).arg(id).toStdString());
73 }
74 }
75};
76
77
89template<class T>
90class ALBERT_EXPORT WeakDependency final : public Dependency<T>
91{
92public:
93
97 explicit WeakDependency(const QString &id, std::function<void(bool)> on_registered = {}):
98 callback(on_registered),
99 id_(id)
100 {
101 try {
102 this->dependency_ = dynamic_cast<T*>(extensionRegistry().extensions().at(id));
103 if (!this->dependency_)
104 WARN << QStringLiteral("Found '%1' but failed casting to expected type.").arg(id);
105 } catch (const std::out_of_range &) { /* okay, optional */ }
106
107 conn_add_ = QObject::connect(&albert::extensionRegistry(), &ExtensionRegistry::added,
108 [this](Extension *e){ onRegistered(e);});
109
110 conn_rem_ = QObject::connect(&albert::extensionRegistry(), &ExtensionRegistry::removed,
111 [this](Extension *e){ onDeregistered(e);});
112 }
113
115 {
116 QObject::disconnect(conn_add_);
117 QObject::disconnect(conn_rem_);
118 }
119
120 std::function<void(bool)> callback;
121
122private:
123
124 void onRegistered(Extension *e)
125 {
126 if (e->id() != this->id_)
127 return;
128
129 if (!this->dependency_)
130 {
131 if (auto *d = dynamic_cast<T*>(e); d)
132 {
133 this->dependency_ = d;
134 if (callback)
135 callback(true);
136 }
137 else
138 WARN << QStringLiteral("Failed casting '%1' to expected type.").arg(this->id_);
139 }
140 else
141 CRIT << "WeakDependency already set. Internal logic error?";
142 }
143
144 void onDeregistered(Extension *e)
145 {
146
147 if (e->id() != this->id_)
148 return;
149
150 if (this->dependency_)
151 {
152 if (auto *d = dynamic_cast<T*>(e); d)
153 {
154 if (callback)
155 callback(false); // the dependency should still be usable in the callback
156 this->dependency_ = nullptr;
157 }
158 else
159 WARN << QStringLiteral("Failed casting '%1' to expected type.").arg(this->id_);
160 }
161 else
162 CRIT << "WeakDependency already unset. Internal logic error?";
163 }
164
165 QMetaObject::Connection conn_add_;
166 QMetaObject::Connection conn_rem_;
167 QString id_;
168
169};
170
171}
const std::map< QString, Extension * > & extensions() const
Get map of all registered extensions.
Abstract extension class.
Definition extension.h:19
virtual QString id() const =0
The identifier of this extension.
Definition plugindependency.h:16
const T * operator->() const
Definition plugindependency.h:21
T * get()
Definition plugindependency.h:24
T * operator->()
Definition plugindependency.h:22
const T * get() const
Definition plugindependency.h:23
T * dependency_
Definition plugindependency.h:31
Convenience holder class for plugin hard dependencies.
Definition plugindependency.h:45
StrongDependency(QString id)
Constructs a StrongDependency with id.
Definition plugindependency.h:53
Convenience holder class for plugin soft dependencies.
Definition plugindependency.h:91
WeakDependency(const QString &id, std::function< void(bool)> on_registered={})
Constructs a WeakDependency with id and callback on_registered.
Definition plugindependency.h:97
~WeakDependency()
Definition plugindependency.h:114
std::function< void(bool)> callback
Definition plugindependency.h:120
#define WARN
Creates a log object (level warning) you can use to pipe text into (<<).
Definition logging.h:20
#define CRIT
Creates a log object (level critial) you can use to pipe text into (<<).
Definition logging.h:23
Albert utility namespace.
Definition albert.h:14
const ExtensionRegistry & extensionRegistry()
Returns a const reference to the central ExtensionRegistry.