coriolis/deprecated/nimbus/src/Grid.cpp

1223 lines
31 KiB
C++
Raw Normal View History

// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Date : 29/01/2004
// Author : Hugo Cl<43>ment <Hugo.Clement@lip6.fr>
#include <math.h>
#include "hurricane/Box.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolBox.h"
#include "crlcore/CellGauge.h"
#include "crlcore/LefDefExtension.h"
#include "nimbus/GCell.h"
#include "nimbus/Fence.h"
#include "nimbus/VFence.h"
#include "nimbus/HFence.h"
#include "nimbus/StepProperty.h"
#include "nimbus/Grid.h"
#include "nimbus/NimbusEngine.h"
namespace Nimbus {
#define RG_HORIZONTAL 0
#define RG_VERTICAL 1
/*
* ********************************************************************
* GCell_GCells declaration
* ********************************************************************
*/
class Grid_GCells : public Collection<GCell*> {
public: typedef Collection<GCell*> Inherit;
public: class Locator : public Hurricane::Locator<GCell*> {
public: typedef Hurricane::Locator<GCell*> Inherit;
private: GCell* _nb;
private: unsigned _direction;
public: Locator(GCell* gcell = NULL);
public: Locator(const Locator& locator);
public: Locator& operator=(const Locator& locator);
public: virtual GCell* getElement() const;
public: virtual Hurricane::Locator<GCell*>* getClone() const;
public: virtual bool isValid() const;
public: virtual void progress();
public: virtual string _getString() const;
};
private: GCell* _nb;
private: unsigned _step;
public: Grid_GCells(const Grid* grid, unsigned step);
public: Grid_GCells(const Grid_GCells& gcelles);
public: Grid_GCells& operator=(const Grid_GCells& gcelles);
public: virtual Collection<GCell*>* getClone() const;
public: virtual Hurricane::Locator<GCell*>* getLocator() const;
public: virtual string _getString() const;
};
/*
* ********************************************************************
* GCell_GCells declaration
* ********************************************************************
*/
class Grid_FastGCells : public Collection<GCell*> {
public: typedef Collection<GCell*> Inherit;
public: class Locator : public Hurricane::Locator<GCell*> {
public: typedef Hurricane::Locator<GCell*> Inherit;
private: GCell* _nb;
private: unsigned _direction;
public: Locator(GCell* gcell = NULL);
public: Locator(const Locator& locator);
public: Locator& operator=(const Locator& locator);
public: virtual GCell* getElement() const;
public: virtual Hurricane::Locator<GCell*>* getClone() const;
public: virtual bool isValid() const;
public: virtual void progress();
public: virtual string _getString() const;
};
private: GCell* _nb;
private: unsigned _step;
public: Grid_FastGCells(const Grid* grid, unsigned step);
public: Grid_FastGCells(const Grid_FastGCells& gcelles);
public: Grid_FastGCells& operator=(const Grid_FastGCells& gcelles);
public: virtual Collection<GCell*>* getClone() const;
public: virtual Hurricane::Locator<GCell*>* getLocator() const;
public: virtual string _getString() const;
};
/*
* ********************************************************************
* Grid
*
* ********************************************************************
*/
Grid::Grid (NimbusEngine* nimbus)
//*******************************
: _nimbus (nimbus)
, _cell (nimbus->getCell())
, _rootGCell(NULL)
, _layer (NULL)
, _fences ()
{
_layer = DataBase::getDB()->getTechnology()->getLayer (Name ("SPL1"));
if ( _layer == NULL )
throw Error("NimbusEngine needs <SPL1> layer to be defined");
Box defBox = LefDefExtension::getRowsBox(_cell);
if ( not _nimbus->getWorkZone().isEmpty() ) {
_rootGCell = GCell::create(_nimbus, 0, _nimbus->getWorkZone());
} else if ( not defBox.isEmpty() ) {
UpdateSession::open();
if ( _cell->getAbutmentBox().isEmpty() )
_cell->setAbutmentBox ( defBox );
cmess1 << " - DEF abutment box found: " << defBox << endl;
_rootGCell = GCell::create(_nimbus, 0, defBox);
UpdateSession::close();
} else if ( _cell->getAbutmentBox().isEmpty() ) {
if ( isNoInstancePlacedOrFixed(_cell) ) {
DbU::Unit minWidth = DbU::Max;
double sumWidth = 0.0;
forEach ( Occurrence, ioccurrence, _cell->getLeafInstanceOccurrences() ) {
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
if ( not instance->isFixed() and instance->isTerminal() ) {
Cell* model = instance->getMasterCell();
sumWidth += DbU::getLambda(model->getAbutmentBox().getWidth());
}
}
// forEach ( Instance*, iinstance, _cell->getInstances() ) {
// Cell* model = iinstance->getMasterCell();
// DbU::Unit width = model->getAbutmentBox().getWidth();
// if ( width < minWidth ) minWidth = width;
// sumWidth += DbU::getLambda(width);
// }
rectangularShape(_nimbus->getMargin(), nimbus->getAspectRatio(), sumWidth, minWidth );
UpdateSession::open();
_cell->setAbutmentBox( Box ( _rootGCell->getXMin(), _rootGCell->getYMin()
, _rootGCell->getXMax(), _rootGCell->getYMax()) );
#if 0
Point center = box.getCenter();
forEach ( Instance*, iinstance, cell->getInstances() ) {
iinstance->setPlacementStatus ( Instance::PlacementStatus::PLACED );
setStep(**iinstance, 0);
Box insABox = iinstance->getAbutmentBox();
Box masterABox = iinstance->getMasterCell()->getAbutmentBox();
DbU::Unit xPos = center.getX();
DbU::Unit yPos = center.getY();
instance->setTransformation
( getTransformation ( masterABox
, xPos - insABox.getHalfWidth()
, yPos - insABox.getHalfHeight()
, Transformation::Orientation::ID
) );
}
#endif
UpdateSession::close();
} else {
Box box = _cell->getBoundingBox();
UpdateSession::open();
_cell->setAbutmentBox ( box );
_rootGCell = GCell::create(_nimbus, 0, box);
UpdateSession::close();
}
} else {
cmess1 << " - Design abutment box found: " << _cell->getAbutmentBox() << endl;
_rootGCell = GCell::create(_nimbus, 0, _cell->getAbutmentBox());
}
_rootGCell->setAsPlacementLeaf();
_rootGCell->setAsRoutingLeaf();
}
Grid::~Grid ()
//************
{
_rootGCell->destroy();
}
#if 0
void Grid::Clear()
// **************
{
_oldBoxes.clear();
_newBoxes.clear();
return;
}
#endif
void Grid::rectangularShape(double margin, double aspectRatio, double sumWidth, DbU::Unit minWidth)
// ************************************************************************************************
{
cmess1 << " o Creating abutment box: (margin:" << (margin*100.0)
<< "%, aspect ratio:" << (aspectRatio*100.0)
<< "%, sumWidth:" << sumWidth << ")" << endl;
double dMinWidth = DbU::getLambda(minWidth);
double rowHeight = DbU::getLambda(_nimbus->getSliceHeight());
DbU::Unit pitch = _nimbus->getPitch();
double marginWidth = (1.0+margin) * sumWidth;
// cerr << "sumWidth:" << sumWidth
// << " rowHeight:" << rowHeight
// << " pitch:" << DbU::getValueString(pitch)
// << " marginWidth:" << marginWidth
// << endl;
// AR = x/y S = x*y = marginWidth*SH x=S/y AR = S/y^2
// y = sqrt(S/AR)
double y = sqrt ( marginWidth*rowHeight / aspectRatio );
unsigned int rows = (unsigned int)(y / rowHeight);
if ( rows == 0 ) ++rows;
double rowWidth = marginWidth / rows;
// cerr << "y:" << y << " rows:" << rows << endl;
// cerr << "rowWidth:" << rowWidth << endl;
// cerr << "dMinWidth:" << dMinWidth << endl;
if ( (minWidth != DbU::Max) and (rowWidth < dMinWidth) ) {
rowWidth = dMinWidth;
rows = (unsigned int)(marginWidth / rowWidth);
if ( rows == 0 ) ++rows;
}
// cerr << "rowWidth:" << rowWidth << endl;
DbU::Unit unitRowWidth = DbU::lambda(rowWidth);
DbU::Unit adjustWidth = unitRowWidth % pitch;
if ( adjustWidth != 0 )
unitRowWidth += pitch - adjustWidth;
Box ab = Box ( 0, 0, unitRowWidth, rows * _nimbus->getSliceHeight() );
#if DEPRECATED
if ( nrows == 0 ) {
nrows = (int)(sqrt((1.0 + margin) * sumwidth / rowHeight) + 0.5);
}
DbU::Unit rowWidth
= DbU::lambda
( (int)((double)((int)((1.0 + margin) * DbU::getLambda(sumwidth)
/ ((double)nrows * DbU::getLambda(pitch)) ))
* DbU::getLambda(pitch) + 0.5)
);
Box ab = Box(0, 0, rowWidth, nrows * rowHeight);
#endif
cmess1 << " - Abutment box: " << ab << endl;
_rootGCell = GCell::create ( _nimbus, (unsigned)0, ab );
}
void Grid::horizontalLongSplit (unsigned step, DbU::Unit& Y) const
//***************************************************************
{
//Clear();
recLS (step, Y, RG_HORIZONTAL, _rootGCell);
return;
}
void Grid::verticalLongSplit (unsigned step, DbU::Unit& X) const
//*************************************************************
{
//Clear();
recLS (step, X, RG_VERTICAL, _rootGCell);
return;
}
void Grid::recLS (unsigned step, DbU::Unit& coord, unsigned direction, GCell* gcell) const
//*************************************************************************************
{
//cout << " recLS : " << step << "-" << gcell->getStep() << endl;
if (gcell->getStep() >= step) {
return;
}
if (gcell->getStep() == step - 1) {
if (!(gcell->hasSubGCells())) {
gcell->makeSub();
}
if (direction == RG_HORIZONTAL) {
//cout << "subHSplit" << endl;
gcell->subHSplit (coord);
//cout << "subHSplitted" << endl;
} else if (direction == RG_VERTICAL) {
//cout << "subVSplit" << endl;
gcell->subVSplit (coord);
//cout << "subVSplitted" << endl;
} else {
cerr << "Nothing to do here" << endl;
abort();
}
return;
} else { // exploration r<>cursive
if (!(gcell->hasSubGCells())) {
gcell->makeSub();
}
for_each_gcell (nb, gcell->getSubGCells()) {
if (direction == RG_HORIZONTAL) {
if (
nb->horizontalIsCrossed (coord)
)
{
recLS (step, coord, direction, nb);
}
} else if (direction == RG_VERTICAL) {
if (
nb->verticalIsCrossed (coord)
)
{
recLS (step, coord, direction, nb);
}
} else {
cerr << "Nothing to do here" << endl;
abort();
}
end_for;
}
}
return;
}
Layer* Grid::getLayer () const {
return _layer;
}
GCell* Grid::recGetGCell (unsigned step, Point& p, GCell* gcell) const {
GCell* res = NULL;
if (! (gcell->contains(p))) {
return NULL;
}
if (gcell->getStep() == step) {
return gcell;
} else {
for_each_gcell (subBox, gcell->getSubGCells()) {
res = recGetGCell (step, p, subBox);
if (res)
break;
//return res;
end_for;
}
}
assert (res);
return res;
} // recGetGCell
GCell* Grid::getGCell (unsigned step, Point& p) const
{
return recGetGCell (step, p, _rootGCell);
}
const Box Grid::getBox (unsigned step, Point& p) const
{
GCell* gcell = getGCell (step, p);
return Box (gcell->getXMin(), gcell->getYMin(), gcell->getXMax(), gcell->getYMax());
}
Point Grid::getPosition (unsigned step, Point& pos) const
{
return (getGCell(step,pos)->getCenter());
}
DbU::Unit Grid::getX (unsigned step, DbU::Unit& X) const
{
Point p = Point (X, DbU::lambda (0));
return getGCell (step, p)->getXCenter();
}
DbU::Unit Grid::getY (unsigned step, DbU::Unit& Y) const
{
Point p = Point (DbU::lambda (0), Y);
return getGCell (step, p)->getYCenter();
}
void Grid::recDumpGrid (GCell* gcell) const{
cout << " Step : " << gcell->getStep() << endl;
gcell->dumpPavement();
for_each_gcell (subBox, gcell->getSubGCells()) {
recDumpGrid(subBox);
end_for;
}
return;
}
void Grid::dumpGrid () const{
cout << " o dumping grid..." << endl;
recDumpGrid (_rootGCell);
cout << " - grid dumped." << endl;
return;
}
/*
* ********************************************************************
* Collection des boites du niveau step
*/
GCells Grid::getGCells (unsigned step) const
{
return Grid_GCells(this, step);
}
GCells Grid::getFastGCells (unsigned step) const
{
return Grid_FastGCells(this, step);
}
/*
* ********************************************************************
*
* Cr<EFBFBD>ation des Fronti<EFBFBD>res
*/
void Grid::createFences (unsigned step)
{
_fences[step] = new FenceSet();
for_each_gcell (gcell, getGCells(step)) {
//cmess1 << gcell << endl;
if (!gcell->getLeftFence()) {
GCell* nbleft = gcell->computeLeftOfMe();
if (nbleft) {
Fence* fence = static_cast<Fence*> (VFence::create (this, nbleft, gcell));
gcell->getContainer()->addInnerFence(fence);
fence->setStep(step);
_fences[step]->_insert(fence);
}
}
if (!gcell->getRightFence()) {
GCell* nbright = gcell->computeRightOfMe();
if (nbright) {
Fence* fence = static_cast<Fence*> (VFence::create (this, gcell, nbright));
gcell->getContainer()->addInnerFence(fence);
fence->setStep(step);
_fences[step]->_insert(fence);
}
}
if (!gcell->getUpFence()) {
GCell* nbup = gcell->computeUpOfMe();
if (nbup) {
Fence* fence = static_cast<Fence*> (HFence::create (this, nbup, gcell));
gcell->getContainer()->addInnerFence(fence);
fence->setStep(step);
_fences[step]->_insert(fence);
}
}
if (!gcell->getDownFence()) {
GCell* nbdown = gcell->computeDownOfMe();
if (nbdown) {
Fence* fence = static_cast<Fence*> (HFence::create (this, gcell, nbdown));
gcell->getContainer()->addInnerFence(fence);
fence->setStep(step);
_fences[step]->_insert(fence);
}
}
end_for;
}
return;
}
/*
* ********************************************************************
*
* Collection des frontieres pour un niveau
*/
Fences Grid::getFences (unsigned step)
{
return _fences[step]->getElements();
}
Fence* Grid::getFenceBetween (GCell* nb1, GCell* nb2) const
{
Fence* fence = testFenceBetween (nb1, nb2);
if (!fence)
{
cerr << "no fence between " << nb1 << " and " << nb2 << "." << endl;
abort();
throw Error ("getFenceBetween : gcelles are not linked together");
}
return fence;
}
Fence* Grid::testFenceBetween (GCell* nb1, GCell* nb2) const
{
if (nb1 == nb2)
{
return NULL;
#if 0
abort();
throw Error ("getFenceBetween : same gcelles");
#endif
}
if (nb1->getStep() != nb2->getStep())
{
return NULL;
#if 0
abort();
throw Error ("getFenceBetween : gcelles from different grid levels");
#endif
}
for_each_fence (fence, nb1->getSurroundingFences())
{
if (fence->getOppositeGCell (nb1) == nb2)
return fence;
end_for;
}
return NULL;
}
// Compat
Grid* Grid::create (unsigned n, DbU::Unit& width, DbU::Unit& height) {
throw Error ("Nimbus: Grid: entering an outdated and deactivated function");
return NULL;
}
Box Grid::getGRBox (unsigned step, Point& p) {
return (getBox (step, p));
}
Contact* Grid::getContact (Net& net, Point& position) {
for_each_contact (contact, net.getContacts()) {
if (contact->getPosition() == position) {
return contact;
} else {
// vide
}
end_for;
}
return NULL;
}
Contact* Grid::getOrCreateContact (Net& net, Point& position, DbU::Unit width, DbU::Unit height) {
Contact* c = NULL;
c = getContact (net, position);
if (!c)
c = Contact::create (&net, getLayer(), position.getX(), position.getY(), width, height);
return c;
}
#if 0
Contact* Grid::getOrCreateContact (Net& net, Point& position) {
Contact* c = NULL;
c = getContact (net, position);
if (!c)
c = Contact::create (&net, getLayer(), position.getX(), position.getY(), DbU::lambda(5), DbU::lambda(5));
return c;
}
#endif
DbU::Unit Grid::getVSplitterHalfLength (unsigned step) {
return DbU::lambda (2);
}
DbU::Unit Grid::getHSplitterHalfLength (unsigned step) {
return DbU::lambda (2);
}
Point Grid::getSubUpLeft (unsigned step, Point& pos) {
GCell* gcell = getGCell (step, pos);
return gcell->getSubUpperLeft()->getCenter();
}
Point Grid::getSubUpRight (unsigned step, Point& pos) {
GCell* gcell = getGCell (step, pos);
assert (gcell);
assert (gcell->getSubUpperRight());
return gcell->getSubUpperRight()->getCenter();
}
Point Grid::getSubDownLeft (unsigned step, Point& pos) {
GCell* gcell = getGCell (step, pos);
return gcell->getSubBottomLeft()->getCenter();
}
Point Grid::getSubDownRight (unsigned step, Point& pos) {
GCell* gcell = getGCell (step, pos);
return gcell->getSubBottomRight()->getCenter();
}
GCell* Grid::getLeftOf (const GCell* gcell) const
{
GCell* nbl = gcell->getLeftOfMe();
if (!nbl) nbl = gcell->computeLeftOfMe();
return nbl;
}
GCell* Grid::getRightOf (const GCell* gcell) const
{
GCell* nbr = gcell->getRightOfMe();
if (!nbr) nbr = gcell->computeRightOfMe();
return nbr;
}
GCell* Grid::getUpOf (const GCell* gcell) const
{
GCell* nbu = gcell->getUpOfMe();
if (!nbu) nbu = gcell->computeUpOfMe();
return nbu;
}
GCell* Grid::getDownOf (const GCell* gcell) const
{
GCell* nbd = gcell->getDownOfMe();
if (!nbd) nbd = gcell->computeDownOfMe();
return nbd;
}
GCell* Grid::getUpperLeftCorner (unsigned step) const
{
GCell* gcell = getRoot();
for (unsigned level = 0 ; level < step ; level++) {
gcell = gcell->getSubUpperLeft();
if (!gcell) throw Error ("Nimbus crushed when diving too deep.");
}
return gcell;
}
GCell* Grid::getUpperRightCorner (unsigned step) const
{
GCell* gcell = getRoot();
for (unsigned level = 0 ; level < step ; level++) {
gcell = gcell->getSubUpperRight();
if (!gcell) throw Error ("Nimbus crushed when diving too deep.");
}
return gcell;
}
GCell* Grid::getLowerLeftCorner (unsigned step) const
{
GCell* gcell = getRoot();
for (unsigned level = 0 ; level < step ; level++) {
gcell = gcell->getSubLowerLeft();
if (!gcell) throw Error ("Nimbus crushed when diving too deep.");
}
return gcell;
}
GCell* Grid::getLowerRightCorner (unsigned step) const
{
GCell* gcell = getRoot();
for (unsigned level = 0 ; level < step ; level++) {
gcell = gcell->getSubLowerRight();
if (!gcell) throw Error ("Nimbus crushed when diving too deep.");
}
return gcell;
}
/*
* ********************************************************************
*
* Grid_GCells implementation
*/
Grid_GCells::Grid_GCells(const Grid* grid, unsigned step)
// ************************************************************************
: Inherit()
, _nb(NULL)
, _step(step)
{
_nb = grid->getRoot();
for (unsigned level = 0 ; level < step ; level++) {
_nb = _nb->getSubUpperLeft();
if (!_nb) throw Error ("Nimbus crushed when diving too deep.");
}
}
Grid_GCells::Grid_GCells(const Grid_GCells& gcelles)
// ************************************************************************
: Inherit()
, _nb(gcelles._nb)
, _step(gcelles._step)
{
}
Grid_GCells& Grid_GCells::operator=(const Grid_GCells& gcelles)
// ***********************************************************************************
{
_nb = gcelles._nb;
_step = gcelles._step;
return *this;
}
Collection<GCell*>* Grid_GCells::getClone() const
// ***********************************************
{
return new Grid_GCells(*this);
}
Locator<GCell*>* Grid_GCells::getLocator() const
// ******************************************************
{
return new Locator(_nb);
}
string Grid_GCells::_getString() const
// *************************************
{
string s = "<" + _TName("GCell::GCells");
if (_nb) s += " " + getString(_nb);
s += ">";
return s;
}
/*
* ********************************************************************
* Grid_GCells::Locator implementation
*/
Grid_GCells::Locator::Locator(GCell* gcell)
// ********************************************************
: Inherit(),
_nb(gcell),
_direction(0)
{
}
Grid_GCells::Locator::Locator(const Locator& locator)
// ****************************************************
: Inherit(),
_nb(locator._nb),
_direction(locator._direction)
{
}
Grid_GCells::Locator& Grid_GCells::Locator::operator=(const Locator& locator)
// ******************************************************************************
{
_nb = locator._nb;
_direction = locator._direction;
return *this;
}
GCell* Grid_GCells::Locator::getElement() const
// *********************************************
{
return _nb;
}
Locator<GCell*>* Grid_GCells::Locator::getClone() const
// *****************************************************
{
return new Locator(*this);
}
bool Grid_GCells::Locator::isValid() const
// *****************************************
{
return (_nb != NULL);
}
void Grid_GCells::Locator::progress()
// ************************************
{
GCell* gcell = NULL;
switch (_direction) {
case 0:
gcell = _nb->computeRightOfMe();
if (!gcell) {
gcell = _nb->computeDownOfMe();
_direction = 1;
}
break;
case 1:
gcell = _nb->computeLeftOfMe();
if (!gcell) {
gcell = _nb->computeDownOfMe();
_direction = 0;
}
break;
default:
gcell = NULL;
break;
}
_nb = gcell;
}
string Grid_GCells::Locator::_getString() const
// **********************************************
{
string s = "<" + _TName("GCells::GCells::Locator");
if (_nb) s += " " + getString(_nb);
s += ">";
return s;
}
/*
* ********************************************************************
* Grid_FastGCells implementation
*/
Grid_FastGCells::Grid_FastGCells(const Grid* grid, unsigned step)
// **************************************************************************************
: Inherit()
, _nb(NULL)
, _step(step)
{
_nb = grid->getRoot();
for (unsigned level = 0 ; level < step ; level++) {
_nb = _nb->getSubUpperLeft();
if (!_nb) throw Error ("Nimbus crushed when diving too deep.");
}
}
Grid_FastGCells::Grid_FastGCells(const Grid_FastGCells& gcelles)
// ************************************************************************************
: Inherit()
, _nb(gcelles._nb)
, _step(gcelles._step)
{
}
Grid_FastGCells& Grid_FastGCells::operator=(const Grid_FastGCells& gcelles)
// ****************************************************************
{
_nb = gcelles._nb;
_step = gcelles._step;
return *this;
}
Collection<GCell*>* Grid_FastGCells::getClone() const
// ***********************************************
{
return new Grid_FastGCells(*this);
}
Locator<GCell*>* Grid_FastGCells::getLocator() const
// **********************************************
{
return new Locator(_nb);
}
string Grid_FastGCells::_getString() const
// *************************************
{
string s = "<" + _TName("GCell::GCells");
if (_nb) s += " " + getString(_nb);
s += ">";
return s;
}
/*
* ********************************************************************
* Grid_FastGCells::Locator implementation
*/
Grid_FastGCells::Locator::Locator(GCell* gcell)
// ********************************************************
: Inherit(),
_nb(gcell),
_direction(0)
{
}
Grid_FastGCells::Locator::Locator(const Locator& locator)
// ****************************************************
: Inherit(),
_nb(locator._nb),
_direction(locator._direction)
{
}
Grid_FastGCells::Locator& Grid_FastGCells::Locator::operator=(const Locator& locator)
// ******************************************************************************
{
_nb = locator._nb;
_direction = locator._direction;
return *this;
}
GCell* Grid_FastGCells::Locator::getElement() const
// *********************************************************
{
return _nb;
}
Locator<GCell*>* Grid_FastGCells::Locator::getClone() const
// *****************************************************************
{
return new Locator(*this);
}
bool Grid_FastGCells::Locator::isValid() const
// **************************************************
{
return (_nb != NULL);
}
void Grid_FastGCells::Locator::progress()
// *********************************************
{
GCell* gcell = NULL;
switch (_direction) {
case 0:
gcell = _nb->getRightOfMe();
if (!gcell) {
gcell = _nb->getDownOfMe();
_direction = 1;
}
break;
case 1:
gcell = _nb->getLeftOfMe();
if (!gcell) {
gcell = _nb->getDownOfMe();
_direction = 0;
}
break;
default:
gcell = NULL;
break;
}
_nb = gcell;
}
string Grid_FastGCells::Locator::_getString() const
// *******************************************************
{
string s = "<" + _TName("Grid::FastGCells::Locator");
if (_nb) s += " " + getString(_nb);
s += ">";
return s;
}
#if 0
/*
* ********************************************************************
* Grid_Fences implementation
*/
Grid_Fences::Grid_Fences(const Grid* grid, unsigned step)
// **************************************************************************************
: Inherit()
, _nb(NULL)
, _fence(NULL)
, _step(step)
{
_nb = grid->getRoot();
for (unsigned level = 0 ; level < step ; level++) {
_nb = _nb->getSubUpperLeft();
if (!_nb) throw Error ("Nimbus crushed while diving too deep.");
}
}
Grid_Fences::Grid_Fences(const Grid_Fences& fences)
// ************************************************************************************
: Inherit()
, _nb(fences._nb)
, _fence(fences._nb)
, _step(fences._step)
{
}
Grid_Fences& Grid_Fences::operator=(const Grid_Fences& fences)
// ****************************************************************
{
_nb = ._nb;
_step = ._step;
return *this;
}
Collection<Fence*>* Grid_Fences::getClone() const
// ***********************************************
{
return new Grid_Fences(*this);
}
Locator<Fence*>* Grid_Fences::getLocator() const
// **********************************************
{
return new Locator(_nb);
}
string Grid_Fences::_getString() const
// *************************************
{
string s = "<" + _TName("Fence::Fencees");
if (_nb) s += " " + getString(_nb);
s += ">";
return s;
}
/*
* ********************************************************************
* Grid_Fences::Locator implementation
*/
Grid_Fences::Locator::Locator(Fence* gcell)
// ********************************************************
: Inherit(),
_nb(gcell),
_direction(0)
{
}
Grid_Fences::Locator::Locator(const Locator& locator)
// ****************************************************
: Inherit(),
_nb(locator._nb),
_direction(locator._direction)
{
}
Grid_Fences::Locator& Grid_Fences::Locator::operator=(const Locator& locator)
// ******************************************************************************
{
_nb = locator._nb;
_direction = locator._direction;
return *this;
}
Fence* Grid_Fences::Locator::getElement() const
// *********************************************************
{
return _nb;
}
Locator<Fence*>* Grid_Fences::Locator::getClone() const
// *****************************************************************
{
return new Locator(*this);
}
bool Grid_Fences::Locator::isValid() const
// **************************************************
{
return (_nb != NULL);
}
void Grid_Fences::Locator::progress()
// *********************************************
{
Fence* gcell = NULL;
switch (_direction) {
case 0:
gcell = _nb->getLeftOfMe();
if (!gcell) {
gcell = _nb->getDownOfMe();
_direction = 1;
}
break;
case 1:
gcell = _nb->getRightOfMe();
if (!gcell) {
gcell = _nb->getDownOfMe();
_direction = 0;
}
break;
default:
gcell = NULL;
break;
}
_nb = gcell;
}
string Grid_Fences::Locator::_getString() const
// *******************************************************
{
string s = "<" + _TName("Grid::FastFencees::Locator");
if (_nb) s += " " + getString(_nb);
s += ">";
return s;
}
#endif
/*
* FenceSet implementation
*
*/
Grid::FenceSet::FenceSet()
// **********************
: Inherit()
{
}
unsigned Grid::FenceSet::_getHashValue(Fence* fence) const
{
return ( (unsigned int)( (unsigned long)fence ) ) / 2;
}
Fence* Grid::FenceSet::_getNextElement(Fence* fence) const
{
return fence->_getNextOfGridFenceSet();
}
void Grid::FenceSet::_setNextElement(Fence* fence, Fence* nextFence) const
{
fence->_setNextOfGridFenceSet(nextFence);
return;
}
}