Merge lp:~compiz-team/compiz/compiz.fix_1101026.1 into lp:compiz/0.9.10

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1101026.1
Merge into: lp:compiz/0.9.10
Diff against target: 1492 lines (+892/-155)
15 files modified
.bzrignore (+1/-0)
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 (+484/-71)
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.1
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Needs Fixing
MC Return Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+165766@code.launchpad.net

This proposal supersedes a proposal from 2013-04-19.

This proposal has been superseded by a proposal from 2013-05-28.

Commit message

Added some new hooks to PluginClassHandler to allow a VTable to specify if loaded.

PluginClassHandler::get () was designed to simply instantiate an instance of that
class for the core structure, but it did this without checking if the plugin was
loaded.

Added some new methods to PluginClassHandler exposed by LoadedPluginClassBridge
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

(LP: #1169620)
(LP: #1101026)

Description of the change

Added some new hooks to PluginClassHandler to allow a VTable to specify if loaded.

PluginClassHandler::get () was designed to simply instantiate an instance of that
class for the core structure, but it did this without checking if the plugin was
loaded.

Added some new methods to PluginClassHandler exposed by LoadedPluginClassBridge
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

(LP: #1169620)
(LP: #1101026)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

This MP sounds very promising.
I guess this: 9 +#define CORE_ABIVERSION 20130415 means all plugins will have to be recompiled ?

Maybe adding 2 newlines here, after public and protected ?:

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() {}

One whitespace too much here:

1124 + * declare PluginKey, which users should inherit from and take

Other than that, I still need to test this, "Abstain" for now.

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

I am on the one hand very excited about this one, but on the other hand this means for me personally, that my self-compiled non-trunk plugins will probably all need fixing, then each branch will have to merge with trunk, then I will
have to recompile all those branches again, then copy the compiled binaries, before I can start to use them again ->

I would really like to see screenshot merged to trunk at least, before this one gets merged...

Abstain for now...

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
MC Return (mc-return) wrote :

Sam, I have linked the 2 corresponding bug reports to this MP.

Revision history for this message
MC Return (mc-return) wrote :

A huge change. :)

Forces me to finally merge trunk with my working branch and fix all the conflicts.
Forces me to recompile all plugins not yet merged with trunk.
Forces me to do a lot of things.

Could not find anything in the code looking bad though and it is great you fixed those nasty bugs with this MP, so this forces me to "Approve" this thingy... ;)

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Hmm strange:

/home/bschaefer/src/compiz.fix_1101026.1/src/plugin/tests/test-plugin.cpp: In member function ‘virtual void PluginClassIntegrationTest_get_plugin_structure_null_on_not_loaded_Test<gtest_TypeParam_>::TestBody()’:
/home/bschaefer/src/compiz.fix_1101026.1/src/plugin/tests/test-plugin.cpp:588:52: error: typedef ‘TestParam’ locally defined but not used [-Werror=unused-local-typedefs]
     typedef PluginClassIntegrationTest <TypeParam> TestParam;
                                                    ^
At global scope:
cc1plus: error: unrecognized command line option "-Wno-unused-private-field" [-Werror]
cc1plus: error: unrecognized command line option "-Wno-unused-private-field" [-Werror]
cc1plus: error: unrecognized command line option "-Wno-unused-private-field" [-Werror]
cc1plus: error: unrecognized command line option "-Wno-unused-private-field" [-Werror]
cc1plus: all warnings being treated as errors

I've not had a huge amount of time to look into why this fails (or if I cmaked it wrong :)

review: Needs Fixing
3727. By Sam Spilsbury

Remove unused typedef

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2013-05-28 23:40:33 +0000
@@ -0,0 +1,1 @@
1.bzr-repo
02
=== modified file 'include/core/abiversion.h'
--- include/core/abiversion.h 2013-01-28 17:54:50 +0000
+++ include/core/abiversion.h 2013-05-28 23:40:33 +0000
@@ -5,6 +5,6 @@
5# error Conflicting definitions of CORE_ABIVERSION5# error Conflicting definitions of CORE_ABIVERSION
6#endif6#endif
77
8#define CORE_ABIVERSION 201301258#define CORE_ABIVERSION 20130415
99
10#endif // COMPIZ_ABIVERSION_H10#endif // COMPIZ_ABIVERSION_H
1111
=== modified file 'include/core/plugin.h'
--- include/core/plugin.h 2013-01-24 14:18:03 +0000
+++ include/core/plugin.h 2013-05-28 23:40:33 +0000
@@ -29,6 +29,7 @@
29#include <core/string.h>29#include <core/string.h>
30#include <core/option.h>30#include <core/option.h>
31#include <core/privateunion.h>31#include <core/privateunion.h>
32#include <core/pluginclasshandler.h>
3233
33#include <string.h>34#include <string.h>
3435
@@ -70,6 +71,37 @@
70extern UnloadPluginProc loaderUnloadPlugin;71extern UnloadPluginProc loaderUnloadPlugin;
71extern ListPluginsProc loaderListPlugins;72extern ListPluginsProc loaderListPlugins;
7273
74namespace compiz
75{
76namespace plugin
77{
78namespace internal
79{
80class VTableBase;
81
82/**
83 * Provide a definition for PluginKey, with a protected
84 * constructor which is a friend of VTableBase */
85class PluginKey
86{
87 protected:
88
89 PluginKey () {}
90
91 friend class VTableBase;
92};
93
94class VTableBase :
95 public PluginKey
96{
97 public:
98
99 virtual ~VTableBase () {};
100};
101}
102}
103}
104
73/**105/**
74 * Base plug-in interface for Compiz. All plugins must implement this106 * Base plug-in interface for Compiz. All plugins must implement this
75 * interface, which provides basics for loading, unloading, options,107 * interface, which provides basics for loading, unloading, options,
@@ -77,8 +109,11 @@
77 */109 */
78class CompPlugin {110class CompPlugin {
79 public:111 public:
80 class VTable {112 class VTable :
113 public compiz::plugin::internal::VTableBase
114 {
81 public:115 public:
116
82 VTable ();117 VTable ();
83 virtual ~VTable ();118 virtual ~VTable ();
84119
@@ -91,9 +126,14 @@
91 const CompString &name () const;126 const CompString &name () const;
92127
93 virtual bool init () = 0;128 virtual bool init () = 0;
94
95 virtual void fini ();129 virtual void fini ();
96130
131 /* Mark the plugin as ready to be instantiated */
132 virtual void markReadyToInstantiate () = 0;
133
134 /* Mark the plugin as disallowing further instantiation */
135 virtual void markNoFurtherInstantiation () = 0;
136
97 virtual bool initScreen (CompScreen *s);137 virtual bool initScreen (CompScreen *s);
98138
99 virtual void finiScreen (CompScreen *s);139 virtual void finiScreen (CompScreen *s);
@@ -111,36 +151,53 @@
111 VTable **mSelf;151 VTable **mSelf;
112 };152 };
113153
114 /**154 /**
115 * TODO (or not?)155 * TODO (or not?)
116 */156 */
117 template <typename T, typename T2>157 template <typename T, typename T2, int ABI = 0>
118 class VTableForScreenAndWindow : public VTable {158 class VTableForScreenAndWindow :
119 bool initScreen (CompScreen *s);159 public VTable
120160 {
121 void finiScreen (CompScreen *s);161 public:
122162
123 bool initWindow (CompWindow *w);163 bool initScreen (CompScreen *s);
124164 void finiScreen (CompScreen *s);
125 void finiWindow (CompWindow *w);165 bool initWindow (CompWindow *w);
126166 void finiWindow (CompWindow *w);
127 CompOption::Vector & getOptions ();167 CompOption::Vector & getOptions ();
128168 bool setOption (const CompString &name,
129 bool setOption (const CompString &name, CompOption::Value &value);169 CompOption::Value &value);
170
171 private:
172
173 /* Mark the plugin as ready to be instantiated */
174 void markReadyToInstantiate ();
175
176 /* Mark the plugin as disallowing further instantiation */
177 void markNoFurtherInstantiation ();
130 };178 };
131179
132 /**180 /**
133 * TODO (or not?)181 * TODO (or not?)
134 */182 */
135 template <typename T>183 template <typename T, int ABI = 0>
136 class VTableForScreen : public VTable {184 class VTableForScreen :
137 bool initScreen (CompScreen *s);185 public VTable
138186 {
139 void finiScreen (CompScreen *s);187 public:
140188
141 CompOption::Vector & getOptions ();189 bool initScreen (CompScreen *s);
142190 void finiScreen (CompScreen *s);
143 bool setOption (const CompString &name, CompOption::Value &value);191 CompOption::Vector & getOptions ();
192 bool setOption (const CompString &name, CompOption::Value &value);
193
194 private:
195
196 /* Mark the plugin as ready to be instantiated */
197 void markReadyToInstantiate ();
198
199 /* Mark the plugin as disallowing further instantiation */
200 void markNoFurtherInstantiation ();
144 };201 };
145 202
146 typedef std::map<CompString, CompPlugin *> Map;203 typedef std::map<CompString, CompPlugin *> Map;
@@ -211,9 +268,47 @@
211268
212};269};
213270
214271/**
215template <typename T, typename T2>272 * Mark the plugin class handlers as ready to be initialized
216bool CompPlugin::VTableForScreenAndWindow<T,T2>::initScreen (CompScreen *s)273 */
274template <typename T, typename T2, int ABI>
275void
276CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::markReadyToInstantiate ()
277{
278 namespace cpi = compiz::plugin::internal;
279
280 typedef typename T::ClassPluginBaseType ScreenBase;
281 typedef typename T2::ClassPluginBaseType WindowBase;
282
283 typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge;
284 typedef cpi::LoadedPluginClassBridge <T2, WindowBase, ABI> WindowBridge;
285
286 ScreenBridge::allowInstantiations (*this);
287 WindowBridge::allowInstantiations (*this);
288}
289
290/**
291 * Allow no further class handler initialization
292 */
293template <typename T, typename T2, int ABI>
294void
295CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::markNoFurtherInstantiation ()
296{
297 namespace cpi = compiz::plugin::internal;
298
299 typedef typename T::ClassPluginBaseType ScreenBase;
300 typedef typename T2::ClassPluginBaseType WindowBase;
301
302 typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge;
303 typedef cpi::LoadedPluginClassBridge <T2, WindowBase, ABI> WindowBridge;
304
305 ScreenBridge::disallowInstantiations (*this);
306 WindowBridge::disallowInstantiations (*this);
307}
308
309template <typename T, typename T2, int ABI>
310bool
311CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::initScreen (CompScreen *s)
217{312{
218 T * ps = T::get (s);313 T * ps = T::get (s);
219 if (!ps)314 if (!ps)
@@ -222,15 +317,17 @@
222 return true;317 return true;
223}318}
224319
225template <typename T, typename T2>320template <typename T, typename T2, int ABI>
226void CompPlugin::VTableForScreenAndWindow<T,T2>::finiScreen (CompScreen *s)321void
322CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::finiScreen (CompScreen *s)
227{323{
228 T * ps = T::get (s);324 T * ps = T::get (s);
229 delete ps;325 delete ps;
230}326}
231327
232template <typename T, typename T2>328template <typename T, typename T2, int ABI>
233bool CompPlugin::VTableForScreenAndWindow<T,T2>::initWindow (CompWindow *w)329bool
330CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::initWindow (CompWindow *w)
234{331{
235 T2 * pw = T2::get (w);332 T2 * pw = T2::get (w);
236 if (!pw)333 if (!pw)
@@ -239,15 +336,16 @@
239 return true;336 return true;
240}337}
241338
242template <typename T, typename T2>339template <typename T, typename T2, int ABI>
243void CompPlugin::VTableForScreenAndWindow<T,T2>::finiWindow (CompWindow *w)340void
341CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::finiWindow (CompWindow *w)
244{342{
245 T2 * pw = T2::get (w);343 T2 * pw = T2::get (w);
246 delete pw;344 delete pw;
247}345}
248346
249template <typename T, typename T2>347template <typename T, typename T2, int ABI>
250CompOption::Vector & CompPlugin::VTableForScreenAndWindow<T,T2>::getOptions ()348CompOption::Vector & CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::getOptions ()
251{349{
252 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));350 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));
253 if (!oc)351 if (!oc)
@@ -255,9 +353,10 @@
255 return oc->getOptions ();353 return oc->getOptions ();
256}354}
257355
258template <typename T, typename T2>356template <typename T, typename T2, int ABI>
259bool CompPlugin::VTableForScreenAndWindow<T,T2>::setOption (const CompString &name,357bool
260 CompOption::Value &value)358CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::setOption (const CompString &name,
359 CompOption::Value &value)
261{360{
262 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));361 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));
263 if (!oc)362 if (!oc)
@@ -265,8 +364,39 @@
265 return oc->setOption (name, value);364 return oc->setOption (name, value);
266}365}
267366
268template <typename T>367/**
269bool CompPlugin::VTableForScreen<T>::initScreen (CompScreen *s)368 * Mark the plugin class handlers as ready to be initialized
369 */
370template <typename T, int ABI>
371void
372CompPlugin::VTableForScreen<T, ABI>::markReadyToInstantiate ()
373{
374 namespace cpi = compiz::plugin::internal;
375
376 typedef typename T::ClassPluginBaseType ScreenBase;
377 typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge;
378
379 ScreenBridge::allowInstantiations (*this);
380}
381
382/**
383 * Allow no further class handler initialization
384 */
385template <typename T, int ABI>
386void
387CompPlugin::VTableForScreen<T, ABI>::markNoFurtherInstantiation ()
388{
389 namespace cpi = compiz::plugin::internal;
390
391 typedef typename T::ClassPluginBaseType ScreenBase;
392 typedef cpi::LoadedPluginClassBridge <T, ScreenBase, ABI> ScreenBridge;
393
394 ScreenBridge::disallowInstantiations (*this);
395}
396
397template <typename T, int ABI>
398bool
399CompPlugin::VTableForScreen<T, ABI>::initScreen (CompScreen *s)
270{400{
271 T * ps = new T (s);401 T * ps = new T (s);
272 if (ps->loadFailed ())402 if (ps->loadFailed ())
@@ -277,15 +407,16 @@
277 return true;407 return true;
278}408}
279409
280template <typename T>410template <typename T, int ABI>
281void CompPlugin::VTableForScreen<T>::finiScreen (CompScreen *s)411void CompPlugin::VTableForScreen<T, ABI>::finiScreen (CompScreen *s)
282{412{
283 T * ps = T::get (s);413 T * ps = T::get (s);
284 delete ps;414 delete ps;
285}415}
286416
287template <typename T>417template <typename T, int ABI>
288CompOption::Vector & CompPlugin::VTableForScreen<T>::getOptions ()418CompOption::Vector &
419CompPlugin::VTableForScreen<T, ABI>::getOptions ()
289{420{
290 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));421 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));
291 if (!oc)422 if (!oc)
@@ -293,8 +424,9 @@
293 return oc->getOptions ();424 return oc->getOptions ();
294}425}
295426
296template <typename T>427template <typename T, int ABI>
297bool CompPlugin::VTableForScreen<T>::setOption (const CompString &name,428bool
429CompPlugin::VTableForScreen<T, ABI>::setOption (const CompString &name,
298 CompOption::Value &value)430 CompOption::Value &value)
299{431{
300 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));432 CompOption::Class *oc = dynamic_cast<CompOption::Class *> (T::get (screen));
301433
=== modified file 'plugins/animation/src/animation.cpp'
--- plugins/animation/src/animation.cpp 2013-05-09 13:43:07 +0000
+++ plugins/animation/src/animation.cpp 2013-05-28 23:40:33 +0000
@@ -94,7 +94,7 @@
94using namespace compiz::core;94using namespace compiz::core;
9595
96class AnimPluginVTable :96class AnimPluginVTable :
97 public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow>97 public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow, ANIMATION_ABI>
98{98{
99public:99public:
100 bool init ();100 bool init ();
101101
=== modified file 'plugins/composite/src/composite.cpp'
--- plugins/composite/src/composite.cpp 2013-05-09 13:43:07 +0000
+++ plugins/composite/src/composite.cpp 2013-05-28 23:40:33 +0000
@@ -33,7 +33,7 @@
3333
3434
35class CompositePluginVTable :35class CompositePluginVTable :
36 public CompPlugin::VTableForScreenAndWindow<CompositeScreen, CompositeWindow>36 public CompPlugin::VTableForScreenAndWindow<CompositeScreen, CompositeWindow, COMPIZ_COMPOSITE_ABI>
37{37{
38 public:38 public:
3939
4040
=== modified file 'plugins/cube/src/cube.cpp'
--- plugins/cube/src/cube.cpp 2013-05-19 11:50:08 +0000
+++ plugins/cube/src/cube.cpp 2013-05-28 23:40:33 +0000
@@ -33,7 +33,7 @@
33#include <privates.h>33#include <privates.h>
3434
35class CubePluginVTable :35class CubePluginVTable :
36 public CompPlugin::VTableForScreenAndWindow<CubeScreen, PrivateCubeWindow>36 public CompPlugin::VTableForScreenAndWindow<CubeScreen, PrivateCubeWindow, COMPIZ_CUBE_ABI>
37{37{
38 public:38 public:
3939
4040
=== modified file 'plugins/opengl/src/opengl.cpp'
--- plugins/opengl/src/opengl.cpp 2013-05-09 13:43:07 +0000
+++ plugins/opengl/src/opengl.cpp 2013-05-28 23:40:33 +0000
@@ -79,7 +79,7 @@
79}79}
8080
81class OpenglPluginVTable :81class OpenglPluginVTable :
82 public CompPlugin::VTableForScreenAndWindow<GLScreen, GLWindow>82 public CompPlugin::VTableForScreenAndWindow<GLScreen, GLWindow, COMPIZ_OPENGL_ABI>
83{83{
84 public:84 public:
8585
8686
=== modified file 'plugins/scale/src/scale.cpp'
--- plugins/scale/src/scale.cpp 2013-05-11 09:30:49 +0000
+++ plugins/scale/src/scale.cpp 2013-05-28 23:40:33 +0000
@@ -39,7 +39,7 @@
39#define EDGE_STATE (CompAction::StateInitEdge)39#define EDGE_STATE (CompAction::StateInitEdge)
4040
41class ScalePluginVTable :41class ScalePluginVTable :
42 public CompPlugin::VTableForScreenAndWindow<ScaleScreen, ScaleWindow>42 public CompPlugin::VTableForScreenAndWindow<ScaleScreen, ScaleWindow, COMPIZ_SCALE_ABI>
43{43{
44 public:44 public:
4545
4646
=== modified file 'src/plugin.cpp'
--- src/plugin.cpp 2013-02-14 02:43:51 +0000
+++ src/plugin.cpp 2013-05-28 23:40:33 +0000
@@ -54,6 +54,9 @@
5454
55 bool init ();55 bool init ();
5656
57 void markReadyToInstantiate ();
58 void markNoFurtherInstantiation ();
59
57 CompOption::Vector & getOptions ();60 CompOption::Vector & getOptions ();
5861
59 bool setOption (const CompString &name,62 bool setOption (const CompString &name,
@@ -78,6 +81,16 @@
78 return true;81 return true;
79}82}
8083
84void
85CorePluginVTable::markReadyToInstantiate ()
86{
87}
88
89void
90CorePluginVTable::markNoFurtherInstantiation ()
91{
92}
93
81CompOption::Vector &94CompOption::Vector &
82CorePluginVTable::getOptions ()95CorePluginVTable::getOptions ()
83{96{
@@ -228,6 +241,8 @@
228 return false;241 return false;
229 }242 }
230243
244 p->vTable->markReadyToInstantiate ();
245
231 if (screen && screen->displayInitialised())246 if (screen && screen->displayInitialised())
232 {247 {
233 if (!p->vTable->initScreen (screen))248 if (!p->vTable->initScreen (screen))
@@ -252,6 +267,7 @@
252void267void
253CompManager::finiPlugin (CompPlugin *p)268CompManager::finiPlugin (CompPlugin *p)
254{269{
270 p->vTable->markNoFurtherInstantiation ();
255271
256 if (screen)272 if (screen)
257 {273 {
258274
=== modified file 'src/plugin/tests/test-plugin.cpp'
--- src/plugin/tests/test-plugin.cpp 2013-02-14 02:43:51 +0000
+++ src/plugin/tests/test-plugin.cpp 2013-05-28 23:40:33 +0000
@@ -1,8 +1,9 @@
1#include <boost/shared_ptr.hpp>
2#include <boost/foreach.hpp>
3#define foreach BOOST_FOREACH
4
1#include "core/plugin.h"5#include "core/plugin.h"
26
3// This prevents an instantiation error - not sure why ATM
4#include "core/screen.h"
5
6// Get rid of stupid macro from X.h7// Get rid of stupid macro from X.h
7// Why, oh why, are we including X.h?8// Why, oh why, are we including X.h?
8#undef None9#undef None
@@ -10,37 +11,54 @@
10#include <gtest/gtest.h>11#include <gtest/gtest.h>
11#include <gmock/gmock.h>12#include <gmock/gmock.h>
12#include <gtest_shared_tmpenv.h>13#include <gtest_shared_tmpenv.h>
1314#include <gtest_shared_autodestroy.h>
14namespace {15
16/* This is a link-seam so that we don't have to include screen.h */
17class CompAction
18{
19};
20
21class CompMatch
22{
23};
24
25namespace
26{
1527
16class PluginFilesystem28class PluginFilesystem
17{29{
18public:30 public:
19 virtual bool31
20 LoadPlugin(CompPlugin *p, const char *path, const char *name) const = 0;32 virtual bool
2133 LoadPlugin(CompPlugin *p, const char *path, const char *name) const = 0;
22 virtual void34
23 UnloadPlugin(CompPlugin *p) const = 0;35 virtual void
2436 UnloadPlugin(CompPlugin *p) const = 0;
25 static PluginFilesystem const* instance;37
2638 static PluginFilesystem const* instance;
27protected:39
28 PluginFilesystem();40 protected:
29 virtual ~PluginFilesystem() {}41
42 PluginFilesystem();
43 virtual ~PluginFilesystem() {}
30};44};
3145
32class MockPluginFilesystem : public PluginFilesystem46class MockPluginFilesystem : public PluginFilesystem
33{47{
34public:48 public:
35 MOCK_CONST_METHOD3(LoadPlugin, bool (CompPlugin *, const char *, const char *));49
3650 MOCK_CONST_METHOD3(LoadPlugin, bool (CompPlugin *, const char *, const char *));
37 MOCK_CONST_METHOD1(UnloadPlugin, void (CompPlugin *p));51
52 MOCK_CONST_METHOD1(UnloadPlugin, void (CompPlugin *p));
38};53};
3954
40class MockVTable : public CompPlugin::VTable55class MockVTable :
56 public CompPlugin::VTable
41{57{
42public:58 public:
43 MOCK_METHOD0(init, bool ());59 MOCK_METHOD0(init, bool ());
60 MOCK_METHOD0(markReadyToInstantiate, void ());
61 MOCK_METHOD0(markNoFurtherInstantiation, void ());
44};62};
4563
4664
@@ -59,22 +77,26 @@
5977
60PluginFilesystem::PluginFilesystem()78PluginFilesystem::PluginFilesystem()
61{79{
62 ::loaderLoadPlugin = ::ThunkLoadPluginProc;80 ::loaderLoadPlugin = ::ThunkLoadPluginProc;
63 ::loaderUnloadPlugin = ::ThunkUnloadPluginProc;81 ::loaderUnloadPlugin = ::ThunkUnloadPluginProc;
6482
65 instance = this;83 instance = this;
66}84}
6785
68PluginFilesystem const* PluginFilesystem::instance = 0;86PluginFilesystem const* PluginFilesystem::instance = 0;
6987
70} // (abstract) namespace88} // (abstract) namespace
7189
7290class PluginTest :
7391 public ::testing::Test
74TEST(PluginTest, load_non_existant_plugin_must_fail)92{
75{93 public:
76 MockPluginFilesystem mockfs;94
7795 MockPluginFilesystem mockfs;
96};
97
98TEST_F (PluginTest, load_non_existant_plugin_must_fail)
99{
78 using namespace testing;100 using namespace testing;
79101
80 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).102 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
@@ -91,10 +113,8 @@
91 ASSERT_EQ(0, CompPlugin::load("dummy"));113 ASSERT_EQ(0, CompPlugin::load("dummy"));
92}114}
93115
94TEST(PluginTest, load_plugin_from_HOME_PLUGINDIR_succeeds)116TEST_F (PluginTest, load_plugin_from_HOME_PLUGINDIR_succeeds)
95{117{
96 MockPluginFilesystem mockfs;
97
98 using namespace testing;118 using namespace testing;
99119
100 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).120 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
@@ -114,10 +134,8 @@
114 CompPlugin::unload(cp);134 CompPlugin::unload(cp);
115}135}
116136
117TEST(PluginTest, load_plugin_from_PLUGINDIR_succeeds)137TEST_F (PluginTest, load_plugin_from_PLUGINDIR_succeeds)
118{138{
119 MockPluginFilesystem mockfs;
120
121 using namespace testing;139 using namespace testing;
122140
123 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).141 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
@@ -137,11 +155,10 @@
137 CompPlugin::unload(cp);155 CompPlugin::unload(cp);
138}156}
139157
140TEST(PluginTest, load_plugin_from_COMPIZ_PLUGIN_DIR_env_succeeds)158TEST_F (PluginTest, load_plugin_from_COMPIZ_PLUGIN_DIR_env_succeeds)
141{159{
142 const char *COMPIZ_PLUGIN_DIR_VALUE = "/path/to/plugin/dir";160 const char *COMPIZ_PLUGIN_DIR_VALUE = "/path/to/plugin/dir";
143 TmpEnv env ("COMPIZ_PLUGIN_DIR", COMPIZ_PLUGIN_DIR_VALUE);161 TmpEnv env ("COMPIZ_PLUGIN_DIR", COMPIZ_PLUGIN_DIR_VALUE);
144 MockPluginFilesystem mockfs;
145162
146 using namespace testing;163 using namespace testing;
147164
@@ -165,10 +182,8 @@
165 CompPlugin::unload(cp);182 CompPlugin::unload(cp);
166}183}
167184
168TEST(PluginTest, load_plugin_from_void_succeeds)185TEST_F (PluginTest, load_plugin_from_void_succeeds)
169{186{
170 MockPluginFilesystem mockfs;
171
172 using namespace testing;187 using namespace testing;
173188
174 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).189 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
@@ -188,31 +203,429 @@
188 CompPlugin::unload(cp);203 CompPlugin::unload(cp);
189}204}
190205
191TEST(PluginTest, when_we_push_plugin_init_is_called)206TEST_F (PluginTest, when_we_load_plugin_init_load_is_called_without_null_pointer)
192{207{
193 MockPluginFilesystem mockfs;208 using namespace testing;
194209
195 using namespace testing;210 EXPECT_CALL (mockfs, LoadPlugin (NotNull (),
196211 EndsWith(HOME_PLUGINDIR),
197 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).212 StrEq("dummy")))
198 WillOnce(Return(true));213 .Times (1)
199214 .WillOnce (Return (true));
200 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).215
201 Times(AtMost(0));216 EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtLeast (0));
202217
203 EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).218 CompPlugin* cp = CompPlugin::load("dummy");
204 Times(AtMost(0));219 CompPlugin::unload(cp);
205220}
206 EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);221
207222TEST_F (PluginTest, when_we_push_plugin_init_is_called)
208 MockVTable mockVtable;223{
209 EXPECT_CALL(mockVtable, init()).WillOnce(Return(true));224 using namespace testing;
210225
211 CompPlugin* cp = CompPlugin::load("dummy");226 EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0));
212227 EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0));
213 cp->vTable = &mockVtable;228
214229 ON_CALL(mockfs, LoadPlugin (_, _, _)).
215 CompPlugin::push(cp);230 WillByDefault (Return (true));
216 ASSERT_EQ(cp, CompPlugin::pop());231
217 CompPlugin::unload(cp);232 MockVTable mockVtable;
233 EXPECT_CALL (mockVtable, markReadyToInstantiate ()).Times (AtLeast (0));
234 EXPECT_CALL (mockVtable, markNoFurtherInstantiation ())
235 .Times (AtLeast (0));
236 EXPECT_CALL (mockVtable, init ()).WillOnce (Return (true));
237
238 CompPlugin* cp = CompPlugin::load("dummy");
239
240 cp->vTable = &mockVtable;
241
242 CompPlugin::push(cp);
243 CompPlugin::pop ();
244 CompPlugin::unload(cp);
245}
246
247TEST_F (PluginTest, when_we_push_plugin_mark_ready_to_instantiate_is_called)
248{
249 using namespace testing;
250
251 EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0));
252 EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0));
253
254 ON_CALL(mockfs, LoadPlugin (_, _, _)).
255 WillByDefault (Return (true));
256
257 MockVTable mockVtable;
258 EXPECT_CALL (mockVtable, init ())
259 .Times (AtLeast (0))
260 .WillOnce (Return (true));
261 EXPECT_CALL (mockVtable, markReadyToInstantiate ()).Times (1);
262 EXPECT_CALL (mockVtable, markNoFurtherInstantiation ())
263 .Times (AtLeast (0));
264
265 CompPlugin* cp = CompPlugin::load("dummy");
266
267 cp->vTable = &mockVtable;
268
269 CompPlugin::push(cp);
270 CompPlugin::pop ();
271 CompPlugin::unload(cp);
272}
273
274TEST_F (PluginTest, when_we_pop_plugin_mark_no_further_instantiation_is_called)
275{
276 using namespace testing;
277
278 EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0));
279 EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0));
280
281 ON_CALL(mockfs, LoadPlugin (_, _, _)).
282 WillByDefault (Return (true));
283
284 MockVTable mockVtable;
285 EXPECT_CALL (mockVtable, init ())
286 .Times (AtLeast (0))
287 .WillOnce (Return (true));
288 EXPECT_CALL (mockVtable, markReadyToInstantiate ()).Times (AtLeast (0));
289
290 CompPlugin* cp = CompPlugin::load("dummy");
291
292 cp->vTable = &mockVtable;
293
294 CompPlugin::push(cp);
295
296 EXPECT_CALL (mockVtable, markNoFurtherInstantiation ())
297 .Times (1);
298
299 CompPlugin::pop ();
300 CompPlugin::unload(cp);
301}
302
303TEST_F (PluginTest, pop_returns_plugin_pointer)
304{
305 using namespace testing;
306
307 EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0));
308 EXPECT_CALL (mockfs, UnloadPlugin(_)).Times (AtLeast (0));
309
310 ON_CALL(mockfs, LoadPlugin (_, _, _)).
311 WillByDefault (Return (true));
312
313 MockVTable mockVtable;
314 EXPECT_CALL (mockVtable, init ())
315 .Times (AtLeast (0))
316 .WillOnce (Return (true));
317 EXPECT_CALL (mockVtable, markReadyToInstantiate ())
318 .Times (AtLeast (0));
319 EXPECT_CALL (mockVtable, markNoFurtherInstantiation ())
320 .Times (AtLeast (0));
321
322 CompPlugin* cp = CompPlugin::load("dummy");
323
324 cp->vTable = &mockVtable;
325
326 CompPlugin::push(cp);
327 EXPECT_EQ (cp, CompPlugin::pop ());
328 CompPlugin::unload(cp);
329}
330
331TEST_F (PluginTest, unload_calls_unload_on_fs)
332{
333 using namespace testing;
334
335 EXPECT_CALL (mockfs, LoadPlugin (_, _, _)).Times (AtLeast (0));
336
337 ON_CALL(mockfs, LoadPlugin (_, _, _)).
338 WillByDefault (Return (true));
339
340 CompPlugin* cp = CompPlugin::load("dummy");
341
342 EXPECT_CALL (mockfs, UnloadPlugin (cp)).Times (1);
343
344 CompPlugin::unload(cp);
345}
346
347namespace
348{
349
350/* TODO (cleanup): Extract this into a separate library because it
351 * duplicates what's in test-pluginclasshandler */
352template <typename BaseType>
353class Base :
354 public PluginClassStorage
355{
356 public:
357
358 typedef BaseType Type;
359
360 Base ();
361 ~Base ();
362
363 static unsigned int allocPluginClassIndex ();
364 static void freePluginClassIndex (unsigned int index);
365
366 private:
367
368 static PluginClassStorage::Indices indices;
369 static std::list <Base *> bases;
370};
371
372template <typename BaseType>
373PluginClassStorage::Indices Base <BaseType>::indices;
374
375template <typename BaseType>
376std::list <Base <BaseType> * > Base <BaseType>::bases;
377
378template <typename BaseType>
379Base <BaseType>::Base () :
380 PluginClassStorage (indices)
381{
382 bases.push_back (this);
383}
384
385template <typename BaseType>
386Base <BaseType>::~Base ()
387{
388 bases.remove (this);
389}
390
391template <typename BaseType>
392unsigned int
393Base <BaseType>::allocPluginClassIndex ()
394{
395 unsigned int i = PluginClassStorage::allocatePluginClassIndex (indices);
396
397 foreach (Base *b, bases)
398 {
399 if (indices.size () != b->pluginClasses.size ())
400 b->pluginClasses.resize (indices.size ());
401 }
402
403 return i;
404}
405
406template <typename BaseType>
407void
408Base <BaseType>::freePluginClassIndex (unsigned int index)
409{
410 PluginClassStorage::freePluginClassIndex (indices, index);
411
412 foreach (Base *b, bases)
413 {
414 if (indices.size () != b->pluginClasses.size ())
415 b->pluginClasses.resize (indices.size ());
416 }
417}
418
419class BaseScreen :
420 public Base <BaseScreen>
421{
422};
423
424class BaseWindow :
425 public Base <BaseWindow>
426{
427};
428
429class DestructionVerifier
430{
431 public:
432
433 DestructionVerifier ();
434
435 virtual ~DestructionVerifier ();
436 MOCK_METHOD0 (destroy, void ());
437};
438
439DestructionVerifier::DestructionVerifier ()
440{
441 using namespace testing;
442
443 /* By default we don't care */
444 EXPECT_CALL (*this, destroy ()).Times (AtLeast (0));
445}
446
447DestructionVerifier::~DestructionVerifier ()
448{
449 destroy ();
450}
451
452class PluginScreen :
453 public PluginClassHandler <PluginScreen, BaseScreen>,
454 public DestructionVerifier
455{
456 public:
457
458 PluginScreen (BaseScreen *s);
459};
460
461class PluginWindow :
462 public PluginClassHandler <PluginWindow, BaseWindow>,
463 public DestructionVerifier
464{
465 public:
466
467 virtual ~PluginWindow () {}
468 PluginWindow (BaseWindow *s);
469};
470
471PluginScreen::PluginScreen (BaseScreen *s) :
472 PluginClassHandler (s)
473{
474}
475
476PluginWindow::PluginWindow (BaseWindow *w) :
477 PluginClassHandler (w)
478{
479}
480
481class MockScreenAndWindowVTable :
482 public CompPlugin::VTableForScreenAndWindow <PluginScreen, PluginWindow>
483{
484 public:
485
486 MOCK_METHOD0 (init, bool ());
487};
488
489template <class BasePluginType>
490class PluginClassIntegrationTest :
491 public PluginTest
492{
493 public:
494
495 PluginClassIntegrationTest ();
496 ~PluginClassIntegrationTest ();
497
498 boost::shared_ptr <CompPlugin>
499 LoadPlugin (MockScreenAndWindowVTable &);
500
501 MockPluginFilesystem mockfs;
502 ValueHolder *valueHolder;
503};
504
505void
506PopAndUnloadPlugin (CompPlugin *p)
507{
508 ASSERT_EQ (p, CompPlugin::pop ());
509 CompPlugin::unload (p);
510}
511
512template <class BasePluginType>
513boost::shared_ptr <CompPlugin>
514PluginClassIntegrationTest <BasePluginType>::LoadPlugin (MockScreenAndWindowVTable &v)
515{
516 typedef PluginClassIntegrationTest <BasePluginType> TestParam;
517
518 using namespace testing;
519
520 EXPECT_CALL (TestParam::mockfs, LoadPlugin (_, _, _))
521 .Times (AtLeast (0))
522 .WillOnce (Return (true));
523 EXPECT_CALL (TestParam::mockfs, UnloadPlugin(_))
524 .Times (AtLeast (0));
525
526 /* Load a plugin, we'll assign the vtable later */
527 CompPlugin *cp = CompPlugin::load("dummy");
528 cp->vTable = &v;
529
530 EXPECT_CALL (v, init ())
531 .Times (AtLeast (0))
532 .WillOnce (Return (true));
533
534 CompPlugin::push(cp);
535
536 return AutoDestroy (cp,
537 PopAndUnloadPlugin);
538}
539
540template <class BasePluginType>
541PluginClassIntegrationTest <BasePluginType>::PluginClassIntegrationTest ()
542{
543 valueHolder = new ValueHolder ();
544 ValueHolder::SetDefault (valueHolder);
545}
546
547template <class BasePluginType>
548PluginClassIntegrationTest <BasePluginType>::~PluginClassIntegrationTest ()
549{
550 delete valueHolder;
551 ValueHolder::SetDefault (NULL);
552}
553
554template <typename BaseType, typename PluginType>
555class BasePluginTemplate
556{
557 public:
558
559 typedef BaseType Base;
560 typedef PluginType Plugin;
561};
562
563typedef BasePluginTemplate <BaseScreen, PluginScreen> BasePluginScreen;
564typedef BasePluginTemplate <BaseWindow, PluginWindow> BasePluginWindow;
565
566}
567
568/* TODO: Extract actual interfaces out of CompScreen
569 * and CompWindow that can be passed to the vTables without
570 * using a link-seam like this one */
571class CompScreen :
572 public BaseScreen
573{
574};
575
576class CompWindow :
577 public BaseWindow
578{
579};
580
581typedef ::testing::Types <BasePluginScreen, BasePluginWindow> PluginTypes;
582TYPED_TEST_CASE (PluginClassIntegrationTest, PluginTypes);
583
584TYPED_TEST (PluginClassIntegrationTest, get_plugin_structure_null_on_not_loaded)
585{
586 using namespace testing;
587
588 /* Can't figure out how to get this out of TestParam::base at the moment */
589 typename TypeParam::Base base;
590 typename TypeParam::Plugin *p = TypeParam::Plugin::get (&base);
591
592 EXPECT_THAT (p, IsNull ());
593}
594
595TYPED_TEST (PluginClassIntegrationTest, get_plugin_structure_nonnull_on_loaded)
596{
597 using namespace testing;
598
599 typedef PluginClassIntegrationTest <TypeParam> TestParam;
600
601 MockScreenAndWindowVTable vTable;
602 boost::shared_ptr <CompPlugin> cp (TestParam::LoadPlugin (vTable));
603
604 typename TypeParam::Base base;
605 typedef boost::shared_ptr <typename TypeParam::Plugin> PluginPtr;
606
607 /* Because CompScreen is not available, we just need to delete
608 * the plugin structure ourselves */
609 PluginPtr p (TypeParam::Plugin::get (&base));
610
611 EXPECT_THAT (p.get (), NotNull ());
612}
613
614TYPED_TEST (PluginClassIntegrationTest, plugin_class_destroyed_when_vtable_is)
615{
616 using namespace testing;
617
618 typedef PluginClassIntegrationTest <TypeParam> TestParam;
619
620 MockScreenAndWindowVTable vTable;
621 boost::shared_ptr <CompPlugin> cp (TestParam::LoadPlugin (vTable));
622
623 typename TypeParam::Base base;
624 typedef boost::shared_ptr <typename TypeParam::Plugin> PluginPtr;
625
626 /* Because CompScreen is not available, we just need to delete
627 * the plugin structure ourselves */
628 PluginPtr p (TypeParam::Plugin::get (&base));
629
630 EXPECT_CALL (*p, destroy ()).Times (1);
218}631}
219632
=== modified file 'src/pluginclasshandler/include/core/pluginclasshandler.h'
--- src/pluginclasshandler/include/core/pluginclasshandler.h 2013-02-26 11:56:10 +0000
+++ src/pluginclasshandler/include/core/pluginclasshandler.h 2013-05-28 23:40:33 +0000
@@ -45,9 +45,50 @@
45 */45 */
46extern unsigned int pluginClassHandlerIndex;46extern unsigned int pluginClassHandlerIndex;
4747
48namespace compiz
49{
50namespace plugin
51{
52namespace internal
53{
54class PluginKey;
55/**
56 * LoadedPluginClassBridge
57 *
58 * This template essentially exists so that we can reduce the
59 * scope of functions which are allowed to mark plugin classes
60 * as instantiatable as we can't really inject the interface
61 * from PluginClassHandler to do that anywhere. We also can't
62 * forward declare a nested class declaration, but we can forward
63 * declare PluginKey, which users should inherit from and take
64 * it by reference. If the class we're depending on can only be
65 * defined in one other place along with a private constructor
66 * accessible only to a friend it means that we've effectively
67 * limited the scope of users of this class.
68 */
69template <class Tp, class Tb, int ABI = 0>
70class LoadedPluginClassBridge
71{
72 public:
73
74 static void
75 allowInstantiations (const PluginKey &);
76
77 static void
78 disallowInstantiations (const PluginKey &);
79};
80}
81}
82}
83
48template<class Tp, class Tb, int ABI = 0>84template<class Tp, class Tb, int ABI = 0>
49class PluginClassHandler {85class PluginClassHandler
86{
50 public:87 public:
88
89 typedef Tp ClassPluginType;
90 typedef Tb ClassPluginBaseType;
91
51 PluginClassHandler (Tb *);92 PluginClassHandler (Tb *);
52 ~PluginClassHandler ();93 ~PluginClassHandler ();
5394
@@ -90,16 +131,49 @@
90 static bool initializeIndex (Tb *base);131 static bool initializeIndex (Tb *base);
91 static inline Tp * getInstance (Tb *base);132 static inline Tp * getInstance (Tb *base);
92133
134 static void allowInstantiations ();
135 static void disallowInstantiations ();
136
137 template <class Plugin, class Base, int PluginABI>
138 friend class compiz::plugin::internal::LoadedPluginClassBridge;
139
93 private:140 private:
94 bool mFailed;141 bool mFailed;
95 Tb *mBase;142 Tb *mBase;
96143
97 static PluginClassIndex mIndex;144 static PluginClassIndex mIndex;
145 static bool mPluginLoaded;
98};146};
99147
148namespace compiz
149{
150namespace plugin
151{
152namespace internal
153{
154template <class Tp, class Tb, int ABI>
155void
156LoadedPluginClassBridge <Tp, Tb, ABI>::allowInstantiations (const PluginKey &)
157{
158 PluginClassHandler <Tp, Tb, ABI>::allowInstantiations ();
159}
160
161template <class Tp, class Tb, int ABI>
162void
163LoadedPluginClassBridge <Tp, Tb, ABI>::disallowInstantiations (const PluginKey &)
164{
165 PluginClassHandler <Tp, Tb, ABI>::disallowInstantiations ();
166}
167}
168}
169}
170
100template<class Tp, class Tb, int ABI>171template<class Tp, class Tb, int ABI>
101PluginClassIndex PluginClassHandler<Tp,Tb,ABI>::mIndex;172PluginClassIndex PluginClassHandler<Tp,Tb,ABI>::mIndex;
102173
174template<class Tp, class Tb, int ABI>
175bool PluginClassHandler<Tp,Tb,ABI>::mPluginLoaded = false;
176
103/**177/**
104 * Attaches a unique instance of the specified plugin class to a178 * Attaches a unique instance of the specified plugin class to a
105 * unique instance of a specified base class179 * unique instance of a specified base class
@@ -253,15 +327,23 @@
253Tp *327Tp *
254PluginClassHandler<Tp,Tb,ABI>::get (Tb *base)328PluginClassHandler<Tp,Tb,ABI>::get (Tb *base)
255{329{
330 /* Never instantiate an instance of this class
331 * if the relevant plugin has not been loaded
332 */
333 if (!mPluginLoaded)
334 return NULL;
335
256 /* Always ensure that the index is initialized before336 /* Always ensure that the index is initialized before
257 * calls to ::get */337 * calls to ::get */
258 if (!mIndex.initiated)338 if (!mIndex.initiated)
259 initializeIndex (base);339 initializeIndex (base);
340
260 /* If pluginClassHandlerIndex == mIndex.pcIndex it means that our341 /* If pluginClassHandlerIndex == mIndex.pcIndex it means that our
261 * mIndex.index is fresh and can be used directly without needing342 * mIndex.index is fresh and can be used directly without needing
262 * to fetch it from ValueHolder */343 * to fetch it from ValueHolder */
263 if (mIndex.initiated && pluginClassHandlerIndex == mIndex.pcIndex)344 if (mIndex.initiated && pluginClassHandlerIndex == mIndex.pcIndex)
264 return getInstance (base);345 return getInstance (base);
346
265 /* If allocating or getting the updated index failed at any point347 /* If allocating or getting the updated index failed at any point
266 * then just return NULL we don't know where our private data is stored */348 * then just return NULL we don't know where our private data is stored */
267 if (mIndex.failed && pluginClassHandlerIndex == mIndex.pcIndex)349 if (mIndex.failed && pluginClassHandlerIndex == mIndex.pcIndex)
@@ -285,4 +367,18 @@
285 }367 }
286}368}
287369
370template<class Tp, class Tb, int ABI>
371void
372PluginClassHandler<Tp, Tb, ABI>::allowInstantiations ()
373{
374 mPluginLoaded = true;
375}
376
377template<class Tp, class Tb, int ABI>
378void
379PluginClassHandler<Tp, Tb, ABI>::disallowInstantiations ()
380{
381 mPluginLoaded = false;
382}
383
288#endif384#endif
289385
=== modified file 'src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp'
--- src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp 2012-01-12 06:48:58 +0000
+++ src/pluginclasshandler/tests/construct/src/test-pch-construct.cpp 2013-05-28 23:40:33 +0000
@@ -1,23 +1,46 @@
1#include <test-pluginclasshandler.h>1#include <test-pluginclasshandler.h>
22
3class ConstructPlugin: public Plugin, public PluginClassHandler<ConstructPlugin,3class BuildPlugin:
4 Base>4 public Plugin,
5{5 public PluginClassHandler <BuildPlugin, Base>
6public:6{
7 ConstructPlugin (Base * base) :7 public:
8 Plugin(base), PluginClassHandler<ConstructPlugin, Base>(base)8 BuildPlugin (Base *base) :
9 {9 Plugin(base),
10 }10 PluginClassHandler <BuildPlugin, Base> (base)
11};11 {
1212 }
13TEST_F( CompizPCHTest, TestConstruct )13};
14
15class PluginClassHandlerConstruction :
16 public CompizPCHTest
17{
18 public:
19
20 PluginClassHandlerConstruction ();
21 ~PluginClassHandlerConstruction ();
22};
23
24PluginClassHandlerConstruction::PluginClassHandlerConstruction ()
25{
26 namespace cpi = compiz::plugin::internal;
27 cpi::LoadedPluginClassBridge <BuildPlugin, Base>::allowInstantiations (key);
28}
29
30PluginClassHandlerConstruction::~PluginClassHandlerConstruction ()
31{
32 namespace cpi = compiz::plugin::internal;
33 cpi::LoadedPluginClassBridge <BuildPlugin, Base>::disallowInstantiations (key);
34}
35
36TEST_F (PluginClassHandlerConstruction, TestConstruction)
14{37{
15 Plugin *p;38 Plugin *p;
1639
17 bases.push_back(new Base());40 bases.push_back(new Base());
18 plugins.push_back(static_cast<Plugin *>(new ConstructPlugin(bases.back())));41 plugins.push_back(static_cast<Plugin *>(new BuildPlugin(bases.back())));
19 bases.push_back(new Base());42 bases.push_back(new Base());
20 plugins.push_back(static_cast<Plugin *>(new ConstructPlugin(bases.back())));43 plugins.push_back(static_cast<Plugin *>(new BuildPlugin(bases.back())));
2144
22 if (bases.front()->pluginClasses.size() != globalPluginClassIndices.size())45 if (bases.front()->pluginClasses.size() != globalPluginClassIndices.size())
23 {46 {
@@ -26,20 +49,20 @@
26 }49 }
2750
28 if (!ValueHolder::Default()->hasValue(51 if (!ValueHolder::Default()->hasValue(
29 compPrintf("%s_index_%lu", typeid(ConstructPlugin).name(), 0)))52 compPrintf("%s_index_%lu", typeid(BuildPlugin).name(), 0)))
30 {53 {
31 FAIL() << "ValueHolder does not have value "54 FAIL() << "ValueHolder does not have value "
32 << compPrintf("%s_index_%lu", typeid(ConstructPlugin).name(), 0);55 << compPrintf("%s_index_%lu", typeid(BuildPlugin).name(), 0);
33 }56 }
3457
35 p = ConstructPlugin::get(bases.front());58 p = BuildPlugin::get(bases.front());
3659
37 if (p != plugins.front())60 if (p != plugins.front())
38 {61 {
39 FAIL() << "Returned Plugin * is not plugins.front ()";62 FAIL() << "Returned Plugin * is not plugins.front ()";
40 }63 }
4164
42 p = ConstructPlugin::get(bases.back());65 p = BuildPlugin::get(bases.back());
4366
44 if (p != plugins.back())67 if (p != plugins.back())
45 {68 {
4669
=== modified file 'src/pluginclasshandler/tests/get/src/test-pch-get.cpp'
--- src/pluginclasshandler/tests/get/src/test-pch-get.cpp 2012-01-12 06:48:58 +0000
+++ src/pluginclasshandler/tests/get/src/test-pch-get.cpp 2013-05-28 23:40:33 +0000
@@ -1,5 +1,9 @@
1#include <test-pluginclasshandler.h>1#include <test-pluginclasshandler.h>
22
3namespace cpi = compiz::plugin::internal;
4
5using ::testing::IsNull;
6
3class GetPlugin :7class GetPlugin :
4 public Plugin,8 public Plugin,
5 public PluginClassHandler <GetPlugin, Base>9 public PluginClassHandler <GetPlugin, Base>
@@ -14,7 +18,26 @@
14{18{
15}19}
1620
17TEST_F( CompizPCHTest, TestGet)21class PluginClassHandlerGet :
22 public CompizPCHTest
23{
24 public:
25
26 PluginClassHandlerGet ();
27 ~PluginClassHandlerGet ();
28};
29
30PluginClassHandlerGet::PluginClassHandlerGet ()
31{
32 cpi::LoadedPluginClassBridge <GetPlugin, Base>::allowInstantiations (key);
33}
34
35PluginClassHandlerGet::~PluginClassHandlerGet ()
36{
37 cpi::LoadedPluginClassBridge <GetPlugin, Base>::disallowInstantiations (key);
38}
39
40TEST_F (PluginClassHandlerGet, TestGet)
18{41{
19 Plugin *p;42 Plugin *p;
2043
@@ -49,3 +72,17 @@
49 FAIL() << "Returned Plugin * is not the plugin for bases.back ()";72 FAIL() << "Returned Plugin * is not the plugin for bases.back ()";
50 }73 }
51}74}
75
76TEST_F (PluginClassHandlerGet, TestGetNoInstantiationsAllowed)
77{
78 cpi::LoadedPluginClassBridge <GetPlugin, Base>::disallowInstantiations (key);
79
80 Plugin *p;
81
82 bases.push_back (new Base ());
83 plugins.push_back (new GetPlugin (bases.back ()));
84
85 p = GetPlugin::get (bases.front ());
86
87 EXPECT_THAT (p, IsNull ());
88}
5289
=== modified file 'src/pluginclasshandler/tests/test-pluginclasshandler.h'
--- src/pluginclasshandler/tests/test-pluginclasshandler.h 2012-01-19 18:12:31 +0000
+++ src/pluginclasshandler/tests/test-pluginclasshandler.h 2013-05-28 23:40:33 +0000
@@ -2,6 +2,7 @@
2#include <core/pluginclasses.h>2#include <core/pluginclasses.h>
33
4#include <gtest/gtest.h>4#include <gtest/gtest.h>
5#include <gmock/gmock.h>
56
6#include <list>7#include <list>
78
@@ -44,6 +45,21 @@
44 Base *b;45 Base *b;
45};46};
4647
48namespace compiz
49{
50namespace plugin
51{
52namespace internal
53{
54/* The version available in the tests is
55 * readily constructed */
56class PluginKey
57{
58};
59}
60}
61}
62
47class CompizPCHTest : public ::testing::Test63class CompizPCHTest : public ::testing::Test
48{64{
49public:65public:
@@ -54,4 +70,6 @@
54 Global *global;70 Global *global;
55 std::list <Base *> bases;71 std::list <Base *> bases;
56 std::list <Plugin *> plugins;72 std::list <Plugin *> plugins;
73
74 compiz::plugin::internal::PluginKey key;
57};75};
5876
=== modified file 'src/privatescreen/tests/test-privatescreen.cpp'
--- src/privatescreen/tests/test-privatescreen.cpp 2012-12-30 11:13:36 +0000
+++ src/privatescreen/tests/test-privatescreen.cpp 2013-05-28 23:40:33 +0000
@@ -249,23 +249,23 @@
249249
250namespace {250namespace {
251251
252class MockVTable: public CompPlugin::VTable {252class MockVTable:
253 public CompPlugin::VTable
254{
253public:255public:
254 MockVTable (CompString const& name) { initVTable (name); }256 MockVTable (CompString const& name) { initVTable (name); }
255257
256 MOCK_METHOD0(init, bool ());258 MOCK_METHOD0(init, bool ());
257 MOCK_METHOD0(fini, void ());259 MOCK_METHOD0(fini, void ());
258260
261 MOCK_METHOD0(markReadyToInstantiate, void ());
262 MOCK_METHOD0(markNoFurtherInstantiation, void ());
263
259 MOCK_METHOD1(initScreen, bool (CompScreen *s));264 MOCK_METHOD1(initScreen, bool (CompScreen *s));
260
261 MOCK_METHOD1(finiScreen, void (CompScreen *s));265 MOCK_METHOD1(finiScreen, void (CompScreen *s));
262
263 MOCK_METHOD1(initWindow, bool (CompWindow *w));266 MOCK_METHOD1(initWindow, bool (CompWindow *w));
264
265 MOCK_METHOD1(finiWindow, void (CompWindow *w));267 MOCK_METHOD1(finiWindow, void (CompWindow *w));
266
267 MOCK_METHOD0(getOptions, CompOption::Vector & ());268 MOCK_METHOD0(getOptions, CompOption::Vector & ());
268
269 MOCK_METHOD2(setOption, bool (const CompString &name, CompOption::Value &value));269 MOCK_METHOD2(setOption, bool (const CompString &name, CompOption::Value &value));
270};270};
271271
@@ -285,7 +285,8 @@
285 virtual ~PluginFilesystem() {}285 virtual ~PluginFilesystem() {}
286};286};
287287
288class MockPluginFilesystem : public PluginFilesystem288class MockPluginFilesystem :
289 public PluginFilesystem
289{290{
290public:291public:
291 MockVTable mockVtableOne;292 MockVTable mockVtableOne;

Subscribers

People subscribed via source and target branches

to all changes: