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