Changeset View
Changeset View
Standalone View
Standalone View
effectloader.h
Show All 37 Lines | |||||
38 | 38 | | |||
39 | /** | 39 | /** | ||
40 | * @brief Flags defining how a Loader should load an Effect. | 40 | * @brief Flags defining how a Loader should load an Effect. | ||
41 | * | 41 | * | ||
42 | * These Flags are only used internally when querying the configuration on whether | 42 | * These Flags are only used internally when querying the configuration on whether | ||
43 | * an Effect should be loaded. | 43 | * an Effect should be loaded. | ||
44 | * | 44 | * | ||
45 | * @see AbstractEffectLoader::readConfig() | 45 | * @see AbstractEffectLoader::readConfig() | ||
46 | */ | 46 | **/ | ||
47 | enum class LoadEffectFlag { | 47 | enum class LoadEffectFlag { | ||
48 | Load = 1 << 0, ///< Effect should be loaded | 48 | Load = 1 << 0, ///< Effect should be loaded | ||
49 | CheckDefaultFunction = 1 << 2 ///< The Check Default Function needs to be invoked if the Effect provides it | 49 | CheckDefaultFunction = 1 << 2 ///< The Check Default Function needs to be invoked if the Effect provides it | ||
50 | }; | 50 | }; | ||
51 | Q_DECLARE_FLAGS(LoadEffectFlags, LoadEffectFlag) | 51 | Q_DECLARE_FLAGS(LoadEffectFlags, LoadEffectFlag) | ||
52 | 52 | | |||
53 | /** | 53 | /** | ||
54 | * @brief Interface to describe how an effect loader has to function. | 54 | * @brief Interface to describe how an effect loader has to function. | ||
55 | * | 55 | * | ||
56 | * The AbstractEffectLoader specifies the methods a concrete loader has to implement and how | 56 | * The AbstractEffectLoader specifies the methods a concrete loader has to implement and how | ||
57 | * those methods are expected to perform. Also it provides an interface to the outside world | 57 | * those methods are expected to perform. Also it provides an interface to the outside world | ||
58 | * (that is EffectsHandlerImpl). | 58 | * (that is EffectsHandlerImpl). | ||
59 | * | 59 | * | ||
60 | * The abstraction is used because there are multiple types of Effects which need to be loaded: | 60 | * The abstraction is used because there are multiple types of Effects which need to be loaded: | ||
61 | * @li Built-In Effects | 61 | * @li Built-In Effects | ||
62 | * @li Scripted Effects | 62 | * @li Scripted Effects | ||
63 | * @li Binary Plugin Effects | 63 | * @li Binary Plugin Effects | ||
64 | * | 64 | * | ||
65 | * Serving all of them with one Effect Loader is rather complex given that different stores need | 65 | * Serving all of them with one Effect Loader is rather complex given that different stores need | ||
66 | * to be queried at the same time. Thus the idea is to have one implementation per type and one | 66 | * to be queried at the same time. Thus the idea is to have one implementation per type and one | ||
67 | * implementation which makes use of all of them and combines the loading. | 67 | * implementation which makes use of all of them and combines the loading. | ||
68 | */ | 68 | **/ | ||
69 | class KWIN_EXPORT AbstractEffectLoader : public QObject | 69 | class KWIN_EXPORT AbstractEffectLoader : public QObject | ||
70 | { | 70 | { | ||
71 | Q_OBJECT | 71 | Q_OBJECT | ||
72 | public: | 72 | public: | ||
73 | virtual ~AbstractEffectLoader(); | 73 | virtual ~AbstractEffectLoader(); | ||
74 | 74 | | |||
75 | /** | 75 | /** | ||
76 | * @brief The KSharedConfig this EffectLoader should operate on. | 76 | * @brief The KSharedConfig this EffectLoader should operate on. | ||
77 | * | 77 | * | ||
78 | * Important: a valid KSharedConfig must be provided before trying to load any effects! | 78 | * Important: a valid KSharedConfig must be provided before trying to load any effects! | ||
79 | * | 79 | * | ||
80 | * @param config | 80 | * @param config | ||
81 | * @internal | 81 | * @internal | ||
82 | */ | 82 | **/ | ||
83 | virtual void setConfig(KSharedConfig::Ptr config); | 83 | virtual void setConfig(KSharedConfig::Ptr config); | ||
84 | 84 | | |||
85 | /** | 85 | /** | ||
86 | * @brief Whether this Effect Loader can load the Effect with the given @p name. | 86 | * @brief Whether this Effect Loader can load the Effect with the given @p name. | ||
87 | * | 87 | * | ||
88 | * The Effect Loader determines whether it knows or can find an Effect called @p name, | 88 | * The Effect Loader determines whether it knows or can find an Effect called @p name, | ||
89 | * and thus whether it can attempt to load the Effect. | 89 | * and thus whether it can attempt to load the Effect. | ||
90 | * | 90 | * | ||
91 | * @param name The name of the Effect to look for. | 91 | * @param name The name of the Effect to look for. | ||
92 | * @return bool @c true if the Effect Loader knows this effect, false otherwise | 92 | * @return bool @c true if the Effect Loader knows this effect, false otherwise | ||
93 | */ | 93 | **/ | ||
94 | virtual bool hasEffect(const QString &name) const = 0; | 94 | virtual bool hasEffect(const QString &name) const = 0; | ||
95 | 95 | | |||
96 | /** | 96 | /** | ||
97 | * @brief All the Effects this loader knows of. | 97 | * @brief All the Effects this loader knows of. | ||
98 | * | 98 | * | ||
99 | * The implementation should re-query its store whenever this method is invoked. | 99 | * The implementation should re-query its store whenever this method is invoked. | ||
100 | * It's possible that the store of effects changed (e.g. a new one got installed) | 100 | * It's possible that the store of effects changed (e.g. a new one got installed) | ||
101 | * | 101 | * | ||
102 | * @return QStringList The internal names of the known Effects | 102 | * @return QStringList The internal names of the known Effects | ||
103 | */ | 103 | **/ | ||
104 | virtual QStringList listOfKnownEffects() const = 0; | 104 | virtual QStringList listOfKnownEffects() const = 0; | ||
105 | 105 | | |||
106 | /** | 106 | /** | ||
107 | * @brief Synchronous loading of the Effect with the given @p name. | 107 | * @brief Synchronous loading of the Effect with the given @p name. | ||
108 | * | 108 | * | ||
109 | * Loads the Effect without checking any configuration value or any enabled by default | 109 | * Loads the Effect without checking any configuration value or any enabled by default | ||
110 | * function provided by the Effect. | 110 | * function provided by the Effect. | ||
111 | * | 111 | * | ||
112 | * The loader is expected to apply the following checks: | 112 | * The loader is expected to apply the following checks: | ||
113 | * If the Effect is already loaded, the Effect should not get loaded again. Thus the loader | 113 | * If the Effect is already loaded, the Effect should not get loaded again. Thus the loader | ||
114 | * is expected to track which Effects it has loaded, and which of those have been destroyed. | 114 | * is expected to track which Effects it has loaded, and which of those have been destroyed. | ||
115 | * The loader should check whether the Effect is supported. If the Effect indicates it is | 115 | * The loader should check whether the Effect is supported. If the Effect indicates it is | ||
116 | * not supported, it should not get loaded. | 116 | * not supported, it should not get loaded. | ||
117 | * | 117 | * | ||
118 | * If the Effect loaded successfully the signal effectLoaded(KWin::Effect*,const QString&) | 118 | * If the Effect loaded successfully the signal effectLoaded(KWin::Effect*,const QString&) | ||
119 | * must be emitted. Otherwise the user of the loader is not able to get the loaded Effect. | 119 | * must be emitted. Otherwise the user of the loader is not able to get the loaded Effect. | ||
120 | * It's not returning the Effect as queryAndLoadAll() is working async and thus the users | 120 | * It's not returning the Effect as queryAndLoadAll() is working async and thus the users | ||
121 | * of the loader are expected to be prepared for async loading. | 121 | * of the loader are expected to be prepared for async loading. | ||
122 | * | 122 | * | ||
123 | * @param name The internal name of the Effect which should be loaded | 123 | * @param name The internal name of the Effect which should be loaded | ||
124 | * @return bool @c true if the effect could be loaded, @c false in error case | 124 | * @return bool @c true if the effect could be loaded, @c false in error case | ||
125 | * @see queryAndLoadAll() | 125 | * @see queryAndLoadAll() | ||
126 | * @see effectLoaded(KWin::Effect*,const QString&) | 126 | * @see effectLoaded(KWin::Effect*,const QString&) | ||
127 | */ | 127 | **/ | ||
128 | virtual bool loadEffect(const QString &name) = 0; | 128 | virtual bool loadEffect(const QString &name) = 0; | ||
129 | 129 | | |||
130 | /** | 130 | /** | ||
131 | * @brief The Effect Loader should query its store for all available effects and try to load them. | 131 | * @brief The Effect Loader should query its store for all available effects and try to load them. | ||
132 | * | 132 | * | ||
133 | * The Effect Loader is supposed to perform this operation in a highly async way. If there is | 133 | * The Effect Loader is supposed to perform this operation in a highly async way. If there is | ||
134 | * IO which needs to be performed this should be done in a background thread and a queue should | 134 | * IO which needs to be performed this should be done in a background thread and a queue should | ||
135 | * be used to load the effects. The loader should make sure to not load more than one Effect | 135 | * be used to load the effects. The loader should make sure to not load more than one Effect | ||
Show All 11 Lines | |||||
147 | * returns @c false the Effect should not get loaded. If the Effect does not provide a way to | 147 | * returns @c false the Effect should not get loaded. If the Effect does not provide a way to | ||
148 | * query whether it's enabled by default at runtime the flag can get ignored. | 148 | * query whether it's enabled by default at runtime the flag can get ignored. | ||
149 | * | 149 | * | ||
150 | * If the Effect loaded successfully the signal effectLoaded(KWin::Effect*,const QString&) | 150 | * If the Effect loaded successfully the signal effectLoaded(KWin::Effect*,const QString&) | ||
151 | * must be emitted. | 151 | * must be emitted. | ||
152 | * | 152 | * | ||
153 | * @see loadEffect(const QString &) | 153 | * @see loadEffect(const QString &) | ||
154 | * @see effectLoaded(KWin::Effect*,const QString&) | 154 | * @see effectLoaded(KWin::Effect*,const QString&) | ||
155 | */ | 155 | **/ | ||
156 | virtual void queryAndLoadAll() = 0; | 156 | virtual void queryAndLoadAll() = 0; | ||
157 | 157 | | |||
158 | /** | 158 | /** | ||
159 | * @brief Whether the Effect with the given @p name is supported by the compositing backend. | 159 | * @brief Whether the Effect with the given @p name is supported by the compositing backend. | ||
160 | * | 160 | * | ||
161 | * @param name The name of the Effect to check. | 161 | * @param name The name of the Effect to check. | ||
162 | * @return bool @c true if it is supported, @c false otherwise | 162 | * @return bool @c true if it is supported, @c false otherwise | ||
163 | */ | 163 | **/ | ||
164 | virtual bool isEffectSupported(const QString &name) const = 0; | 164 | virtual bool isEffectSupported(const QString &name) const = 0; | ||
165 | 165 | | |||
166 | /** | 166 | /** | ||
167 | * @brief Clears the load queue, that is all scheduled Effects are discarded from loading. | 167 | * @brief Clears the load queue, that is all scheduled Effects are discarded from loading. | ||
168 | **/ | 168 | **/ | ||
169 | virtual void clear() = 0; | 169 | virtual void clear() = 0; | ||
170 | 170 | | |||
171 | Q_SIGNALS: | 171 | Q_SIGNALS: | ||
172 | /** | 172 | /** | ||
173 | * @brief The loader emits this signal when it successfully loaded an effect. | 173 | * @brief The loader emits this signal when it successfully loaded an effect. | ||
174 | * | 174 | * | ||
175 | * @param effect The created Effect | 175 | * @param effect The created Effect | ||
176 | * @param name The internal name of the loaded Effect | 176 | * @param name The internal name of the loaded Effect | ||
177 | * @return void | 177 | * @return void | ||
178 | */ | 178 | **/ | ||
179 | void effectLoaded(KWin::Effect *effect, const QString &name); | 179 | void effectLoaded(KWin::Effect *effect, const QString &name); | ||
180 | 180 | | |||
181 | protected: | 181 | protected: | ||
182 | explicit AbstractEffectLoader(QObject *parent = nullptr); | 182 | explicit AbstractEffectLoader(QObject *parent = nullptr); | ||
183 | /** | 183 | /** | ||
184 | * @brief Checks the configuration for the Effect identified by @p effectName. | 184 | * @brief Checks the configuration for the Effect identified by @p effectName. | ||
185 | * | 185 | * | ||
186 | * For each Effect there could be a key called "<effectName>Enabled". If there is such a key | 186 | * For each Effect there could be a key called "<effectName>Enabled". If there is such a key | ||
187 | * the returned flags will contain Load in case it's @c true. If the key does not exist the | 187 | * the returned flags will contain Load in case it's @c true. If the key does not exist the | ||
188 | * @p defaultValue determines whether the Effect should be loaded. A value of @c true means | 188 | * @p defaultValue determines whether the Effect should be loaded. A value of @c true means | ||
189 | * that Load | CheckDefaultFunction is returned, in case of @c false no Load flags are returned. | 189 | * that Load | CheckDefaultFunction is returned, in case of @c false no Load flags are returned. | ||
190 | * | 190 | * | ||
191 | * @param effectName The name of the Effect to look for in the configuration | 191 | * @param effectName The name of the Effect to look for in the configuration | ||
192 | * @param defaultValue Whether the Effect is enabled by default or not. | 192 | * @param defaultValue Whether the Effect is enabled by default or not. | ||
193 | * @returns Flags indicating whether the Effect should be loaded and how it should be loaded | 193 | * @returns Flags indicating whether the Effect should be loaded and how it should be loaded | ||
194 | */ | 194 | **/ | ||
195 | LoadEffectFlags readConfig(const QString &effectName, bool defaultValue) const; | 195 | LoadEffectFlags readConfig(const QString &effectName, bool defaultValue) const; | ||
196 | 196 | | |||
197 | private: | 197 | private: | ||
198 | KSharedConfig::Ptr m_config; | 198 | KSharedConfig::Ptr m_config; | ||
199 | }; | 199 | }; | ||
200 | 200 | | |||
201 | /** | 201 | /** | ||
202 | * @brief Helper class to queue the loading of Effects. | 202 | * @brief Helper class to queue the loading of Effects. | ||
203 | * | 203 | * | ||
204 | * Loading an Effect has to be done in the compositor thread and thus the Compositor is blocked | 204 | * Loading an Effect has to be done in the compositor thread and thus the Compositor is blocked | ||
205 | * while the Effect loads. To not block the compositor for several frames the loading of all | 205 | * while the Effect loads. To not block the compositor for several frames the loading of all | ||
206 | * Effects need to be queued. By invoking the slot dequeue() through a QueuedConnection the queue | 206 | * Effects need to be queued. By invoking the slot dequeue() through a QueuedConnection the queue | ||
207 | * can ensure that events are processed between the loading of two Effects and thus the compositor | 207 | * can ensure that events are processed between the loading of two Effects and thus the compositor | ||
208 | * doesn't block. | 208 | * doesn't block. | ||
209 | * | 209 | * | ||
210 | * As it needs to be a slot, the queue must subclass QObject, but it also needs to be templated as | 210 | * As it needs to be a slot, the queue must subclass QObject, but it also needs to be templated as | ||
211 | * the information to load an Effect is specific to the Effect Loader. Thus there is the | 211 | * the information to load an Effect is specific to the Effect Loader. Thus there is the | ||
212 | * AbstractEffectLoadQueue providing the slots as pure virtual functions and the templated | 212 | * AbstractEffectLoadQueue providing the slots as pure virtual functions and the templated | ||
213 | * EffectLoadQueue inheriting from AbstractEffectLoadQueue. | 213 | * EffectLoadQueue inheriting from AbstractEffectLoadQueue. | ||
214 | * | 214 | * | ||
215 | * The queue operates like a normal queue providing enqueue and a scheduleDequeue instead of dequeue. | 215 | * The queue operates like a normal queue providing enqueue and a scheduleDequeue instead of dequeue. | ||
216 | * | 216 | * | ||
217 | */ | 217 | **/ | ||
218 | class AbstractEffectLoadQueue : public QObject | 218 | class AbstractEffectLoadQueue : public QObject | ||
219 | { | 219 | { | ||
220 | Q_OBJECT | 220 | Q_OBJECT | ||
221 | public: | 221 | public: | ||
222 | explicit AbstractEffectLoadQueue(QObject *parent = nullptr) | 222 | explicit AbstractEffectLoadQueue(QObject *parent = nullptr) | ||
223 | : QObject(parent) | 223 | : QObject(parent) | ||
224 | { | 224 | { | ||
225 | } | 225 | } | ||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Line(s) | 261 | private: | |||
269 | } | 269 | } | ||
270 | Loader *m_effectLoader; | 270 | Loader *m_effectLoader; | ||
271 | bool m_dequeueScheduled; | 271 | bool m_dequeueScheduled; | ||
272 | QQueue<QPair<QueueType, LoadEffectFlags>> m_queue; | 272 | QQueue<QPair<QueueType, LoadEffectFlags>> m_queue; | ||
273 | }; | 273 | }; | ||
274 | 274 | | |||
275 | /** | 275 | /** | ||
276 | * @brief Can load the Built-In-Effects | 276 | * @brief Can load the Built-In-Effects | ||
277 | * | 277 | **/ | ||
278 | */ | | |||
279 | class BuiltInEffectLoader : public AbstractEffectLoader | 278 | class BuiltInEffectLoader : public AbstractEffectLoader | ||
280 | { | 279 | { | ||
281 | Q_OBJECT | 280 | Q_OBJECT | ||
282 | public: | 281 | public: | ||
283 | explicit BuiltInEffectLoader(QObject *parent = nullptr); | 282 | explicit BuiltInEffectLoader(QObject *parent = nullptr); | ||
284 | ~BuiltInEffectLoader() override; | 283 | ~BuiltInEffectLoader() override; | ||
285 | 284 | | |||
286 | bool hasEffect(const QString &name) const override; | 285 | bool hasEffect(const QString &name) const override; | ||
Show All 9 Lines | 294 | private: | |||
296 | bool loadEffect(const QString &name, BuiltInEffect effect, LoadEffectFlags flags); | 295 | bool loadEffect(const QString &name, BuiltInEffect effect, LoadEffectFlags flags); | ||
297 | QString internalName(const QString &name) const; | 296 | QString internalName(const QString &name) const; | ||
298 | EffectLoadQueue<BuiltInEffectLoader, BuiltInEffect> *m_queue; | 297 | EffectLoadQueue<BuiltInEffectLoader, BuiltInEffect> *m_queue; | ||
299 | QMap<BuiltInEffect, Effect*> m_loadedEffects; | 298 | QMap<BuiltInEffect, Effect*> m_loadedEffects; | ||
300 | }; | 299 | }; | ||
301 | 300 | | |||
302 | /** | 301 | /** | ||
303 | * @brief Can load scripted Effects | 302 | * @brief Can load scripted Effects | ||
304 | * | 303 | **/ | ||
305 | */ | | |||
306 | class KWIN_EXPORT ScriptedEffectLoader : public AbstractEffectLoader | 304 | class KWIN_EXPORT ScriptedEffectLoader : public AbstractEffectLoader | ||
307 | { | 305 | { | ||
308 | Q_OBJECT | 306 | Q_OBJECT | ||
309 | public: | 307 | public: | ||
310 | explicit ScriptedEffectLoader(QObject* parent = nullptr); | 308 | explicit ScriptedEffectLoader(QObject* parent = nullptr); | ||
311 | ~ScriptedEffectLoader() override; | 309 | ~ScriptedEffectLoader() override; | ||
312 | 310 | | |||
313 | bool hasEffect(const QString &name) const override; | 311 | bool hasEffect(const QString &name) const override; | ||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |