Merge lp:~compiz-team/compiz/compiz.fix_1101026 into lp:compiz/0.9.10
- compiz.fix_1101026
- Merge into 0.9.10
Status: | Superseded | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~compiz-team/compiz/compiz.fix_1101026 | ||||||||
Merge into: | lp:compiz/0.9.10 | ||||||||
Diff against target: |
1483 lines (+888/-154) 14 files modified
include/core/abiversion.h (+1/-1) include/core/plugin.h (+184/-52) plugins/animation/src/animation.cpp (+1/-1) plugins/composite/src/composite.cpp (+1/-1) plugins/cube/src/cube.cpp (+1/-1) plugins/opengl/src/opengl.cpp (+1/-1) plugins/scale/src/scale.cpp (+1/-1) src/plugin.cpp (+16/-0) src/plugin/tests/test-plugin.cpp (+481/-70) src/pluginclasshandler/include/core/pluginclasshandler.h (+97/-1) src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp (+40/-17) src/pluginclasshandler/tests/get/src/test-pch-get.cpp (+38/-1) src/pluginclasshandler/tests/test-pluginclasshandler.h (+18/-0) src/privatescreen/tests/test-privatescreen.cpp (+8/-7) |
||||||||
To merge this branch: | bzr merge lp:~compiz-team/compiz/compiz.fix_1101026 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Compiz Maintainers | Pending | ||
Review via email: mp+159307@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-04-19.
Commit message
Added some new hooks to PluginClassHandler to allow a VTable to specify if loaded.
PluginClassHand
class for the core structure, but it did this without checking if the plugin was
loaded.
Added some new methods to PluginClassHandler exposed by LoadedPluginCla
and only accessible by those who implement PluginKey to specify globally
whether or not a plugin is actually loaded, so that PluginClassHandler can
return accordingly.
Integration and unit tests added as appropriate
Description of the change
Added some new hooks to PluginClassHandler to allow a VTable to specify if loaded.
PluginClassHand
class for the core structure, but it did this without checking if the plugin was
loaded.
Added some new methods to PluginClassHandler exposed by LoadedPluginCla
and only accessible by those who implement PluginKey to specify globally
whether or not a plugin is actually loaded, so that PluginClassHandler can
return accordingly.
I note that the LoadedPluginBridge / PluginKey abstraction is a little weird. I'd like to make it so that CompPlugin::VTable had access to a specific interface on PluginClassHandler to mark certain classes as loaded and unloaded. Unfortunately, in order to do that it would require substantial changes of the API - and I don't really want to do that.
Integration and unit tests added as appropriate
PS Jenkins bot (ps-jenkins) wrote : | # |
- 3659. By Sam Spilsbury
-
Add whitespace where it makes sense, remove double whitespace
Unmerged revisions
Preview Diff
1 | === modified file 'include/core/abiversion.h' |
2 | --- include/core/abiversion.h 2013-01-28 17:54:50 +0000 |
3 | +++ include/core/abiversion.h 2013-04-17 07:34:12 +0000 |
4 | @@ -5,6 +5,6 @@ |
5 | # error Conflicting definitions of CORE_ABIVERSION |
6 | #endif |
7 | |
8 | -#define CORE_ABIVERSION 20130125 |
9 | +#define CORE_ABIVERSION 20130415 |
10 | |
11 | #endif // COMPIZ_ABIVERSION_H |
12 | |
13 | === modified file 'include/core/plugin.h' |
14 | --- include/core/plugin.h 2013-01-24 14:18:03 +0000 |
15 | +++ include/core/plugin.h 2013-04-17 07:34:12 +0000 |
16 | @@ -29,6 +29,7 @@ |
17 | #include <core/string.h> |
18 | #include <core/option.h> |
19 | #include <core/privateunion.h> |
20 | +#include <core/pluginclasshandler.h> |
21 | |
22 | #include <string.h> |
23 | |
24 | @@ -70,6 +71,37 @@ |
25 | extern UnloadPluginProc loaderUnloadPlugin; |
26 | extern ListPluginsProc loaderListPlugins; |
27 | |
28 | +namespace compiz |
29 | +{ |
30 | +namespace plugin |
31 | +{ |
32 | +namespace internal |
33 | +{ |
34 | +class VTableBase; |
35 | + |
36 | +/** |
37 | + * Provide a definition for PluginKey, with a protected |
38 | + * constructor which is a friend of VTableBase */ |
39 | +class PluginKey |
40 | +{ |
41 | + protected: |
42 | + |
43 | + PluginKey () {} |
44 | + |
45 | + friend class VTableBase; |
46 | +}; |
47 | + |
48 | +class VTableBase : |
49 | + public PluginKey |
50 | +{ |
51 | + public: |
52 | + |
53 | + virtual ~VTableBase () {}; |
54 | +}; |
55 | +} |
56 | +} |
57 | +} |
58 | + |
59 | /** |
60 | * Base plug-in interface for Compiz. All plugins must implement this |
61 | * interface, which provides basics for loading, unloading, options, |
62 | @@ -77,8 +109,11 @@ |
63 | */ |
64 | class CompPlugin { |
65 | public: |
66 | - class VTable { |
67 | + class VTable : |
68 | + public compiz::plugin::internal::VTableBase |
69 | + { |
70 | public: |
71 | + |
72 | VTable (); |
73 | virtual ~VTable (); |
74 | |
75 | @@ -91,9 +126,14 @@ |
76 | const CompString &name () const; |
77 | |
78 | virtual bool init () = 0; |
79 | - |
80 | virtual void fini (); |
81 | |
82 | + /* Mark the plugin as ready to be instantiated */ |
83 | + virtual void markReadyToInstantiate () = 0; |
84 | + |
85 | + /* Mark the plugin as disallowing further instantiation */ |
86 | + virtual void markNoFurtherInstantiation () = 0; |
87 | + |
88 | virtual bool initScreen (CompScreen *s); |
89 | |
90 | virtual void finiScreen (CompScreen *s); |
91 | @@ -111,36 +151,53 @@ |
92 | VTable **mSelf; |
93 | }; |
94 | |
95 | - /** |
96 | - * TODO (or not?) |
97 | - */ |
98 | - template <typename T, typename T2> |
99 | - class VTableForScreenAndWindow : public VTable { |
100 | - bool initScreen (CompScreen *s); |
101 | - |
102 | - void finiScreen (CompScreen *s); |
103 | - |
104 | - bool initWindow (CompWindow *w); |
105 | - |
106 | - void finiWindow (CompWindow *w); |
107 | - |
108 | - CompOption::Vector & getOptions (); |
109 | - |
110 | - bool setOption (const CompString &name, CompOption::Value &value); |
111 | + /** |
112 | + * TODO (or not?) |
113 | + */ |
114 | + template <typename T, typename T2, int ABI = 0> |
115 | + class VTableForScreenAndWindow : |
116 | + public VTable |
117 | + { |
118 | + public: |
119 | + |
120 | + bool initScreen (CompScreen *s); |
121 | + void finiScreen (CompScreen *s); |
122 | + bool initWindow (CompWindow *w); |
123 | + void finiWindow (CompWindow *w); |
124 | + CompOption::Vector & getOptions (); |
125 | + bool setOption (const CompString &name, |
126 | + CompOption::Value &value); |
127 | + |
128 | + private: |
129 | + |
130 | + /* Mark the plugin as ready to be instantiated */ |
131 | + void markReadyToInstantiate (); |
132 | + |
133 | + /* Mark the plugin as disallowing further instantiation */ |
134 | + void markNoFurtherInstantiation (); |
135 | }; |
136 | |
137 | - /** |
138 | - * TODO (or not?) |
139 | - */ |
140 | - template <typename T> |
141 | - class VTableForScreen : public VTable { |
142 | - bool initScreen (CompScreen *s); |
143 | - |
144 | - void finiScreen (CompScreen *s); |
145 | - |
146 | - CompOption::Vector & getOptions (); |
147 | - |
148 | - bool setOption (const CompString &name, CompOption::Value &value); |
149 | + /** |
150 | + * TODO (or not?) |
151 | + */ |
152 | + template <typename T, int ABI = 0> |
153 | + class VTableForScreen : |
154 | + public VTable |
155 | + { |
156 | + public: |
157 | + |
158 | + bool initScreen (CompScreen *s); |
159 | + void finiScreen (CompScreen *s); |
160 | + CompOption::Vector & getOptions (); |
161 | + bool setOption (const CompString &name, CompOption::Value &value); |
162 | + |
163 | + private: |
164 | + |
165 | + /* Mark the plugin as ready to be instantiated */ |
166 | + void markReadyToInstantiate (); |
167 | + |
168 | + /* Mark the plugin as disallowing further instantiation */ |
169 | + void markNoFurtherInstantiation (); |
170 | }; |
171 | |
172 | typedef std::map<CompString, CompPlugin *> Map; |
173 | @@ -211,9 +268,47 @@ |
174 | |
175 | }; |
176 | |
177 | - |
178 | -template <typename T, typename T2> |
179 | -bool CompPlugin::VTableForScreenAndWindow<T,T2>::initScreen (CompScreen *s) |
180 | +/** |
181 | + * Mark the plugin class handlers as ready to be initialized |
182 | + */ |
183 | +template <typename T, typename T2, int ABI> |
184 | +void |
185 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::markReadyToInstantiate () |
186 | +{ |
187 | + namespace cpi = compiz::plugin::internal; |
188 | + |
189 | + typedef typename T::ClassPluginBaseType ScreenBase; |
190 | + typedef typename T2::ClassPluginBaseType WindowBase; |
191 | + |
192 | + typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge; |
193 | + typedef cpi::LoadedPluginClassBridge <T2, WindowBase, ABI> WindowBridge; |
194 | + |
195 | + ScreenBridge::allowInstantiations (*this); |
196 | + WindowBridge::allowInstantiations (*this); |
197 | +} |
198 | + |
199 | +/** |
200 | + * Allow no further class handler initialization |
201 | + */ |
202 | +template <typename T, typename T2, int ABI> |
203 | +void |
204 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::markNoFurtherInstantiation () |
205 | +{ |
206 | + namespace cpi = compiz::plugin::internal; |
207 | + |
208 | + typedef typename T::ClassPluginBaseType ScreenBase; |
209 | + typedef typename T2::ClassPluginBaseType WindowBase; |
210 | + |
211 | + typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge; |
212 | + typedef cpi::LoadedPluginClassBridge <T2, WindowBase, ABI> WindowBridge; |
213 | + |
214 | + ScreenBridge::disallowInstantiations (*this); |
215 | + WindowBridge::disallowInstantiations (*this); |
216 | +} |
217 | + |
218 | +template <typename T, typename T2, int ABI> |
219 | +bool |
220 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::initScreen (CompScreen *s) |
221 | { |
222 | T * ps = T::get (s); |
223 | if (!ps) |
224 | @@ -222,15 +317,17 @@ |
225 | return true; |
226 | } |
227 | |
228 | -template <typename T, typename T2> |
229 | -void CompPlugin::VTableForScreenAndWindow<T,T2>::finiScreen (CompScreen *s) |
230 | +template <typename T, typename T2, int ABI> |
231 | +void |
232 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::finiScreen (CompScreen *s) |
233 | { |
234 | T * ps = T::get (s); |
235 | delete ps; |
236 | } |
237 | |
238 | -template <typename T, typename T2> |
239 | -bool CompPlugin::VTableForScreenAndWindow<T,T2>::initWindow (CompWindow *w) |
240 | +template <typename T, typename T2, int ABI> |
241 | +bool |
242 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::initWindow (CompWindow *w) |
243 | { |
244 | T2 * pw = T2::get (w); |
245 | if (!pw) |
246 | @@ -239,15 +336,16 @@ |
247 | return true; |
248 | } |
249 | |
250 | -template <typename T, typename T2> |
251 | -void CompPlugin::VTableForScreenAndWindow<T,T2>::finiWindow (CompWindow *w) |
252 | +template <typename T, typename T2, int ABI> |
253 | +void |
254 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::finiWindow (CompWindow *w) |
255 | { |
256 | T2 * pw = T2::get (w); |
257 | delete pw; |
258 | } |
259 | |
260 | -template <typename T, typename T2> |
261 | -CompOption::Vector & CompPlugin::VTableForScreenAndWindow<T,T2>::getOptions () |
262 | +template <typename T, typename T2, int ABI> |
263 | +CompOption::Vector & CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::getOptions () |
264 | { |
265 | CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen)); |
266 | if (!oc) |
267 | @@ -255,9 +353,10 @@ |
268 | return oc->getOptions (); |
269 | } |
270 | |
271 | -template <typename T, typename T2> |
272 | -bool CompPlugin::VTableForScreenAndWindow<T,T2>::setOption (const CompString &name, |
273 | - CompOption::Value &value) |
274 | +template <typename T, typename T2, int ABI> |
275 | +bool |
276 | +CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::setOption (const CompString &name, |
277 | + CompOption::Value &value) |
278 | { |
279 | CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen)); |
280 | if (!oc) |
281 | @@ -265,8 +364,39 @@ |
282 | return oc->setOption (name, value); |
283 | } |
284 | |
285 | -template <typename T> |
286 | -bool CompPlugin::VTableForScreen<T>::initScreen (CompScreen *s) |
287 | +/** |
288 | + * Mark the plugin class handlers as ready to be initialized |
289 | + */ |
290 | +template <typename T, int ABI> |
291 | +void |
292 | +CompPlugin::VTableForScreen<T, ABI>::markReadyToInstantiate () |
293 | +{ |
294 | + namespace cpi = compiz::plugin::internal; |
295 | + |
296 | + typedef typename T::ClassPluginBaseType ScreenBase; |
297 | + typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge; |
298 | + |
299 | + ScreenBridge::allowInstantiations (*this); |
300 | +} |
301 | + |
302 | +/** |
303 | + * Allow no further class handler initialization |
304 | + */ |
305 | +template <typename T, int ABI> |
306 | +void |
307 | +CompPlugin::VTableForScreen<T, ABI>::markNoFurtherInstantiation () |
308 | +{ |
309 | + namespace cpi = compiz::plugin::internal; |
310 | + |
311 | + typedef typename T::ClassPluginBaseType ScreenBase; |
312 | + typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge; |
313 | + |
314 | + ScreenBridge::disallowInstantiations (*this); |
315 | +} |
316 | + |
317 | +template <typename T, int ABI> |
318 | +bool |
319 | +CompPlugin::VTableForScreen<T, ABI>::initScreen (CompScreen *s) |
320 | { |
321 | T * ps = new T (s); |
322 | if (ps->loadFailed ()) |
323 | @@ -277,15 +407,16 @@ |
324 | return true; |
325 | } |
326 | |
327 | -template <typename T> |
328 | -void CompPlugin::VTableForScreen<T>::finiScreen (CompScreen *s) |
329 | +template <typename T, int ABI> |
330 | +void CompPlugin::VTableForScreen<T, ABI>::finiScreen (CompScreen *s) |
331 | { |
332 | T * ps = T::get (s); |
333 | delete ps; |
334 | } |
335 | |
336 | -template <typename T> |
337 | -CompOption::Vector & CompPlugin::VTableForScreen<T>::getOptions () |
338 | +template <typename T, int ABI> |
339 | +CompOption::Vector & |
340 | +CompPlugin::VTableForScreen<T, ABI>::getOptions () |
341 | { |
342 | CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen)); |
343 | if (!oc) |
344 | @@ -293,8 +424,9 @@ |
345 | return oc->getOptions (); |
346 | } |
347 | |
348 | -template <typename T> |
349 | -bool CompPlugin::VTableForScreen<T>::setOption (const CompString &name, |
350 | +template <typename T, int ABI> |
351 | +bool |
352 | +CompPlugin::VTableForScreen<T, ABI>::setOption (const CompString &name, |
353 | CompOption::Value &value) |
354 | { |
355 | CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen)); |
356 | |
357 | === modified file 'plugins/animation/src/animation.cpp' |
358 | --- plugins/animation/src/animation.cpp 2013-02-27 11:33:10 +0000 |
359 | +++ plugins/animation/src/animation.cpp 2013-04-17 07:34:12 +0000 |
360 | @@ -94,7 +94,7 @@ |
361 | using namespace compiz::core; |
362 | |
363 | class AnimPluginVTable : |
364 | - public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow> |
365 | + public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow, ANIMATION_ABI> |
366 | { |
367 | public: |
368 | bool init (); |
369 | |
370 | === modified file 'plugins/composite/src/composite.cpp' |
371 | --- plugins/composite/src/composite.cpp 2012-02-08 10:54:35 +0000 |
372 | +++ plugins/composite/src/composite.cpp 2013-04-17 07:34:12 +0000 |
373 | @@ -33,7 +33,7 @@ |
374 | |
375 | |
376 | class CompositePluginVTable : |
377 | - public CompPlugin::VTableForScreenAndWindow<CompositeScreen, CompositeWindow> |
378 | + public CompPlugin::VTableForScreenAndWindow<CompositeScreen, CompositeWindow, COMPIZ_COMPOSITE_ABI> |
379 | { |
380 | public: |
381 | |
382 | |
383 | === modified file 'plugins/cube/src/cube.cpp' |
384 | --- plugins/cube/src/cube.cpp 2012-12-04 15:42:09 +0000 |
385 | +++ plugins/cube/src/cube.cpp 2013-04-17 07:34:12 +0000 |
386 | @@ -33,7 +33,7 @@ |
387 | #include <privates.h> |
388 | |
389 | class CubePluginVTable : |
390 | - public CompPlugin::VTableForScreenAndWindow<CubeScreen, PrivateCubeWindow> |
391 | + public CompPlugin::VTableForScreenAndWindow<CubeScreen, PrivateCubeWindow, COMPIZ_CUBE_ABI> |
392 | { |
393 | public: |
394 | |
395 | |
396 | === modified file 'plugins/opengl/src/opengl.cpp' |
397 | --- plugins/opengl/src/opengl.cpp 2012-09-07 23:29:42 +0000 |
398 | +++ plugins/opengl/src/opengl.cpp 2013-04-17 07:34:12 +0000 |
399 | @@ -79,7 +79,7 @@ |
400 | } |
401 | |
402 | class OpenglPluginVTable : |
403 | - public CompPlugin::VTableForScreenAndWindow<GLScreen, GLWindow> |
404 | + public CompPlugin::VTableForScreenAndWindow<GLScreen, GLWindow, COMPIZ_OPENGL_ABI> |
405 | { |
406 | public: |
407 | |
408 | |
409 | === modified file 'plugins/scale/src/scale.cpp' |
410 | --- plugins/scale/src/scale.cpp 2013-01-29 23:16:32 +0000 |
411 | +++ plugins/scale/src/scale.cpp 2013-04-17 07:34:12 +0000 |
412 | @@ -39,7 +39,7 @@ |
413 | #define EDGE_STATE (CompAction::StateInitEdge) |
414 | |
415 | class ScalePluginVTable : |
416 | - public CompPlugin::VTableForScreenAndWindow<ScaleScreen, ScaleWindow> |
417 | + public CompPlugin::VTableForScreenAndWindow<ScaleScreen, ScaleWindow, COMPIZ_SCALE_ABI> |
418 | { |
419 | public: |
420 | |
421 | |
422 | === modified file 'src/plugin.cpp' |
423 | --- src/plugin.cpp 2013-02-14 02:43:51 +0000 |
424 | +++ src/plugin.cpp 2013-04-17 07:34:12 +0000 |
425 | @@ -54,6 +54,9 @@ |
426 | |
427 | bool init (); |
428 | |
429 | + void markReadyToInstantiate (); |
430 | + void markNoFurtherInstantiation (); |
431 | + |
432 | CompOption::Vector & getOptions (); |
433 | |
434 | bool setOption (const CompString &name, |
435 | @@ -78,6 +81,16 @@ |
436 | return true; |
437 | } |
438 | |
439 | +void |
440 | +CorePluginVTable::markReadyToInstantiate () |
441 | +{ |
442 | +} |
443 | + |
444 | +void |
445 | +CorePluginVTable::markNoFurtherInstantiation () |
446 | +{ |
447 | +} |
448 | + |
449 | CompOption::Vector & |
450 | CorePluginVTable::getOptions () |
451 | { |
452 | @@ -228,6 +241,8 @@ |
453 | return false; |
454 | } |
455 | |
456 | + p->vTable->markReadyToInstantiate (); |
457 | + |
458 | if (screen && screen->displayInitialised()) |
459 | { |
460 | if (!p->vTable->initScreen (screen)) |
461 | @@ -252,6 +267,7 @@ |
462 | void |
463 | CompManager::finiPlugin (CompPlugin *p) |
464 | { |
465 | + p->vTable->markNoFurtherInstantiation (); |
466 | |
467 | if (screen) |
468 | { |
469 | |
470 | === modified file 'src/plugin/tests/test-plugin.cpp' |
471 | --- src/plugin/tests/test-plugin.cpp 2013-02-14 02:43:51 +0000 |
472 | +++ src/plugin/tests/test-plugin.cpp 2013-04-17 07:34:12 +0000 |
473 | @@ -1,8 +1,9 @@ |
474 | +#include <boost/shared_ptr.hpp> |
475 | +#include <boost/foreach.hpp> |
476 | +#define foreach BOOST_FOREACH |
477 | + |
478 | #include "core/plugin.h" |
479 | |
480 | -// This prevents an instantiation error - not sure why ATM |
481 | -#include "core/screen.h" |
482 | - |
483 | // Get rid of stupid macro from X.h |
484 | // Why, oh why, are we including X.h? |
485 | #undef None |
486 | @@ -10,37 +11,51 @@ |
487 | #include <gtest/gtest.h> |
488 | #include <gmock/gmock.h> |
489 | #include <gtest_shared_tmpenv.h> |
490 | - |
491 | -namespace { |
492 | +#include <gtest_shared_autodestroy.h> |
493 | + |
494 | +/* This is a link-seam so that we don't have to include screen.h */ |
495 | +class CompAction |
496 | +{ |
497 | +}; |
498 | + |
499 | +class CompMatch |
500 | +{ |
501 | +}; |
502 | + |
503 | +namespace |
504 | +{ |
505 | |
506 | class PluginFilesystem |
507 | { |
508 | -public: |
509 | - virtual bool |
510 | - LoadPlugin(CompPlugin *p, const char *path, const char *name) const = 0; |
511 | - |
512 | - virtual void |
513 | - UnloadPlugin(CompPlugin *p) const = 0; |
514 | - |
515 | - static PluginFilesystem const* instance; |
516 | - |
517 | -protected: |
518 | - PluginFilesystem(); |
519 | - virtual ~PluginFilesystem() {} |
520 | + public: |
521 | + virtual bool |
522 | + LoadPlugin(CompPlugin *p, const char *path, const char *name) const = 0; |
523 | + |
524 | + virtual void |
525 | + UnloadPlugin(CompPlugin *p) const = 0; |
526 | + |
527 | + static PluginFilesystem const* instance; |
528 | + |
529 | + protected: |
530 | + PluginFilesystem(); |
531 | + virtual ~PluginFilesystem() {} |
532 | }; |
533 | |
534 | class MockPluginFilesystem : public PluginFilesystem |
535 | { |
536 | -public: |
537 | - MOCK_CONST_METHOD3(LoadPlugin, bool (CompPlugin *, const char *, const char *)); |
538 | + public: |
539 | + MOCK_CONST_METHOD3(LoadPlugin, bool (CompPlugin *, const char *, const char *)); |
540 | |
541 | - MOCK_CONST_METHOD1(UnloadPlugin, void (CompPlugin *p)); |
542 | + MOCK_CONST_METHOD1(UnloadPlugin, void (CompPlugin *p)); |
543 | }; |
544 | |
545 | -class MockVTable : public CompPlugin::VTable |
546 | +class MockVTable : |
547 | + public CompPlugin::VTable |
548 | { |
549 | -public: |
550 | - MOCK_METHOD0(init, bool ()); |
551 | + public: |
552 | + MOCK_METHOD0(init, bool ()); |
553 | + MOCK_METHOD0(markReadyToInstantiate, void ()); |
554 | + MOCK_METHOD0(markNoFurtherInstantiation, void ()); |
555 | }; |
556 | |
557 | |
558 | @@ -59,22 +74,26 @@ |
559 | |
560 | PluginFilesystem::PluginFilesystem() |
561 | { |
562 | - ::loaderLoadPlugin = ::ThunkLoadPluginProc; |
563 | - ::loaderUnloadPlugin = ::ThunkUnloadPluginProc; |
564 | + ::loaderLoadPlugin = ::ThunkLoadPluginProc; |
565 | + ::loaderUnloadPlugin = ::ThunkUnloadPluginProc; |
566 | |
567 | - instance = this; |
568 | + instance = this; |
569 | } |
570 | |
571 | PluginFilesystem const* PluginFilesystem::instance = 0; |
572 | |
573 | } // (abstract) namespace |
574 | |
575 | - |
576 | - |
577 | -TEST(PluginTest, load_non_existant_plugin_must_fail) |
578 | -{ |
579 | - MockPluginFilesystem mockfs; |
580 | - |
581 | +class PluginTest : |
582 | + public ::testing::Test |
583 | +{ |
584 | + public: |
585 | + |
586 | + MockPluginFilesystem mockfs; |
587 | +}; |
588 | + |
589 | +TEST_F (PluginTest, load_non_existant_plugin_must_fail) |
590 | +{ |
591 | using namespace testing; |
592 | |
593 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))). |
594 | @@ -91,10 +110,8 @@ |
595 | ASSERT_EQ(0, CompPlugin::load("dummy")); |
596 | } |
597 | |
598 | -TEST(PluginTest, load_plugin_from_HOME_PLUGINDIR_succeeds) |
599 | +TEST_F (PluginTest, load_plugin_from_HOME_PLUGINDIR_succeeds) |
600 | { |
601 | - MockPluginFilesystem mockfs; |
602 | - |
603 | using namespace testing; |
604 | |
605 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))). |
606 | @@ -114,10 +131,8 @@ |
607 | CompPlugin::unload(cp); |
608 | } |
609 | |
610 | -TEST(PluginTest, load_plugin_from_PLUGINDIR_succeeds) |
611 | +TEST_F (PluginTest, load_plugin_from_PLUGINDIR_succeeds) |
612 | { |
613 | - MockPluginFilesystem mockfs; |
614 | - |
615 | using namespace testing; |
616 | |
617 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))). |
618 | @@ -137,11 +152,10 @@ |
619 | CompPlugin::unload(cp); |
620 | } |
621 | |
622 | -TEST(PluginTest, load_plugin_from_COMPIZ_PLUGIN_DIR_env_succeeds) |
623 | +TEST_F (PluginTest, load_plugin_from_COMPIZ_PLUGIN_DIR_env_succeeds) |
624 | { |
625 | const char *COMPIZ_PLUGIN_DIR_VALUE = "/path/to/plugin/dir"; |
626 | TmpEnv env ("COMPIZ_PLUGIN_DIR", COMPIZ_PLUGIN_DIR_VALUE); |
627 | - MockPluginFilesystem mockfs; |
628 | |
629 | using namespace testing; |
630 | |
631 | @@ -165,10 +179,8 @@ |
632 | CompPlugin::unload(cp); |
633 | } |
634 | |
635 | -TEST(PluginTest, load_plugin_from_void_succeeds) |
636 | +TEST_F (PluginTest, load_plugin_from_void_succeeds) |
637 | { |
638 | - MockPluginFilesystem mockfs; |
639 | - |
640 | using namespace testing; |
641 | |
642 | EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))). |
643 | @@ -188,31 +200,430 @@ |
644 | CompPlugin::unload(cp); |
645 | } |
646 | |
647 | -TEST(PluginTest, when_we_push_plugin_init_is_called) |
648 | -{ |
649 | - MockPluginFilesystem mockfs; |
650 | - |
651 | - using namespace testing; |
652 | - |
653 | - EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))). |
654 | - WillOnce(Return(true)); |
655 | - |
656 | - EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))). |
657 | - Times(AtMost(0)); |
658 | - |
659 | - EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))). |
660 | - Times(AtMost(0)); |
661 | - |
662 | - EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1); |
663 | - |
664 | - MockVTable mockVtable; |
665 | - EXPECT_CALL(mockVtable, init()).WillOnce(Return(true)); |
666 | - |
667 | - CompPlugin* cp = CompPlugin::load("dummy"); |
668 | - |
669 | - cp->vTable = &mockVtable; |
670 | - |
671 | - CompPlugin::push(cp); |
672 | - ASSERT_EQ(cp, CompPlugin::pop()); |
673 | - CompPlugin::unload(cp); |
674 | +TEST_F (PluginTest, when_we_load_plugin_init_load_is_called_without_null_pointer) |
675 | +{ |
676 | + using namespace testing; |
677 | + |
678 | + EXPECT_CALL (mockfs, LoadPlugin (NotNull (), |
679 | + EndsWith(HOME_PLUGINDIR), |
680 | + StrEq("dummy"))) |
681 | + .Times (1) |
682 | + .WillOnce (Return (true)); |
683 | + |
684 | + EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtLeast (0)); |
685 | + |
686 | + CompPlugin* cp = CompPlugin::load("dummy"); |
687 | + CompPlugin::unload(cp); |
688 | +} |
689 | + |
690 | +TEST_F (PluginTest, when_we_push_plugin_init_is_called) |
691 | +{ |
692 | + using namespace testing; |
693 | + |
694 | + EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0)); |
695 | + EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0)); |
696 | + |
697 | + ON_CALL(mockfs, LoadPlugin (_, _, _)). |
698 | + WillByDefault (Return (true)); |
699 | + |
700 | + MockVTable mockVtable; |
701 | + EXPECT_CALL (mockVtable, markReadyToInstantiate ()).Times (AtLeast (0)); |
702 | + EXPECT_CALL (mockVtable, markNoFurtherInstantiation ()) |
703 | + .Times (AtLeast (0)); |
704 | + EXPECT_CALL (mockVtable, init ()).WillOnce (Return (true)); |
705 | + |
706 | + CompPlugin* cp = CompPlugin::load("dummy"); |
707 | + |
708 | + cp->vTable = &mockVtable; |
709 | + |
710 | + CompPlugin::push(cp); |
711 | + CompPlugin::pop (); |
712 | + CompPlugin::unload(cp); |
713 | +} |
714 | + |
715 | +TEST_F (PluginTest, when_we_push_plugin_mark_ready_to_instantiate_is_called) |
716 | +{ |
717 | + using namespace testing; |
718 | + |
719 | + EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0)); |
720 | + EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0)); |
721 | + |
722 | + ON_CALL(mockfs, LoadPlugin (_, _, _)). |
723 | + WillByDefault (Return (true)); |
724 | + |
725 | + MockVTable mockVtable; |
726 | + EXPECT_CALL (mockVtable, init ()) |
727 | + .Times (AtLeast (0)) |
728 | + .WillOnce (Return (true)); |
729 | + EXPECT_CALL (mockVtable, markReadyToInstantiate ()).Times (1); |
730 | + EXPECT_CALL (mockVtable, markNoFurtherInstantiation ()) |
731 | + .Times (AtLeast (0)); |
732 | + |
733 | + CompPlugin* cp = CompPlugin::load("dummy"); |
734 | + |
735 | + cp->vTable = &mockVtable; |
736 | + |
737 | + CompPlugin::push(cp); |
738 | + CompPlugin::pop (); |
739 | + CompPlugin::unload(cp); |
740 | +} |
741 | + |
742 | +TEST_F (PluginTest, when_we_pop_plugin_mark_no_further_instantiation_is_called) |
743 | +{ |
744 | + using namespace testing; |
745 | + |
746 | + EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0)); |
747 | + EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0)); |
748 | + |
749 | + ON_CALL(mockfs, LoadPlugin (_, _, _)). |
750 | + WillByDefault (Return (true)); |
751 | + |
752 | + MockVTable mockVtable; |
753 | + EXPECT_CALL (mockVtable, init ()) |
754 | + .Times (AtLeast (0)) |
755 | + .WillOnce (Return (true)); |
756 | + EXPECT_CALL (mockVtable, markReadyToInstantiate ()).Times (AtLeast (0)); |
757 | + |
758 | + CompPlugin* cp = CompPlugin::load("dummy"); |
759 | + |
760 | + cp->vTable = &mockVtable; |
761 | + |
762 | + CompPlugin::push(cp); |
763 | + |
764 | + EXPECT_CALL (mockVtable, markNoFurtherInstantiation ()) |
765 | + .Times (1); |
766 | + |
767 | + CompPlugin::pop (); |
768 | + CompPlugin::unload(cp); |
769 | +} |
770 | + |
771 | +TEST_F (PluginTest, pop_returns_plugin_pointer) |
772 | +{ |
773 | + using namespace testing; |
774 | + |
775 | + EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0)); |
776 | + EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0)); |
777 | + |
778 | + ON_CALL(mockfs, LoadPlugin (_, _, _)). |
779 | + WillByDefault (Return (true)); |
780 | + |
781 | + MockVTable mockVtable; |
782 | + EXPECT_CALL (mockVtable, init ()) |
783 | + .Times (AtLeast (0)) |
784 | + .WillOnce (Return (true)); |
785 | + EXPECT_CALL (mockVtable, markReadyToInstantiate ()) |
786 | + .Times (AtLeast (0)); |
787 | + EXPECT_CALL (mockVtable, markNoFurtherInstantiation ()) |
788 | + .Times (AtLeast (0)); |
789 | + |
790 | + CompPlugin* cp = CompPlugin::load("dummy"); |
791 | + |
792 | + cp->vTable = &mockVtable; |
793 | + |
794 | + CompPlugin::push(cp); |
795 | + EXPECT_EQ (cp, CompPlugin::pop ()); |
796 | + CompPlugin::unload(cp); |
797 | +} |
798 | + |
799 | +TEST_F (PluginTest, unload_calls_unload_on_fs) |
800 | +{ |
801 | + using namespace testing; |
802 | + |
803 | + EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0)); |
804 | + |
805 | + ON_CALL(mockfs, LoadPlugin (_, _, _)). |
806 | + WillByDefault (Return (true)); |
807 | + |
808 | + CompPlugin* cp = CompPlugin::load("dummy"); |
809 | + |
810 | + EXPECT_CALL (mockfs, UnloadPlugin (cp)).Times (1); |
811 | + |
812 | + CompPlugin::unload(cp); |
813 | +} |
814 | + |
815 | +namespace |
816 | +{ |
817 | + |
818 | +/* TODO (cleanup): Extract this into a separate library because it |
819 | + * duplicates what's in test-pluginclasshandler */ |
820 | +template <typename BaseType> |
821 | +class Base : |
822 | + public PluginClassStorage |
823 | +{ |
824 | + public: |
825 | + |
826 | + typedef BaseType Type; |
827 | + |
828 | + Base (); |
829 | + ~Base (); |
830 | + |
831 | + static unsigned int allocPluginClassIndex (); |
832 | + static void freePluginClassIndex (unsigned int index); |
833 | + |
834 | + private: |
835 | + |
836 | + static PluginClassStorage::Indices indices; |
837 | + static std::list <Base *> bases; |
838 | +}; |
839 | + |
840 | +template <typename BaseType> |
841 | +PluginClassStorage::Indices Base <BaseType>::indices; |
842 | + |
843 | +template <typename BaseType> |
844 | +std::list <Base <BaseType> * > Base <BaseType>::bases; |
845 | + |
846 | +template <typename BaseType> |
847 | +Base <BaseType>::Base () : |
848 | + PluginClassStorage (indices) |
849 | +{ |
850 | + bases.push_back (this); |
851 | +} |
852 | + |
853 | +template <typename BaseType> |
854 | +Base <BaseType>::~Base () |
855 | +{ |
856 | + bases.remove (this); |
857 | +} |
858 | + |
859 | +template <typename BaseType> |
860 | +unsigned int |
861 | +Base <BaseType>::allocPluginClassIndex () |
862 | +{ |
863 | + unsigned int i = PluginClassStorage::allocatePluginClassIndex (indices); |
864 | + |
865 | + foreach (Base *b, bases) |
866 | + { |
867 | + if (indices.size () != b->pluginClasses.size ()) |
868 | + b->pluginClasses.resize (indices.size ()); |
869 | + } |
870 | + |
871 | + return i; |
872 | +} |
873 | + |
874 | +template <typename BaseType> |
875 | +void |
876 | +Base <BaseType>::freePluginClassIndex (unsigned int index) |
877 | +{ |
878 | + PluginClassStorage::freePluginClassIndex (indices, index); |
879 | + |
880 | + foreach (Base *b, bases) |
881 | + { |
882 | + if (indices.size () != b->pluginClasses.size ()) |
883 | + b->pluginClasses.resize (indices.size ()); |
884 | + } |
885 | +} |
886 | + |
887 | +class BaseScreen : |
888 | + public Base <BaseScreen> |
889 | +{ |
890 | +}; |
891 | + |
892 | +class BaseWindow : |
893 | + public Base <BaseWindow> |
894 | +{ |
895 | +}; |
896 | + |
897 | +class DestructionVerifier |
898 | +{ |
899 | + public: |
900 | + |
901 | + DestructionVerifier (); |
902 | + |
903 | + virtual ~DestructionVerifier (); |
904 | + MOCK_METHOD0 (destroy, void ()); |
905 | +}; |
906 | + |
907 | +DestructionVerifier::DestructionVerifier () |
908 | +{ |
909 | + using namespace testing; |
910 | + |
911 | + /* By default we don't care */ |
912 | + EXPECT_CALL (*this, destroy ()).Times (AtLeast (0)); |
913 | +} |
914 | + |
915 | +DestructionVerifier::~DestructionVerifier () |
916 | +{ |
917 | + destroy (); |
918 | +} |
919 | + |
920 | +class PluginScreen : |
921 | + public PluginClassHandler <PluginScreen, BaseScreen>, |
922 | + public DestructionVerifier |
923 | +{ |
924 | + public: |
925 | + |
926 | + PluginScreen (BaseScreen *s); |
927 | +}; |
928 | + |
929 | +class PluginWindow : |
930 | + public PluginClassHandler <PluginWindow, BaseWindow>, |
931 | + public DestructionVerifier |
932 | +{ |
933 | + public: |
934 | + |
935 | + virtual ~PluginWindow () {} |
936 | + PluginWindow (BaseWindow *s); |
937 | +}; |
938 | + |
939 | +PluginScreen::PluginScreen (BaseScreen *s) : |
940 | + PluginClassHandler (s) |
941 | +{ |
942 | +} |
943 | + |
944 | +PluginWindow::PluginWindow (BaseWindow *w) : |
945 | + PluginClassHandler (w) |
946 | +{ |
947 | +} |
948 | + |
949 | +class MockScreenAndWindowVTable : |
950 | + public CompPlugin::VTableForScreenAndWindow <PluginScreen, PluginWindow> |
951 | +{ |
952 | + public: |
953 | + |
954 | + MOCK_METHOD0 (init, bool ()); |
955 | +}; |
956 | + |
957 | +template <class BasePluginType> |
958 | +class PluginClassIntegrationTest : |
959 | + public PluginTest |
960 | +{ |
961 | + public: |
962 | + |
963 | + PluginClassIntegrationTest (); |
964 | + ~PluginClassIntegrationTest (); |
965 | + |
966 | + boost::shared_ptr <CompPlugin> |
967 | + LoadPlugin (MockScreenAndWindowVTable &); |
968 | + |
969 | + MockPluginFilesystem mockfs; |
970 | + ValueHolder *valueHolder; |
971 | +}; |
972 | + |
973 | +void |
974 | +PopAndUnloadPlugin (CompPlugin *p) |
975 | +{ |
976 | + ASSERT_EQ (p, CompPlugin::pop ()); |
977 | + CompPlugin::unload (p); |
978 | +} |
979 | + |
980 | +template <class BasePluginType> |
981 | +boost::shared_ptr <CompPlugin> |
982 | +PluginClassIntegrationTest <BasePluginType>::LoadPlugin (MockScreenAndWindowVTable &v) |
983 | +{ |
984 | + typedef PluginClassIntegrationTest <BasePluginType> TestParam; |
985 | + |
986 | + using namespace testing; |
987 | + |
988 | + EXPECT_CALL (TestParam::mockfs, LoadPlugin (_, _, _)) |
989 | + .Times (AtLeast (0)) |
990 | + .WillOnce (Return (true)); |
991 | + EXPECT_CALL (TestParam::mockfs, UnloadPlugin(_)) |
992 | + .Times (AtLeast (0)); |
993 | + |
994 | + /* Load a plugin, we'll assign the vtable later */ |
995 | + CompPlugin *cp = CompPlugin::load("dummy"); |
996 | + cp->vTable = &v; |
997 | + |
998 | + EXPECT_CALL (v, init ()) |
999 | + .Times (AtLeast (0)) |
1000 | + .WillOnce (Return (true)); |
1001 | + |
1002 | + CompPlugin::push(cp); |
1003 | + |
1004 | + return AutoDestroy (cp, |
1005 | + PopAndUnloadPlugin); |
1006 | +} |
1007 | + |
1008 | +template <class BasePluginType> |
1009 | +PluginClassIntegrationTest <BasePluginType>::PluginClassIntegrationTest () |
1010 | +{ |
1011 | + valueHolder = new ValueHolder (); |
1012 | + ValueHolder::SetDefault (valueHolder); |
1013 | +} |
1014 | + |
1015 | +template <class BasePluginType> |
1016 | +PluginClassIntegrationTest <BasePluginType>::~PluginClassIntegrationTest () |
1017 | +{ |
1018 | + delete valueHolder; |
1019 | + ValueHolder::SetDefault (NULL); |
1020 | +} |
1021 | + |
1022 | +template <typename BaseType, typename PluginType> |
1023 | +class BasePluginTemplate |
1024 | +{ |
1025 | + public: |
1026 | + |
1027 | + typedef BaseType Base; |
1028 | + typedef PluginType Plugin; |
1029 | +}; |
1030 | + |
1031 | +typedef BasePluginTemplate <BaseScreen, PluginScreen> BasePluginScreen; |
1032 | +typedef BasePluginTemplate <BaseWindow, PluginWindow> BasePluginWindow; |
1033 | + |
1034 | +} |
1035 | + |
1036 | +/* TODO: Extract actual interfaces out of CompScreen |
1037 | + * and CompWindow that can be passed to the vTables without |
1038 | + * using a link-seam like this one */ |
1039 | +class CompScreen : |
1040 | + public BaseScreen |
1041 | +{ |
1042 | +}; |
1043 | + |
1044 | +class CompWindow : |
1045 | + public BaseWindow |
1046 | +{ |
1047 | +}; |
1048 | + |
1049 | +typedef ::testing::Types <BasePluginScreen, BasePluginWindow> PluginTypes; |
1050 | +TYPED_TEST_CASE (PluginClassIntegrationTest, PluginTypes); |
1051 | + |
1052 | +TYPED_TEST (PluginClassIntegrationTest, get_plugin_structure_null_on_not_loaded) |
1053 | +{ |
1054 | + using namespace testing; |
1055 | + |
1056 | + typedef PluginClassIntegrationTest <TypeParam> TestParam; |
1057 | + |
1058 | + /* Can't figure out how to get this out of TestParam::base at the moment */ |
1059 | + typename TypeParam::Base base; |
1060 | + typename TypeParam::Plugin *p = TypeParam::Plugin::get (&base); |
1061 | + |
1062 | + EXPECT_THAT (p, IsNull ()); |
1063 | +} |
1064 | + |
1065 | +TYPED_TEST (PluginClassIntegrationTest, get_plugin_structure_nonnull_on_loaded) |
1066 | +{ |
1067 | + using namespace testing; |
1068 | + |
1069 | + typedef PluginClassIntegrationTest <TypeParam> TestParam; |
1070 | + |
1071 | + MockScreenAndWindowVTable vTable; |
1072 | + boost::shared_ptr <CompPlugin> cp (TestParam::LoadPlugin (vTable)); |
1073 | + |
1074 | + typename TypeParam::Base base; |
1075 | + typedef boost::shared_ptr <typename TypeParam::Plugin> PluginPtr; |
1076 | + |
1077 | + /* Because CompScreen is not available, we just need to delete |
1078 | + * the plugin structure ourselves */ |
1079 | + PluginPtr p (TypeParam::Plugin::get (&base)); |
1080 | + |
1081 | + EXPECT_THAT (p.get (), NotNull ()); |
1082 | +} |
1083 | + |
1084 | +TYPED_TEST (PluginClassIntegrationTest, plugin_class_destroyed_when_vtable_is) |
1085 | +{ |
1086 | + using namespace testing; |
1087 | + |
1088 | + typedef PluginClassIntegrationTest <TypeParam> TestParam; |
1089 | + |
1090 | + MockScreenAndWindowVTable vTable; |
1091 | + boost::shared_ptr <CompPlugin> cp (TestParam::LoadPlugin (vTable)); |
1092 | + |
1093 | + typename TypeParam::Base base; |
1094 | + typedef boost::shared_ptr <typename TypeParam::Plugin> PluginPtr; |
1095 | + /* Because CompScreen is not available, we just need to delete |
1096 | + * the plugin structure ourselves */ |
1097 | + PluginPtr p (TypeParam::Plugin::get (&base)); |
1098 | + |
1099 | + EXPECT_CALL (*p, destroy ()).Times (1); |
1100 | } |
1101 | |
1102 | === modified file 'src/pluginclasshandler/include/core/pluginclasshandler.h' |
1103 | --- src/pluginclasshandler/include/core/pluginclasshandler.h 2013-02-26 11:56:10 +0000 |
1104 | +++ src/pluginclasshandler/include/core/pluginclasshandler.h 2013-04-17 07:34:12 +0000 |
1105 | @@ -45,9 +45,50 @@ |
1106 | */ |
1107 | extern unsigned int pluginClassHandlerIndex; |
1108 | |
1109 | +namespace compiz |
1110 | +{ |
1111 | +namespace plugin |
1112 | +{ |
1113 | +namespace internal |
1114 | +{ |
1115 | +class PluginKey; |
1116 | +/** |
1117 | + * LoadedPluginClassBridge |
1118 | + * |
1119 | + * This template essentially exists so that we can reduce the |
1120 | + * scope of functions which are allowed to mark plugin classes |
1121 | + * as instantiatable as we can't really inject the interface |
1122 | + * from PluginClassHandler to do that anywhere. We also can't |
1123 | + * forward declare a nested class declaration, but we can forward |
1124 | + * declare PluginKey, which users should inherit from and take |
1125 | + * it by reference. If the class we're depending on can only be |
1126 | + * defined in one other place along with a private constructor |
1127 | + * accessible only to a friend it means that we've effectively |
1128 | + * limited the scope of users of this class. |
1129 | + */ |
1130 | +template <class Tp, class Tb, int ABI = 0> |
1131 | +class LoadedPluginClassBridge |
1132 | +{ |
1133 | + public: |
1134 | + |
1135 | + static void |
1136 | + allowInstantiations (const PluginKey &); |
1137 | + |
1138 | + static void |
1139 | + disallowInstantiations (const PluginKey &); |
1140 | +}; |
1141 | +} |
1142 | +} |
1143 | +} |
1144 | + |
1145 | template<class Tp, class Tb, int ABI = 0> |
1146 | -class PluginClassHandler { |
1147 | +class PluginClassHandler |
1148 | +{ |
1149 | public: |
1150 | + |
1151 | + typedef Tp ClassPluginType; |
1152 | + typedef Tb ClassPluginBaseType; |
1153 | + |
1154 | PluginClassHandler (Tb *); |
1155 | ~PluginClassHandler (); |
1156 | |
1157 | @@ -90,16 +131,49 @@ |
1158 | static bool initializeIndex (Tb *base); |
1159 | static inline Tp * getInstance (Tb *base); |
1160 | |
1161 | + static void allowInstantiations (); |
1162 | + static void disallowInstantiations (); |
1163 | + |
1164 | + template <class Plugin, class Base, int PluginABI> |
1165 | + friend class compiz::plugin::internal::LoadedPluginClassBridge; |
1166 | + |
1167 | private: |
1168 | bool mFailed; |
1169 | Tb *mBase; |
1170 | |
1171 | static PluginClassIndex mIndex; |
1172 | + static bool mPluginLoaded; |
1173 | }; |
1174 | |
1175 | +namespace compiz |
1176 | +{ |
1177 | +namespace plugin |
1178 | +{ |
1179 | +namespace internal |
1180 | +{ |
1181 | +template <class Tp, class Tb, int ABI> |
1182 | +void |
1183 | +LoadedPluginClassBridge <Tp, Tb, ABI>::allowInstantiations (const PluginKey &) |
1184 | +{ |
1185 | + PluginClassHandler <Tp, Tb, ABI>::allowInstantiations (); |
1186 | +} |
1187 | + |
1188 | +template <class Tp, class Tb, int ABI> |
1189 | +void |
1190 | +LoadedPluginClassBridge <Tp, Tb, ABI>::disallowInstantiations (const PluginKey &) |
1191 | +{ |
1192 | + PluginClassHandler <Tp, Tb, ABI>::disallowInstantiations (); |
1193 | +} |
1194 | +} |
1195 | +} |
1196 | +} |
1197 | + |
1198 | template<class Tp, class Tb, int ABI> |
1199 | PluginClassIndex PluginClassHandler<Tp,Tb,ABI>::mIndex; |
1200 | |
1201 | +template<class Tp, class Tb, int ABI> |
1202 | +bool PluginClassHandler<Tp,Tb,ABI>::mPluginLoaded = false; |
1203 | + |
1204 | /** |
1205 | * Attaches a unique instance of the specified plugin class to a |
1206 | * unique instance of a specified base class |
1207 | @@ -253,15 +327,23 @@ |
1208 | Tp * |
1209 | PluginClassHandler<Tp,Tb,ABI>::get (Tb *base) |
1210 | { |
1211 | + /* Never instantiate an instance of this class |
1212 | + * if the relevant plugin has not been loaded |
1213 | + */ |
1214 | + if (!mPluginLoaded) |
1215 | + return NULL; |
1216 | + |
1217 | /* Always ensure that the index is initialized before |
1218 | * calls to ::get */ |
1219 | if (!mIndex.initiated) |
1220 | initializeIndex (base); |
1221 | + |
1222 | /* If pluginClassHandlerIndex == mIndex.pcIndex it means that our |
1223 | * mIndex.index is fresh and can be used directly without needing |
1224 | * to fetch it from ValueHolder */ |
1225 | if (mIndex.initiated && pluginClassHandlerIndex == mIndex.pcIndex) |
1226 | return getInstance (base); |
1227 | + |
1228 | /* If allocating or getting the updated index failed at any point |
1229 | * then just return NULL we don't know where our private data is stored */ |
1230 | if (mIndex.failed && pluginClassHandlerIndex == mIndex.pcIndex) |
1231 | @@ -285,4 +367,18 @@ |
1232 | } |
1233 | } |
1234 | |
1235 | +template<class Tp, class Tb, int ABI> |
1236 | +void |
1237 | +PluginClassHandler<Tp, Tb, ABI>::allowInstantiations () |
1238 | +{ |
1239 | + mPluginLoaded = true; |
1240 | +} |
1241 | + |
1242 | +template<class Tp, class Tb, int ABI> |
1243 | +void |
1244 | +PluginClassHandler<Tp, Tb, ABI>::disallowInstantiations () |
1245 | +{ |
1246 | + mPluginLoaded = false; |
1247 | +} |
1248 | + |
1249 | #endif |
1250 | |
1251 | === modified file 'src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp' |
1252 | --- src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp 2012-01-12 06:48:58 +0000 |
1253 | +++ src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp 2013-04-17 07:34:12 +0000 |
1254 | @@ -1,23 +1,46 @@ |
1255 | #include <test-pluginclasshandler.h> |
1256 | |
1257 | -class ConstructPlugin: public Plugin, public PluginClassHandler<ConstructPlugin, |
1258 | - Base> |
1259 | -{ |
1260 | -public: |
1261 | - ConstructPlugin (Base * base) : |
1262 | - Plugin(base), PluginClassHandler<ConstructPlugin, Base>(base) |
1263 | - { |
1264 | - } |
1265 | -}; |
1266 | - |
1267 | -TEST_F( CompizPCHTest, TestConstruct ) |
1268 | +class BuildPlugin: |
1269 | + public Plugin, |
1270 | + public PluginClassHandler <BuildPlugin, Base> |
1271 | +{ |
1272 | + public: |
1273 | + BuildPlugin (Base *base) : |
1274 | + Plugin(base), |
1275 | + PluginClassHandler <BuildPlugin, Base> (base) |
1276 | + { |
1277 | + } |
1278 | +}; |
1279 | + |
1280 | +class PluginClassHandlerConstruction : |
1281 | + public CompizPCHTest |
1282 | +{ |
1283 | + public: |
1284 | + |
1285 | + PluginClassHandlerConstruction (); |
1286 | + ~PluginClassHandlerConstruction (); |
1287 | +}; |
1288 | + |
1289 | +PluginClassHandlerConstruction::PluginClassHandlerConstruction () |
1290 | +{ |
1291 | + namespace cpi = compiz::plugin::internal; |
1292 | + cpi::LoadedPluginClassBridge <BuildPlugin, Base>::allowInstantiations (key); |
1293 | +} |
1294 | + |
1295 | +PluginClassHandlerConstruction::~PluginClassHandlerConstruction () |
1296 | +{ |
1297 | + namespace cpi = compiz::plugin::internal; |
1298 | + cpi::LoadedPluginClassBridge <BuildPlugin, Base>::disallowInstantiations (key); |
1299 | +} |
1300 | + |
1301 | +TEST_F (PluginClassHandlerConstruction, TestConstruction) |
1302 | { |
1303 | Plugin *p; |
1304 | |
1305 | bases.push_back(new Base()); |
1306 | - plugins.push_back(static_cast<Plugin *>(new ConstructPlugin(bases.back()))); |
1307 | + plugins.push_back(static_cast<Plugin *>(new BuildPlugin(bases.back()))); |
1308 | bases.push_back(new Base()); |
1309 | - plugins.push_back(static_cast<Plugin *>(new ConstructPlugin(bases.back()))); |
1310 | + plugins.push_back(static_cast<Plugin *>(new BuildPlugin(bases.back()))); |
1311 | |
1312 | if (bases.front()->pluginClasses.size() != globalPluginClassIndices.size()) |
1313 | { |
1314 | @@ -26,20 +49,20 @@ |
1315 | } |
1316 | |
1317 | if (!ValueHolder::Default()->hasValue( |
1318 | - compPrintf("%s_index_%lu", typeid(ConstructPlugin).name(), 0))) |
1319 | + compPrintf("%s_index_%lu", typeid(BuildPlugin).name(), 0))) |
1320 | { |
1321 | FAIL() << "ValueHolder does not have value " |
1322 | - << compPrintf("%s_index_%lu", typeid(ConstructPlugin).name(), 0); |
1323 | + << compPrintf("%s_index_%lu", typeid(BuildPlugin).name(), 0); |
1324 | } |
1325 | |
1326 | - p = ConstructPlugin::get(bases.front()); |
1327 | + p = BuildPlugin::get(bases.front()); |
1328 | |
1329 | if (p != plugins.front()) |
1330 | { |
1331 | FAIL() << "Returned Plugin * is not plugins.front ()"; |
1332 | } |
1333 | |
1334 | - p = ConstructPlugin::get(bases.back()); |
1335 | + p = BuildPlugin::get(bases.back()); |
1336 | |
1337 | if (p != plugins.back()) |
1338 | { |
1339 | |
1340 | === modified file 'src/pluginclasshandler/tests/get/src/test-pch-get.cpp' |
1341 | --- src/pluginclasshandler/tests/get/src/test-pch-get.cpp 2012-01-12 06:48:58 +0000 |
1342 | +++ src/pluginclasshandler/tests/get/src/test-pch-get.cpp 2013-04-17 07:34:12 +0000 |
1343 | @@ -1,5 +1,9 @@ |
1344 | #include <test-pluginclasshandler.h> |
1345 | |
1346 | +namespace cpi = compiz::plugin::internal; |
1347 | + |
1348 | +using ::testing::IsNull; |
1349 | + |
1350 | class GetPlugin : |
1351 | public Plugin, |
1352 | public PluginClassHandler <GetPlugin, Base> |
1353 | @@ -14,7 +18,26 @@ |
1354 | { |
1355 | } |
1356 | |
1357 | -TEST_F( CompizPCHTest, TestGet) |
1358 | +class PluginClassHandlerGet : |
1359 | + public CompizPCHTest |
1360 | +{ |
1361 | + public: |
1362 | + |
1363 | + PluginClassHandlerGet (); |
1364 | + ~PluginClassHandlerGet (); |
1365 | +}; |
1366 | + |
1367 | +PluginClassHandlerGet::PluginClassHandlerGet () |
1368 | +{ |
1369 | + cpi::LoadedPluginClassBridge <GetPlugin, Base>::allowInstantiations (key); |
1370 | +} |
1371 | + |
1372 | +PluginClassHandlerGet::~PluginClassHandlerGet () |
1373 | +{ |
1374 | + cpi::LoadedPluginClassBridge <GetPlugin, Base>::disallowInstantiations (key); |
1375 | +} |
1376 | + |
1377 | +TEST_F (PluginClassHandlerGet, TestGet) |
1378 | { |
1379 | Plugin *p; |
1380 | |
1381 | @@ -49,3 +72,17 @@ |
1382 | FAIL() << "Returned Plugin * is not the plugin for bases.back ()"; |
1383 | } |
1384 | } |
1385 | + |
1386 | +TEST_F (PluginClassHandlerGet, TestGetNoInstantiationsAllowed) |
1387 | +{ |
1388 | + cpi::LoadedPluginClassBridge <GetPlugin, Base>::disallowInstantiations (key); |
1389 | + |
1390 | + Plugin *p; |
1391 | + |
1392 | + bases.push_back (new Base ()); |
1393 | + plugins.push_back (new GetPlugin (bases.back ())); |
1394 | + |
1395 | + p = GetPlugin::get (bases.front ()); |
1396 | + |
1397 | + EXPECT_THAT (p, IsNull ()); |
1398 | +} |
1399 | |
1400 | === modified file 'src/pluginclasshandler/tests/test-pluginclasshandler.h' |
1401 | --- src/pluginclasshandler/tests/test-pluginclasshandler.h 2012-01-19 18:12:31 +0000 |
1402 | +++ src/pluginclasshandler/tests/test-pluginclasshandler.h 2013-04-17 07:34:12 +0000 |
1403 | @@ -2,6 +2,7 @@ |
1404 | #include <core/pluginclasses.h> |
1405 | |
1406 | #include <gtest/gtest.h> |
1407 | +#include <gmock/gmock.h> |
1408 | |
1409 | #include <list> |
1410 | |
1411 | @@ -44,6 +45,21 @@ |
1412 | Base *b; |
1413 | }; |
1414 | |
1415 | +namespace compiz |
1416 | +{ |
1417 | +namespace plugin |
1418 | +{ |
1419 | +namespace internal |
1420 | +{ |
1421 | +/* The version available in the tests is |
1422 | + * readily constructed */ |
1423 | +class PluginKey |
1424 | +{ |
1425 | +}; |
1426 | +} |
1427 | +} |
1428 | +} |
1429 | + |
1430 | class CompizPCHTest : public ::testing::Test |
1431 | { |
1432 | public: |
1433 | @@ -54,4 +70,6 @@ |
1434 | Global *global; |
1435 | std::list <Base *> bases; |
1436 | std::list <Plugin *> plugins; |
1437 | + |
1438 | + compiz::plugin::internal::PluginKey key; |
1439 | }; |
1440 | |
1441 | === modified file 'src/privatescreen/tests/test-privatescreen.cpp' |
1442 | --- src/privatescreen/tests/test-privatescreen.cpp 2012-12-30 11:13:36 +0000 |
1443 | +++ src/privatescreen/tests/test-privatescreen.cpp 2013-04-17 07:34:12 +0000 |
1444 | @@ -249,23 +249,23 @@ |
1445 | |
1446 | namespace { |
1447 | |
1448 | -class MockVTable: public CompPlugin::VTable { |
1449 | +class MockVTable: |
1450 | + public CompPlugin::VTable |
1451 | +{ |
1452 | public: |
1453 | MockVTable (CompString const& name) { initVTable (name); } |
1454 | |
1455 | MOCK_METHOD0(init, bool ()); |
1456 | MOCK_METHOD0(fini, void ()); |
1457 | |
1458 | + MOCK_METHOD0(markReadyToInstantiate, void ()); |
1459 | + MOCK_METHOD0(markNoFurtherInstantiation, void ()); |
1460 | + |
1461 | MOCK_METHOD1(initScreen, bool (CompScreen *s)); |
1462 | - |
1463 | MOCK_METHOD1(finiScreen, void (CompScreen *s)); |
1464 | - |
1465 | MOCK_METHOD1(initWindow, bool (CompWindow *w)); |
1466 | - |
1467 | MOCK_METHOD1(finiWindow, void (CompWindow *w)); |
1468 | - |
1469 | MOCK_METHOD0(getOptions, CompOption::Vector & ()); |
1470 | - |
1471 | MOCK_METHOD2(setOption, bool (const CompString &name, CompOption::Value &value)); |
1472 | }; |
1473 | |
1474 | @@ -285,7 +285,8 @@ |
1475 | virtual ~PluginFilesystem() {} |
1476 | }; |
1477 | |
1478 | -class MockPluginFilesystem : public PluginFilesystem |
1479 | +class MockPluginFilesystem : |
1480 | + public PluginFilesystem |
1481 | { |
1482 | public: |
1483 | MockVTable mockVtableOne; |
FAILED: Continuous integration, rev:3658 jenkins. qa.ubuntu. com/job/ compiz- ci/135/ jenkins. qa.ubuntu. com/job/ compiz- gles-ci/ ./build= pbuilder, distribution= raring, flavor= amd64/172/ console jenkins. qa.ubuntu. com/job/ compiz- pbuilder/ ./build= pbuilder, distribution= raring, flavor= amd64/524/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ compiz- ci/135/ rebuild
http://