// 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 // **************************************************************************************************** // File: Splitter.cpp // **************************************************************************************************** #include "hurricane/Net.h" #include "hurricane/Layer.h" #include "hurricane/BasicLayer.h" #include "hurricane/ContactLayer.h" #include "hurricane/Plug.h" #include "hurricane/Error.h" #include "hurricane/Collection.h" #include "nimbus/Fence.h" #include "nimbus/HFence.h" #include "nimbus/VFence.h" #include "nimbus/GCell.h" #include "nimbus/GCells.h" #include "nimbus/Splitter.h" #include "nimbus/SplitterContact.h" namespace Nimbus { using namespace std; using namespace Hurricane; // **************************************************************************************************** // Splitter_Hooks declaration // **************************************************************************************************** class Splitter_Hooks : public Collection { // ******************************************* // Types // ***** public: typedef Collection Inherit; public: class Locator : public Hurricane::Locator { // ***************************************************** public: typedef Hurricane::Locator Inherit; private: const Splitter* _splitter; private: Hook* _hook; public: Locator(const Splitter* splitter = NULL); public: Locator(const Locator& locator); public: Locator& operator=(const Locator& locator); public: virtual Hook* getElement() const; public: virtual Hurricane::Locator* getClone() const; public: virtual bool isValid() const; public: virtual void progress(); public: virtual string _getString() const; }; // Attributes // ********** private: const Splitter* _splitter; // Constructors // ************ public: Splitter_Hooks(const Splitter* splitter = NULL); public: Splitter_Hooks(const Splitter_Hooks& hooks); // Operators // ********* public: Splitter_Hooks& operator=(const Splitter_Hooks& hooks); // Accessors // ********* public: virtual Collection* getClone() const; public: virtual Hurricane::Locator* getLocator() const; // Others // ****** public: virtual string _getString() const; }; // **************************************************************************************************** // Splitter implementation // **************************************************************************************************** Splitter::Splitter(Net* net, Layer* layer, const SplitterOrientation direction, const DbU::Unit& x, const DbU::Unit& y, const DbU::Unit& width, const DbU::Unit& height, const DbU::Unit& halfLength) // **************************************************************************************************** : Inherit(net), _layer(layer), _direction (direction), _dx(x), _dy(y), _width(width), _height(height), _halfLength(halfLength), _c1(NULL), _c2(NULL), _fence(NULL) { if (!_layer) throw Error("Can't create " + _TName("Splitter") + " : null layer"); } Splitter* Splitter::create( Net* net, Layer* layer, const DbU::Unit& x, const DbU::Unit& y, const DbU::Unit& halfLength, const DbU::Unit& width, const DbU::Unit& height) { Splitter* splitter = new Splitter(net, layer, undefined, x, y, width, height, halfLength); splitter->_postCreate(); return splitter; } Splitter* Splitter::create( Net* net, Layer* layer, Fence* fence, GCell* gc1, GCell* gc2, const DbU::Unit& halfLength, const DbU::Unit& width, const DbU::Unit& height) { Splitter* splitter = new Splitter( net, layer, ( (dynamic_cast (fence)) ? Vertical : Horizontal ), fence->getXCenter(), fence->getYCenter(), width, height, halfLength ) ; splitter->_postCreate(); splitter->setFence(fence); //splitter->_attachTo(fence, gc1, gc2); return splitter; } // ******************************************************************** Splitter* Splitter::createHorizontal( Net* net, Layer* layer, Fence* fence, const DbU::Unit& halfLength, const DbU::Unit& width, const DbU::Unit& height) { assert (fence); Splitter* splitter = new Splitter(net, layer, Horizontal, fence->getXCenter(), fence->getY(), halfLength, width, height); splitter->_postCreate(); splitter->setFence(fence); return splitter; } Splitter* Splitter::createHorizontal( Net* net, Layer* layer, const DbU::Unit& x, const DbU::Unit& y, const DbU::Unit& halfLength, const DbU::Unit& width, const DbU::Unit& height) { Splitter* splitter = new Splitter(net, layer, Horizontal, x, y, halfLength, width, height); splitter->_postCreate(); return splitter; } // ******************************************************************** Splitter* Splitter::createVertical( Net* net, Layer* layer, Fence* fence, const DbU::Unit& halfLength, const DbU::Unit& width, const DbU::Unit& height) { assert (fence); Splitter* splitter = new Splitter(net, layer, Vertical, fence->getX(), fence->getYCenter(), halfLength, width, height); splitter->_postCreate(); splitter->setFence(fence); return splitter; } Splitter* Splitter::createVertical( Net* net, Layer* layer, const DbU::Unit& x, const DbU::Unit& y, const DbU::Unit& halfLength, const DbU::Unit& width, const DbU::Unit& height) { Splitter* splitter = new Splitter(net, layer, Vertical, x, y, halfLength, width, height); splitter->_postCreate(); return splitter; } // ******************************************************************** void Splitter::_postCreate () // **************************************************************************************************** { if (_direction == Horizontal) { _c1 = SplitterContact::create (this, _layer, -_halfLength, 0, _width, _height); // XXX FIXME _c2 = SplitterContact::create (this, _layer, _halfLength, 0, _width, _height); // XXX FIXME } else if (_direction == Vertical) { _c1 = SplitterContact::create (this, _layer, 0, _halfLength, _width, _height); // XXX FIXME _c2 = SplitterContact::create (this, _layer, 0, -_halfLength, _width, _height); // XXX FIXME } else { _c1 = SplitterContact::create (this, _layer, 0, 0, _width, _height); // XXX FIXME _c2 = SplitterContact::create (this, _layer, 0, 0, _width, _height); // XXX FIXME } Inherit::_postCreate(); /* class RoutShell -> tiens en main la largeur de segments, contacts, splitter, layer de routage etc. */ return; } void Splitter::_attachTo(Fence* fence, GCell* gc1, GCell* gc2) { _fence = fence; _c1->setGCell(gc1); _c2->setGCell(gc2); return; } void Splitter::setFence(Fence* fence) { //if (_fence) // throw Error ("Splitter is already attached to a Fence"); _fence = fence; _c1->setGCell(_fence->getGCell1()); _c2->setGCell(_fence->getGCell2()); return; } void Splitter::onDeletedFence() { this->destroy(); return; } Hook* Splitter::getHook1() const { return (_c1->getBodyHook()); } Hook* Splitter::getHook2() const { return (_c2->getBodyHook()); } Hook* Splitter::getLeftHook () const { return getHook1(); } Hook* Splitter::getBottomHook () const { return getHook2(); } Hook* Splitter::getDownHook () const { return getHook2(); } Hook* Splitter::getRightHook () const { return getHook2(); } Hook* Splitter::getUpHook () const { return getHook1(); } Hook* Splitter::getTopHook () const { return getHook1(); } Hook* Splitter::getOppositeBodyHook(const Hook* hook) const // ********************************************** { if (hook) { if (hook == _c1->getBodyHook()) return _c2->getBodyHook(); if (hook == _c2->getBodyHook()) return _c1->getBodyHook(); } return NULL; } Hooks Splitter::getHooks() const // **************************** { return Splitter_Hooks(this); } DbU::Unit Splitter::getX() const // *********************** { return _dx; } DbU::Unit Splitter::getY() const // *********************** { return _dy; } Point Splitter::getPosition() const // ******************************* { return Point(_dx, _dy); } Box Splitter::getBoundingBox() const // ******************************** { DbU::Unit size = _getSize(); return Box(getPosition()).inflate(getHalfWidth() + size, getHalfHeight() + size); } Box Splitter::getBoundingBox(const BasicLayer* basicLayer) const // ****************************************************** { if (!_layer->contains(basicLayer)) return Box(); DbU::Unit size = _getSize(basicLayer); return Box(getPosition()).inflate(getHalfWidth() + size, getHalfHeight() + size); } void Splitter::invalidate(bool propagateFlag) // ************************ { Inherit::invalidate(propagateFlag); _c1->invalidate(true); _c2->invalidate(true); return; } void Splitter::translate(const DbU::Unit& dx, const DbU::Unit& dy) // **************************************************** { if ((dx != 0) || (dy != 0)) { invalidate(true); _dx += dx; _dy += dy; } } void Splitter::setLayer(Layer* layer) // ********************************* { if (!layer) throw Error("Can't set layer : null layer"); if (layer != _layer) { invalidate(false); _layer = layer; } } void Splitter::setWidth(const DbU::Unit& width) // ************************************** { if (width != _width) { invalidate(false); _width = width; } } void Splitter::setHeight(const DbU::Unit& height) // **************************************** { if (height != _height) { invalidate(false); _height = height; } } void Splitter::setSizes(const DbU::Unit& width, const DbU::Unit& height) // ********************************************************** { if ((width != _width) || (height != _height)) { invalidate(false); _width = width; _height = height; } } void Splitter::setX(const DbU::Unit& x) // ****************************** { setPosition(x, getY()); } void Splitter::setY(const DbU::Unit& y) // ****************************** { setPosition(getX(), y); } void Splitter::setPosition(const DbU::Unit& x, const DbU::Unit& y) // **************************************************** { setOffset(x, y); } void Splitter::setPosition(const Point& position) // ********************************************* { setPosition(position.getX(), position.getY()); } void Splitter::setDx(const DbU::Unit& dx) // ******************************** { setOffset(dx, _dy); } void Splitter::setDy(const DbU::Unit& dy) // ******************************** { setOffset(_dx, dy); } void Splitter::setOffset(const DbU::Unit& dx, const DbU::Unit& dy) // **************************************************** { if ((dx != _dx) || (dy != _dy)) { invalidate(true); _dx = dx; _dy = dy; } } void Splitter::_preDestroy() // *********************** { Inherit::_preDestroy(); if (_fence) _fence->detachSplitter(this); } string Splitter::_getString() const // ******************************* { string s = Inherit::_getString(); s.insert(s.length() - 1, " " + getString(_layer->getName())); s.insert(s.length() - 1, " [" + DbU::getValueString(getX())); s.insert(s.length() - 1, " " + DbU::getValueString(getY())); s.insert(s.length() - 1, "] " + DbU::getValueString(_width)); s.insert(s.length() - 1, "x" + DbU::getValueString(_height)); return s; } Record* Splitter::_getRecord() const // ************************** { Record* record = Inherit::_getRecord(); if (record) { record->add(getSlot("Layer", _layer)); record->add(getSlot("SplitterContact 1", _c1)); record->add(getSlot("SplitterContact 2", _c2)); record->add(getSlot("Dx", &_dx)); record->add(getSlot("Dy", &_dy)); record->add(getSlot("Width", &_width)); record->add(getSlot("Height", &_height)); record->add(getSlot("Fence", _fence)); record->add(getSlot("GCell1", _c1->getGCell())); record->add(getSlot("GCell2", _c2->getGCell())); } return record; } DbU::Unit Splitter::_getSize() const // *************************** { //Layer* layer = getLayer(); //if (is_a(layer)) // size = ((CompositeLayer*)layer)->getMaximalSplitterSize(); return (_height < _width ? _width : _height); } DbU::Unit Splitter::_getSize(const BasicLayer* basicLayer) const // ************************************************* { const Layer* layer = getLayer(); if (!layer->contains(basicLayer)) return 0; //if (is_a(layer)) // size = ((CompositeLayer*)layer)->getSplitterSize(basicLayer); return _getSize(); } // void Splitter::_Draw(View* view, BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) // // **************************************************************************************************** // { // if (_width && _height) { // if (1 < view->getScreenSize(max(_width, _height))) // basicLayer->_Fill(view, transformation.getBox(getBoundingBox(basicLayer))); // } // if (basicLayer == _layer->_getSymbolicBasicLayer()) { // if (view->CutPointsAreVisible() && (3 < view->getScale())) { // Point position = getPosition(); // view->DrawPoint(transformation.getPoint(position), 3); // if (_width) { // Box box = transformation.getBox(Box(position).inflate(getHalfWidth(), 0)); // view->DrawLine(box.getXMin(), box.getYMin(), box.getXMax(), box.getYMax()); // } // if (_height) { // Box box = transformation.getBox(Box(position).inflate(0, getHalfHeight())); // view->DrawLine(box.getXMin(), box.getYMin(), box.getXMax(), box.getYMax()); // } // } // } // } // void Splitter::_Highlight(View* view, const Box& updateArea, const Transformation& transformation) // // ********************************************************************************************** // { // if (_width && _height) { // if (1 < view->getScreenSize(max(_width, _height))) { // for_each_basic_layer(basicLayer, getLayer()->getBasicLayers()) { // basicLayer->_Fill(view, transformation.getBox(getBoundingBox(basicLayer))); // end_for; // } // } // } // if (view->getScale() <= 1) // view->DrawPoint(transformation.getPoint(getPosition()), 1); // else if (view->getScale() <= 3) // { // view->DrawPoint(transformation.getPoint(getPosition()), 2); // if ( view->isTextVisible() ) // { // string text = "(" // + getString ( getValue ( getX() ) ) + "," // + getString ( getValue ( getY() ) ) + ") : Fence(" // + getString ( getValue ( _fence->getXMin() ) ) + ":" + getString ( getValue ( _fence->getXMax() ) ) + "," // + getString ( getValue ( _fence->getY() ) ) + ":" + getString ( getValue ( _fence->getYMax() ) ) + ")"; // view->DrawString ( text, // transformation.getBox ( getBoundingBox() ).getXMin(), // transformation.getBox ( getBoundingBox() ).getYMax() ); // } // } // else { // Point position = getPosition(); // view->DrawPoint(transformation.getPoint(position), 3); // if (_width) { // Box box = transformation.getBox(Box(position).inflate(getHalfWidth(), 0)); // view->DrawLine(box.getXMin(), box.getYMin(), box.getXMax(), box.getYMax()); // } // if (_height) { // Box box = transformation.getBox(Box(position).inflate(0, getHalfHeight())); // view->DrawLine(box.getXMin(), box.getYMin(), box.getXMax(), box.getYMax()); // } // if ( view->isTextVisible() ) // { // string text = "(" // + getString ( getValue ( getX() ) ) + "," // + getString ( getValue ( getY() ) ) + ") : Fence(" // + getString ( getValue ( _fence->getXMin() ) ) + ":" + getString ( getValue ( _fence->getXMax() ) ) + "," // + getString ( getValue ( _fence->getY() ) ) + ":" + getString ( getValue ( _fence->getYMax() ) ) + ")"; // view->DrawString ( text, // transformation.getBox ( getBoundingBox() ).getXMin(), // transformation.getBox ( getBoundingBox() ).getYMax() ); // } // } // view->DrawRectangle ( transformation.getBox ( getBoundingBox() ) ); // } // void Splitter::_SaveHeaderTo(OutputFile& outputFile) // // ************************************************ // { // Inherit::_SaveHeaderTo(outputFile); // outputFile << " " << outputFile.getId(getLayer()); // outputFile << " " << getValueString(getDx()); // outputFile << " " << getValueString(getDy()); // outputFile << " " << getValueString(getWidth()); // outputFile << " " << getValueString(getHeight()); // } // **************************************************************************************************** // Splitter_Hooks implementation // **************************************************************************************************** Splitter_Hooks::Splitter_Hooks(const Splitter* splitter) // ************************************************* : Inherit(), _splitter(splitter) { } Splitter_Hooks::Splitter_Hooks(const Splitter_Hooks& hooks) // ***************************************************** : Inherit(), _splitter(hooks._splitter) { } Splitter_Hooks& Splitter_Hooks::operator=(const Splitter_Hooks& hooks) // **************************************************************** { _splitter = hooks._splitter; return *this; } Collection* Splitter_Hooks::getClone() const // *********************************************** { return new Splitter_Hooks(*this); } Locator* Splitter_Hooks::getLocator() const // ********************************************** { return new Locator(_splitter); } string Splitter_Hooks::_getString() const // ************************************* { string s = "<" + _TName("Splitter::Hooks"); if (_splitter) s += " " + getString(_splitter); s += ">"; return s; } // **************************************************************************************************** // Splitter_Hooks::Locator implementation // **************************************************************************************************** Splitter_Hooks::Locator::Locator(const Splitter* splitter) // **************************************************** : Inherit(), _splitter(splitter), _hook(NULL) { if (_splitter) _hook = ((Splitter*)_splitter)->getBodyHook(); } Splitter_Hooks::Locator::Locator(const Locator& locator) // **************************************************** : Inherit(), _splitter(locator._splitter), _hook(locator._hook) { } Splitter_Hooks::Locator& Splitter_Hooks::Locator::operator=(const Locator& locator) // ****************************************************************************** { _splitter = locator._splitter; _hook = locator._hook; return *this; } Hook* Splitter_Hooks::Locator::getElement() const // ********************************************* { return _hook; } Locator* Splitter_Hooks::Locator::getClone() const // ***************************************************** { return new Locator(*this); } bool Splitter_Hooks::Locator::isValid() const // ***************************************** { return (_hook != NULL); } void Splitter_Hooks::Locator::progress() // ************************************ { if (_hook) { //if (_hook = ((Splitter*)_splitter)->getBodyHook()) //if (_hook = ((Splitter*)_splitter)->getLeftHook()) // _hook = ((Splitter*)_splitter)->getRightHook(); //else // _hook = ((Splitter*)_splitter)->getLeftHook(); //else _hook = NULL; #if 0 if (_hook == ((Splitter*)_splitter)->getBodyHook()) _hook = ((Splitter*)_splitter)->getAnchorHook(); else #endif #if 0 _hook = NULL; #endif } } string Splitter_Hooks::Locator::_getString() const // ********************************************** { string s = "<" + _TName("Splitter::Hooks::Locator"); if (_splitter) s += " " + getString(_splitter); s += ">"; return s; } }