1 /*============================================================================= 2 3 Library: CTK 4 5 Copyright (c) German Cancer Research Center, 6 Division of Medical and Biological Informatics 7 8 Licensed under the Apache License, Version 2.0 (the "License"); 9 you may not use this file except in compliance with the License. 10 You may obtain a copy of the License at 11 12 http://www.apache.org/licenses/LICENSE-2.0 13 14 Unless required by applicable law or agreed to in writing, software 15 distributed under the License is distributed on an "AS IS" BASIS, 16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 See the License for the specific language governing permissions and 18 limitations under the License. 19 20 =============================================================================*/ 21 22 23 #ifndef CTKPLUGINTRACKER_H 24 #define CTKPLUGINTRACKER_H 25 26 #include <QScopedPointer> 27 28 #include "ctkPluginFrameworkExport.h" 29 30 #include "ctkPlugin.h" 31 #include "ctkPluginTrackerCustomizer.h" 32 33 template<class T> class ctkTrackedPlugin; 34 template<class T> class ctkPluginTrackerPrivate; 35 36 /** 37 * \ingroup PluginFramework 38 * 39 * The <code>ctkPluginTracker</code> class simplifies tracking plugins much like 40 * the <code>ctkServiceTracker</code> simplifies tracking services. 41 * <p> 42 * A <code>ctkPluginTracker</code> is constructed with state criteria and a 43 * <code>ctkPluginTrackerCustomizer</code> object. A <code>ctkPluginTracker</code> can 44 * use the <code>ctkPluginTrackerCustomizer</code> to select which plugins are 45 * tracked and to create a customized object to be tracked with the plugin. The 46 * <code>ctkPluginTracker</code> can then be opened to begin tracking all plugins 47 * whose state matches the specified state criteria. 48 * <p> 49 * The <code>getPlugins</code> method can be called to get the 50 * <code>ctkPlugin</code> objects of the plugins being tracked. The 51 * <code>getObject</code> method can be called to get the customized object for 52 * a tracked plugin. 53 * <p> 54 * The <code>ctkPluginTracker</code> class is thread-safe. It does not call a 55 * <code>ctkPluginTrackerCustomizer</code> while holding any locks. 56 * <code>ctkPluginTrackerCustomizer</code> implementations must also be 57 * thread-safe. 58 * 59 * \tparam T The type of the tracked object. The type must be an assignable 60 * datatype, provide a boolean conversion function, and provide 61 * a constructor and an assignment operator which can handle 0 as an argument. 62 * \remarks This class is thread safe. 63 */ 64 template<class T = QSharedPointer<ctkPlugin> > 65 class ctkPluginTracker : protected ctkPluginTrackerCustomizer<T> 66 { 67 public: 68 69 ~ctkPluginTracker(); 70 71 /** 72 * Create a <code>ctkPluginTracker</code> for plugins whose state is present in 73 * the specified state mask. 74 * 75 * <p> 76 * Plugins whose state is present on the specified state mask will be 77 * tracked by this <code>ctkPluginTracker</code>. 78 * 79 * @param context The <code>ctkPluginContext</code> against which the tracking 80 * is done. 81 * @param stateMask The bit mask of the <code>OR</code>ing of the plugin 82 * states to be tracked. 83 * @param customizer The customizer object to call when plugins are added, 84 * modified, or removed in this <code>ctkPluginTracker</code>. If 85 * customizer is <code>null</code>, then this 86 * <code>ctkPluginTracker</code> will be used as the 87 * <code>ctkPluginTrackerCustomizer</code> and this 88 * <code>ctkPluginTracker</code> will call the 89 * <code>ctkPluginTrackerCustomizer</code> methods on itself. If the 90 * customizer is not <code>null</code>, this <code>ctkPluginTracker</code> 91 * takes ownership of the customizer. 92 * @see ctkPlugin#getState() 93 */ 94 ctkPluginTracker(ctkPluginContext* context, ctkPlugin::States stateMask, 95 ctkPluginTrackerCustomizer<T>* customizer = 0); 96 97 /** 98 * Open this <code>ctkPluginTracker</code> and begin tracking plugins. 99 * 100 * <p> 101 * ctkPlugin's which match the state criteria specified when this 102 * <code>ctkPluginTracker</code> was created are now tracked by this 103 * <code>ctkPluginTracker</code>. 104 * 105 * @throws ctkIllegalStateException If the <code>ctkPluginContext</code> 106 * with which this <code>ctkPluginTracker</code> was created is no 107 * longer valid. 108 */ 109 virtual void open(); 110 111 /** 112 * Close this <code>ctkPluginTracker</code>. 113 * 114 * <p> 115 * This method should be called when this <code>ctkPluginTracker</code> should 116 * end the tracking of plugins. 117 * 118 * <p> 119 * This implementation calls getPlugins() to get the list of 120 * tracked plugins to remove. 121 */ 122 virtual void close(); 123 124 /** 125 * Return a list of <code>ctkPlugin</code>s for all plugins being tracked by 126 * this <code>ctkPluginTracker</code>. 127 * 128 * @return A list of <code>ctkPlugin</code>s. 129 */ 130 virtual QList<QSharedPointer<ctkPlugin> > getPlugins() const; 131 132 /** 133 * Returns the customized object for the specified <code>ctkPlugin</code> if 134 * the specified plugin is being tracked by this <code>ctkPluginTracker</code>. 135 * 136 * @param plugin The <code>ctkPlugin</code> being tracked. 137 * @return The customized object for the specified <code>ctkPlugin</code> or 138 * <code>null</code> if the specified <code>ctkPlugin</code> is not 139 * being tracked. 140 */ 141 virtual T getObject(QSharedPointer<ctkPlugin> plugin) const; 142 143 /** 144 * Remove a plugin from this <code>ctkPluginTracker</code>. 145 * 146 * The specified plugin will be removed from this <code>ctkPluginTracker</code>. 147 * If the specified plugin was being tracked then the 148 * <code>ctkPluginTrackerCustomizer::removedPlugin</code> method will be called 149 * for that plugin. 150 * 151 * @param plugin The <code>ctkPlugin</code> to be removed. 152 */ 153 virtual void remove(QSharedPointer<ctkPlugin> plugin); 154 155 /** 156 * Return the number of plugins being tracked by this 157 * <code>ctkPluginTracker</code>. 158 * 159 * @return The number of plugins being tracked. 160 */ 161 virtual int size() const; 162 163 /** 164 * Returns the tracking count for this <code>ctkPluginTracker</code>. 165 * 166 * The tracking count is initialized to 0 when this 167 * <code>ctkPluginTracker</code> is opened. Every time a plugin is added, 168 * modified or removed from this <code>ctkPluginTracker</code> the tracking 169 * count is incremented. 170 * 171 * <p> 172 * The tracking count can be used to determine if this 173 * <code>ctkPluginTracker</code> has added, modified or removed a plugin by 174 * comparing a tracking count value previously collected with the current 175 * tracking count value. If the value has not changed, then no plugin has 176 * been added, modified or removed from this <code>ctkPluginTracker</code> 177 * since the previous tracking count was collected. 178 * 179 * @return The tracking count for this <code>ctkPluginTracker</code> or -1 if 180 * this <code>ctkPluginTracker</code> is not open. 181 */ 182 virtual int getTrackingCount() const; 183 184 /** 185 * Return a <code>QMap</code> with the <code>ctkPlugin</code>s and customized 186 * objects for all plugins being tracked by this <code>ctkPluginTracker</code>. 187 * 188 * @return A <code>QMap</code> with the <code>ctkPlugin</code>s and customized 189 * objects for all services being tracked by this 190 * <code>ctkPluginTracker</code>. If no plugins are being tracked, then 191 * the returned map is empty. 192 */ 193 virtual QMap<QSharedPointer<ctkPlugin>, T> getTracked() const; 194 195 /** 196 * Return if this <code>ctkPluginTracker</code> is empty. 197 * 198 * @return <code>true</code> if this <code>ctkPluginTracker</code> is not tracking any 199 * plugins. 200 */ 201 virtual bool isEmpty() const; 202 203 protected: 204 205 /** 206 * Default implementation of the 207 * <code>ctkPluginTrackerCustomizer::addingPlugin</code> method. 208 * 209 * <p> 210 * This method is only called when this <code>ctkPluginTracker</code> has been 211 * constructed with a <code>null</code> ctkPluginTrackerCustomizer argument. 212 * 213 * <p> 214 * This implementation simply returns the specified <code>ctkPlugin*</code> in 215 * a QVariant. 216 * 217 * <p> 218 * This method can be overridden in a subclass to customize the object to be 219 * tracked for the plugin being added. 220 * 221 * @param plugin The <code>ctkPlugin</code> being added to this 222 * <code>ctkPluginTracker</code> object. 223 * @param event The plugin event which caused this customizer method to be 224 * called or an invalid event if there is no plugin event associated 225 * with the call to this method. 226 * @return The specified plugin. 227 * @see ctkPluginTrackerCustomizer::addingPlugin(ctkPlugin*, const ctkPluginEvent&) 228 */ 229 T addingPlugin(QSharedPointer<ctkPlugin> plugin, const ctkPluginEvent& event); 230 231 /** 232 * Default implementation of the 233 * <code>ctkPluginTrackerCustomizer::modifiedPlugin</code> method. 234 * 235 * <p> 236 * This method is only called when this <code>ctkPluginTracker</code> has been 237 * constructed with a <code>null</code> ctkPluginTrackerCustomizer argument. 238 * 239 * <p> 240 * This implementation does nothing. 241 * 242 * @param plugin The <code>ctkPlugin</code> whose state has been modified. 243 * @param event The plugin event which caused this customizer method to be 244 * called or an invalid event if there is no plugin event associated 245 * with the call to this method. 246 * @param object The customized object for the specified ctkPlugin. 247 * @see ctkPluginTrackerCustomizer::modifiedPlugin(ctkPlugin*, const ctkPluginEvent&, QVariant) 248 */ 249 void modifiedPlugin(QSharedPointer<ctkPlugin> plugin, const ctkPluginEvent& event, T object); 250 251 /** 252 * Default implementation of the 253 * <code>ctkPluginTrackerCustomizer::removedPlugin</code> method. 254 * 255 * <p> 256 * This method is only called when this <code>ctkPluginTracker</code> has been 257 * constructed with a <code>null</code> ctkPluginTrackerCustomizer argument. 258 * 259 * <p> 260 * This implementation does nothing. 261 * 262 * @param plugin The <code>ctkPlugin</code> being removed. 263 * @param event The plugin event which caused this customizer method to be 264 * called or an invalid event if there is no plugin event associated 265 * with the call to this method. 266 * @param object The customized object for the specified plugin. 267 * @see ctkPluginTrackerCustomizer::removedPlugin(ctkPlugin*, const ctkPluginEvent&, QVariant) 268 */ 269 void removedPlugin(QSharedPointer<ctkPlugin> plugin, const ctkPluginEvent& event, T object); 270 271 private: 272 273 typedef ctkPluginTracker<T> PluginTracker; 274 typedef ctkTrackedPlugin<T> TrackedPlugin; 275 typedef ctkPluginTrackerPrivate<T> PluginTrackerPrivate; 276 typedef ctkPluginTrackerCustomizer<T> PluginTrackerCustomizer; 277 278 friend class ctkTrackedPlugin<T>; 279 friend class ctkPluginTrackerPrivate<T>; 280 d_func()281 inline PluginTrackerPrivate* d_func() 282 { 283 return reinterpret_cast<PluginTrackerPrivate*>(qGetPtrHelper(d_ptr)); 284 } 285 d_func()286 inline const PluginTrackerPrivate* d_func() const 287 { 288 return reinterpret_cast<const PluginTrackerPrivate*>(qGetPtrHelper(d_ptr)); 289 } 290 291 const QScopedPointer<PluginTrackerPrivate> d_ptr; 292 }; 293 294 295 #include "ctkPluginTracker.tpp" 296 297 #endif // CTKPLUGINTRACKER_H 298