Anabatic transient commit 5.
* Bug: In Anabatic: - In Dijkstra/Vertex, use the new Observer for fast access from the GCells. - In Dijktra::propagate() loop detection. - In Dijkstra, reset the "_from" of vertexes between two propagates on the same Net (otherwise: loops...). - In Matrix, there must be two different way of calculating an index from a position. One for the min, which is rounded to superior. And one for the max which is rounded to inferior. - In Matrix::updateArea(), checks for invalid indexes.
This commit is contained in:
parent
747027f23a
commit
aa20813342
|
@ -54,11 +54,21 @@ namespace Anabatic {
|
|||
string s = "<Vertex " + getString(_id)
|
||||
+ " connexId:" + getString(_connexId)
|
||||
+ " d:" + ((_distance == unreached) ? "unreached" : getString(_distance) )
|
||||
+ " stamp:" + (hasValidStamp() ? "valid" : "outdated")
|
||||
+ " from:" + ((_from) ? "set" : "NULL")
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void Vertex::notify ( Vertex* vertex, unsigned int flags )
|
||||
{
|
||||
//Vertex* vertex = getOwner();
|
||||
cdebug.log(111) << "Vertex::notify() " << vertex << endl;
|
||||
// Take into account the GCell modification here.
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Dijkstra".
|
||||
|
||||
|
@ -117,12 +127,13 @@ namespace Anabatic {
|
|||
|
||||
_searchArea.merge( rpBb );
|
||||
|
||||
Vertex* vertex = gcell->lookup<Vertex>();
|
||||
Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
if (vertex->getConnexId() < 0) {
|
||||
cdebug.log(111) << "Add Vertex: " << vertex << endl;
|
||||
|
||||
vertex->setStamp ( _stamp );
|
||||
vertex->setConnexId( _targets.size() );
|
||||
vertex->setFrom ( NULL );
|
||||
Contact* gcontact = vertex->getGContact( _net );
|
||||
rp->getBodyHook()->detach();
|
||||
rp->getBodyHook()->attach( gcontact->getBodyHook() );
|
||||
|
@ -182,7 +193,7 @@ namespace Anabatic {
|
|||
if (edge == current->getFrom()) continue;
|
||||
|
||||
GCell* gneighbor = edge->getOpposite(current->getGCell());
|
||||
Vertex* vneighbor = gneighbor->lookup<Vertex>();
|
||||
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
|
||||
cdebug.log(111) << "Neighbor: " << vneighbor << endl;
|
||||
|
||||
|
@ -212,10 +223,21 @@ namespace Anabatic {
|
|||
while ( current ) {
|
||||
cdebug.log(111) << "| " << current << endl;
|
||||
|
||||
if ( (current->getConnexId() == _connectedsId) and (current->getFrom()) ) {
|
||||
cerr << Error( "Dijkstra::propagate(): There is a loop in the traceback path\n"
|
||||
" while routing %s."
|
||||
, getString(_net).c_str()
|
||||
) <<endl;
|
||||
break;
|
||||
}
|
||||
|
||||
_sources.insert( current );
|
||||
current->setDistance( 0.0 );
|
||||
current->setConnexId( _connectedsId );
|
||||
current = current->getPredecessor();
|
||||
|
||||
Vertex* predecessor = current->getPredecessor();
|
||||
current->setFrom( NULL );
|
||||
current = predecessor;
|
||||
}
|
||||
|
||||
cdebug.tabw(111,-1);
|
||||
|
|
|
@ -32,14 +32,14 @@ namespace Anabatic {
|
|||
, _flags(Flags::EastSide)
|
||||
, _iedge(0)
|
||||
{
|
||||
cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl;
|
||||
// cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl;
|
||||
if (_gcell->getEastEdges().empty()) progress();
|
||||
}
|
||||
|
||||
|
||||
EdgesHL* GCell_Edges::Locator::getClone () const
|
||||
{
|
||||
cdebug.log(110) << "GCell_Edges::Locator::getClone()" << endl;
|
||||
// cdebug.log(110) << "GCell_Edges::Locator::getClone()" << endl;
|
||||
return new Locator (*this);
|
||||
}
|
||||
|
||||
|
@ -60,48 +60,48 @@ namespace Anabatic {
|
|||
|
||||
void GCell_Edges::Locator::progress ()
|
||||
{
|
||||
cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl;
|
||||
cdebug.log(110) << " East:" << _gcell->getEastEdges().size()
|
||||
<< " North:" << _gcell->getNorthEdges().size()
|
||||
<< " West:" << _gcell->getWestEdges().size()
|
||||
<< " South:" << _gcell->getSouthEdges().size() << endl;
|
||||
cdebug.log(110) << this << endl;
|
||||
// cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl;
|
||||
// cdebug.log(110) << " East:" << _gcell->getEastEdges().size()
|
||||
// << " North:" << _gcell->getNorthEdges().size()
|
||||
// << " West:" << _gcell->getWestEdges().size()
|
||||
// << " South:" << _gcell->getSouthEdges().size() << endl;
|
||||
// cdebug.log(110) << this << endl;
|
||||
|
||||
++_iedge;
|
||||
while (_flags) {
|
||||
if (_flags.contains(Flags::EastSide)) {
|
||||
if (_iedge < _gcell->getEastEdges().size()) break;
|
||||
cdebug.log(110) << "Switching to North side." << endl;
|
||||
// cdebug.log(110) << "Switching to North side." << endl;
|
||||
_flags = Flags::NorthSide;
|
||||
_iedge = 0;
|
||||
cdebug.log(110) << this << endl;
|
||||
// cdebug.log(110) << this << endl;
|
||||
continue;
|
||||
}
|
||||
if (_flags.contains(Flags::NorthSide)) {
|
||||
if (_iedge < _gcell->getNorthEdges().size()) break;
|
||||
cdebug.log(110) << "Switching to West side." << endl;
|
||||
// cdebug.log(110) << "Switching to West side." << endl;
|
||||
_flags = Flags::WestSide;
|
||||
_iedge = 0;
|
||||
cdebug.log(110) << this << endl;
|
||||
// cdebug.log(110) << this << endl;
|
||||
continue;
|
||||
}
|
||||
if (_flags.contains(Flags::WestSide)) {
|
||||
if (_iedge < _gcell->getWestEdges().size()) break;
|
||||
cdebug.log(110) << "Switching to South side." << endl;
|
||||
// cdebug.log(110) << "Switching to South side." << endl;
|
||||
_flags = Flags::SouthSide;
|
||||
_iedge = 0;
|
||||
continue;
|
||||
}
|
||||
if (_flags.contains(Flags::SouthSide)) {
|
||||
if (_iedge < _gcell->getSouthEdges().size()) break;
|
||||
cdebug.log(110) << "All edges done." << endl;
|
||||
// cdebug.log(110) << "All edges done." << endl;
|
||||
_flags = 0;
|
||||
_iedge = 0;
|
||||
break;;
|
||||
}
|
||||
}
|
||||
|
||||
cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl;
|
||||
// cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Anabatic {
|
|||
|
||||
GCell::GCell ( AnabaticEngine* anabatic, DbU::Unit xmin, DbU::Unit ymin )
|
||||
: Super(anabatic->getCell())
|
||||
, _observable()
|
||||
, _anabatic (anabatic)
|
||||
, _flags (Flags::NoFlags)
|
||||
, _westEdges ()
|
||||
|
@ -43,7 +44,6 @@ namespace Anabatic {
|
|||
, _xmin (xmin)
|
||||
, _ymin (ymin)
|
||||
, _contacts ()
|
||||
, _lookup (NULL)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -418,6 +418,7 @@ namespace Anabatic {
|
|||
cerr << Error( "GCell::_revalidate(): %s, Y Min is greater than Max.", getString(this).c_str() );
|
||||
|
||||
_anabatic->_updateLookup( this );
|
||||
_anabatic->getMatrix()->show();
|
||||
cdebug.tabw(110,-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "hurricane/Cell.h"
|
||||
#include "anabatic/Matrix.h"
|
||||
#include "anabatic/GCell.h"
|
||||
|
@ -26,6 +27,8 @@ namespace Anabatic {
|
|||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::setw;
|
||||
using std::setfill;
|
||||
using std::ostringstream;
|
||||
using Hurricane::Error;
|
||||
|
||||
|
@ -46,8 +49,8 @@ namespace Anabatic {
|
|||
, _imax (0)
|
||||
, _jmax (0)
|
||||
{
|
||||
_imax = _area.getWidth () / side;
|
||||
_jmax = _area.getHeight() / side;
|
||||
_imax = _area.getWidth () / side + ((_area.getWidth () % side) ? 1 : 0);
|
||||
_jmax = _area.getHeight() / side + ((_area.getHeight() % side) ? 1 : 0);
|
||||
_gcells.resize( _imax*_jmax );
|
||||
}
|
||||
|
||||
|
@ -60,25 +63,47 @@ namespace Anabatic {
|
|||
{
|
||||
_area = cell->getAbutmentBox();
|
||||
_side = side;
|
||||
_imax = _area.getWidth () / side;
|
||||
_jmax = _area.getHeight() / side;
|
||||
_imax = _area.getWidth () / side + ((_area.getWidth () % side) ? 1 : 0);
|
||||
_jmax = _area.getHeight() / side + ((_area.getHeight() % side) ? 1 : 0);
|
||||
_gcells.resize( _imax*_jmax );
|
||||
|
||||
cdebug.log(110) << "Matrix::setCell(): " << this << endl;
|
||||
}
|
||||
|
||||
|
||||
GCell* Matrix::getUnder ( DbU::Unit x, DbU::Unit y ) const
|
||||
{ int index = xy2index(x,y); return (index < 0) ? NULL : _gcells[index]->getUnder(x,y); }
|
||||
{
|
||||
int index = xy2maxIndex(x,y);
|
||||
cdebug.log(110) << "Matrix::getUnder() ("
|
||||
<< DbU::getValueString(x) << " "
|
||||
<< DbU::getValueString(y) << " " << index << endl;
|
||||
return (index < 0) ? NULL : _gcells[index]->getUnder(x,y);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::updateLookup ( GCell* gcell )
|
||||
{
|
||||
//cdebug.log(110,1) << "Matrix::updateLookup(): " << gcell << endl;
|
||||
cdebug.log(110,1) << "Matrix::updateLookup(): " << gcell << endl;
|
||||
|
||||
if (gcell->isFlat()) return;
|
||||
if (gcell->isFlat()) {
|
||||
cdebug.log(110) << " GCell is flat, no update." << endl;
|
||||
cdebug.tabw(110,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
Box gcellBb = gcell->getBoundingBox();
|
||||
Box updateArea = _area.getIntersection( gcellBb );
|
||||
|
||||
cdebug.log(110) << "_side " << _side << endl;
|
||||
cdebug.log(110) << "_area.getXMin() " << _area.getXMin() << endl;
|
||||
cdebug.log(110) << "_area.getYMin() " << _area.getYMin() << endl;
|
||||
cdebug.log(110) << "_area.getXMax() " << _area.getXMax() << endl;
|
||||
cdebug.log(110) << "_area.getYMax() " << _area.getYMax() << endl;
|
||||
cdebug.log(110) << "updateArea.getXMin() " << updateArea.getXMin() << endl;
|
||||
cdebug.log(110) << "updateArea.getYMin() " << updateArea.getYMin() << endl;
|
||||
cdebug.log(110) << "updateArea.getXMax() " << updateArea.getXMax() << endl;
|
||||
cdebug.log(110) << "updateArea.getYMax() " << updateArea.getYMax() << endl;
|
||||
|
||||
if (updateArea.isEmpty()) {
|
||||
cerr << Error( "Matrix::updateLookup(): %s is not under area of %s."
|
||||
, getString(gcell).c_str()
|
||||
|
@ -86,12 +111,20 @@ namespace Anabatic {
|
|||
) << endl;
|
||||
}
|
||||
|
||||
Index indexMin = Index( this, updateArea.getXMin(), updateArea.getYMin() );
|
||||
Index indexMax = Index( this, updateArea.getXMax(), updateArea.getYMax() );
|
||||
Index indexMin = Index::asMin( this, updateArea.getXMin(), updateArea.getYMin() );
|
||||
Index indexMax = Index::asMax( this, updateArea.getXMax(), updateArea.getYMax() );
|
||||
int xspan = indexMax.i() - indexMin.i();
|
||||
|
||||
//cdebug.log(110) << "indexMin:" << indexMin << endl;
|
||||
//cdebug.log(110) << "indexMax:" << indexMax << endl;
|
||||
DbU::Unit dx = updateArea.getXMin() - _area.getXMin();
|
||||
DbU::Unit dy = updateArea.getYMin() - _area.getYMin();
|
||||
|
||||
cdebug.log(110) << "raw_i:" << (dx / _side + ((dx%_side) ? 1 : 0))
|
||||
<< " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl;
|
||||
cdebug.log(110) << "indexMin:" << indexMin << endl;
|
||||
cdebug.log(110) << "indexMax:" << indexMax << endl;
|
||||
cdebug.log(110) << "xspan: " << xspan << endl;
|
||||
|
||||
if (not indexMin.valid() or not indexMax.valid()) { cdebug.tabw(110,-1); return; }
|
||||
|
||||
int index = indexMin.index();
|
||||
while ( index <= indexMax.index() ) {
|
||||
|
@ -101,7 +134,18 @@ namespace Anabatic {
|
|||
else index += _imax - xspan;
|
||||
}
|
||||
|
||||
//cdebug.tabw(110,-1);
|
||||
cdebug.tabw(110,-1);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::show () const
|
||||
{
|
||||
cdebug.log(111) << this << endl;
|
||||
for ( size_t i=0 ; i<_gcells.size() ; ++i ) {
|
||||
cdebug.log(111) << "[" << setw(3) << setfill('0') << i << setfill(' ') << "] ("
|
||||
<< setw(3) << index2i(i) << ","
|
||||
<< setw(3) << index2j(i) << ") " << _gcells[i] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace Anabatic {
|
|||
virtual Configuration* getConfiguration ();
|
||||
inline CellViewer* getViewer () const;
|
||||
inline void setViewer ( CellViewer* );
|
||||
inline const Matrix* getMatrix () const;
|
||||
inline const vector<GCell*>& getGCells () const;
|
||||
inline GCell* getSouthWestGCell () const;
|
||||
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
|
@ -98,6 +99,7 @@ namespace Anabatic {
|
|||
|
||||
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
|
||||
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
|
||||
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
|
||||
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
|
||||
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
#include "hurricane/Observer.h"
|
||||
namespace Hurricane {
|
||||
class Net;
|
||||
}
|
||||
|
@ -29,6 +30,7 @@ namespace Anabatic {
|
|||
|
||||
using std::set;
|
||||
using std::multiset;
|
||||
using Hurricane::Observer;
|
||||
using Hurricane::Net;
|
||||
class AnabaticEngine;
|
||||
|
||||
|
@ -44,6 +46,8 @@ namespace Anabatic {
|
|||
};
|
||||
public:
|
||||
static float unreached;
|
||||
public:
|
||||
static void notify ( Vertex*, unsigned flags );
|
||||
public:
|
||||
inline Vertex ( GCell* );
|
||||
inline Vertex ( size_t id );
|
||||
|
@ -69,29 +73,33 @@ namespace Anabatic {
|
|||
Vertex ( const Vertex& );
|
||||
Vertex& operator= ( const Vertex& );
|
||||
private:
|
||||
size_t _id;
|
||||
GCell* _gcell;
|
||||
int _connexId;
|
||||
int _stamp;
|
||||
float _distance;
|
||||
Edge* _from;
|
||||
size_t _id;
|
||||
GCell* _gcell;
|
||||
Observer<Vertex> _observer;
|
||||
int _connexId;
|
||||
int _stamp;
|
||||
float _distance;
|
||||
Edge* _from;
|
||||
};
|
||||
|
||||
|
||||
inline Vertex::Vertex ( GCell* gcell )
|
||||
: _id (gcell->getId())
|
||||
, _gcell (gcell)
|
||||
, _observer(this)
|
||||
, _connexId(-1)
|
||||
, _stamp (-1)
|
||||
, _distance(unreached)
|
||||
, _from (NULL)
|
||||
{
|
||||
gcell->setLookup<Vertex>( this );
|
||||
//gcell->setLookup<Vertex>( this );
|
||||
gcell->setObserver( GCell::Observable::Vertex, &_observer );
|
||||
}
|
||||
|
||||
inline Vertex::Vertex ( size_t id )
|
||||
: _id (id)
|
||||
, _gcell (NULL)
|
||||
, _observer((Vertex*)0x1) // To trick the NULL detection.
|
||||
, _connexId(-1)
|
||||
, _stamp (-1)
|
||||
, _distance(unreached)
|
||||
|
@ -114,11 +122,12 @@ namespace Anabatic {
|
|||
inline void Vertex::setConnexId ( int id ) { _connexId=id; }
|
||||
|
||||
inline Vertex* Vertex::getPredecessor () const
|
||||
{ return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->lookup<Vertex>() : NULL; }
|
||||
{ return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; }
|
||||
|
||||
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs )
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
||||
|
||||
typedef set<Vertex*,Vertex::CompareById> VertexSet;
|
||||
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace Anabatic {
|
|||
, _flags(locator._flags)
|
||||
, _iedge(locator._iedge)
|
||||
{
|
||||
cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
|
||||
// cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace Anabatic {
|
|||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using Hurricane::StaticObservable;
|
||||
using Hurricane::BaseObserver;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::DbU;
|
||||
|
@ -54,6 +56,17 @@ namespace Anabatic {
|
|||
class GCell : public ExtensionGo {
|
||||
public:
|
||||
typedef ExtensionGo Super;
|
||||
public:
|
||||
class Observable : public StaticObservable<1> {
|
||||
public:
|
||||
enum Indexes { Vertex = 0
|
||||
};
|
||||
public:
|
||||
inline Observable ();
|
||||
private:
|
||||
Observable ( const StaticObservable& );
|
||||
Observable& operator= ( const StaticObservable& );
|
||||
};
|
||||
public:
|
||||
static Box getBorder ( const GCell*, const GCell* );
|
||||
public:
|
||||
|
@ -88,10 +101,6 @@ namespace Anabatic {
|
|||
GCell* vcut ( DbU::Unit x );
|
||||
bool doGrid ();
|
||||
Contact* getGContact ( Net* );
|
||||
template<typename Type>
|
||||
inline void setLookup ( Type* decorator );
|
||||
template<typename Type>
|
||||
inline Type* lookup () const;
|
||||
// Misc. functions.
|
||||
inline const Flags& flags () const;
|
||||
inline Flags& flags ();
|
||||
|
@ -102,27 +111,33 @@ namespace Anabatic {
|
|||
void _revalidate ();
|
||||
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
|
||||
public:
|
||||
// Observers.
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void notify ( unsigned int flags );
|
||||
// ExtensionGo support.
|
||||
inline const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
virtual Box getBoundingBox () const;
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual ~GCell ();
|
||||
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
GCell ( const GCell& );
|
||||
GCell& operator= ( const GCell& );
|
||||
inline const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
virtual Box getBoundingBox () const;
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual ~GCell ();
|
||||
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
GCell ( const GCell& );
|
||||
GCell& operator= ( const GCell& );
|
||||
private:
|
||||
static Name _extensionName;
|
||||
Observable _observable;
|
||||
AnabaticEngine* _anabatic;
|
||||
Flags _flags;
|
||||
vector<Edge*> _westEdges;
|
||||
|
@ -132,7 +147,6 @@ namespace Anabatic {
|
|||
DbU::Unit _xmin;
|
||||
DbU::Unit _ymin;
|
||||
vector<Contact*> _contacts;
|
||||
void* _lookup;
|
||||
};
|
||||
|
||||
|
||||
|
@ -172,11 +186,17 @@ namespace Anabatic {
|
|||
return Interval( getXMin(), getXMax() );
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
inline void GCell::setLookup ( Type* decorator ) { _lookup=reinterpret_cast<void*>(decorator); }
|
||||
inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
|
||||
{ _observable.setObserver( slot, observer ); }
|
||||
|
||||
template<typename Type>
|
||||
inline Type* GCell::lookup () const { return reinterpret_cast<Type*>( _lookup ); }
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* GCell::getObserver ( size_t slot )
|
||||
{ return _observable.getObserver<OwnerT>(slot); }
|
||||
|
||||
inline void GCell::notify ( unsigned int flags )
|
||||
{ _observable.notify( flags ); }
|
||||
|
||||
inline GCell::Observable::Observable () : StaticObservable<1>() { }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -43,11 +43,14 @@ namespace Anabatic {
|
|||
class Matrix {
|
||||
public:
|
||||
class Index {
|
||||
public:
|
||||
static inline Matrix::Index asMin ( Matrix*, DbU::Unit x, DbU::Unit y );
|
||||
static inline Matrix::Index asMax ( Matrix*, DbU::Unit x, DbU::Unit y );
|
||||
static inline Matrix::Index asMin ( Matrix*, Point position );
|
||||
static inline Matrix::Index asMax ( Matrix*, Point position );
|
||||
public:
|
||||
inline Index ( Matrix*, int index );
|
||||
inline Index ( Matrix*, int i, int j );
|
||||
inline Index ( Matrix*, DbU::Unit x, DbU::Unit y );
|
||||
inline Index ( Matrix*, Point position );
|
||||
inline Matrix* matrix () const;
|
||||
inline const int& index () const;
|
||||
inline int& index ();
|
||||
|
@ -78,8 +81,10 @@ namespace Anabatic {
|
|||
inline int index2i ( const Index& ) const;
|
||||
inline int index2j ( const Index& ) const;
|
||||
inline int ij2index ( int i, int j ) const;
|
||||
inline int xy2index ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline int xy2index ( Point ) const;
|
||||
inline int xy2minIndex ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline int xy2minIndex ( Point ) const;
|
||||
inline int xy2maxIndex ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline int xy2maxIndex ( Point ) const;
|
||||
inline Index& west ( Index& ) const;
|
||||
inline Index& east ( Index& ) const;
|
||||
inline Index& south ( Index& ) const;
|
||||
|
@ -88,6 +93,7 @@ namespace Anabatic {
|
|||
inline GCell* getUnder ( Point ) const;
|
||||
void setCell ( Cell*, DbU::Unit side );
|
||||
void updateLookup ( GCell* );
|
||||
void show () const;
|
||||
// Inspector support.
|
||||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
|
@ -127,14 +133,29 @@ namespace Anabatic {
|
|||
{
|
||||
if ((i < 0) or (i >= _imax)) return -1;
|
||||
if ((j < 0) or (j >= _jmax)) return -1;
|
||||
return j*_jmax + i;
|
||||
return j*_imax + i;
|
||||
}
|
||||
|
||||
inline int Matrix::xy2index ( DbU::Unit x, DbU::Unit y ) const
|
||||
{ return ij2index( (x - _area.getXMin()) / _side, (y - _area.getYMin()) / _side ); }
|
||||
inline int Matrix::xy2minIndex ( DbU::Unit x, DbU::Unit y ) const
|
||||
{
|
||||
DbU::Unit dx = x - _area.getXMin();
|
||||
DbU::Unit dy = y - _area.getYMin();
|
||||
return ij2index( dx / _side + ((dx%_side) ? 1 : 0)
|
||||
, dy / _side + ((dy%_side) ? 1 : 0) );
|
||||
}
|
||||
|
||||
inline int Matrix::xy2index ( Point p ) const
|
||||
{ return xy2index( p.getX(), p.getY() ); }
|
||||
inline int Matrix::xy2minIndex ( Point p ) const
|
||||
{ return xy2minIndex( p.getX(), p.getY() ); }
|
||||
|
||||
inline int Matrix::xy2maxIndex ( DbU::Unit x, DbU::Unit y ) const
|
||||
{
|
||||
DbU::Unit dx = x - _area.getXMin();
|
||||
DbU::Unit dy = y - _area.getYMin();
|
||||
return ij2index( dx / _side, dy / _side );
|
||||
}
|
||||
|
||||
inline int Matrix::xy2maxIndex ( Point p ) const
|
||||
{ return xy2maxIndex( p.getX(), p.getY() ); }
|
||||
|
||||
inline Matrix::Index& Matrix::west ( Matrix::Index& index ) const
|
||||
{
|
||||
|
@ -186,11 +207,13 @@ namespace Anabatic {
|
|||
|
||||
// Matrix::Index inline functions.
|
||||
|
||||
inline Matrix::Index::Index ( Matrix* m, int index ) : _matrix(m), _index(index) { }
|
||||
inline Matrix::Index::Index ( Matrix* m, int i, int j ) : _matrix(m), _index(m->ij2index(i,j)) { }
|
||||
inline Matrix::Index::Index ( Matrix* m, DbU::Unit x, DbU::Unit y ) : _matrix(m), _index(m->xy2index(x,y)) { }
|
||||
inline Matrix::Index::Index ( Matrix* m, Point position ) : _matrix(m), _index(m->xy2index(position)) { }
|
||||
inline Matrix::Index::Index ( Matrix* m, int index ) : _matrix(m), _index(index) { }
|
||||
inline Matrix::Index::Index ( Matrix* m, int i, int j ) : _matrix(m), _index(m->ij2index(i,j)) { }
|
||||
|
||||
inline Matrix::Index Matrix::Index::asMin ( Matrix* m, DbU::Unit x, DbU::Unit y ) { return Index( m, m->xy2minIndex(x,y) ); }
|
||||
inline Matrix::Index Matrix::Index::asMin ( Matrix* m, Point position ) { return Index( m, m->xy2minIndex(position) ); }
|
||||
inline Matrix::Index Matrix::Index::asMax ( Matrix* m, DbU::Unit x, DbU::Unit y ) { return Index( m, m->xy2maxIndex(x,y) ); }
|
||||
inline Matrix::Index Matrix::Index::asMax ( Matrix* m, Point position ) { return Index( m, m->xy2maxIndex(position) ); }
|
||||
inline Matrix* Matrix::Index::matrix () const { return _matrix; }
|
||||
inline const int& Matrix::Index::index () const { return _index; }
|
||||
inline int& Matrix::Index::index () { return _index; }
|
||||
|
|
Loading…
Reference in New Issue