From cfe8322b50c9ef08ffbc3e52b0849bca4cd1d0bf Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Thu, 11 May 2017 17:55:06 +0200 Subject: [PATCH 1/1] added patterns and started OP computation --- AbstractBlock.cpp | 27 +++++ AbstractBlock.h | 25 ++++- AbstractBoxItem.cpp | 26 ++--- AbstractBoxItem.h | 22 ++-- AbstractInterface.h | 14 +++ BoxItem.cpp | 45 +++----- ConnectionItem.cpp | 264 ++++++++++++++++++++++++++++++-------------- Dispatcher.cpp | 196 +++++++------------------------- Dispatcher.h | 12 +- FunctionalBlock.cpp | 211 ++++++++++++++++++++++++++++++++++- FunctionalBlock.h | 33 +++++- GroupBlock.cpp | 17 +++ GroupBlock.h | 13 ++- GroupItem.cpp | 16 +-- GroupScene.cpp | 7 ++ InterfaceItem.cpp | 2 +- Parameters.cpp | 4 +- ReferenceBlock.cpp | 4 + ReferenceBlock.h | 4 + SourceItem.cpp | 22 ++-- blast.creator.user | 8 +- 21 files changed, 639 insertions(+), 333 deletions(-) diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index 87c973c..c71b2e0 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -52,6 +52,13 @@ bool AbstractBlock::isSourceBlock() { return false; } +bool AbstractBlock::isGeneratorBlock() { + foreach(AbstractInterface* iface, inputs) { + if (iface->getPurpose() == AbstractInterface::Data) return false; + } + return true; +} + void AbstractBlock::addParameter(BlockParameter *param) { params.append(param); } @@ -137,6 +144,26 @@ QList AbstractBlock::getDataInputs() { return list; } +QList AbstractBlock::getControlInputs() { + QList list; + foreach(AbstractInterface* iface, inputs) { + if (iface->getPurpose() == AbstractInterface::Control) { + list.append(iface); + } + } + return list; +} + +QList AbstractBlock::getControlOutputs() { + QList list; + foreach(AbstractInterface* iface, outputs) { + if (iface->getPurpose() == AbstractInterface::Control) { + list.append(iface); + } + } + return list; +} + AbstractInterface* AbstractBlock::getIfaceFromName(QString name) { foreach(AbstractInterface* iface, inputs) { diff --git a/AbstractBlock.h b/AbstractBlock.h index a132bc8..c8aa023 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -18,7 +18,7 @@ using namespace Qt; class AbstractBlock { public: - + AbstractBlock(); AbstractBlock(const QString& _name); virtual ~AbstractBlock(); @@ -35,16 +35,22 @@ public: QList getPortParameters(); QList getWishboneParameters(); inline AbstractBlock* getParent() { return parent; } + inline QList getProductionCounter() { return productionCounter; } + inline int getDelta() { return delta; } + // setters void setName(const QString& str); virtual void setParent(AbstractBlock* _parent); + inline void setProductionCounter(QList pattern) { productionCounter = pattern; } + inline void setDelta(int _delta) { delta = _delta; } // testers virtual bool isReferenceBlock(); virtual bool isFunctionalBlock(); virtual bool isGroupBlock(); - virtual bool isSourceBlock(); + virtual bool isSourceBlock(); //! a source block is outside the top group and simulates a peripheral (NB: this is also a generator) virtual bool isTopGroupBlock(); + bool isGeneratorBlock(); //! a generator block has no data inputs and thus executes infinitely bool isWBConfigurable(); // others @@ -58,9 +64,14 @@ public: QList getInterfaces(); //! return all interfaces QList getDataInputs(); //! return all inputs of type data + QList getControlInputs(); //! return all inputs of type control + QList getControlOutputs(); //! return all outputs of type control AbstractInterface* getIfaceFromName(QString name); BlockParameter* getParameterFromName(QString name); + // patterns + virtual void computeOutputPattern(int nbExec = -1) = 0; + protected: @@ -73,10 +84,14 @@ protected: QList inputs; QList outputs; QList bidirs; - + // others - - // NB: only GroupBlock and FunctionalBlock have a real parent + + // patterns + QList productionCounter; //! only usefull for output interfaces + int delta; + + // NB: only GroupBlock and FunctionalBlock have a real parent, except sources that have no parents AbstractBlock* parent; }; diff --git a/AbstractBoxItem.cpp b/AbstractBoxItem.cpp index 391f795..925cd6f 100644 --- a/AbstractBoxItem.cpp +++ b/AbstractBoxItem.cpp @@ -99,7 +99,7 @@ void AbstractBoxItem::setRstClkVisible(bool b) { ifaceItem->visible = b; } } - resetInterfacesPosition(); + resetInterfaceItemsPosition(); updateGeometry(InterfaceMove); update(); getScene()->updateConnectionItemsShape(); @@ -114,7 +114,7 @@ void AbstractBoxItem::setWishboneVisible(bool b) { ifaceItem->visible = b; } } - resetInterfacesPosition(); + resetInterfaceItemsPosition(); updateGeometry(InterfaceMove); update(); getScene()->updateConnectionItemsShape(); @@ -128,7 +128,7 @@ void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) { nameHeight = fmId.height(); } -void AbstractBoxItem::initInterfaces() { +void AbstractBoxItem::initInterfaceItems() { /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */ int orientation = Parameters::West; @@ -151,7 +151,7 @@ void AbstractBoxItem::initInterfaces() { } } -InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) { +InterfaceItem* AbstractBoxItem::searchInterfaceItemByName(QString name) { foreach(InterfaceItem *inter, interfaces){ if(inter->getName() == name) return inter; @@ -159,7 +159,7 @@ InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) { return NULL; } -InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) { +InterfaceItem* AbstractBoxItem::searchInterfaceItemByRef(ConnectedInterface *ref) { foreach(InterfaceItem *inter, interfaces){ if(inter->refInter == ref) { return inter; @@ -168,16 +168,16 @@ InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) { return NULL; } -void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) { +void AbstractBoxItem::addInterfaceItem(InterfaceItem *i, bool resetPosition) { interfaces.append(i); - if (resetPosition) resetInterfacesPosition(); + if (resetPosition) resetInterfaceItemsPosition(); updateGeometry(InterfaceMove); update(); } -void AbstractBoxItem::removeInterface(InterfaceItem *i) { +void AbstractBoxItem::removeInterfaceItem(InterfaceItem *i) { // NB : removing from model is done in dispatcher - interfaces.removeOne(i); + interfaces.removeAll(i); delete i; //resetInterfacesPosition(); @@ -186,7 +186,7 @@ void AbstractBoxItem::removeInterface(InterfaceItem *i) { } -void AbstractBoxItem::resetInterfacesPosition() { +void AbstractBoxItem::resetInterfaceItemsPosition() { int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0; double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0; @@ -231,7 +231,7 @@ void AbstractBoxItem::resetInterfacesPosition() { } } -void AbstractBoxItem::moveInterfaceTo(QPointF pos) { +void AbstractBoxItem::moveInterfaceItemTo(QPointF pos) { double positionRatio; if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){ if(pos.x() < 0){ @@ -308,7 +308,7 @@ int AbstractBoxItem::nbInterfacesByOrientation(int orientation) { return nb; } -void AbstractBoxItem::updateInterfacesAndConnections() { +void AbstractBoxItem::updateInterfaceAndConnectionItems() { // update all interfaces positions foreach(InterfaceItem *item, interfaces){ @@ -330,7 +330,7 @@ void AbstractBoxItem::setDimension(int x, int y) { boxHeight = y; } -InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) { +InterfaceItem* AbstractBoxItem::getInterfaceItemFromCursor(qreal x, qreal y) { foreach(InterfaceItem* inter, interfaces) { if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){ diff --git a/AbstractBoxItem.h b/AbstractBoxItem.h index fe08535..fb2bdcc 100644 --- a/AbstractBoxItem.h +++ b/AbstractBoxItem.h @@ -14,6 +14,10 @@ class AbstractBlock; class GroupScene; class ConnectedInterface; +#define ABI_TO_BI(ptr) ((BoxItem*)ptr) +#define ABI_TO_GI(ptr) ((GroupItem*)ptr) +#define ABI_TO_SI(ptr) ((SourceItem*)ptr) + class AbstractBoxItem : public QGraphicsItem { public: @@ -61,9 +65,9 @@ public: // others QRectF boundingRectInScene(); virtual void nameChanged() = 0; // called when an interface or box name have changed - void addInterface(InterfaceItem* i, bool resetPosition = false); - void removeInterface(InterfaceItem* i); - void resetInterfacesPosition(); + void addInterfaceItem(InterfaceItem* i, bool resetPosition = false); + void removeInterfaceItem(InterfaceItem* i); + void resetInterfaceItemsPosition(); /*! * \brief moveInterfaceTo * \param pos the new position (in scene) of the interface @@ -71,7 +75,7 @@ public: * This method is called when user moves an InterfaceItem. * see BoxItem::mouseMoveEvent() and GroupItem::mouseMoveEvent() */ - void moveInterfaceTo(QPointF pos); + void moveInterfaceItemTo(QPointF pos); /*! * \brief updateInterfacesAndConnections * @@ -86,11 +90,11 @@ public: * that is called in this method. Thus, there is no need to call update() after the termination of * this method. */ - void updateInterfacesAndConnections(); + void updateInterfaceAndConnectionItems(); - InterfaceItem *searchInterfaceByName(QString name); - InterfaceItem *searchInterfaceByRef(ConnectedInterface* ref); - InterfaceItem* getInterfaceFromCursor(qreal x, qreal y); + InterfaceItem *searchInterfaceItemByName(QString name); + InterfaceItem *searchInterfaceItemByRef(ConnectedInterface* ref); + InterfaceItem* getInterfaceItemFromCursor(qreal x, qreal y); protected: Dispatcher *dispatcher; @@ -134,7 +138,7 @@ protected: virtual QRectF boundingRect() const =0; */ - void initInterfaces(); + void initInterfaceItems(); int nbInterfacesByOrientation(int orientation); }; diff --git a/AbstractInterface.h b/AbstractInterface.h index 39157a6..e26f5c5 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -49,6 +49,10 @@ public : inline AbstractInterface* getAssociatedIface() { return associatedIface; } double getDoubleWidth() throw(QException); + + inline QList getConsumptionPattern() { return consumptionPattern; } + inline QList getProductionPattern() { return productionPattern; } + inline QList getOutputPattern() { return outputPattern; } //virtual QList getConnectedTo() = 0; @@ -66,6 +70,10 @@ public : void setPurpose(int _purpose); void setDirection(int _direction); bool setAssociatedIface(AbstractInterface* iface); + + inline void setConsumptionPattern(QList pattern) { consumptionPattern = pattern; } + inline void setProductionPattern(QList pattern) { productionPattern = pattern; } + inline void setOutputPattern(QList pattern) { outputPattern = pattern; } // testers virtual bool isReferenceInterface(); @@ -106,6 +114,12 @@ protected: * (NB: a test is done in the method to prevent the other case). */ AbstractInterface* associatedIface; + + // patterns + QList consumptionPattern; //! only usefull for input interfaces + QList productionPattern; //! only usefull for output interfaces + + QList outputPattern; //! only usefull for output interfaces }; diff --git a/BoxItem.cpp b/BoxItem.cpp index 43cceec..92f89b8 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -33,9 +33,9 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, setZValue(100); setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); - initInterfaces(); + initInterfaceItems(); updateGeometry(InterfaceMove); - resetInterfacesPosition(); + resetInterfaceItemsPosition(); QPointF initPos = QPointF(0.0,0.0) - originPoint; setPos(initPos); //cout << "total size of block: " << totalWidth << "," << totalHeight << endl; @@ -173,7 +173,7 @@ bool BoxItem::updateGeometry(ChangeType type) { } } if (boxSizeChanged) { - updateInterfacesAndConnections(); + updateInterfaceAndConnectionItems(); } @@ -293,7 +293,7 @@ void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { } else if(params->editState == Parameters::EditInterfaceMove) { prepareGeometryChange(); - moveInterfaceTo(event->pos()); + moveInterfaceItemTo(event->pos()); // recompute the geometry of the block if (updateGeometry(InterfaceMove)) { //cout << "must recompute group item geometry" << endl; @@ -323,7 +323,7 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget()); if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) { - InterfaceItem *inter = getInterfaceFromCursor(x,y); + InterfaceItem *inter = getInterfaceItemFromCursor(x,y); if (inter != NULL) { if (params->editState == Parameters::EditNoOperation) { @@ -344,7 +344,7 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { else if (mode == GroupScene::ItemEdition) { //setZValue(zValue()+100); if (params->cursorState == Parameters::CursorOnInterface) { - InterfaceItem *inter = getInterfaceFromCursor(x,y); + InterfaceItem *inter = getInterfaceItemFromCursor(x,y); if (inter != NULL) { if (inter == currentInterface) { params->setEditState(Parameters::EditInterfaceDeselect); @@ -429,7 +429,7 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { int mode = getScene()->getEditionMode(); if (mode == GroupScene::AddConnection) { - InterfaceItem* iface = getInterfaceFromCursor(x,y); + InterfaceItem* iface = getInterfaceItemFromCursor(x,y); if (iface != NULL) { params->cursorState = Parameters::CursorOnInterface; setCursor(Qt::PointingHandCursor); @@ -443,7 +443,7 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { int marginE = 5; int marginS = 5; - InterfaceItem* iface = getInterfaceFromCursor(x,y); + InterfaceItem* iface = getInterfaceItemFromCursor(x,y); if (iface != NULL) { params->cursorState = Parameters::CursorOnInterface; setCursor(Qt::PointingHandCursor); @@ -497,8 +497,7 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { QAction* removeAction = NULL; QAction* duplicateAction = NULL; QAction* renameAction = NULL; - QAction* connectToGroup = NULL; - QAction* disconnectFromGroup = NULL; + QAction* connectToGroup = NULL; QAction* showProperties = NULL; QAction* cloneInterface = NULL; QAction* openWindow = NULL; @@ -506,7 +505,7 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { QAction* showWishboneIface = NULL; QAction* showParameters = NULL; - InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y()); + InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y()); // menu for interface if( ifaceItem != NULL){ @@ -522,7 +521,6 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { ConnectedInterface* ifaceGroup = NULL; bool canRemove = true; - if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) { connectToGroup = menu.addAction("Connect to group input"); } @@ -530,22 +528,14 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { connectToGroup = menu.addAction("Connect to group output"); } else if (iface->getConnectionFromParentGroup() != NULL) { - ifaceGroup = iface->getConnectionFromParentGroup(); - //if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) { - if (!ifaceGroup->isConnectedFrom()) { - disconnectFromGroup = menu.addAction("Disconnect from group"); - } - else { + ifaceGroup = iface->getConnectionFromParentGroup(); + if (ifaceGroup->isConnectedFrom()) { canRemove = false; } } else if (iface->getConnectionToParentGroup() != NULL) { - ifaceGroup = iface->getConnectionToParentGroup(); - //if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) { - if (!ifaceGroup->isConnectedTo()) { - disconnectFromGroup = menu.addAction("Disconnect from group"); - } - else { + ifaceGroup = iface->getConnectionToParentGroup(); + if (ifaceGroup->isConnectedTo()) { canRemove = false; } } @@ -622,9 +612,6 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { else if (selectedAction == connectToGroup){ dispatcher->connectInterToGroup(ifaceItem); } - else if (selectedAction == disconnectFromGroup) { - dispatcher->disconnectInterFromGroup(ifaceItem); - } else if (selectedAction == cloneInterface){ dispatcher->duplicateInterfaceItem(ifaceItem); } @@ -759,7 +746,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { } // creating InterfaceItem - initInterfaces(); + initInterfaceItems(); // setting them with saved values for(int i=0; isetId(id); interfaceItem->setOrientation(orientation); interfaceItem->setPositionRatio(position); diff --git a/ConnectionItem.cpp b/ConnectionItem.cpp index c99d489..5dcd338 100644 --- a/ConnectionItem.cpp +++ b/ConnectionItem.cpp @@ -92,7 +92,7 @@ ConnectionItem::ConnectionItem(InterfaceItem* _iface1, setAcceptHoverEvents(true); setFlag(ItemSendsGeometryChanges); setCursor(Qt::PointingHandCursor); - setZValue(0); + setZValue(200); if (fromInterfaceItem->refInter->getPurpose() == AbstractInterface::Data) { visible = true; @@ -397,8 +397,8 @@ void ConnectionItem::setPath() { } } - pps.setWidth(5); - pathShape = pps.createStroke(pathPaint); + //pps.setWidth(5); + //pathShape = pps.createStroke(pathPaint); } @@ -406,86 +406,123 @@ void ConnectionItem::computeEsse(int orientationFrom) { //cout << "drawing an esse" << endl; pathPaint = QPainterPath(pointFrom); + QPainterPath s; interPoints.clear(); - double gap = marginConn; + double gap = marginConn; + if ((orientationFrom == Parameters::North)||(orientationFrom == Parameters::West)) gap = -gap; QPointF p(0.0,0.0); if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) { + // must draw a complete esse - p = QPointF(pointFrom.x()+gap,pointFrom.y()); + p = QPointF(pointFrom.x()+gap,pointFrom.y()); + s.moveTo(p); pathPaint.lineTo(p); interPoints.append(p); p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x()-gap,(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x()-gap,pointTo.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) { // must draw a complete esse - p = QPointF(pointFrom.x(),pointFrom.y()+gap); + p = QPointF(pointFrom.x(),pointFrom.y()+gap); pathPaint.lineTo(p); + s.moveTo(p); interPoints.append(p); p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()-gap); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x(), pointTo.y()-gap); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } + pps.setWidth(5); + pathShape = pps.createStroke(s); } void ConnectionItem::computeStaircase(int orientationFrom) { pathPaint = QPainterPath(pointFrom); - interPoints.clear(); + QPainterPath s; + double gap = marginConn; + interPoints.clear(); QPointF p(0.0,0.0); if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) { + + if (orientationFrom == Parameters::West) gap = -gap; + p = QPointF(pointFrom.x()+gap,pointFrom.y()); + s.moveTo(p); + if (pointFrom.y() == pointTo.y()) { //cout << "drawing straight line" << endl; pathPaint.lineTo(pointTo); + } else { //cout << "drawing a staircase" << endl; // sufficient place to draw a simple staircase p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } + p = QPointF(pointTo.x()-gap,pointTo.y()); + s.lineTo(p); } else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) { + + if (orientationFrom == Parameters::North) gap = -gap; + + p = QPointF(pointFrom.x(),pointFrom.y()+gap); + s.moveTo(p); + if (pointFrom.x() == pointTo.x()) { //cout << "drawing straight line" << endl; - pathPaint.lineTo(pointTo); + pathPaint.lineTo(pointTo); } else { //cout << "drawing a staircase" << endl; // sufficient place to draw a simple staircase p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } + p = QPointF(pointTo.x(),pointTo.y()-gap); + s.lineTo(p); } + pps.setWidth(5); + pathShape = pps.createStroke(s); } /* drawCorner(): @@ -500,20 +537,37 @@ void ConnectionItem::computeCorner(int orientationFrom) { pathPaint = QPainterPath(pointFrom); interPoints.clear(); QPointF p(0.0,0.0); + QPainterPath s; + double gap = marginConn; + //cout << "drawing a corner" << endl; if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) { + if (orientationFrom == Parameters::West) gap = -gap; + p = QPointF(pointFrom.x()+gap,pointFrom.y()); + s.moveTo(p); p = QPointF(pointTo.x(),pointFrom.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); + p = QPointF(pointTo.x(),pointTo.y()-gap); + s.lineTo(p); } else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) { + if (orientationFrom == Parameters::North) gap = -gap; + p = QPointF(pointFrom.x(),pointFrom.y()+gap); + s.moveTo(p); p = QPointF(pointFrom.x(),pointTo.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); + p = QPointF(pointTo.x()-gap,pointTo.y()); + s.lineTo(p); } + pps.setWidth(5); + pathShape = pps.createStroke(s); } /* drawOpenRect(): @@ -522,6 +576,8 @@ void ConnectionItem::computeCorner(int orientationFrom) { __ | |_| + + Its beginning and end have always a size of marginConn */ void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) { pathPaint = QPainterPath(pointFrom); @@ -529,6 +585,7 @@ void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) { QPointF p(0.0,0.0); double gap1 = marginConn; double gap2 = marginConn; + QPainterPath s; //cout << "drawing an OpenRect" << endl; if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) { @@ -540,12 +597,15 @@ void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) { } p = QPointF(pointFrom.x()+gap1,pointFrom.y()); pathPaint.lineTo(p); + s.moveTo(p); interPoints.append(p); p = QPointF(pointFrom.x()+gap1,pointTo.y()+gap2); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x(),pointTo.y()+gap2); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); @@ -559,17 +619,23 @@ void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) { } p = QPointF(pointFrom.x(),pointFrom.y()+gap1); pathPaint.lineTo(p); + s.moveTo(p); interPoints.append(p); p = QPointF(pointTo.x()+gap2,pointFrom.y()+gap1); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x()+gap2,pointTo.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } + pps.setWidth(5); + pathShape = pps.createStroke(s); } + /* drawHookSmallEnd(): A Hook has the following shape : @@ -581,41 +647,57 @@ void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) { void ConnectionItem::computeHookSmallEnd(int orientationFrom, int orientationTo) { pathPaint = QPainterPath(pointFrom); interPoints.clear(); - QPointF p(0.0,0.0); - double gap = marginConn; + QPointF p(0.0,0.0); + QPainterPath s; + double gap2 = marginConn; + double gap1 = marginConn; //cout << "drawing a Hook with small end" << endl; if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) { - if (orientationTo == Parameters::North) gap = -gap; + if (orientationFrom == Parameters::West) gap1 = -gap1; + if (orientationTo == Parameters::North) gap2 = -gap2; + p = QPointF(pointFrom.x()+gap1,pointFrom.y()); + s.moveTo(p); p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); - p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()+gap); + p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()+gap2); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); - p = QPointF(pointTo.x(),pointTo.y()+gap); + p = QPointF(pointTo.x(),pointTo.y()+gap2); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) { - if (orientationTo == Parameters::West) gap = -gap; - + if (orientationFrom == Parameters::North) gap1 = -gap1; + if (orientationTo == Parameters::West) gap2 = -gap2; + + p = QPointF(pointFrom.x(),pointFrom.y()+gap1); + s.moveTo(p); p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); - p = QPointF(pointTo.x()+gap,(pointFrom.y()+pointTo.y())/2.0); + p = QPointF(pointTo.x()+gap2,(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); - p = QPointF(pointTo.x()+gap,pointTo.y()); + p = QPointF(pointTo.x()+gap2,pointTo.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); } + pps.setWidth(5); + pathShape = pps.createStroke(s); } /* drawHookSmallStart(): @@ -630,39 +712,55 @@ void ConnectionItem::computeHookSmallStart(int orientationFrom, int orientationT pathPaint = QPainterPath(pointFrom); interPoints.clear(); QPointF p(0.0,0.0); - double gap = marginConn; + QPainterPath s; + double gap1 = marginConn; + double gap2 = marginConn; //cout << "drawing a Hook with small start" << endl; if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) { - if (orientationFrom == Parameters::West) gap = -gap; + if (orientationFrom == Parameters::West) gap1 = -gap1; + if (orientationTo == Parameters::North) gap2 = -gap2; - p = QPointF(pointFrom.x()+gap,pointFrom.y()); + p = QPointF(pointFrom.x()+gap1,pointFrom.y()); + s.moveTo(p); pathPaint.lineTo(p); interPoints.append(p); - p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0); + p = QPointF(pointFrom.x()+gap1,(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); + p = QPointF(pointTo.x(),pointFrom.y()+gap2); + s.lineTo(p); } else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) { - if (orientationFrom == Parameters::North) gap = -gap; + if (orientationFrom == Parameters::North) gap1 = -gap1; + if (orientationTo == Parameters::West) gap2 = -gap2; - p = QPointF(pointFrom.x(),pointFrom.y()+gap); + p = QPointF(pointFrom.x(),pointFrom.y()+gap1); + s.moveTo(p); pathPaint.lineTo(p); interPoints.append(p); - p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap); + p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap1); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()); pathPaint.lineTo(p); + s.lineTo(p); interPoints.append(p); pathPaint.lineTo(pointTo); + p = QPointF(pointTo.x()+gap2,pointFrom.y()); + s.lineTo(p); } + pps.setWidth(5); + pathShape = pps.createStroke(s); } /* drawElle(): @@ -677,78 +775,84 @@ void ConnectionItem::computeElle(int orientationFrom) { pathPaint = QPainterPath(pointFrom); interPoints.clear(); QPointF p(0.0,0.0); + QPainterPath s; + double gap = marginConn; + double x; double y; - switch(orientationFrom){ - case Parameters::North : - if(pointFrom.y() < pointTo.y()) { - y = pointFrom.y()-marginConn; - } - else { - y = pointTo.y()-marginConn; - } - p = QPointF(pointFrom.x(),y); - pathPaint.lineTo(p); - interPoints.append(p); - p = QPointF(pointTo.x(),y); - pathPaint.lineTo(p); - interPoints.append(p); - pathPaint.lineTo(pointTo); - break; - case Parameters::South : - if(pointFrom.y() > pointTo.y()) { - y = pointFrom.y()+marginConn; - } - else { - y = pointTo.y()+marginConn; + if ((orientationFrom == Parameters::North) || (orientationFrom == Parameters::South)) { + double diffPos = pointFrom.y() - pointTo.y(); + if (orientationFrom == Parameters::North) { + gap = -gap; + diffPos = -diffPos; } - p = QPointF(pointFrom.x(),y); - pathPaint.lineTo(p); - interPoints.append(p); - p = QPointF(pointTo.x(),y); - pathPaint.lineTo(p); - interPoints.append(p); - pathPaint.lineTo(pointTo); - break; - case Parameters::West : - if(pointFrom.x() < pointTo.x()) { - x = pointFrom.x()-marginConn; + p = QPointF(pointFrom.x(),pointFrom.y()+gap); + s.moveTo(p); + if (diffPos >= 0.0) { + pathPaint.lineTo(p); + interPoints.append(p); + p = QPointF(pointTo.x(),pointFrom.y()+gap); + pathPaint.lineTo(p); + s.lineTo(p); + interPoints.append(p); + pathPaint.lineTo(pointTo); + p = QPointF(pointTo.x(),pointTo.y()+gap); + s.lineTo(p); } else { - x = pointTo.x()-marginConn; + p = QPointF(pointFrom.x(),pointTo.y()+gap); + pathPaint.lineTo(p); + s.lineTo(p); + interPoints.append(p); + p = QPointF(pointTo.x(),pointTo.y()+gap); + pathPaint.lineTo(p); + s.lineTo(p); + interPoints.append(p); + pathPaint.lineTo(pointTo); + } + } + else if ((orientationFrom == Parameters::West) || (orientationFrom == Parameters::East)) { + double diffPos = pointFrom.x() - pointTo.x(); + if (orientationFrom == Parameters::West) { + gap = -gap; + diffPos = -diffPos; } - p = QPointF(x, pointFrom.y()); - pathPaint.lineTo(p); - interPoints.append(p); - p = QPointF(x, pointTo.y()); - pathPaint.lineTo(p); - interPoints.append(p); - pathPaint.lineTo(pointTo); - break; - case Parameters::East : - if(pointFrom.x() > pointTo.x()) { - x = pointFrom.x()+marginConn; + p = QPointF(pointFrom.x()+gap,pointFrom.y()); + s.moveTo(p); + if (diffPos >= 0.0) { + pathPaint.lineTo(p); + interPoints.append(p); + p = QPointF(pointTo.x()+gap,pointFrom.y()); + pathPaint.lineTo(p); + s.lineTo(p); + interPoints.append(p); + pathPaint.lineTo(pointTo); + p = QPointF(pointTo.x()+gap,pointTo.y()); + s.lineTo(p); } else { - x = pointTo.x()+marginConn; + p = QPointF(pointFrom.x()+gap,pointTo.y()); + pathPaint.lineTo(p); + s.lineTo(p); + interPoints.append(p); + p = QPointF(pointTo.x()+gap,pointTo.y()); + pathPaint.lineTo(p); + s.lineTo(p); + interPoints.append(p); + pathPaint.lineTo(pointTo); } - p = QPointF(x, pointFrom.y()); - pathPaint.lineTo(p); - interPoints.append(p); - p = QPointF(x, pointTo.y()); - pathPaint.lineTo(p); - interPoints.append(p); - pathPaint.lineTo(pointTo); - break; } + + pps.setWidth(5); + pathShape = pps.createStroke(s); } void ConnectionItem::setSelected(bool selected) { this->selected = selected; if(selected){ - setZValue(50); + setZValue(201); } else { - setZValue(0); + setZValue(200); } } diff --git a/Dispatcher.cpp b/Dispatcher.cpp index 238c7e5..9035183 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -419,7 +419,7 @@ void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) { refB->addInterface(cloneIface); InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params); - item->getOwner()->addInterface(cloneIfaceItem,true); + item->getOwner()->addInterfaceItem(cloneIfaceItem,true); // creating control interface if needed if (refI->getAssociatedIface() != NULL) { @@ -442,7 +442,7 @@ void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) { GroupScene *scene = getSceneById(idScene); ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock); // if block has no inputs, propose to add it as a source to top scene - if ((scene->isTopScene()) && (ref->getDataInputs().isEmpty())) { + if ((scene->isTopScene()) && (ref->isGeneratorBlock())) { int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a source for the top scene. Do you want to add it as a source ?"); if (ret == QMessageBox::Yes) { newSource = true; @@ -889,42 +889,32 @@ void Dispatcher::removeSourceItem(SourceItem *item) { } -void Dispatcher::removeConnection(ConnectionItem *conn) { +void Dispatcher::removeConnection(ConnectionItem *connItem) { static QString fctName = "Dispatcher::removeConnection()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif - InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem(); - InterfaceItem* toIfaceItem = conn->getToInterfaceItem(); + InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem(); + InterfaceItem* toIfaceItem = connItem->getToInterfaceItem(); #ifdef DEBUG cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl; #endif - InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem - GroupItem* groupItem = NULL; + InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not + GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem ConnectedInterface *fromInter = fromIfaceItem->refInter; - ConnectedInterface *toInter = toIfaceItem->refInter; - // process the special case source->group apart - if (fromIfaceItem->getOwner()->isSourceItem()) { - // remove from graph - fromInter->disconnectTo(toInter); - // remove from scene - fromIfaceItem->removeConnectionItem(conn); - toIfaceItem->removeConnectionItem(conn); - groupItem->getScene()->removeConnectionItem(conn); - return; - } - + ConnectedInterface *toInter = toIfaceItem->refInter; + // test if one of the interface bounded to item is owned by a GroupItem if (fromIfaceItem->getOwner()->isGroupItem()) { - groupIfaceItem = fromIfaceItem; - groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem(); + groupItem = ABI_TO_GI(fromIfaceItem->getOwner()); + groupIfaceItem = fromIfaceItem; } else if (toIfaceItem->getOwner()->isGroupItem()) { - groupIfaceItem = toIfaceItem; - groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem(); + groupItem = ABI_TO_GI(toIfaceItem->getOwner()); + groupIfaceItem = toIfaceItem; } else { groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem(); @@ -943,29 +933,35 @@ void Dispatcher::removeConnection(ConnectionItem *conn) { // removing the connection from scene #ifdef DEBUG cout << "removing connections from scene ..." ; -#endif - fromIfaceItem->removeConnectionItem(conn); - toIfaceItem->removeConnectionItem(conn); - groupItem->getScene()->removeConnectionItem(conn); +#endif + groupItem->getScene()->removeConnectionItem(connItem); #ifdef DEBUG cout << "done." << endl ; #endif - + + // if one of the interface bounded to connItem is owned by the GroupItem of the scene if (groupIfaceItem != NULL) { + // determine if the interface must be removed since it has no more connections. bool groupInterRemove = false; - if ((groupIfaceItem->nter->isConnectedTo() == false) && (groupInter->isConnectedFrom() == false)) groupInterRemove = true; + if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true; - ConnectedInterface* groupInter = groupIfaceItem->refInter; - groupItem->removeInterface(groupIfaceItem); - - BoxItem* parent2Item = groupItem->getParentItem(); - if (parent2Item != NULL) { - InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter); - parent2Item->removeInterface(group2IfaceItem); + if (groupInterRemove) { + // get the GroupInterface from interface item + ConnectedInterface* groupInter = groupIfaceItem->refInter; + // remove interface from GroupItem, and delete it. + groupItem->removeInterfaceItem(groupIfaceItem); + // get the parent BoxItem of GroupItem if it exists. + BoxItem* parent2Item = groupItem->getParentItem(); + if (parent2Item != NULL) { + InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter); + // remove interface intem in parent BoxItem + parent2Item->removeInterfaceItem(group2IfaceItem); + } + // remove GroupInterface in the graph. + groupInter->getOwner()->removeInterface(groupInter); } - groupInter->getOwner()->removeInterface(groupInter); } } @@ -975,8 +971,7 @@ void Dispatcher::showBlocksLibrary(){ mainWindow->getLibrary()->raise(); } -void Dispatcher::showProperties(InterfaceItem *inter) -{ +void Dispatcher::showProperties(InterfaceItem *inter) { new InterfacePropertiesWindow(inter); } @@ -1004,7 +999,7 @@ void Dispatcher::connectInterToGroup(InterfaceItem *item){ parentItem->getRefBlock()->addInterface(groupCtlInter); // creating/adding the group interface in the current scene model, and connection item InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params); - parentItem->addInterface(groupIfaceItem,true); + parentItem->addInterfaceItem(groupIfaceItem,true); // creating the connection, in graph and with an item createConnection(item, groupIfaceItem); @@ -1013,120 +1008,15 @@ void Dispatcher::connectInterToGroup(InterfaceItem *item){ BoxItem* parent2Item = parentItem->getParentItem(); if(parent2Item != NULL){ InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params); - parent2Item->addInterface(blockIfaceItem,true); + parent2Item->addInterfaceItem(blockIfaceItem,true); } parentItem->getScene()->updateConnectionItemsShape(); unselectAllItems(); params->unsaveModif = true; - - } -void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) { - static QString fctName = "Dispatcher::disconnectInterFromGroup()"; -#ifdef DEBUG_FCTNAME - cout << "call to " << qPrintable(fctName) << endl; -#endif - - // getting the GroupBlock and GroupItem that are parent of the block that owns item - ConnectedInterface *refInter = item->refInter; - ConnectedInterface *groupInter = NULL; - GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent()); - GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem(); - - // removing the connection from graph -#ifdef DEBUG - cout << "removing connections from graph ..." ; -#endif - - if (refInter->getDirection() == AbstractInterface::Output) { - groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to - refInter->removeConnectedTo(groupInter); - groupInter->clearConnectedFrom(); - } - else if (refInter->getDirection() == AbstractInterface::Input) { - groupInter = refInter->getConnectedFrom(); - refInter->clearConnectedFrom(); - groupInter->removeConnectedTo(refInter); - } - else if (refInter->getDirection() == AbstractInterface::InOut) { - groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to - refInter->clearConnectedTo(); - refInter->clearConnectedFrom(); - groupInter->clearConnectedTo(); - groupInter->clearConnectedFrom(); - } -#ifdef DEBUG - cout << "done." << endl ; -#endif - - if (groupInter == NULL) { - cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl; - } - -#ifdef DEBUG - cout << "getting group interface item, and connection item ..." ; -#endif - - - InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter); - if (groupIfaceItem == NULL) { - cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl; - } - ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem); - if (conn == NULL) { - cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl; - } -#ifdef DEBUG - cout << "done." << endl ; -#endif - - // removing the interface group item from the group item, and the connection item -#ifdef DEBUG - cout << "removing group interface item, and connection item ..." ; -#endif - - bool groupInterRemove = false; - if ((groupInter->isConnectedTo() == false) && (groupInter->isConnectedFrom() == false)) groupInterRemove = true; - - item->removeConnectionItem(conn); - groupIfaceItem->removeConnectionItem(conn); - if (groupInterRemove) { - parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item. - } - parentItem->getScene()->removeConnectionItem(conn); -#ifdef DEBUG - cout << "done." << endl ; -#endif - - if (groupInterRemove) { - // removing the interface box item in the parent scene -#ifdef DEBUG - cout << "removing the inteeface item of box item in parent scene if needed ..." ; -#endif - - BoxItem* parent2Item = parentItem->getParentItem(); - if (parent2Item != NULL) { - InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter); - parent2Item->removeInterface(group2IfaceItem); - } -#ifdef DEBUG - cout << "done." << endl ; -#endif - - // removing the interface group from the group -#ifdef DEBUG - cout << "removing group interface ..." ; -#endif - parentGroup->removeInterface(groupInter); -#ifdef DEBUG - cout << "done." << endl ; -#endif - } - -} void Dispatcher::removeFunctionalInterface(InterfaceItem *item) { static QString fctName = "Dispatcher::removeBlockInterface()"; #ifdef DEBUG_FCTNAME @@ -1145,7 +1035,7 @@ void Dispatcher::removeFunctionalInterface(InterfaceItem *item) { } ConnectedInterface* ref = item->refInter; - item->getOwner()->removeInterface(item); + item->getOwner()->removeInterfaceItem(item); FunctionalBlock* fun = AB_TO_FUN(ref->getOwner()); fun->removeInterface(ref); } @@ -1156,15 +1046,11 @@ void Dispatcher::removeGroupInterface(InterfaceItem *item) { cout << "call to " << qPrintable(fctName) << endl; #endif - /* NB: there is a single connection between item and another one that is owned - by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup(); + /* NB: just remove all connections from/to this item, since when there are no more + ones to a GroupItem, it is automatically deleted. */ - ConnectionItem* conn = item->connections.at(0); - if (conn->getFromInterfaceItem() == item) { - disconnectInterFromGroup(conn->getToInterfaceItem()); - } - else { - disconnectInterFromGroup(conn->getFromInterfaceItem()); + foreach(ConnectionItem* conn, item->connections) { + removeConnection(conn); } } diff --git a/Dispatcher.h b/Dispatcher.h index 95e0183..3181137 100644 --- a/Dispatcher.h +++ b/Dispatcher.h @@ -90,17 +90,7 @@ public slots: * connect to group in the contextual menu. * Thus, parameter item is always owned by a BoxItem */ - void connectInterToGroup(InterfaceItem* item); - /*! - * \brief disconnectInterFromGroup - * \param item item is always owned by a BoxItem - * - * This method is called only when the user right clicks on an InterfaceItem (that belongs - * to a BoxItem and if it IS connected to an InterfaceItem of the GroupItem) and chooses - * disconnect from group in the contextual menu. - * Thus, parameter item is always owned by a BoxItem - */ - void disconnectInterFromGroup(InterfaceItem* item); + void connectInterToGroup(InterfaceItem* item); /*! * \brief removeFunctionalInterface * \param item item is always owned by a BoxItem diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 51bebe8..93e8377 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -13,6 +13,12 @@ FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference reference = _reference; parent = _parent; name = reference->getName(); + consumptionPattern = NULL; + lengthCP = 0; + nbConsumingPorts = 0; + productionPattern = NULL; + lengthPP = 0; + nbProducingPorts = 0; } @@ -96,7 +102,208 @@ QString FunctionalBlock::getReferenceXmlFile() { return ((ReferenceBlock *)reference)->getXmlFile(); } -QString FunctionalBlock::getReferenceHashMd5() -{ +QString FunctionalBlock::getReferenceHashMd5() { return ((ReferenceBlock *)reference)->getHashMd5(); } + +void FunctionalBlock::computeOutputPattern(int nbExec) { + + /* case 1: the block is a generator for which output pattern + must be computed for a nbExec following executions + */ + + if (nbExec > 0) { + foreach(AbstractInterface* iface, getControlOutputs()) { + QList pattern; + for(int i=0;igetProductionPattern(); + iface->setOutputPattern(pattern); + } + } + else { + // initialize consumption and production patterns + initConsumptionPattern(); + initProductionPattern(); + + // collect the input patterns for each input + char** inputPattern = NULL; + int idIface = 0; + inputPattern = new char*[nbConsumingPorts]; + int minLen = -1; + foreach(AbstractInterface* iface, getControlInputs()) { + QList in = iface->getConnectedFrom()->getOutputPattern(); + if (minLen == -1) { + minLen = in.size(); + } + else { + if (in.size() < minLen) minLen = in.size(); + } + inputPattern[idIface] = new char[in.size()]; + int i = 0; + foreach(char c, in) inputPattern[idIface][i++] = c; + idIface += 1; + } + // initialize the output pattern + char** outputPattern = NULL; + outputPattern = new char*[nbProducingPorts]; + int lengthOP = 0; + idIface = 0; + foreach(AbstractInterface* iface, getControlOutputs()) { + lengthOP = minLen+iface->getProductionPattern().size(); + outputPattern[idIface] = new char[lengthOP]; + memset(outputPattern[idIface],0,lengthOP); + idIface += 1; + } + + int clock = 0; + nbExec = 0; + // search for the beginning of the first execution. + while (! isValidDataGroup(inputPattern,nbConsumingPorts,clock)) clock++; + + while (clock < minLen) { + // initialize counters for current execution. + int p = 0; // index in production pattern + int o = 0; // clock+o will give the clock cycle of each output group + int cip = 0; // clock+cip give the clock cycle of an input group + int ccp = 0; // ccp give a column in the consumptio pattern + int nip = 0; // number of input data groups already consumed during the current execution, used while exploring IP + int ncp = 0; // number of input data groups already consumed during the current execution, used while exploring CP + bool cannotCompleteExec = false; + for(int m=0;m pattern; + for(int i=0;isetOutputPattern(pattern); + idIface += 1; + } + + // clear inputPattern and outputPattern + for(int i=0;i in = iface->getConsumptionPattern(); + lengthCP = in.size(); // normally, all inputs have the same lenght for CP + consumptionPattern[idIface] = new char[lengthCP]; + int i = 0; + foreach(char c, in) consumptionPattern[idIface][i++] = c; + idIface += 1; + } +} + +void FunctionalBlock::initProductionPattern() { + if (productionPattern != NULL) clearProductionPattern(); + + nbProducingPorts = getControlOutputs().size(); + int idIface = 0; + productionPattern = new char*[nbProducingPorts]; + foreach(AbstractInterface* iface, getControlOutputs()) { + + QList in = iface->getProductionPattern(); + lengthPP = in.size(); // normally, all inputs have the same lenght for PP + productionPattern[idIface] = new char[lengthPP]; + int i = 0; + foreach(char c, in) productionPattern[idIface][i++] = c; + idIface += 1; + } +} diff --git a/FunctionalBlock.h b/FunctionalBlock.h index c122dcf..9852eb7 100644 --- a/FunctionalBlock.h +++ b/FunctionalBlock.h @@ -32,7 +32,7 @@ public: // testers bool isFunctionalBlock(); - bool isSourceBlock(); //! a source block has no parent + bool isSourceBlock(); //! a source block has no parent and has no data inputs // others @@ -41,8 +41,37 @@ public: QString getReferenceXmlFile(); QString getReferenceHashMd5(); - + + // patterns + void initConsumptionPattern(); // initialize a char** from patterns defined for each interface + void initProductionPattern(); // initialize a char** from patterns defined for each interface + void clearConsumptionPattern(); + void clearProductionPattern(); + private: + // patterns + void computeOutputPattern(int nbExec = -1); + bool isValidDataGroup(char** pattern, int nbPorts, int clock); + /*! + * \brief combinePatterns + * \param patternSrc the pattern that must be combined with patternDest (patternDest = patternDest OR patternSrc) + * \param srcCol the column index within patternSrc + * \param patternDest the pattern that is modified by the combination (patternDest = patternDest OR patternSrc) + * \param destClock the column index within patternDest + * \param nbCols the numer of columns to combine + * \param nbPorts the number of rows in both patterns + * BEWARE: no check is done if nbCols is consistent with the real length of both patterns, thus an access outside + * the patterns is possible. + */ + void combinePatterns(char** patternSrc, int srcCol, char** patternDest, int destCol, int nbCols, int nbPorts ); + + char** consumptionPattern; + int nbConsumingPorts; + int lengthCP; + char** productionPattern; + int nbProducingPorts; + int lengthPP; + ReferenceBlock* reference; }; diff --git a/GroupBlock.cpp b/GroupBlock.cpp index 7995e62..716cea6 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -103,3 +103,20 @@ void GroupBlock::removeGenericParameter(QString name) { BlockParameter* p = getParameterFromName(name); if (p != NULL) params.removeAll(p); } + +void GroupBlock::initInputPattern() { + foreach(AbstractInterface* iface, getControlInputs()) { + iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern()); + } +} + +void GroupBlock::computeOutputPattern(int nbExec) { + + // get the input pattern on each inputs + initInputPattern(); + // find blocks that are connected to that inputs + + foreach(AbstractInterface* iface, getControlOutputs()) { + iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern()); + } +} diff --git a/GroupBlock.h b/GroupBlock.h index 0e1c894..0aeb006 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -42,7 +42,18 @@ public: // public attributes static int counter; -private: + +private: + // patterns + /*! + * \brief initInputPattern + * Since input GroupInterface are just tunnels to input interfaces of inner blocks, they must + * have an output pattern that can be provided to inner interfaces. That outpu pattern is just + * found by taking the output pattern of the connectedFrom interface. + */ + void initInputPattern(); + void computeOutputPattern(int nbExec = -1); + bool topGroup; QList blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group diff --git a/GroupItem.cpp b/GroupItem.cpp index 27f539c..38d70eb 100644 --- a/GroupItem.cpp +++ b/GroupItem.cpp @@ -212,7 +212,7 @@ bool GroupItem::updateGeometry(ChangeType type) { } if (boxSizeChanged) { - updateInterfacesAndConnections(); + updateInterfaceAndConnectionItems(); } @@ -359,7 +359,7 @@ void GroupItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { } else if(params->editState == Parameters::EditInterfaceMove) { prepareGeometryChange(); - moveInterfaceTo(event->pos()); + moveInterfaceItemTo(event->pos()); // recompute the geometry of the block updateGeometry(InterfaceMove); // update connection from/to the selected interface @@ -387,7 +387,7 @@ void GroupItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget()); if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) { - InterfaceItem *inter = getInterfaceFromCursor(x,y); + InterfaceItem *inter = getInterfaceItemFromCursor(x,y); if (inter != NULL) { if (params->editState == Parameters::EditNoOperation) { @@ -408,7 +408,7 @@ void GroupItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { else if (mode == GroupScene::ItemEdition) { if (params->cursorState == Parameters::CursorOnInterface) { - InterfaceItem *inter = getInterfaceFromCursor(x,y); + InterfaceItem *inter = getInterfaceItemFromCursor(x,y); if (inter != NULL) { currentInterface = inter; params->setEditState(Parameters::EditInterfaceMove); @@ -481,7 +481,7 @@ void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { int mode = getScene()->getEditionMode(); if (mode == GroupScene::AddConnection) { - InterfaceItem* iface = getInterfaceFromCursor(x,y); + InterfaceItem* iface = getInterfaceItemFromCursor(x,y); if (iface != NULL) { params->cursorState = Parameters::CursorOnInterface; setCursor(Qt::PointingHandCursor); @@ -495,7 +495,7 @@ void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { int marginE = 5; int marginS = 5; - InterfaceItem* iface = getInterfaceFromCursor(x,y); + InterfaceItem* iface = getInterfaceItemFromCursor(x,y); if (iface != NULL) { params->cursorState = Parameters::CursorOnInterface; setCursor(Qt::PointingHandCursor); @@ -549,7 +549,7 @@ void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QAction* renameAction = NULL; QAction* showParameters = NULL; - InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y()); + InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y()); // menu for interface if( ifaceItem != NULL) { @@ -668,7 +668,7 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) { interfaceItem->setId(id); groupBlock->addInterface(groupInterface); - addInterface(interfaceItem, false); + addInterfaceItem(interfaceItem, false); cout << "interface add to " << groupBlock->getName().toStdString() << endl; } diff --git a/GroupScene.cpp b/GroupScene.cpp index 531f62b..7fddacd 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -166,6 +166,13 @@ void GroupScene::addConnectionItem(ConnectionItem* item) { } void GroupScene::removeConnectionItem(ConnectionItem* item) { + + // remove connection from/to InterfaceItem + InterfaceItem* fromIfaceItem = item->getFromInterfaceItem(); + InterfaceItem* toIfaceItem = item->getToInterfaceItem(); + fromIfaceItem->removeConnectionItem(item); + toIfaceItem->removeConnectionItem(item); + // remove item from the viewport removeItem(item); // remove item from the QList diff --git a/InterfaceItem.cpp b/InterfaceItem.cpp index ff5f5c6..10158d7 100644 --- a/InterfaceItem.cpp +++ b/InterfaceItem.cpp @@ -257,7 +257,7 @@ void InterfaceItem::addConnectionItem(ConnectionItem* item) { } void InterfaceItem::removeConnectionItem(ConnectionItem* item) { - connections.removeOne(item); + connections.removeAll(item); } QDataStream &operator <<(QDataStream &out, InterfaceItem *i) { diff --git a/Parameters.cpp b/Parameters.cpp index 848ef7f..c12fead 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -342,10 +342,10 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { double position = currentInterfaceNode.attribute("position","none").toDouble(&ok); if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); - ConnectedInterface *refInter = insideGroup->searchInterfaceByName(refName)->refInter; + ConnectedInterface *refInter = insideGroup->searchInterfaceItemByName(refName)->refInter; InterfaceItem *ifaceItem = new InterfaceItem(position, orientation, refInter, upperItem, this); ifaceItem->setId(id); - upperItem->addInterface(ifaceItem); + upperItem->addInterfaceItem(ifaceItem); } } } diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index f8a99ca..ae7f0ce 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -566,3 +566,7 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { return in; } + +void ReferenceBlock::computeOutputPattern(int nbExec) { + // does strictly nothing +} diff --git a/ReferenceBlock.h b/ReferenceBlock.h index ebd46c9..2e34984 100644 --- a/ReferenceBlock.h +++ b/ReferenceBlock.h @@ -65,6 +65,10 @@ private: // AbstractBlock interface public: void parametersValidation(QList* checkedBlocks, QList* blocksToConfigure); + +private: + // patterns + void computeOutputPattern(int nbExec = -1); }; #endif // __REFERENCEBLOCK_H__ diff --git a/SourceItem.cpp b/SourceItem.cpp index 62f601a..27db2a3 100644 --- a/SourceItem.cpp +++ b/SourceItem.cpp @@ -30,9 +30,9 @@ SourceItem::SourceItem(AbstractBlock *_refBlock, setZValue(100); setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); - initInterfaces(); + initInterfaceItems(); updateGeometry(InterfaceMove); - resetInterfacesPosition(); + resetInterfaceItemsPosition(); QPointF initPos = QPointF(0.0,0.0) - originPoint; setPos(initPos); //cout << "total size of block: " << totalWidth << "," << totalHeight << endl; @@ -177,7 +177,7 @@ bool SourceItem::updateGeometry(ChangeType type) { } } if (boxSizeChanged) { - updateInterfacesAndConnections(); + updateInterfaceAndConnectionItems(); } @@ -288,7 +288,7 @@ void SourceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { } else if(params->editState == Parameters::EditInterfaceMove) { prepareGeometryChange(); - moveInterfaceTo(event->pos()); + moveInterfaceItemTo(event->pos()); // recompute the geometry of the block if (updateGeometry(InterfaceMove)) { //cout << "must recompute group item geometry" << endl; @@ -318,7 +318,7 @@ void SourceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget()); if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) { - InterfaceItem *inter = getInterfaceFromCursor(x,y); + InterfaceItem *inter = getInterfaceItemFromCursor(x,y); if (inter != NULL) { if (params->editState == Parameters::EditNoOperation) { @@ -339,7 +339,7 @@ void SourceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { else if (mode == GroupScene::ItemEdition) { //setZValue(zValue()+100); if (params->cursorState == Parameters::CursorOnInterface) { - InterfaceItem *inter = getInterfaceFromCursor(x,y); + InterfaceItem *inter = getInterfaceItemFromCursor(x,y); if (inter != NULL) { if (inter == currentInterface) { params->setEditState(Parameters::EditInterfaceDeselect); @@ -424,7 +424,7 @@ void SourceItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { int mode = getScene()->getEditionMode(); if (mode == GroupScene::AddConnection) { - InterfaceItem* iface = getInterfaceFromCursor(x,y); + InterfaceItem* iface = getInterfaceItemFromCursor(x,y); if (iface != NULL) { params->cursorState = Parameters::CursorOnInterface; setCursor(Qt::PointingHandCursor); @@ -438,7 +438,7 @@ void SourceItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { int marginE = 5; int marginS = 5; - InterfaceItem* iface = getInterfaceFromCursor(x,y); + InterfaceItem* iface = getInterfaceItemFromCursor(x,y); if (iface != NULL) { params->cursorState = Parameters::CursorOnInterface; setCursor(Qt::PointingHandCursor); @@ -498,7 +498,7 @@ void SourceItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { QAction* showParameters = NULL; - InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y()); + InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y()); // menu for interface if( ifaceItem != NULL){ @@ -670,7 +670,7 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) { } // creating InterfaceItem - initInterfaces(); + initInterfaceItems(); // setting them with saved values for(int i=0; isetId(id); interfaceItem->setOrientation(orientation); interfaceItem->setPositionRatio(position); diff --git a/blast.creator.user b/blast.creator.user index 5d3c6f4..6673fe4 100755 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {c8006d66-d34f-42be-ad10-d0207752286d} + {1d077e47-e3a1-47fd-8b12-4de650e39df5} ProjectExplorer.Project.ActiveTarget @@ -60,12 +60,12 @@ Desktop Desktop - {2c9bf876-3476-44eb-8065-1f0844704dda} + {451ee8a3-56ff-4aba-8a8e-3da882cc142e} 0 0 0 - /home/sdomas/Projet/Blast/code/blast + /localhome/sdomas/Projet/Blast/code/blast -- 2.39.5