File: [Development] / inventor / lib / database / src / so / SoLists.c++ (download)
Revision 1.2, Tue Sep 25 00:45:35 2001 UTC (16 years, 1 month ago) by jlim
Branch: MAIN
CVS Tags: release-2_1_5-9, release-2_1_5-8, release-2_1_5-10, HEAD Changes since 1.1: +5 -5
lines
Various changes:
* Fixed Bug 63 and 64.
* Handled nonstandard sed location.
* Used for-loop in man page install.
* Included casts for 64-bit builds.
* Added placeholder for FreeBSD options.
* Included unistd.h for getopt() and stdlib.h for malloc().
* Implemented SoText[23] workaround for glibc-2.2.* iconv().
* Split long lines in SoHandleBoxDraggerGeom.h and
SoTransformerDraggerGeom.h in lib/interaction/src/draggers/geom.
* Added IV_NO_OVERLAYS/OIV_NO_OVERLAYS variables to disable overlay planes.
|
/*
*
* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
*
*/
/*
* Copyright (C) 1990,91 Silicon Graphics, Inc.
*
_______________________________________________________________________
______________ S I L I C O N G R A P H I C S I N C . ____________
|
| $Revision: 1.2 $
|
| Classes:
| SoBaseList
|
| Author(s) : Nick Thompson
|
______________ S I L I C O N G R A P H I C S I N C . ____________
_______________________________________________________________________
*/
#include <stdlib.h>
#include <Inventor/SoLists.h>
#include <Inventor/SoPath.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/details/SoDetail.h>
#include <Inventor/misc/SoBase.h>
////////////////////////////////////////////////////////////////////////
//
// Description:
// Default constructor.
//
// Use: public
SoBaseList::SoBaseList() : SbPList()
//
////////////////////////////////////////////////////////////////////////
{
// By default, this adds references to things in the list when
// they are added
addRefs = TRUE;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Constructor that takes initial approximate size (number of items
// in list).
//
// Use: public
SoBaseList::SoBaseList(int size) : SbPList(size)
//
////////////////////////////////////////////////////////////////////////
{
// By default, this adds references to things in the list when
// they are added
addRefs = TRUE;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Constructor that takes another list to copy values from.
//
// Use: public
SoBaseList::SoBaseList(const SoBaseList &l)
//
////////////////////////////////////////////////////////////////////////
{
// By default, this adds references to things in the list when
// they are added
addRefs = TRUE;
copy(l);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Add a pointer to the end of the list
//
// Use: public
void
SoBaseList::append(SoBase * ptr) // pointer to append
//
////////////////////////////////////////////////////////////////////////
{
SbPList::append((void *) ptr);
if (addRefs && ptr)
ptr->ref();
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Insert given pointer into list before pointer with given index
//
// Use: public
void
SoBaseList::insert(SoBase *ptr, // pointer to insert
int addBefore) // index to add before
//
////////////////////////////////////////////////////////////////////////
{
if (addRefs && ptr)
ptr->ref();
SbPList::insert((void *) ptr, addBefore);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Remove pointer with given index
//
// Use: public
void
SoBaseList::remove(int which) // index of pointer to remove
//
////////////////////////////////////////////////////////////////////////
{
if (addRefs && (*this)[which])
(*this)[which]->unref();
SbPList::remove(which);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Remove all pointers from one with given index on, inclusive
//
// Use: public
void
SoBaseList::truncate(int start) // first index to remove
//
////////////////////////////////////////////////////////////////////////
{
int i;
if (addRefs) {
for ( i = start; i < getLength(); i++) {
if ( (*this)[i] ) {
(*this)[i]->unref();
}
}
}
SbPList::truncate(start);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Copy a list, keeping all reference counts correct
//
// Use: public
void
SoBaseList::copy(const SoBaseList &bList) // list to copy from
//
////////////////////////////////////////////////////////////////////////
{
int i;
truncate(0);
if (addRefs) {
for (i = 0; i < bList.getLength(); i++) {
if ( bList[i] ) {
bList[i]->ref();
}
}
}
SbPList::copy(bList);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Set an element of a list
//
// Use: public
void
SoBaseList::set(int i, // index to set
SoBase *ptr) // new pointer value
//
////////////////////////////////////////////////////////////////////////
{
if (addRefs) {
if ( ptr ) {
ptr->ref() ;
}
if ( (*this)[i] ) {
(*this)[i]->unref();
}
}
(*(const SbPList *) this) [i] = (void *) ptr;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Looks in the SoPathList for a path that matches a given one, using the
// == operator. If it is found, return that index, otherwise retun -1
//
// Use: public
int
SoPathList::findPath(const SoPath &path)
//
////////////////////////////////////////////////////////////////////////
{
int i;
SoPath *testPath;
for(i = 0; i < getLength(); i++) {
testPath = (*this)[i];
if (*testPath == path)
return i;
}
return -1; // not found
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Sorts path list in place based on (1) increasing address of head
// node, then (2) increasing indices of children.
//
// Use: public
void
SoPathList::sort()
//
////////////////////////////////////////////////////////////////////////
{
SoPath **paths = new SoPath *[getLength()];
int i;
// Use qsort to do the work
for (i = 0; i < getLength(); i++) {
paths[i] = (*this)[i];
paths[i]->ref();
}
qsort(paths, getLength(), sizeof(SoPath *), comparePaths);
// Move the paths back into this list
for (i = 0; i < getLength(); i++)
set(i, paths[i]);
// Get rid of the array
for (i = 0; i < getLength(); i++)
paths[i]->unref();
delete [] paths;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Given a sorted list, removes any path that (1) is a duplicate,
// or (2) goes through a node that is the tail of another path.
//
// Use: public
void
SoPathList::uniquify()
//
////////////////////////////////////////////////////////////////////////
{
int i, lastSame;
const SoPath *p1;
const SoPath *p2;
// Remove duplicates from the end to minimize array shuffling
for (i = getLength() - 2; i >= 0; i--) {
// Use the SoPath::findFork() method to determine the last
// node that is on a common chain for both paths. Since the
// paths are sorted, we can just check if this node is at the
// end of the first path. If it is, the second one is a
// duplicate and can be removed.
p1 = (*this)[i];
p2 = (*this)[i + 1];
lastSame = p1->findFork(p2);
if (lastSame == p1->getLength() - 1)
remove(i + 1);
}
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Comparison method for path list sorting.
//
// Use: private
int
SoPathList::comparePaths(const void *p1Ptr, const void *p2Ptr)
//
////////////////////////////////////////////////////////////////////////
{
const SoPath *p1, *p2;
p1 = * (const SoPath * const *) p1Ptr;
p2 = * (const SoPath * const *) p2Ptr;
// Most likely, the head nodes will be the same, so test this first
if (p1->getHead() == p2->getHead()) {
// Test indices in order. A missing child comes before an
// existing child
int depth;
for (depth = 1; depth < p1->getLength(); depth++) {
if (depth >= p2->getLength())
return 1;
if (p1->getIndex(depth) < p2->getIndex(depth))
return -1;
if (p1->getIndex(depth) > p2->getIndex(depth))
return 1;
}
// If we get here, then the paths are the same up to the end
// of path 1. If path2 is longer, then it comes after
if (p2->getLength() > p1->getLength())
return -1;
// Exact same paths
return 0;
}
else if (p1->getHead() < p2->getHead())
return -1;
else
return 1;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Add a typeId to the end of the list
//
// Use: public
void
SoTypeList::append(SoType typeId) // typeId to append
//
////////////////////////////////////////////////////////////////////////
{
// we have to do some hackage to cast an SoType into a void *...
void *hackage = (void*)(unsigned long)(*(int32_t *)&typeId);
SbPList::append(hackage);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Returns index of given typeId in list, or -1 if not found.
//
// Use: public
int
SoTypeList::find(SoType typeId) const
//
////////////////////////////////////////////////////////////////////////
{
// we have to do some hackage to cast an SoType into a void *...
void *hackage = (void*)(unsigned long)(*(int32_t *)&typeId);
return SbPList::find(hackage);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Insert given typeId into list before typeId with given index
//
// Use: public
void
SoTypeList::insert(SoType typeId, // typeId to insert
int addBefore) // index to add before
//
////////////////////////////////////////////////////////////////////////
{
// we have to do some hackage to cast an SoType into a void *...
void *hackage = (void*)(unsigned long)(*(int32_t *)&typeId);
SbPList::insert(hackage, addBefore);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Access an element of a list
//
// Use: public
SoType
SoTypeList::operator [](int i) const
//
////////////////////////////////////////////////////////////////////////
{
// we have to do some hackage to cast our void * back to an SoType...
int32_t hackage = (long)(* (const SbPList *) this)[i];
return *(SoType*)&hackage;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Set an element of a list
//
// Use: public
void
SoTypeList::set(int i, // index to set
SoType typeId) // new typeId value
//
////////////////////////////////////////////////////////////////////////
{
// we have to do some hackage to cast an SoType into a void *...
void *hackage = (void*)(unsigned long)(*(int32_t *)&typeId);
(*(const SbPList *) this) [i] = hackage;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Copy constructor.
//
// Use: public
SoDetailList::SoDetailList(const SoDetailList &l) : SbPList(l)
{
// We need to copy the details, since we delete them when we
// truncate the list
for (int i = 0; i < getLength(); i++)
(* (const SbPList *) this)[i] = (void *) (*this)[i]->copy();
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Delete all details on the list from one with given index on,
// inclusive.
//
// Use: public
void
SoDetailList::truncate(int start)
//
////////////////////////////////////////////////////////////////////////
{
int i;
for ( i = start; i < getLength(); i++) {
if ( (*this)[i] ) {
delete (*this)[i];
}
}
SbPList::truncate(start);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Copies list, making copy instances of each detail in list.
//
// Use: public
void
SoDetailList::copy(const SoDetailList &l)
//
////////////////////////////////////////////////////////////////////////
{
truncate(0);
int num = l.getLength();
for (int i = 0; i < num; i ++) {
SoDetail* detail = l[i];
if (detail)
append(detail->copy());
}
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Sets an element of a list, deleting old entry.
//
// Use: public
void
SoDetailList::set(int i, SoDetail *detail)
//
////////////////////////////////////////////////////////////////////////
{
if ((*this)[i] != NULL)
delete (*this)[i];
(* (const SbPList *) this)[i] = (void *) detail;
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Copy constructor.
//
// Use: public
SoPickedPointList::SoPickedPointList(const SoPickedPointList &l) : SbPList(l)
{
// We need to copy the pickedPoints, since we delete them when we
// truncate the list
for (int i = 0; i < getLength(); i++)
(* (const SbPList *) this)[i] = (void *) (*this)[i]->copy();
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Delete all pickedPoints on the list from one with given index on,
// inclusive.
//
// Use: public
void
SoPickedPointList::truncate(int start)
//
////////////////////////////////////////////////////////////////////////
{
int i;
for (i = start; i < getLength(); i++)
if ((*this)[i] != NULL)
delete (*this)[i];
SbPList::truncate(start);
}
////////////////////////////////////////////////////////////////////////
//
// Description:
// Sets an element of a list, deleting old entry.
//
// Use: public
void
SoPickedPointList::set(int i, SoPickedPoint *pickedPoint)
//
////////////////////////////////////////////////////////////////////////
{
if ((*this)[i] != NULL)
delete (*this)[i];
(* (const SbPList *) this)[i] = (void *) pickedPoint;
}