1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkCollection.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class   vtkCollection
17  * @brief   create and manipulate ordered lists of objects
18  *
19  * vtkCollection is a general object for creating and manipulating lists
20  * of objects. The lists are ordered and allow duplicate entries.
21  * vtkCollection also serves as a base class for lists of specific types
22  * of objects.
23  *
24  * @sa
25  * vtkActorCollection vtkAssemblyPaths vtkDataSetCollection
26  * vtkImplicitFunctionCollection vtkLightCollection vtkPolyDataCollection
27  * vtkRenderWindowCollection vtkRendererCollection
28  * vtkStructuredPointsCollection vtkTransformCollection vtkVolumeCollection
29  */
30 
31 #ifndef vtkCollection_h
32 #define vtkCollection_h
33 
34 #include "vtkCommonCoreModule.h" // For export macro
35 #include "vtkObject.h"
36 
37 class vtkCollectionElement //;prevents pick-up by man page generator
38 {
39 public:
vtkCollectionElement()40   vtkCollectionElement()
41     : Item(nullptr)
42     , Next(nullptr)
43   {
44   }
45   vtkObject* Item;
46   vtkCollectionElement* Next;
47 };
48 typedef void* vtkCollectionSimpleIterator;
49 
50 class vtkCollectionIterator;
51 
52 class VTKCOMMONCORE_EXPORT vtkCollection : public vtkObject
53 {
54 public:
55   vtkTypeMacro(vtkCollection, vtkObject);
56   void PrintSelf(ostream& os, vtkIndent indent) override;
57 
58   /**
59    * Construct with empty list.
60    */
61   static vtkCollection* New();
62 
63   /**
64    * Add an object to the bottom of the list. Does not prevent duplicate entries.
65    */
66   void AddItem(vtkObject*);
67 
68   /**
69    * Insert item into the list after the i'th item. Does not prevent duplicate entries.
70    * If i < 0 the item is placed at the top of the list.
71    */
72   void InsertItem(int i, vtkObject*);
73 
74   /**
75    * Replace the i'th item in the collection with another item.
76    */
77   void ReplaceItem(int i, vtkObject*);
78 
79   /**
80    * Remove the i'th item in the list.
81    * Be careful if using this function during traversal of the list using
82    * GetNextItemAsObject (or GetNextItem in derived class).  The list WILL
83    * be shortened if a valid index is given!  If this->Current is equal to the
84    * element being removed, have it point to then next element in the list.
85    */
86   void RemoveItem(int i);
87 
88   /**
89    * Remove an object from the list. Removes the first object found, not
90    * all occurrences. If no object found, list is unaffected.  See warning
91    * in description of RemoveItem(int).
92    */
93   void RemoveItem(vtkObject*);
94 
95   /**
96    * Remove all objects from the list.
97    */
98   void RemoveAllItems();
99 
100   /**
101    * Search for an object and return location in list. If the return value is
102    * 0, the object was not found. If the object was found, the location is
103    * the return value-1.
104    */
105   int IsItemPresent(vtkObject* a);
106 
107   /**
108    * Return the number of objects in the list.
109    */
GetNumberOfItems()110   int GetNumberOfItems() { return this->NumberOfItems; }
111 
112   /**
113    * Initialize the traversal of the collection. This means the data pointer
114    * is set at the beginning of the list.
115    */
InitTraversal()116   void InitTraversal() { this->Current = this->Top; }
117 
118   /**
119    * A reentrant safe way to iterate through a collection.
120    * Just pass the same cookie value around each time
121    */
InitTraversal(vtkCollectionSimpleIterator & cookie)122   void InitTraversal(vtkCollectionSimpleIterator& cookie)
123   {
124     cookie = static_cast<vtkCollectionSimpleIterator>(this->Top);
125   }
126 
127   /**
128    * Get the next item in the collection. nullptr is returned if the collection
129    * is exhausted.
130    */
131   vtkObject* GetNextItemAsObject();
132 
133   /**
134    * Get the i'th item in the collection. nullptr is returned if i is out
135    * of range
136    */
137   vtkObject* GetItemAsObject(int i);
138 
139   /**
140    * A reentrant safe way to get the next object as a collection. Just pass the
141    * same cookie back and forth.
142    */
143   vtkObject* GetNextItemAsObject(vtkCollectionSimpleIterator& cookie);
144 
145   /**
146    * Get an iterator to traverse the objects in this collection.
147    */
148   VTK_NEWINSTANCE vtkCollectionIterator* NewIterator();
149 
150   ///@{
151   /**
152    * Participate in garbage collection.
153    */
154   void Register(vtkObjectBase* o) override;
155   void UnRegister(vtkObjectBase* o) override;
156   ///@}
157 
158 protected:
159   vtkCollection();
160   ~vtkCollection() override;
161 
162   virtual void RemoveElement(vtkCollectionElement* element, vtkCollectionElement* previous);
163   virtual void DeleteElement(vtkCollectionElement*);
164   int NumberOfItems;
165   vtkCollectionElement* Top;
166   vtkCollectionElement* Bottom;
167   vtkCollectionElement* Current;
168 
169   friend class vtkCollectionIterator;
170 
171   // See vtkGarbageCollector.h:
172   void ReportReferences(vtkGarbageCollector* collector) override;
173 
174 private:
175   vtkCollection(const vtkCollection&) = delete;
176   void operator=(const vtkCollection&) = delete;
177 };
178 
GetNextItemAsObject()179 inline vtkObject* vtkCollection::GetNextItemAsObject()
180 {
181   vtkCollectionElement* elem = this->Current;
182 
183   if (elem != nullptr)
184   {
185     this->Current = elem->Next;
186     return elem->Item;
187   }
188   else
189   {
190     return nullptr;
191   }
192 }
193 
GetNextItemAsObject(void * & cookie)194 inline vtkObject* vtkCollection::GetNextItemAsObject(void*& cookie)
195 {
196   vtkCollectionElement* elem = static_cast<vtkCollectionElement*>(cookie);
197 
198   if (elem != nullptr)
199   {
200     cookie = static_cast<void*>(elem->Next);
201     return elem->Item;
202   }
203   else
204   {
205     return nullptr;
206   }
207 }
208 
209 #endif
210