You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
6.3 KiB
323 lines
6.3 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkCollection.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkCollection.h"
|
|
|
|
#include "vtkCollectionIterator.h"
|
|
#include "vtkGarbageCollector.h"
|
|
#include "vtkObjectFactory.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
vtkCxxRevisionMacro(vtkCollection, "$Revision: 1.45 $");
|
|
vtkStandardNewMacro(vtkCollection);
|
|
|
|
// Construct with empty list.
|
|
vtkCollection::vtkCollection()
|
|
{
|
|
this->NumberOfItems = 0;
|
|
this->Top = NULL;
|
|
this->Bottom = NULL;
|
|
this->Current = NULL;
|
|
}
|
|
|
|
// Desctructor for the vtkCollection class. This removes all
|
|
// objects from the collection.
|
|
vtkCollection::~vtkCollection()
|
|
{
|
|
vtkCollectionElement *elem;
|
|
|
|
while (this->NumberOfItems )
|
|
{
|
|
elem = this->Top;
|
|
this->Top = elem->Next;
|
|
this->Current = elem->Next;
|
|
this->NumberOfItems--;
|
|
this->DeleteElement(elem);
|
|
}
|
|
}
|
|
|
|
// protected function to delete an element. Internal use only.
|
|
void vtkCollection::DeleteElement(vtkCollectionElement *e)
|
|
{
|
|
if (e->Item != NULL)
|
|
{
|
|
e->Item->UnRegister(this);
|
|
}
|
|
delete e;
|
|
}
|
|
|
|
// Add an object to the list. Does not prevent duplicate entries.
|
|
void vtkCollection::AddItem(vtkObject *a)
|
|
{
|
|
vtkCollectionElement *elem;
|
|
|
|
elem = new vtkCollectionElement;
|
|
|
|
if (!this->Top)
|
|
{
|
|
this->Top = elem;
|
|
}
|
|
else
|
|
{
|
|
this->Bottom->Next = elem;
|
|
}
|
|
this->Bottom = elem;
|
|
|
|
a->Register(this);
|
|
elem->Item = a;
|
|
elem->Next = NULL;
|
|
|
|
this->Modified();
|
|
|
|
this->NumberOfItems++;
|
|
}
|
|
|
|
// Remove an object from the list. Removes the first object found, not
|
|
// all occurrences. If no object found, list is unaffected. See warning
|
|
// in description of RemoveItem(int).
|
|
void vtkCollection::RemoveItem(vtkObject *a)
|
|
{
|
|
int i;
|
|
vtkCollectionElement *elem;
|
|
|
|
if (!this->Top)
|
|
{
|
|
return;
|
|
}
|
|
|
|
elem = this->Top;
|
|
for (i = 0; i < this->NumberOfItems; i++)
|
|
{
|
|
if (elem->Item == a)
|
|
{
|
|
this->RemoveItem(i);
|
|
this->Modified();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
elem = elem->Next;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove all objects from the list.
|
|
void vtkCollection::RemoveAllItems()
|
|
{
|
|
vtkCollectionElement *elem;
|
|
|
|
while (this->NumberOfItems )
|
|
{
|
|
elem = this->Top;
|
|
this->Top = elem->Next;
|
|
this->Current = elem->Next;
|
|
this->NumberOfItems--;
|
|
this->DeleteElement(elem);
|
|
}
|
|
|
|
this->Modified();
|
|
}
|
|
|
|
// Search for an object and return location in list. If location == 0,
|
|
// object was not found.
|
|
int vtkCollection::IsItemPresent(vtkObject *a)
|
|
{
|
|
int i;
|
|
vtkCollectionElement *elem;
|
|
|
|
if (!this->Top)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
elem = this->Top;
|
|
for (i = 0; i < this->NumberOfItems; i++)
|
|
{
|
|
if (elem->Item == a)
|
|
{
|
|
return i + 1;
|
|
}
|
|
else
|
|
{
|
|
elem = elem->Next;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Return the number of objects in the list.
|
|
int vtkCollection::GetNumberOfItems()
|
|
{
|
|
return this->NumberOfItems;
|
|
}
|
|
|
|
|
|
void vtkCollection::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Number Of Items: " << this->NumberOfItems << "\n";
|
|
}
|
|
|
|
|
|
// Get the i'th item in the collection. NULL is returned if i is out
|
|
// of range
|
|
vtkObject *vtkCollection::GetItemAsObject(int i)
|
|
{
|
|
vtkCollectionElement *elem=this->Top;
|
|
|
|
if (i < 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (i == this->NumberOfItems - 1)
|
|
{
|
|
// optimize for the special case where we're looking for the last elem
|
|
elem = this->Bottom;
|
|
}
|
|
else
|
|
{
|
|
while (elem != NULL && i > 0)
|
|
{
|
|
elem = elem->Next;
|
|
i--;
|
|
}
|
|
}
|
|
if ( elem != NULL )
|
|
{
|
|
return elem->Item;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// Replace the i'th item in the collection with a
|
|
void vtkCollection::ReplaceItem(int i, vtkObject *a)
|
|
{
|
|
vtkCollectionElement *elem;
|
|
|
|
if( i < 0 || i >= this->NumberOfItems )
|
|
{
|
|
return;
|
|
}
|
|
|
|
elem = this->Top;
|
|
if (i == this->NumberOfItems - 1)
|
|
{
|
|
elem = this->Bottom;
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < i; j++, elem = elem->Next )
|
|
{}
|
|
}
|
|
|
|
// Take care of reference counting
|
|
if (elem->Item != NULL)
|
|
{
|
|
elem->Item->UnRegister(this);
|
|
}
|
|
a->Register(this);
|
|
|
|
// j == i
|
|
elem->Item = a;
|
|
|
|
this->Modified();
|
|
}
|
|
|
|
|
|
// Remove the i'th item in the list.
|
|
// Be careful if using this function during traversal of the list using
|
|
// GetNextItemAsObject (or GetNextItem in derived class). The list WILL
|
|
// be shortened if a valid index is given! If this->Current is equal to the
|
|
// element being removed, have it point to then next element in the list.
|
|
void vtkCollection::RemoveItem(int i)
|
|
{
|
|
vtkCollectionElement *elem,*prev;
|
|
|
|
if( i < 0 || i >= this->NumberOfItems )
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->Modified();
|
|
|
|
elem = this->Top;
|
|
prev = NULL;
|
|
for (int j = 0; j < i; j++)
|
|
{
|
|
prev = elem;
|
|
elem = elem->Next;
|
|
}
|
|
|
|
// j == i
|
|
if (prev)
|
|
{
|
|
prev->Next = elem->Next;
|
|
}
|
|
else
|
|
{
|
|
this->Top = elem->Next;
|
|
}
|
|
|
|
if (!elem->Next)
|
|
{
|
|
this->Bottom = prev;
|
|
}
|
|
|
|
if ( this->Current == elem )
|
|
{
|
|
this->Current = elem->Next;
|
|
}
|
|
|
|
this->NumberOfItems--;
|
|
this->DeleteElement(elem);
|
|
}
|
|
|
|
vtkCollectionIterator* vtkCollection::NewIterator()
|
|
{
|
|
vtkCollectionIterator* it = vtkCollectionIterator::New();
|
|
it->SetCollection(this);
|
|
return it;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkCollection::Register(vtkObjectBase* o)
|
|
{
|
|
this->RegisterInternal(o, 1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkCollection::UnRegister(vtkObjectBase* o)
|
|
{
|
|
this->UnRegisterInternal(o, 1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkCollection::ReportReferences(vtkGarbageCollector* collector)
|
|
{
|
|
this->Superclass::ReportReferences(collector);
|
|
for(vtkCollectionElement* elem = this->Top; elem; elem = elem->Next)
|
|
{
|
|
vtkGarbageCollectorReport(collector, elem->Item, "Element");
|
|
}
|
|
}
|
|
|