// -*- C++ -*- namespace Katabatic { /*! \class AutoContact * * \brief Abstract base class for AutoContact * * \section secACCache Caching Mechanism * * To bypass the Ring/Hook mechanism \e and the subsequent Session::Lookup() * call, the AutoSegments anchored on an AutoContact are cached in the * AutoContact itself. They can be accessed through \c getHorizontalN() and * getVerticalN() accessors \c N depending on the subtype of AutoContact. * * Cached AutoSegments are updated in the AutoContact::updateTopology() * function only. * * * \section secACInvalidate Invalidate on AutoContacts * * The invalidation of an AutoContact invalidate all the segments * that are anchored on it. * * <b>Special Case of HTee & VTee</b> * * When invalidating an HTee or VTee, two out of the three anchored * segments are parallels. The \e aligned constraint is passed on * those two. By default, when we invalidate an AutoSegment, the * invalidation is applied to the whole aligned set through the * AutoSegment::getAligneds() collection. So if one of the parallel * is invalidated and the other not, it should only be because we * are already in \c getAligneds(), then we do not want to invalidate * again the whole aligned set. In that case, we perform an atomic only * invalidation (reset Katabatic::KbPropagate). * * For the complete invalidation/revalidation mechanism see * \ref secSessionAlgo "Session Algorithm". * * * \section secDiffFromKatabatic2 Notes - Differences from Katabatic 2 * * From the previous version of Katabatic, AutoContact have * been greatly stripped down (again). They are now always punctual * objetcs with stricly fixed topologies: * <ul> * <li>AutoContactTerminal to connect to a terminal (one segment). * <li>AutoContactTurn to make a turn: two perpandiculars segments. * <li>AutoContactHTee an horizontal tee: two \e aligned horizonals * and one vertical. * <li>AutoContactVTee an horizontal tee: two \e aligned verticals * and one horizontal. * </ul> */ //! \enum AutoContactFlag //! Set of flags to describe the internal state of an AutoContact. //! \var AutoContactFlag::CntFixed //! This contact cannot be moved. //! \var AutoContactFlag::CntTerminal //! This contact is anchored on a terminal (AutoContactTerminal), <b>must not be changed</b>. //! \var AutoContactFlag::CntTurn //! The object true class is AutoContactTurn, <b>must not be changed</b>. //! \var AutoContactFlag::CntHTee //! The object true class is AutoContactHTee, <b>must not be changed</b>. //! \var AutoContactFlag::CntVTee //! The object true class is AutoContactVTee, <b>must not be changed</b>. //! \var AutoContactFlag::CntInvalidated //! At least one AutoSegment of this contact has been moved, the contact //! position must be recomputed (in the Session revalidation). //! \var AutoContactFlag::CntInvalidatedCache //! At least one AutoSegment has been broken or moved up, the connexity //! must be checked and possibly corrected (in Session revalidation). //! \var AutoContactFlag::CntInCreationStage //! Sets only during the initial creation process. //! \var AutoContactFlag::CntBadTopology //! Something wrong has happened and the connexity of the AutoContact is //! no longer ensured (too much or too less AutoSegments, too wide span of //! AutoSegment layers). //! \function Hook* AutoContact::getBodyHook (); //! <em>Base class method proxy.</em> //! \function Hook* AutoContact::getAnchorHook (); //! <em>Base class method proxy.</em> //! \function Component* AutoContact::getAnchor () const; //! <em>Base class method proxy.</em> //! \function Net* AutoContact::getNet () const; //! <em>Base class method proxy.</em> //! \function const Layer* AutoContact::getLayer () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getX () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getY () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getDx () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getDy () const; //! <em>Base class method proxy.</em> //! \function Point AutoContact::getCenter () const; //! <em>Base class method proxy.</em> //! \function Point AutoContact::getPosition () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getWidth () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getHalfWidth () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getHeight () const; //! <em>Base class method proxy.</em> //! \function DbU::Unit AutoContact::getHalfHeight () const; //! <em>Base class method proxy.</em> //! \function Components AutoContact::getSlaveComponents () const; //! <em>Base class method proxy.</em> //! \function void AutoContact::setLayer ( const Layer* ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setWidth ( DbU::Unit ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setHeight ( DbU::Unit ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setSizes ( DbU::Unit w, DbU::Unit h ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setX ( DbU::Unit ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setY ( DbU::Unit ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setPosition ( DbU::Unit w, DbU::Unit h ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setPosition ( const Point& ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setDx ( DbU::Unit ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setDy ( DbU::Unit ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::setOffset ( DbU::Unit w, DbU::Unit h ) ; //! <em>Base class method proxy.</em> //! \function void AutoContact::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) ; //! <em>Base class method proxy.</em> //! \function bool AutoContact::isInCreationStage () const; //! \sreturn \true if the AutoContact is still in it's initial creation stage. //! \function bool AutoContact::isInvalidated () const; //! \sreturn \true if the some AutoSegment has changed and the AutoContact needs //! to be repositionned (through a call to AutoContact::updateGeometry()). //! \function bool AutoContact::isInvalidatedCache () const; //! \sreturn \true if the some AutoSegment has changed and the AutoContact //! topology needs to be restored, as a gap may have appeared //! (through a call to AutoSegment::updateTopology()). //! \function bool AutoContact::isTurn () const; //! \sreturn \true if the dynamic type of the AutoContact is of type Turn. //! \function bool AutoContact::isTee ( unsigned int direction ) const; //! \sreturn \true if the dynamic type of the AutoContact is either of type //! AutoContactHTee or AutoContactVTee, according to \c direction. //! \function bool AutoContact::isHTee () const; //! \sreturn \true if the dynamic type of the AutoContact is of type AutoContactHTee. //! \function bool AutoContact::isVTee () const; //! \sreturn \true if the dynamic type of the AutoContact is of type AutoContactHTee. //! \function bool AutoContact::isFixed () const; //! \sreturn \true if the AutoContact cannot be moved. //! \function bool AutoContact::hasBadTopology () const; //! \sreturn \true if the AutoContact topology has been broken and a gap has appeared. //! (sould not happen...) //! \function bool AutoContact::canDestroy ( unsigned int flags ) const; //! \sreturn \true if the AutoContact could be destroyed, that is, no segments //! remains anchored on it. If \c flags contains Katabatic::KbWarnOnError, //! issue an error message. //! \function bool AutoContact::canMoveUp ( const AutoSegment* moved ) const; //! \sreturn \true if \c segment can be moved up without triggering a topological //! modification. It meaans that: //! - Without \c moved, the AutoContact needs only one layer. //! - \c moved go from \e below the AutoContact to \e above. //! \function Contact* AutoContact::base () const; //! \sreturn The Hurricane::Contact which is decorated. //! \function size_t AutoContact::getAllocateds (); //! \sreturn The total number of AutoContact currently allocateds. //! \function const Name& AutoContact::getStaticName (); //! \sreturn The name of the Hurricane::ExtensionGo slice. //! \function const Name& AutoContact::getName () const; //! \sreturn The name of the Hurricane::ExtensionGo slice. //! \function const Name& AutoContact::getId () const; //! \sreturn The unique \c identifer of the AutoSegment. //! \function Box AutoContact::getBoundingBox () const; //! \see Contact::getBoundingBox(). //! \function GCell* AutoContact::getGCell () const; //! \sreturn The GCell into which the AutoContact is located. //! \function AutoSegment* AutoContact::getOpposite ( const AutoSegment* segment ) const; //! \sreturn The AutoSegment other the same direction as \c segment, this is //! only meaningful on AutoContactHTee or AutoContactVTee. It there is //! no opposite, \c NULL is returned. //! \function AutoSegment* AutoContact::getSegment ( unsigned int index ) const; //! \sreturn The nth anchored AutoSegment. The index is significant: //! - \b 0 : first horizontal (\b h1). //! - \b 1 : second horizontal (\b h2). //! - \b 2 : first vertical (\b b1). //! - \b 3 : second vertical (\b b2). //! //! Not all the indexes are filled for every AutoContact. For example //! \c Turn have \b h1 and \b b1, and \c HTee have \b h1, \b h2 and //! \b v1. //! \function unsigned int AutoContact::getMinDepth () const; //! \sreturn The layer depth of the bottom layer of the AutoContact. //! \function unsigned int AutoContact::getMaxDepth () const; //! \sreturn The layer depth of the top layer of the AutoContact. //! \function void AutoContact::getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& processeds ); //! \param lengths A table of DbU::Unit, the size of all routing layers used. //! \param processeds An AutoSegment sorted set holding all the already processeds //! AutoSegments. //! //! Compute the lengths over the owning GCell of all the AutoSegments anchored //! on this AutoContact. The lengths are added to the total length table //! \c lengths. To avoid double accounting of the local AutoSegments //! that have both source & target in the same GCell, we keep a set //! of already processeds AutoSegments in \c processeds. //! \function Box AutoContact::getNativeConstraintBox () const; //! \sreturn The native constraint box (that is, whithout any user constraints //! applied). For AutoContactTerminal, this is the Box of the supporting //! external component, and for all others the bounding box of the //! owning GCell. //! \function Interval AutoContact::getUConstraints ( unsigned int direction ) const; //! \sreturn The constraint interval in \c direction (that is, the relevant side //! of the constraint box). //! \function DbU::Unit AutoContact::getCBXMin () const; //! \sreturn The X coordinate of the bottom left corner of the constraint box. //! \function DbU::Unit AutoContact::getCBYMin () const; //! \sreturn The Y coordinate of the bottom left corner of the constraint box. //! \function DbU::Unit AutoContact::getCBXMax () const; //! \sreturn The X coordinate of the top right corner of the constraint box. //! \function DbU::Unit AutoContact::getCBYMax () const; //! \sreturn The Y coordinate of the top right corner of the constraint box. //! \function Box AutoContact::getConstraintBox () const; //! \sreturn The current constraint box: the native constraint box with all //! the user's contraints applieds. //! \function Box& AutoContact::intersectConstraintBox ( Box& box ) const; //! \sreturn The intersection between \c box and the constraint box. The //! result is stored into \c box and a reference to it is returned. //! \function void AutoContact::invalidate ( unsigned int flags=0 ); //! Invalidate the AutoContact, schedule it for revalidation in the //! Session. If flag containt Katabatic::CntInvalidTopology, //! the topology of the AutoContact will also be checked and //! possible gap closeds. //! //! The revalidations methods associated are: //! - AutoSegment::updateGeometry(), recompute the punctual contact position. //! - AutoSegment::updateTopology(), restore the connexity. //! \function void AutoContact::updateGeometry (); //! Compute the new position of the AutoContact based on the AutoSegment //! positions. The Session mechanism ensure that all AutoSegment are //! set into their final positions before calling this updator. //! \function void AutoContact::updateTopology (); //! Modificate the AutoContact topology to close any gap. This could //! be by changing layer or creating a new dogleg on an incident //! AutoSegment. //! \function void AutoContact::_getTopology ( Component*& anchor, Horizontal**& hs, Vertical**& vs, size_t sz ); //! \param anchor The anchor, if any. //! \param hs The Hurricane::Horizontal anchored. //! \param vs The Hurricane::Vertical anchored. //! \param sz The size of boths \c hs & \c vs table passed as arguments. //! //! Fill \c anchor , \c hs and \c vs with the components anchored on this //! AutoContact. //! \function void AutoContact::showTopologyError ( const std::string& message ); //! Comprensive display of the topology of the AutoContact to ease the //! debug work. Prepend with the error message \c message. Do no throw //! an error. //! \function void AutoContact::checkTopology (); //! Check for topology correctness (no gaps), display an error message //! if needed. //! \function void AutoContact::setGCell ( GCell* gcell ); //! Set the owning GCell. //! \function void AutoContact::setCBXMin ( DbU::Unit xMin ); //! Set the lower left X coordinate of the constraint box. //! //! \remark It cannot go outside the GCell bounding box. //! \function void AutoContact::setCBYMin ( DbU::Unit yMin ); //! Set the lower left Y coordinate of the constraint box. //! //! \remark It cannot go outside the GCell bounding box. //! \function void AutoContact::setCBXMax ( DbU::Unit xMax ); //! Set the upper right X coordinate of the constraint box. //! //! \remark It cannot go outside the GCell bounding box. //! \function void AutoContact::setCBYMax ( DbU::Unit yMax ); //! Set the upper right Y coordinate of the constraint box. //! //! \remark It cannot go outside the GCell bounding box. //! \function void AutoContact::setConstraintBox ( const Box& box ); //! Set the constraint box. //! //! \remark It cannot go outside the GCell bounding box. //! \function bool AutoContact::restrictConstraintBox ( DbU::Unit min, DbU::Unit max, unsigned int flags=KbWarnOnError ); //! \param min The minimum of the restriction interval. //! \param max The maximum of the restriction interval. //! \param flags Gives the direction of the restriction. //! \return \true if the restriction was actually applied. //! //! Restrict the current constraint box but check if the restriction //! will not lead to an empty interval, in that case, do nothing and //! return \false. /*! \class LocatorHelper * * \brief Locator Helper Collection's Locators * * Provide a small uniform walktough over the AutoSegments anchored * on AutoContacts. The \c flags argument allows to choose between * direction and include perpandiculars (in that case all segments * are processeds). * * * \section secLocHelperImplementation Implementation Details * * As, at most, two horizontals and two verticals may be anchored on * any AutoContact subtype, the locator helper perform a walk through * a virtual table of 4 elements. The two first are the horizontals, * the two last the verticals. The meaning of this index is consistent * whith the \c index argument of AutoContact::getSegment(). When * a segment is not present in an AutoContact, the \c getSegment() * returns \c NULL and the LocatorHelper::progress() function will * skip it. * * The private methods: * - \c LocatorHelper::_min() * - \c LocatorHelper::_max() * * Computes the bounds of \c _index according to the value of \c _flags: * - \c KbHorizontal : \c 0 to less than \c 2. * - \c KbVertical : \c 2 to less than \c 4. * - \c KbHorizontal|KbVertical : \c 0 to less than \c 4. */ //! \function LocatorHelper::LocatorHelper ( AutoContact* contact, unsigned int flags ); //! Create a helper to iterate over the AutoSegments anchored on \c contact. //! The \c flags arguments allow to select: //! - The direction: Katabatic::KbHorizontal or Katabatic::KbVertical. //! - Perpandicular inclusion: Katabatic::KbWithPerpands. //! //! When setting KbWithPerpands, all the segments will be iterated over. //! It may seems a somewhat contorted way of doing things, the reason is //! the ability to share (an pass) flags directly between different //! functions. //! \function bool LocatorHelper::isValid() const; //! \sreturn \true if there is an AutoSegment to be processed. //! \function AutoSegment* LocatorHelper::getSegment() const; //! \sreturn The current AutoSegment. \c NULL if the loop is over. //! \function void LocatorHelper::progress(); //! \sreturn Go to the next AutoSegment. }