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
12{
13
18template<class T>
20{
21public:
22
23 inline operator T() const { return dependency_; }
24 inline operator bool() const { return dependency_ != nullptr; }
25 const T* operator->() const { return dependency_; }
26 T* operator->() { return dependency_; }
27 const T* get() const { return dependency_; }
28 T* get() { return dependency_; }
29
30protected:
31
32 T *dependency_ = nullptr;
33};
34
44template<class T>
45class ALBERT_EXPORT StrongDependency final : public Dependency<T>
46{
47public:
48
54 StrongDependency(QString id)
55 {
56 try
57 {
58 this->dependency_ = dynamic_cast<T*>(extensionRegistry().extensions().at(id));
59
60 if (!this->dependency_)
61 throw std::runtime_error(
62 QCoreApplication::translate(
63 "Dependency",
64 "Extension '%1' is available, but it is not of the expected type."
65 ).arg(id).toStdString());
66 }
67 catch (const std::out_of_range &)
68 {
69 throw std::runtime_error(
70 QCoreApplication::translate(
71 "Dependency",
72 "The required extension '%1' is not available."
73 ).arg(id).toStdString());
74 }
75 }
76};
77
78
90template<class T>
91class ALBERT_EXPORT WeakDependency final : public Dependency<T>
92{
93public:
94
98 explicit WeakDependency(const QString &id, std::function<void(bool)> on_registered = {}):
99 callback(on_registered),
100 id_(id)
101 {
102 try {
103 this->dependency_ = dynamic_cast<T*>(extensionRegistry().extensions().at(id));
104 if (!this->dependency_)
105 WARN << QString("Found '%1' but failed casting to expected type.").arg(id);
106 } catch (const std::out_of_range &) { /* okay, optional */ }
107
108 conn_add_ = QObject::connect(&albert::extensionRegistry(), &ExtensionRegistry::added,
109 [this](Extension *e){ onRegistered(e);});
110
111 conn_rem_ = QObject::connect(&albert::extensionRegistry(), &ExtensionRegistry::removed,
112 [this](Extension *e){ onDeregistered(e);});
113 }
114
116 {
117 QObject::disconnect(conn_add_);
118 QObject::disconnect(conn_rem_);
119 }
120
121 std::function<void(bool)> callback;
122
123private:
124
125 void onRegistered(Extension *e)
126 {
127 if (e->id() != this->id_)
128 return;
129
130 if (!this->dependency_)
131 {
132 if (auto *d = dynamic_cast<T*>(e); d)
133 {
134 this->dependency_ = d;
135 if (callback)
136 callback(true);
137 }
138 else
139 WARN << QString("Failed casting '%1' to expected type.").arg(this->id_);
140 }
141 else
142 CRIT << "WeakDependency already set. Internal logic error?";
143 }
144
145 void onDeregistered(Extension *e)
146 {
147
148 if (e->id() != this->id_)
149 return;
150
151 if (this->dependency_)
152 {
153 if (auto *d = dynamic_cast<T*>(e); d)
154 {
155 if (callback)
156 callback(false); // the dependency should still be usable in the callback
157 this->dependency_ = nullptr;
158 }
159 else
160 WARN << QString("Failed casting '%1' to expected type.").arg(this->id_);
161 }
162 else
163 CRIT << "WeakDependency already unset. Internal logic error?";
164 }
165
166 QMetaObject::Connection conn_add_;
167 QMetaObject::Connection conn_rem_;
168 QString id_;
169
170};
171
172}
Base class for StrongDependency and WeakDependency.
Definition plugindependency.h:20
T * dependency_
Definition plugindependency.h:32
const T * get() const
Definition plugindependency.h:27
const T * operator->() const
Definition plugindependency.h:25
T * get()
Definition plugindependency.h:28
T * operator->()
Definition plugindependency.h:26
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.
Convenience holder class for plugin hard dependencies.
Definition plugindependency.h:46
StrongDependency(QString id)
Constructs a StrongDependency with id.
Definition plugindependency.h:54
Convenience holder class for plugin soft dependencies.
Definition plugindependency.h:92
~WeakDependency()
Definition plugindependency.h:115
WeakDependency(const QString &id, std::function< void(bool)> on_registered={})
Constructs a WeakDependency with id and callback on_registered.
Definition plugindependency.h:98
std::function< void(bool)> callback
Definition plugindependency.h:121
#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
Definition action.h:10
const ExtensionRegistry & extensionRegistry()
The extension registry.