1223 lines
31 KiB
C++
1223 lines
31 KiB
C++
|
|
// 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é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éation des Frontiè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;
|
|
}
|
|
|
|
|
|
}
|