Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

vtkUniqueCollection.h

Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 * 00003 * $Id: vtkUniqueCollection.h,v 1.7 2004/08/10 07:37:21 xpxqx Exp $ 00004 * 00005 * Copyright (c) 2004 Sean McInerney 00006 * All rights reserved. 00007 * 00008 * See Copyright.txt or http://vtkextensions.sourceforge.net/Copyright.html 00009 * for details. 00010 * 00011 * This software is distributed WITHOUT ANY WARRANTY; without even 00012 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00013 * PURPOSE. See the above copyright notice for more information. 00014 * 00015 */ 00016 #ifndef VTK_UNIQUE_COLLECTION_H_ 00017 # define VTK_UNIQUE_COLLECTION_H_ 00018 # include "vtkExtensionsCommonConfigure.h" // vtkExtensions configuration 00019 // VTK Common 00020 # include "vtkCollection.h" 00021 00022 VTK_EXTENSIONS_NAMESPACE_BEGIN 00023 00041 class VTK_EXTENSIONS_COMMON_EXPORT vtkUniqueCollection 00042 : public vtkCollection 00043 { 00044 public: 00045 static vtkUniqueCollection* New (void); 00046 vtkTypeRevisionMacro (vtkUniqueCollection, vtkCollection); 00047 void PrintSelf (ostream&, vtkIndent); 00048 00051 vtkSetMacro (CheckUnique, int); 00052 vtkGetMacro (CheckUnique, int); 00053 vtkBooleanMacro (CheckUnique, int); 00057 void AddItem (vtkObject* item); 00058 00065 //BTX 00066 void ReplaceItem (int i, vtkObject* item, vtkObject** ret); 00067 //ETX 00068 void ReplaceItem (int i, vtkObject* item) 00069 { this->ReplaceItem(i, item, NULL); } 00082 //BTX 00083 void RemoveItem (int i, vtkObject** ret); 00084 //ETX 00085 void RemoveItem (int i) 00086 { this->RemoveItem(i, NULL); } 00099 //BTX 00100 void RemoveItem (vtkObject* item, vtkObject** ret); 00101 //ETX 00102 void RemoveItem (vtkObject* item) 00103 { this->RemoveItem(item, NULL); } 00107 int IndexOf (vtkObject* item); 00108 00114 vtkObject* GetNextItem (void); 00115 00121 vtkObject* GetItem (int i); 00122 00124 vtkObject* GetFirstItem (void); 00125 00127 vtkObject* GetLastItem (void); 00128 00135 //BTX 00136 void RemoveLastItem (vtkObject** removed); 00137 //ETX 00138 void RemoveLastItem (void) 00139 { this->RemoveLastItem(NULL); } 00143 int PrependItem (vtkObject* item); 00144 00146 int AppendItem (vtkObject* item); 00147 00149 int InsertItemAt (vtkObject* item, int i); 00150 00152 int GetNumberOfItemsByType (const char* type); 00153 00155 vtkObject* InitTraversalByType (const char* type); 00156 00158 vtkObject* GetNthItemByType (int n, const char* type); 00159 00161 vtkObject* GetNextItemByType (const char* type); 00162 00164 virtual unsigned long GetMTime (void); 00165 00166 protected: 00167 vtkUniqueCollection (void) : CheckUnique(1) {} 00168 ~vtkUniqueCollection() {} 00169 00170 int CheckUnique; 00171 00178 vtkCollectionElement* FindCollectionElementAt (int i); 00179 00180 private: 00186 vtkUniqueCollection (const vtkUniqueCollection&); 00187 void operator= (const vtkUniqueCollection&); 00189 }; 00190 00191 // ---------------------------------------------------------------------------- 00192 inline void 00193 vtkUniqueCollection::AddItem (vtkObject* aItem) 00194 { 00195 if (!this->CheckUnique || !this->IsItemPresent(aItem)) 00196 { 00197 this->vtkCollection::AddItem(aItem); 00198 } 00199 } 00200 00201 // ---------------------------------------------------------------------------- 00202 inline void 00203 vtkUniqueCollection::ReplaceItem (int aIndex, 00204 vtkObject* aNewItem, 00205 vtkObject** aReturn) 00206 { 00207 vtkObject* oldItem = this->GetItemAsObject(aIndex); 00208 vtkObject* newItem = aNewItem; 00209 00210 if (oldItem == NULL || oldItem == aNewItem) 00211 { 00212 return; // No replacement done. 00213 } 00214 00215 if (aReturn != NULL) 00216 { 00217 // Pass the replaced item out through the call parameter. 00218 *aReturn = oldItem; 00219 (*aReturn)->Register(this); 00220 } 00221 00222 int existingLocation = this->IsItemPresent(aNewItem); 00223 00224 this->vtkCollection::ReplaceItem(aIndex, aNewItem); 00225 00226 if (this->CheckUnique && existingLocation != 0) 00227 { 00228 this->vtkCollection::RemoveItem(existingLocation - 1); 00229 } 00230 } 00231 00232 // ---------------------------------------------------------------------------- 00233 inline void 00234 vtkUniqueCollection::RemoveItem (int aIndex, vtkObject** aReturn) 00235 { 00236 vtkObject* item; 00237 00238 if (aReturn != NULL && (item = this->GetItem(aIndex)) != NULL) 00239 { 00240 // Pass the removed item out through the call parameter. 00241 *aReturn = item; 00242 (*aReturn)->Register(this); 00243 } 00244 00245 this->vtkCollection::RemoveItem(aIndex); 00246 } 00247 00248 // ---------------------------------------------------------------------------- 00249 inline void 00250 vtkUniqueCollection::RemoveItem (vtkObject* aItem, vtkObject** aReturn) 00251 { 00252 if (aReturn != NULL && this->IsItemPresent(aItem)) 00253 { 00254 // Pass the removed item out through the call parameter. 00255 *aReturn = aItem; 00256 (*aReturn)->Register(this); 00257 } 00258 00259 this->vtkCollection::RemoveItem(aItem); 00260 } 00261 00262 // ---------------------------------------------------------------------------- 00263 inline int 00264 vtkUniqueCollection::IndexOf (vtkObject* aItem) 00265 { return this->IsItemPresent(aItem) - 1; } 00266 00267 // ---------------------------------------------------------------------------- 00268 inline vtkObject* 00269 vtkUniqueCollection::GetNextItem (void) 00270 { return this->GetNextItemAsObject(); } 00271 00272 // ---------------------------------------------------------------------------- 00273 inline vtkObject* 00274 vtkUniqueCollection::GetItem (int aIndex) 00275 { return this->GetItemAsObject(aIndex); } 00276 00277 // ---------------------------------------------------------------------------- 00278 inline vtkObject* 00279 vtkUniqueCollection::GetFirstItem (void) 00280 { return (this->Top != NULL ? this->Top->Item : NULL); } 00281 00282 // ---------------------------------------------------------------------------- 00283 inline vtkObject* 00284 vtkUniqueCollection::GetLastItem (void) 00285 { return (this->Bottom != NULL ? this->Bottom->Item : NULL); } 00286 00287 // ---------------------------------------------------------------------------- 00288 inline void 00289 vtkUniqueCollection::RemoveLastItem (vtkObject** aReturn) 00290 { this->RemoveItem(this->GetLastItem(), aReturn); } 00291 00292 // ---------------------------------------------------------------------------- 00293 inline int 00294 vtkUniqueCollection::PrependItem (vtkObject* aItem) 00295 { 00296 if (aItem == NULL) 00297 { 00298 vtkErrorMacro(<< "PrependItem() called with NULL node pointer."); 00299 return VTK_ERROR; 00300 } 00301 00302 int index = this->IndexOf(aItem); 00303 00304 if (index == 0) 00305 { 00306 return VTK_OK; // aItem is already at head of list. 00307 } 00308 else if (index > 0) 00309 { 00310 this->RemoveItem(index, &aItem); // aItem is being moved. 00311 } 00312 00313 vtkCollectionElement* newElem; 00314 00315 try 00316 { 00317 newElem = new vtkCollectionElement; 00318 } 00319 catch (...) 00320 { 00321 delete newElem; 00322 return VTK_ERROR; 00323 } 00324 00325 newElem->Item = aItem; 00326 00327 if (index < 0/*index may ONLY be used to know if item is new or moved.*/) 00328 { // If the item is not merely being moved, increment its reference count. 00329 newElem->Item->Register(this); 00330 } 00331 00332 newElem->Next = this->Top; 00333 this->Top = newElem; 00334 00335 if (this->Bottom == NULL) 00336 { 00337 this->Bottom = this->Top; 00338 } 00339 00340 this->NumberOfItems++; 00341 this->Modified(); 00342 00343 return VTK_OK; 00344 } 00345 00346 // ---------------------------------------------------------------------------- 00347 inline int 00348 vtkUniqueCollection::AppendItem (vtkObject* aItem) 00349 { 00350 if (aItem == NULL) 00351 { 00352 vtkErrorMacro(<< "AppendItem() called with NULL node pointer."); 00353 return VTK_ERROR; 00354 } 00355 00356 if (this->Bottom == NULL) 00357 { 00358 return this->PrependItem(aItem); 00359 } 00360 00361 int index = this->IndexOf(aItem); 00362 00363 if (index == (this->NumberOfItems - 1)) 00364 { 00365 return VTK_OK; // aItem is already at end of list. 00366 } 00367 else if (index >= 0) 00368 { 00369 this->RemoveItem(index, &aItem); // aItem is being moved. 00370 } 00371 00372 vtkCollectionElement* newElem; 00373 00374 try 00375 { 00376 newElem = new vtkCollectionElement; 00377 } 00378 catch (...) 00379 { 00380 delete newElem; 00381 return VTK_ERROR; 00382 } 00383 00384 newElem->Item = aItem; 00385 00386 if (index < 0/*index may ONLY be used to know if item is new or moved.*/) 00387 { // If the item is not merely being moved, increment its reference count. 00388 newElem->Item->Register(this); 00389 } 00390 00391 this->Bottom->Next = newElem; 00392 this->Bottom = newElem; 00393 00394 this->NumberOfItems++; 00395 this->Modified(); 00396 00397 return VTK_OK; 00398 } 00399 00400 // ---------------------------------------------------------------------------- 00401 inline vtkCollectionElement* 00402 vtkUniqueCollection::FindCollectionElementAt (int aIndex) 00403 { 00404 int i = 0; 00405 00406 for (vtkCollectionElement* elem = this->Top; elem != NULL; elem = elem->Next) 00407 { 00408 if (i == aIndex) 00409 { 00410 return elem; 00411 } 00412 i++; 00413 } 00414 00415 return NULL; 00416 } 00417 00418 // ---------------------------------------------------------------------------- 00419 inline int 00420 vtkUniqueCollection::InsertItemAt (vtkObject* aItem, int aIndex) 00421 { 00422 if (aItem == NULL) 00423 { 00424 vtkWarningMacro(<< "InsertItemAt() called with NULL node pointer."); 00425 return VTK_ERROR; 00426 } 00427 00428 if (aIndex < 0 || aIndex > this->NumberOfItems) 00429 { 00430 vtkWarningMacro(<< "InsertItemAt() called with invalid index."); 00431 return VTK_ERROR; 00432 } 00433 00434 if (aIndex == 0) 00435 { 00436 return this->PrependItem(aItem); 00437 } 00438 else if (aIndex == this->NumberOfItems) 00439 { 00440 return this->AppendItem(aItem); 00441 } 00442 00443 int index = this->IndexOf(aItem); 00444 00445 if (index == aIndex) 00446 { 00447 return VTK_OK; // aItem is already at specified index. 00448 } 00449 else if (index >= 0) 00450 { 00451 this->RemoveItem(index, &aItem); // aItem is being moved. 00452 } 00453 00454 vtkCollectionElement* currElem; 00455 00456 if ((currElem = this->FindCollectionElementAt(aIndex-1)) != NULL) 00457 { 00458 vtkCollectionElement* newElem; 00459 00460 try 00461 { 00462 newElem = new vtkCollectionElement; 00463 } 00464 catch (...) 00465 { 00466 delete newElem; 00467 return VTK_ERROR; 00468 } 00469 00470 newElem->Next = currElem->Next; 00471 newElem->Item = aItem; 00472 00473 if (index < 0/*index may ONLY be used to know if item is new or moved.*/) 00474 { // If the item is not merely being moved, increment its reference count. 00475 newElem->Item->Register(this); 00476 } 00477 00478 currElem->Next = newElem; 00479 00480 this->NumberOfItems++; 00481 this->Modified(); 00482 00483 return VTK_OK; 00484 } 00485 00486 return VTK_ERROR; 00487 } 00488 00489 // ---------------------------------------------------------------------------- 00490 inline int 00491 vtkUniqueCollection::GetNumberOfItemsByType (const char* aType) 00492 { 00493 vtkCollectionElement* elem = this->Top; 00494 int num = 0; 00495 00496 while (elem != NULL) 00497 { 00498 if (elem->Item->IsA(aType)) num++; 00499 elem = elem->Next; 00500 } 00501 00502 return num; 00503 } 00504 00505 inline vtkObject* 00506 vtkUniqueCollection::GetNextItemByType (const char* aType) 00507 { 00508 vtkCollectionElement* elem = this->Current; 00509 00510 if (elem != NULL) elem = elem->Next; 00511 00512 while (elem != NULL && !elem->Item->IsA(aType)) elem = elem->Next; 00513 00514 if (elem != NULL) 00515 { 00516 this->Current = elem; 00517 return this->Current->Item; 00518 } 00519 00520 return NULL; 00521 } 00522 00523 inline vtkObject* 00524 vtkUniqueCollection::InitTraversalByType (const char* aType) 00525 { 00526 vtkCollectionElement* elem = this->Top; 00527 00528 while (elem != NULL && !elem->Item->IsA(aType)) elem = elem->Next; 00529 00530 if (elem != NULL) 00531 { 00532 this->Current = elem; 00533 return this->Current->Item; 00534 } 00535 00536 return NULL; 00537 } 00538 00539 inline vtkObject* 00540 vtkUniqueCollection::GetNthItemByType (int aIndex, const char* aType) 00541 { 00542 vtkCollectionElement* elem = this->Top; 00543 int j = 0; 00544 00545 while (elem != NULL) 00546 { 00547 if (elem->Item->IsA(aType)) 00548 if (aIndex == j++) 00549 return elem->Item; 00550 00551 elem = elem->Next; 00552 } 00553 00554 return NULL; 00555 } 00556 00557 // ---------------------------------------------------------------------------- 00558 inline unsigned long 00559 vtkUniqueCollection::GetMTime (void) 00560 { 00561 vtkObject* item; 00562 unsigned long itemMTime; 00563 unsigned long mtime = this->vtkCollection::GetMTime(); 00564 00565 for (this->InitTraversal(); (item = this->GetNextItem()) != NULL; ) 00566 { 00567 if ((itemMTime = item->GetMTime()) > mtime) 00568 { 00569 mtime = itemMTime; 00570 } 00571 } 00572 00573 return mtime; 00574 } 00575 00576 VTK_EXTENSIONS_NAMESPACE_END 00577 00578 #endif /* VTK_UNIQUE_COLLECTION_H_ */ 00579 /* 00580 * End of: $Id: vtkUniqueCollection.h,v 1.7 2004/08/10 07:37:21 xpxqx Exp $. 00581 * 00582 */

Generated on Tue Aug 10 03:38:43 2004 for vtkExtensions by doxygen 1.3.7