ctkPluginAbstractTracked_p.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #ifndef CTKPLUGINABSTRACTTRACKED_P_H
  16. #define CTKPLUGINABSTRACTTRACKED_P_H
  17. #include <QHash>
  18. #include <QMutex>
  19. #include <QWaitCondition>
  20. #include <QLinkedList>
  21. #include <QVariant>
  22. /**
  23. * Abstract class to track items. If a Tracker is reused (closed then reopened),
  24. * then a new ctkPluginAbstractTracked object is used. This class acts as a map of tracked
  25. * item -> customized object. Subclasses of this class will act as the listener
  26. * object for the tracker. This class is used to synchronize access to the
  27. * tracked items. This is not a public class. It is only for use by the
  28. * implementation of the Tracker class.
  29. *
  30. * @ThreadSafe
  31. */
  32. template<class Item, class Related>
  33. class ctkPluginAbstractTracked : public QMutex
  34. {
  35. public:
  36. /* set this to true to compile in debug messages */
  37. static const bool DEBUG; // = false;
  38. /**
  39. * ctkPluginAbstractTracked constructor.
  40. */
  41. ctkPluginAbstractTracked();
  42. virtual ~ctkPluginAbstractTracked();
  43. bool wait(unsigned long timeout);
  44. void wakeAll();
  45. /**
  46. * Set initial list of items into tracker before events begin to be
  47. * received.
  48. *
  49. * This method must be called from Tracker's open method while synchronized
  50. * on this object in the same synchronized block as the add listener call.
  51. *
  52. * @param list The initial list of items to be tracked. <code>null</code>
  53. * entries in the list are ignored.
  54. * @GuardedBy this
  55. */
  56. void setInitial(const QList<Item>& list);
  57. //void setInitial(const QList<Item*>& list);
  58. /**
  59. * Track the initial list of items. This is called after events can begin to
  60. * be received.
  61. *
  62. * This method must be called from Tracker's open method while not
  63. * synchronized on this object after the add listener call.
  64. *
  65. */
  66. void trackInitial();
  67. /**
  68. * Called by the owning Tracker object when it is closed.
  69. */
  70. void close();
  71. /**
  72. * Begin to track an item.
  73. *
  74. * @param item Item to be tracked.
  75. * @param related Action related object.
  76. */
  77. void track(Item item, Related related);
  78. /**
  79. * Discontinue tracking the item.
  80. *
  81. * @param item Item to be untracked.
  82. * @param related Action related object.
  83. */
  84. void untrack(Item item, Related related);
  85. /**
  86. * Returns the number of tracked items.
  87. *
  88. * @return The number of tracked items.
  89. *
  90. * @GuardedBy this
  91. */
  92. int size() const;
  93. /**
  94. * Return the customized object for the specified item
  95. *
  96. * @param item The item to lookup in the map
  97. * @return The customized object for the specified item.
  98. *
  99. * @GuardedBy this
  100. */
  101. QVariant getCustomizedObject(Item item) const;
  102. /**
  103. * Return the list of tracked items.
  104. *
  105. * @return The tracked items.
  106. * @GuardedBy this
  107. */
  108. QList<Item> getTracked() const;
  109. /**
  110. * Increment the modification count. If this method is overridden, the
  111. * overriding method MUST call this method to increment the tracking count.
  112. *
  113. * @GuardedBy this
  114. */
  115. virtual void modified();
  116. /**
  117. * Returns the tracking count for this <code>ServiceTracker</code> object.
  118. *
  119. * The tracking count is initialized to 0 when this object is opened. Every
  120. * time an item is added, modified or removed from this object the tracking
  121. * count is incremented.
  122. *
  123. * @GuardedBy this
  124. * @return The tracking count for this object.
  125. */
  126. int getTrackingCount() const;
  127. /**
  128. * Call the specific customizer adding method. This method must not be
  129. * called while synchronized on this object.
  130. *
  131. * @param item Item to be tracked.
  132. * @param related Action related object.
  133. * @return Customized object for the tracked item or <code>null</code> if
  134. * the item is not to be tracked.
  135. */
  136. virtual QVariant customizerAdding(Item item, Related related) = 0;
  137. /**
  138. * Call the specific customizer modified method. This method must not be
  139. * called while synchronized on this object.
  140. *
  141. * @param item Tracked item.
  142. * @param related Action related object.
  143. * @param object Customized object for the tracked item.
  144. */
  145. virtual void customizerModified(Item item, Related related,
  146. QVariant object) = 0;
  147. /**
  148. * Call the specific customizer removed method. This method must not be
  149. * called while synchronized on this object.
  150. *
  151. * @param item Tracked item.
  152. * @param related Action related object.
  153. * @param object Customized object for the tracked item.
  154. */
  155. virtual void customizerRemoved(Item item, Related related,
  156. QVariant object) = 0;
  157. /**
  158. * List of items in the process of being added. This is used to deal with
  159. * nesting of events. Since events may be synchronously delivered, events
  160. * can be nested. For example, when processing the adding of a service and
  161. * the customizer causes the service to be unregistered, notification to the
  162. * nested call to untrack that the service was unregistered can be made to
  163. * the track method.
  164. *
  165. * Since the QList implementation is not synchronized, all access to
  166. * this list must be protected by the same synchronized object for
  167. * thread-safety.
  168. *
  169. * @GuardedBy this
  170. */
  171. QList<Item> adding;
  172. /**
  173. * true if the tracked object is closed.
  174. *
  175. * This field is volatile because it is set by one thread and read by
  176. * another.
  177. */
  178. volatile bool closed;
  179. /**
  180. * Initial list of items for the tracker. This is used to correctly process
  181. * the initial items which could be modified before they are tracked. This
  182. * is necessary since the initial set of tracked items are not "announced"
  183. * by events and therefore the event which makes the item untracked could be
  184. * delivered before we track the item.
  185. *
  186. * An item must not be in both the initial and adding lists at the same
  187. * time. An item must be moved from the initial list to the adding list
  188. * "atomically" before we begin tracking it.
  189. *
  190. * Since the LinkedList implementation is not synchronized, all access to
  191. * this list must be protected by the same synchronized object for
  192. * thread-safety.
  193. *
  194. * @GuardedBy this
  195. */
  196. QLinkedList<Item> initial;
  197. /**
  198. * Common logic to add an item to the tracker used by track and
  199. * trackInitial. The specified item must have been placed in the adding list
  200. * before calling this method.
  201. *
  202. * @param item Item to be tracked.
  203. * @param related Action related object.
  204. */
  205. void trackAdding(Item item, Related related);
  206. private:
  207. QWaitCondition waitCond;
  208. /**
  209. * Map of tracked items to customized objects.
  210. *
  211. * @GuardedBy this
  212. */
  213. QHash<Item, QVariant> tracked;
  214. /**
  215. * Modification count. This field is initialized to zero and incremented by
  216. * modified.
  217. *
  218. * @GuardedBy this
  219. */
  220. QAtomicInt trackingCount;
  221. bool customizerAddingFinal(Item item, const QVariant& custom);
  222. };
  223. #include "ctkPluginAbstractTracked.cpp"
  224. #endif // CTKPLUGINABSTRACTTRACKED_P_H