678 lines
23 KiB
C++
678 lines
23 KiB
C++
#include <cmath>
|
|
#include <algorithm>
|
|
#include "hurricane/Technology.h"
|
|
#include "hurricane/DataBase.h"
|
|
#include "knik/Vertex.h"
|
|
#include "knik/Edge.h"
|
|
#include "knik/Graph.h"
|
|
|
|
namespace {
|
|
using namespace Knik;
|
|
struct EdgeToYComp : public binary_function<const Edge*, const Edge*, bool> {
|
|
public:
|
|
bool operator() ( Edge* edge1, Edge* edge2 ) const
|
|
{
|
|
return ( edge1->getTo()->getY() < edge2->getTo()->getY() );
|
|
}
|
|
};
|
|
struct EdgeToXComp : public binary_function<const Edge*, const Edge*, bool> {
|
|
public:
|
|
bool operator() ( Edge* edge1, Edge* edge2 ) const
|
|
{
|
|
return ( edge1->getTo()->getX() > edge2->getTo()->getX() );
|
|
}
|
|
};
|
|
struct EdgeFromYComp : public binary_function<const Edge*, const Edge*, bool> {
|
|
public:
|
|
bool operator() ( Edge* edge1, Edge* edge2 ) const
|
|
{
|
|
return ( edge1->getFrom()->getY() > edge2->getFrom()->getY() );
|
|
}
|
|
};
|
|
struct EdgeFromXComp : public binary_function<const Edge*, const Edge*, bool> {
|
|
public:
|
|
bool operator() ( Edge* edge1, Edge* edge2 ) const
|
|
{
|
|
return ( edge1->getFrom()->getX() < edge2->getFrom()->getX() );
|
|
}
|
|
};
|
|
}
|
|
|
|
namespace Knik {
|
|
|
|
extern unsigned __congestion__;
|
|
extern unsigned __precongestion__;
|
|
|
|
const Name Vertex::_extensionName = "Knik::Vertex";
|
|
|
|
// ********************************************************************
|
|
// VERTEX_Edges declaration
|
|
// ********************************************************************
|
|
class VERTEX_Edges : public Collection<Edge*> {
|
|
public:
|
|
typedef Collection<Edge*> Inherit;
|
|
public:
|
|
class Locator : public Hurricane::Locator<Edge*> {
|
|
public:
|
|
typedef Hurricane::Locator<Edge*> Inherit;
|
|
|
|
private:
|
|
const Vertex* _vertex;
|
|
Edge* _edge;
|
|
int _direction;
|
|
|
|
public:
|
|
Locator(const Vertex* vertex = NULL, Edge* edge = NULL, int direction = 0);
|
|
Locator(const Locator& locator);
|
|
|
|
Locator& operator=(const Locator& locator);
|
|
|
|
virtual Edge* getElement() const;
|
|
virtual Hurricane::Locator<Edge*>* getClone() const;
|
|
|
|
virtual bool isValid() const;
|
|
|
|
virtual void progress();
|
|
|
|
virtual string _getString() const;
|
|
};
|
|
|
|
private:
|
|
const Vertex* _vertex;
|
|
Edge* _edge;
|
|
int _direction;
|
|
|
|
public:
|
|
VERTEX_Edges(const Vertex* vertex);
|
|
VERTEX_Edges(const VERTEX_Edges& edges);
|
|
|
|
VERTEX_Edges& operator=(const VERTEX_Edges& edges);
|
|
virtual Collection<Edge*>* getClone() const;
|
|
virtual Hurricane::Locator<Edge*>* getLocator() const;
|
|
virtual string _getString() const;
|
|
};
|
|
|
|
|
|
Vertex::Vertex ( Graph* routingGraph, Point position, DbU::Unit halfWidth, DbU::Unit halfHeight )
|
|
// **********************************************************************************************
|
|
: Inherit (routingGraph->getCell())
|
|
, _routingGraph (routingGraph)
|
|
, _predecessor (NULL)
|
|
, _contact (NULL)
|
|
, _position (position)
|
|
, _vtuple (NULL)
|
|
, _distance ((float)(HUGE_VAL))
|
|
, _connexID (-1)
|
|
, _netStamp (0)
|
|
, _halfWidth (halfWidth)
|
|
, _halfHeight (halfHeight)
|
|
, _flags(0)
|
|
{
|
|
_firstEdges[0] = NULL;
|
|
_firstEdges[1] = NULL;
|
|
_firstEdges[2] = NULL;
|
|
_firstEdges[3] = NULL;
|
|
}
|
|
|
|
Vertex* Vertex::create ( Graph* routingGraph, Point position, DbU::Unit halfWidth, DbU::Unit halfHeight )
|
|
// *******************************************************************************************************
|
|
{
|
|
Vertex* vertex = new Vertex ( routingGraph, position, halfWidth, halfHeight );
|
|
|
|
vertex->_postCreate();
|
|
|
|
return vertex;
|
|
}
|
|
|
|
void Vertex::_postCreate()
|
|
// ***********************
|
|
{
|
|
Inherit::_postCreate();
|
|
}
|
|
|
|
Vertex::~Vertex()
|
|
// **************
|
|
{
|
|
}
|
|
|
|
void Vertex::destroy()
|
|
// ******************
|
|
{
|
|
_preDestroy();
|
|
delete this;
|
|
}
|
|
|
|
void Vertex::_preDestroy()
|
|
// **********************
|
|
{
|
|
Inherit::_preDestroy();
|
|
}
|
|
|
|
void Vertex::attachToLocalRing ( Component* component )
|
|
// ****************************************************
|
|
{
|
|
// XXX plus utilisée ? XXX
|
|
//assert ( component );
|
|
|
|
//Hook* hook = component->getBodyHook();
|
|
//hook->detach();
|
|
//if ( Hook* previousHook = getLocalRingHook() ) {
|
|
// //cerr << "Vertex::attachToLocalRingHook : going to attach " << previousHook << " to " << hook << endl;
|
|
// hook->attach ( previousHook );
|
|
//}
|
|
//setLocalRingHook ( hook );
|
|
}
|
|
|
|
void Vertex::sortEdges()
|
|
// *********************
|
|
{
|
|
vector<Edge*> hEdgesOut;
|
|
vector<Edge*> vEdgesOut;
|
|
vector<Edge*> hEdgesIn;
|
|
vector<Edge*> vEdgesIn;
|
|
|
|
Edge* currentEdge;
|
|
//ltracein(425);
|
|
if ( (currentEdge = getHEdgeOut()) ) { // si pas de HEdgeOut : rien a faire ^^
|
|
while ( currentEdge ) {
|
|
//ltrace(425) << "Pushing_back edge " << getString(currentEdge) << endl;
|
|
hEdgesOut.push_back ( currentEdge );
|
|
currentEdge = currentEdge->getNextFrom();
|
|
}
|
|
//ltrace(425) << "sorting vector..." << endl;
|
|
sort ( hEdgesOut.begin(), hEdgesOut.end(), EdgeToYComp() );
|
|
//ltrace(425) << "setting " << getString(hEdgesOut[0]) << " as hEdgeOut for vertex " << getString(this) << endl;
|
|
setHEdgeOut ( hEdgesOut[0] );
|
|
for ( unsigned i = 1 ; i < hEdgesOut.size() ; i++ ) {
|
|
//ltrace(425) << "next : " << getString(hEdgesOut[i]) << endl;
|
|
hEdgesOut[i-1]->setNextFrom ( hEdgesOut[i] );
|
|
}
|
|
hEdgesOut[hEdgesOut.size()-1]->setNextFrom ( NULL ); // si jamais avant en milieu de chaine ...
|
|
}
|
|
//ltraceout(425);
|
|
if ( (currentEdge = getVEdgeOut()) ) {
|
|
while ( currentEdge ) {
|
|
vEdgesOut.push_back ( currentEdge );
|
|
currentEdge = currentEdge->getNextFrom();
|
|
}
|
|
sort ( vEdgesOut.begin(), vEdgesOut.end(), EdgeToXComp() );
|
|
setVEdgeOut ( vEdgesOut[0]);
|
|
for ( unsigned i = 1 ; i < vEdgesOut.size() ; i++ ) {
|
|
vEdgesOut[i-1]->setNextFrom ( vEdgesOut[i] );
|
|
}
|
|
vEdgesOut[vEdgesOut.size()-1]->setNextFrom ( NULL );
|
|
}
|
|
if ( (currentEdge = getHEdgeIn()) ) {
|
|
while ( currentEdge ) {
|
|
hEdgesIn.push_back ( currentEdge );
|
|
currentEdge = currentEdge->getNextTo();
|
|
}
|
|
sort ( hEdgesIn.begin(), hEdgesIn.end(), EdgeFromYComp() );
|
|
setHEdgeIn ( hEdgesIn[0] );
|
|
for ( unsigned i = 1 ; i < hEdgesIn.size() ; i++ ) {
|
|
hEdgesIn[i-1]->setNextTo ( hEdgesIn[i] );
|
|
}
|
|
hEdgesIn[hEdgesIn.size()-1]->setNextTo ( NULL );
|
|
}
|
|
if ( (currentEdge = getVEdgeIn()) ) {
|
|
while ( currentEdge ) {
|
|
vEdgesIn.push_back ( currentEdge );
|
|
currentEdge = currentEdge->getNextTo();
|
|
}
|
|
sort ( vEdgesIn.begin(), vEdgesIn.end(), EdgeFromXComp() );
|
|
setVEdgeIn ( vEdgesIn[0] );
|
|
for ( unsigned i = 1 ; i < vEdgesIn.size() ; i++ ) {
|
|
vEdgesIn[i-1]->setNextTo ( vEdgesIn[i] );
|
|
}
|
|
vEdgesIn[vEdgesIn.size()-1]->setNextTo ( NULL );
|
|
}
|
|
|
|
}
|
|
|
|
Edges Vertex::getAdjacentEdges() const
|
|
// ***********************************
|
|
{
|
|
return VERTEX_Edges ( this );
|
|
}
|
|
|
|
Contact* Vertex::getContact ( Edge* arrivalEdge )
|
|
// **********************************************
|
|
{
|
|
|
|
if ( _contact ) {
|
|
// il y deja un contact associe au vertex XXX on verifie que le contact appartient bien au workingNet du routingGraph XXX
|
|
if ( _routingGraph->getWorkingNet() == _contact->getNet() )
|
|
return _contact;
|
|
_contact = NULL;
|
|
}
|
|
|
|
//assert ( arrivalEdge ); // ca change si on se decide quele vertex pointe sur le contact et pas le hook d'un routingPad ou autre
|
|
if ( arrivalEdge ) {
|
|
int arrivalConnexID = arrivalEdge->getConnexID();
|
|
bool createContact = false;
|
|
bool straightOn = false;
|
|
if ( arrivalEdge->isVertical() ) {
|
|
if ( _firstEdges[0] && ( _firstEdges[0]->getConnexID() == arrivalConnexID ) && ( _firstEdges[0]->getNetStamp() == _netStamp ) )
|
|
createContact = true;
|
|
else if ( _firstEdges[2] && ( _firstEdges[2]->getConnexID() == arrivalConnexID ) && ( _firstEdges[2]->getNetStamp() == _netStamp ) )
|
|
createContact = true;
|
|
else if ( ( _firstEdges[1] == arrivalEdge )
|
|
&& ( _firstEdges[3] && ( _firstEdges[3]->getConnexID() == arrivalConnexID ) && ( _firstEdges[3]->getNetStamp() == _netStamp ) ) )
|
|
straightOn = true;
|
|
else if ( ( _firstEdges[3] == arrivalEdge )
|
|
&& ( _firstEdges[1] && ( _firstEdges[1]->getConnexID() == arrivalConnexID ) && ( _firstEdges[1]->getNetStamp() == _netStamp ) ) )
|
|
straightOn = true;
|
|
else
|
|
throw Error ( "Vertex::getContact(): problem with edges configuration *1." );
|
|
}
|
|
else {
|
|
if ( _firstEdges[1] && ( _firstEdges[1]->getConnexID() == arrivalConnexID ) && ( _firstEdges[1]->getNetStamp() == _netStamp ) )
|
|
createContact = true;
|
|
else if ( _firstEdges[3] && ( _firstEdges[3]->getConnexID() == arrivalConnexID ) && ( _firstEdges[3]->getNetStamp() == _netStamp ) )
|
|
createContact = true;
|
|
else if ( ( _firstEdges[0] == arrivalEdge )
|
|
&& ( _firstEdges[2] && ( _firstEdges[2]->getConnexID() == arrivalConnexID ) && ( _firstEdges[2]->getNetStamp() == _netStamp ) ) )
|
|
straightOn = true;
|
|
else if ( ( _firstEdges[2] == arrivalEdge )
|
|
&& ( _firstEdges[0] && ( _firstEdges[0]->getConnexID() == arrivalConnexID ) && ( _firstEdges[0]->getNetStamp() == _netStamp ) ) )
|
|
straightOn = true;
|
|
else
|
|
throw Error ( "Vertex::getContact(): problem with Edges configuration *2." );
|
|
}
|
|
if ( createContact ) {
|
|
Contact* contact = Contact::create ( _routingGraph->getWorkingNet()
|
|
//, getLayer(1)
|
|
, DataBase::getDB()->getTechnology()->getLayer("metal2")
|
|
, _position.getX()
|
|
, _position.getY()
|
|
, _halfWidth/5
|
|
, _halfHeight/5
|
|
);
|
|
// on a besoin de tester si par routage précédent il n'y a pas un segment du net qui traverse le vertex ....
|
|
Segment* segment0 = NULL;
|
|
Segment* segment1 = NULL;
|
|
Segment* segment2 = NULL;
|
|
Segment* segment3 = NULL;
|
|
if ( _firstEdges[0] )
|
|
segment0 = _firstEdges[0]->getSegmentFor ( _routingGraph->getWorkingNet() );
|
|
if ( _firstEdges[1] )
|
|
segment1 = _firstEdges[1]->getSegmentFor ( _routingGraph->getWorkingNet() );
|
|
if ( _firstEdges[2] )
|
|
segment2 = _firstEdges[2]->getSegmentFor ( _routingGraph->getWorkingNet() );
|
|
if ( _firstEdges[3] )
|
|
segment3 = _firstEdges[3]->getSegmentFor ( _routingGraph->getWorkingNet() );
|
|
|
|
if ( (segment0 != NULL) && (segment0 == segment2) ) {
|
|
if ( !dynamic_cast<Contact*>(segment0->getSource()) ) throw Error ("Vertex::getContact(): does not consider Segment not based on Contact (source).");
|
|
if ( !dynamic_cast<Contact*>(segment0->getTarget()) ) throw Error ("Vertex::getContact(): does not consider Segment not based on Contact (target).");
|
|
Contact* targetContact = static_cast<Contact*>(segment0->getTarget());
|
|
_routingGraph->removeSegment(segment0);
|
|
segment0->getTargetHook()->detach();
|
|
segment0->getTargetHook()->attach(contact->getBodyHook());
|
|
_routingGraph->insertSegment(segment0);
|
|
Segment* newSeg = _routingGraph->createSegment(contact, targetContact);
|
|
_routingGraph->insertSegment(newSeg);
|
|
}
|
|
if ( (segment1 != NULL) && (segment1 == segment3) ) {
|
|
if ( !dynamic_cast<Contact*>(segment1->getSource()) ) throw Error ("Vertex::getContact(): does not consider Segment not based on Contact (Source).");
|
|
if ( !dynamic_cast<Contact*>(segment1->getTarget()) ) throw Error ("Vertex::getContact(): does not consider Segment not based on Contact (Target).");
|
|
Contact* targetContact = static_cast<Contact*>(segment1->getTarget());
|
|
_routingGraph->removeSegment(segment1);
|
|
segment1->getTargetHook()->detach();
|
|
segment1->getTargetHook()->attach(contact->getBodyHook());
|
|
_routingGraph->insertSegment(segment1);
|
|
Segment* newSeg = _routingGraph->createSegment(contact, targetContact);
|
|
_routingGraph->insertSegment(newSeg);
|
|
}
|
|
return contact;
|
|
}
|
|
if ( straightOn )
|
|
return NULL;
|
|
}
|
|
|
|
throw Error ( "Vertex::getContact(): what are you doing here O_o?" );
|
|
}
|
|
|
|
Edge* Vertex::getHEdgeLeadingTo ( Vertex* to )
|
|
// *******************************************
|
|
{
|
|
Edge* edge = getHEdgeOut();
|
|
while ( edge ) {
|
|
if ( edge->getTo() == to )
|
|
break;
|
|
edge = edge->getNextFrom();
|
|
}
|
|
return edge;
|
|
}
|
|
|
|
Edge* Vertex::getVEdgeLeadingTo ( Vertex* to )
|
|
// *******************************************
|
|
{
|
|
Edge* edge = getVEdgeOut();
|
|
while ( edge ) {
|
|
if ( edge->getTo() == to )
|
|
break;
|
|
edge = edge->getNextFrom();
|
|
}
|
|
return edge;
|
|
}
|
|
|
|
Edge* Vertex::getHEdgeComingFrom ( Vertex* from )
|
|
// **********************************************
|
|
{
|
|
Edge* edge = getHEdgeIn();
|
|
while ( edge ) {
|
|
if ( edge->getFrom() == from )
|
|
break;
|
|
edge = edge->getNextTo();
|
|
}
|
|
return edge;
|
|
}
|
|
|
|
Edge* Vertex::getVEdgeComingFrom ( Vertex* from )
|
|
// **********************************************
|
|
{
|
|
Edge* edge = getVEdgeIn();
|
|
while ( edge ) {
|
|
if ( edge->getFrom() == from )
|
|
break;
|
|
edge = edge->getNextTo();
|
|
}
|
|
return edge;
|
|
}
|
|
|
|
Edge* Vertex::getBestHEdgeOut ( DbU::Unit yDest )
|
|
// *****************************************
|
|
{
|
|
Edge* bestEdge = getHEdgeOut();
|
|
Edge* currentEdge = bestEdge;
|
|
|
|
while ( (currentEdge = currentEdge->getNextFrom()) ) {
|
|
if ( abs(currentEdge->getTo()->getY() - yDest) < abs(bestEdge->getTo()->getY() - yDest) )
|
|
bestEdge = currentEdge;
|
|
}
|
|
|
|
return bestEdge;
|
|
}
|
|
|
|
Edge* Vertex::getBestVEdgeOut ( DbU::Unit xDest )
|
|
// *****************************************
|
|
{
|
|
Edge* bestEdge = getVEdgeOut();
|
|
Edge* currentEdge = bestEdge;
|
|
|
|
while ( (currentEdge = currentEdge->getNextFrom()) ) {
|
|
if ( abs(currentEdge->getTo()->getX() - xDest) < abs(bestEdge->getTo()->getX() - xDest) )
|
|
bestEdge = currentEdge;
|
|
}
|
|
|
|
return bestEdge;
|
|
}
|
|
|
|
Edge* Vertex::getBestHEdgeIn ( DbU::Unit yDest )
|
|
// ****************************************
|
|
{
|
|
Edge* bestEdge = getHEdgeIn();
|
|
Edge* currentEdge = bestEdge;
|
|
|
|
while ( (currentEdge = currentEdge->getNextTo()) ) {
|
|
if ( abs(currentEdge->getFrom()->getY() - yDest) < abs(bestEdge->getFrom()->getY() - yDest) )
|
|
bestEdge = currentEdge;
|
|
}
|
|
|
|
return bestEdge;
|
|
}
|
|
|
|
Edge* Vertex::getBestVEdgeIn ( DbU::Unit xDest )
|
|
// ****************************************
|
|
{
|
|
Edge* bestEdge = getVEdgeIn();
|
|
Edge* currentEdge = bestEdge;
|
|
|
|
while ( (currentEdge = currentEdge->getNextTo()) ) {
|
|
if ( abs(currentEdge->getFrom()->getX() - xDest) < abs(bestEdge->getFrom()->getX() - xDest) )
|
|
bestEdge = currentEdge;
|
|
}
|
|
|
|
return bestEdge;
|
|
}
|
|
|
|
bool Vertex::hasInfo() const
|
|
// *************************
|
|
{
|
|
return (_netStamp == _routingGraph->getNetStamp());
|
|
}
|
|
|
|
void Vertex::translate ( const DbU::Unit& dx, const DbU::Unit& dy )
|
|
// ****************************************************************
|
|
{
|
|
_position.translate ( dx, dy );
|
|
}
|
|
|
|
Cell* Vertex::getCell() const
|
|
// **************************
|
|
{
|
|
return _routingGraph->getCell();
|
|
}
|
|
|
|
// void Vertex::_Draw ( View* view, BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation )
|
|
// // *******************************************************************************************************************
|
|
// {
|
|
// DbU::Unit size = DbU::lambda(5);
|
|
// view->FillCircle ( transformation.getPoint ( getPosition() ), size );
|
|
// //if ( _distance < (float)(HUGE_VAL) )
|
|
// if ( _netStamp == _routingGraph->getNetStamp() && _distance < (float)(HUGE_VAL) )
|
|
// view->DrawString ( getString(_distance), getXMax() - (_halfWidth), getYMax() - (_halfHeight/2) );
|
|
// if ( _connexID != -1 )
|
|
// view->DrawString ( getString(_connexID)+","+getString(_netStamp), getXMax() - (_halfWidth), getYMin() + (_halfHeight/2) );
|
|
// //if ( _predecessor ) {
|
|
// // Vertex* oppositeVertex = _predecessor->getOpposite ( this );
|
|
// // Point position = transformation.getPoint ( _position );
|
|
// // Point oppPos = transformation.getPoint ( oppositeVertex->getPosition() );
|
|
// // DbU::Unit origX = position.getX();
|
|
// // DbU::Unit origY = position.getY();
|
|
// // DbU::Unit destX = position.getX() + (4*(oppPos.getX() - position.getX()))/5;
|
|
// // DbU::Unit destY = position.getY() + (4*(oppPos.getY() - position.getY()))/5;
|
|
// // view->DrawLine ( origX, origY, destX, destY );
|
|
// //}
|
|
// }
|
|
|
|
// void Vertex::_Highlight ( View* view, const Box& updateArea, const Transformation& transformation )
|
|
// // ************************************************************************************************
|
|
// {
|
|
// DbU::Unit size = DbU::lambda(5);
|
|
// view->FillCircle ( transformation.getPoint ( getPosition() ), size );
|
|
// }
|
|
|
|
// bool Vertex::_IsInterceptedBy ( View* view, const Point& point, const DbU::Unit& aperture ) const
|
|
// // *****************************************************************************************
|
|
// {
|
|
// Box area ( point );
|
|
// area.inflate(aperture);
|
|
|
|
// return getBoundingBox().intersect ( area );
|
|
// // return false;
|
|
// }
|
|
|
|
void Vertex::invalidate ( bool propagateFlag )
|
|
// *******************************************
|
|
{
|
|
Inherit::invalidate ( false );
|
|
|
|
// Invalider toutes les Edges associées ?
|
|
}
|
|
|
|
string Vertex::_getString() const
|
|
// ******************************
|
|
{
|
|
return "<" + _TName ( "Vertex" )
|
|
+ " id:" + getString ( _connexID )
|
|
+ " s:" + getString ( _netStamp )
|
|
+ " " + getString ( DbU::getValueString(_position.getX()) )
|
|
+ " " + getString ( DbU::getValueString(_position.getY()) ) + ">";
|
|
}
|
|
|
|
Record* Vertex::_getRecord() const
|
|
// *************************
|
|
{
|
|
Record* record = Inherit::_getRecord();
|
|
|
|
if ( !record )
|
|
record = new Record ( getString ( this ) );
|
|
|
|
record->add ( getSlot ( "hEdgeOut", getHEdgeOut() ) );
|
|
record->add ( getSlot ( "vEdgeOut", getVEdgeOut() ) );
|
|
record->add ( getSlot ( "hEdgeIn", getHEdgeIn() ) );
|
|
record->add ( getSlot ( "vEdgeIn", getVEdgeIn() ) );
|
|
record->add ( getSlot ( "predecessor", _predecessor ) );
|
|
//if ( _localRingHook) record->add ( getSlot ( "localRingHook", _localRingHook ) );
|
|
record->add ( getSlot ( "contact", _contact ) );
|
|
record->add ( getSlot ( "connexID", _connexID ) );
|
|
record->add ( getSlot ( "position", _position ) );
|
|
record->add ( getSlot ( "distance", _distance ) );
|
|
record->add ( getSlot ( "netStamp", _netStamp ) );
|
|
record->add ( getSlot ( "halfWidth", _halfWidth ) );
|
|
record->add ( getSlot ( "halfHeight", _halfHeight ) );
|
|
|
|
return record;
|
|
}
|
|
|
|
|
|
// ************************************************************************************************
|
|
// VERTEX_Edges implementation
|
|
// ************************************************************************************************
|
|
VERTEX_Edges::VERTEX_Edges ( const Vertex* vertex )
|
|
// ************************************************
|
|
: Inherit()
|
|
, _vertex(vertex)
|
|
, _edge(NULL)
|
|
, _direction(0)
|
|
{
|
|
// _direction represents one of the four direction in the routing graph. these ditections are set as follow :
|
|
// 0 = East
|
|
// 1 = North
|
|
// 2 = West
|
|
// 3 = South
|
|
for ( _direction = 0 ; _direction < 4 ; _direction++ ) {
|
|
if ( (_edge = _vertex->getFirstEdges(_direction)) )
|
|
return;
|
|
}
|
|
}
|
|
|
|
VERTEX_Edges::VERTEX_Edges ( const VERTEX_Edges& edges )
|
|
// *****************************************************
|
|
: Inherit()
|
|
, _vertex(edges._vertex)
|
|
, _edge(edges._edge)
|
|
, _direction(edges._direction)
|
|
{
|
|
}
|
|
|
|
VERTEX_Edges& VERTEX_Edges::operator=(const VERTEX_Edges& edges)
|
|
// *************************************************************
|
|
{
|
|
_vertex = edges._vertex;
|
|
_edge = edges._edge;
|
|
_direction = edges._direction;
|
|
return *this;
|
|
}
|
|
|
|
Collection<Edge*>* VERTEX_Edges::getClone() const
|
|
// **********************************************
|
|
{
|
|
return new VERTEX_Edges(*this);
|
|
}
|
|
|
|
Locator<Edge*>* VERTEX_Edges::getLocator() const
|
|
// *********************************************
|
|
{
|
|
return new Locator(_vertex, _edge, _direction);
|
|
}
|
|
|
|
string VERTEX_Edges::_getString() const
|
|
// ************************************
|
|
{
|
|
string s = "<" + _TName("Vertex::Edges");
|
|
if (_vertex) s += " " + getString(_vertex);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
// ************************************************************************************************
|
|
// VERTEX_Edges::Locator implementation
|
|
// ************************************************************************************************
|
|
VERTEX_Edges::Locator::Locator(const Vertex* vertex, Edge* edge, int direction)
|
|
// ****************************************************************************
|
|
: Inherit()
|
|
, _vertex(vertex)
|
|
, _edge(edge)
|
|
, _direction(direction)
|
|
{
|
|
}
|
|
|
|
VERTEX_Edges::Locator::Locator(const Locator& locator)
|
|
// ***************************************************
|
|
: Inherit()
|
|
, _vertex(locator._vertex)
|
|
, _edge(locator._edge)
|
|
, _direction(locator._direction)
|
|
{
|
|
}
|
|
|
|
VERTEX_Edges::Locator& VERTEX_Edges::Locator::operator=(const Locator& locator)
|
|
// ****************************************************************************
|
|
{
|
|
_vertex = locator._vertex;
|
|
_edge = locator._edge;
|
|
_direction = locator._direction;
|
|
return *this;
|
|
}
|
|
|
|
Edge* VERTEX_Edges::Locator::getElement() const
|
|
// ********************************************
|
|
{
|
|
return _edge;
|
|
}
|
|
|
|
Locator<Edge*>* VERTEX_Edges::Locator::getClone() const
|
|
// ****************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool VERTEX_Edges::Locator::isValid() const
|
|
// ****************************************
|
|
{
|
|
return (_edge != NULL );
|
|
}
|
|
|
|
void VERTEX_Edges::Locator::progress()
|
|
// ***********************************
|
|
{
|
|
if ( !_edge )
|
|
return;
|
|
|
|
if ( _direction == 0 || _direction == 1 )
|
|
_edge = _edge->getNextFrom();
|
|
else
|
|
_edge = _edge->getNextTo();
|
|
|
|
while ( !_edge ) {
|
|
if ( _direction == 3 )
|
|
return;
|
|
_direction++;
|
|
_edge = _vertex->getFirstEdges(_direction);
|
|
}
|
|
}
|
|
|
|
string VERTEX_Edges::Locator::_getString() const
|
|
// *********************************************
|
|
{
|
|
string s = "<" + _TName("Vertex::Edges::Locator");
|
|
if (_vertex) s += " " + getString(_vertex);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
} // namespace Knik
|