📄 mapper.cpp
字号:
/*******************************************************************************//* Project: SOFTWARE RADIO - LCM Laboratoire de Communications Mobiles *//* -------------------------------------------------------------------------- *//* Filename: mapper.cpp *//* Description: The mapper is the object that decides in which order the *//* modules are to be drawn on the canvas. It then draws them. *//* This object contains the list of all modules (instances) *//* currently used in the software radio system. *//* -------------------------------------------------------------------------- *//* Date: January 09 2003 *//* Version: v1.0 *//* Author: Braure Jerome, Ferreiro Jose *//* Communication Systems (9th semester) - EPFL *//* Changelog: ineiti - 04/03/01 - replaced MODULE_MIN_HEIGHT with modules->height*//*******************************************************************************//*******************************************************************************//* This program is free software; you can redistribute it and/or modify it *//* under the terms of the GNU General Public License as published by the Free *//* Software Foundation; either version 2 of the License, or (at your option) *//* any later version. *//*******************************************************************************/#include <iostream>#include "mapper.h"#include "defines.h"#include "global.h"using namespace std;#define STATE_DRAW_DIRECT_SUITE 1#define STATE_DRAW_REMAINING_LINKS 2#define STATE_DRAW_INTERZONE_LINKS 3#define DRAW_LINE(x1,y1,x2,y2) { \ QCanvasLine *line = new QCanvasLine( canvas ); \ line->setPoints(x1,y1,x2,y2); \ line->setPen(pen); \ line->show(); \ connectionList.append( line ); \ }#define DRAW_POLY_START(x,y) startX = x; startY = y#define DRAW_POLY(x,y) DRAW_LINE(startX,startY,x,y); \ DRAW_POLY_START(x,y)#define DRAW_POLY_REL(dx,dy) DRAW_LINE(startX,startY, \ startX+dx, startY+dy ); \ DRAW_POLY(startX+dx, startY+dy)/*******************************************************************************//* Function: Mapper() - (constuctor) *//* Description: Constructs an instance of class Mapper. *//* Inputs: none. *//*******************************************************************************/Mapper::Mapper() { moduleList.setAutoDelete( true ); connectionList.setAutoDelete( true ); for ( int i=0; i<MAX_STFAS; i++ ){ stfas[i] = NULL; }}#define atp_(a,v,i,n) if ( i >= (int)v.size() ){ \cout << i << " is bigger or equal to " << v.size() << " at " << n << endl; return; \} else { a=&v.at(i); }/*******************************************************************************//* Function: map() *//* Description: This function decides in which order the modules are to be *//* displayed on the canvas and then draws them. *//* Inputs: canvas: pointer to the QCanvas on which the mapper is to draw. *//* Returns: void. *//*******************************************************************************/void Mapper::map( QCanvas* canvas ) { if ( canvas == NULL ) return ; Module* previousModule; Module* currentModule; IOLink* currentLink; QPen pen( LINK_COLOR, LINK_WIDTH ); int currentY, currentX; int startX, startY, endX, endY; QValueVector<IOLink> remainingLinkVect; QValueVector<IOLink> interzoneLinkVect; QValueList<int> inputMaxXTab; QValueList<int> inputMinYTab; QValueList<int> outputMaxXTab; QValueList<int> outputMaxYTab; Module* fromModule; Module* toModule; bool columnFinished; bool interzoneFinished; int state; Module *stfa = stfas[stfaChosen]; if ( !stfa ){ cout << "Don't have a valid stfa!!" << stfaChosen << endl; return; } // Clear previous connections connectionList.clear(); // Reset modules and stfa for ( uint m=0; m<moduleList.count(); m++ ){ if ( !moduleList.at(m)->reset() ){ moduleList.remove( m ); m--; } else { moduleList.at(m)->hide(); } } for ( int s=0; s<stfaNbr; s++ ){ stfas[s]->hide(); } stfa->reset(); // initialization for ( int i = 0; i < stfa->numberIn; i++ ) { inputMaxXTab.append( stfa->x ); inputMinYTab.append( stfa->y ); } for ( int i = 0; i < stfa->numberOut; i++ ) { outputMaxXTab.append( stfa->x ); outputMaxYTab.append( stfa->y + stfa->height ); } // draw the STFA choosen in canvasview and provided by the mod generator stfa->show(); /************************************************************************/ /* Part 1: Draw the modules that are above the STFA. */ /************************************************************************/ // for all input ports of the stfa for ( int portNb = 0; portNb < stfa->greatestPortUsed; portNb++ ) { if ( portNb >= stfa->numberIn ){ break; } // update maxX inputMaxXTab[ portNb ] = MAXIMUM( inputMaxXTab[ portNb ], inputMaxXTab[ MAXIMUM( portNb - 1, 0 ) ] ); currentY = stfa->y; // currentLink = &(stfa->inputLinkVect.at(portNb)); atp_( currentLink, stfa->inputLinkVect, portNb, 0 ); if ( !currentLink ) { cout << "currentLink is NULL at mapper.c:99\n"; continue; } if ( currentLink->fromModule < 0 ) continue; previousModule = stfa; columnFinished = false; interzoneFinished = false; state = STATE_DRAW_DIRECT_SUITE; fromModule = NULL; while ( !( columnFinished && interzoneFinished ) ) { switch ( state ) { case STATE_DRAW_DIRECT_SUITE: /****************************************************************/ /* Part 1.1: Draw the modules that are met for the first time. */ /* Draw the link between the modules. When entering */ /* this state, currentLink's 'toModule' must be the */ /* last module that was drawn and 'fromModule' is */ /* valid. */ /****************************************************************/ // the next module to draw currentModule = getModule( currentLink->fromModule ); if ( currentModule == NULL ) { cout << "There is no module " << currentLink->fromModule << "\n"; columnFinished = interzoneFinished = true; continue; } if ( currentModule->visible ) { // the module has already been drawn, draw the link later if ( currentModule->zone == previousModule->zone ) { // the two modules are in the same zone remainingLinkVect.push_back( *currentLink ); } // end if(currentModule->zone == previousModule->zone) else { // the two modules are not in the same zone interzoneLinkVect.push_back( *currentLink ); } bool linkFound = false; // get the following 'valid' link for ( int i = currentLink->toPort; i < previousModule->numberIn; i++ ) { IOLink* link; // = &previousModule->inputLinkVect.at(i); atp_( link, previousModule->inputLinkVect, i, 1 ); if ( !link ) { cout << "Link " << i << " is NULL at mapper.cpp:147" << endl; continue; } if ( link->fromModule >= 0 && !getModule( link->fromModule ) ->visible ) { currentLink = link; currentModule = getModule( currentLink->fromModule ); linkFound = true; break; } } // end for(i) if ( !linkFound ) { state = STATE_DRAW_REMAINING_LINKS; break; } } // end if(currentModule->visible) else { // currentModule is not visible // draw the module // set the zone number currentModule->zone = portNb; // set the 'neighbor' information previousModule->upperNeighbor = currentModule->getId(); currentModule->lowerNeighbor = previousModule->getId(); // set the vertical (Y) position of 'currentModule' currentModule->setY( currentY - currentModule->height - MAXIMUM( ( previousModule->numberInUsed ) * LINK_Y_INTERVAL + ( currentModule->numberOutUsed ) * LINK_Y_INTERVAL, MODULE_Y_INTERVAL ) ); // update the minimum Y coordinate used by this column (of modules) inputMinYTab[ portNb ] = currentModule->y; // update the current x position if ( portNb == 0 ) { currentX = previousModule->getInputXPosition( currentLink->toPort ) - LEG_LEFT_OFFSET - LEG_WIDTH / 2; } else { if ( previousModule == stfa ) { currentX = MAXIMUM( inputMaxXTab[ portNb - 1 ], previousModule->getInputXPosition( currentLink->toPort ) - LEG_LEFT_OFFSET - LEG_WIDTH / 2 ); } else { currentX = MAXIMUM( inputMaxXTab[ portNb - 1 ], previousModule->x ); } } // end else // set the horizontal (X) position currentModule->setX( currentX ); // update the maximum X coordinate used by this column (of modules) inputMaxXTab[ portNb ] = currentModule->getMaxX() + MODULE_X_INTERVAL / 2; currentModule->show(); // draw the direct-link lines between 'previousModule' and 'currentModule' if ( ( previousModule == stfa ) || ( currentLink->toModule == previousModule->getId() ) ) { DRAW_LINE( previousModule->getInputXPosition( currentLink->toPort ), previousModule->getInputYPosition(), currentModule->getOutputXPosition( currentLink->fromPort ), currentModule->getOutputYPosition() ); } currentY = currentModule->y; // check if the previous module had more than one input if ( previousModule != stfa && previousModule->numberInUsed > 1 ) { for ( int j = 1; j < previousModule->numberIn; j++ ) { IOLink *link; // = new IOLink(previousModule->inputLinkVect.at(j)); atp_( link, previousModule->inputLinkVect, j, 2 ); if ( link->fromModule >= 0 && link->toModule >= 0 ) { // then put all remaining links to the vectors if ( getModule( link->fromModule ) ->zone == portNb || !getModule( link->fromModule ) ->visible ) { remainingLinkVect.push_back( *link ); } else interzoneLinkVect.push_back( *link ); } } // end for } // end if(previousModule->numberInUsed > 1) // update currentLink previousModule = currentModule; bool linkFound = false; // get the following 'valid' link for ( int i = 0; i < currentModule->numberIn; i++ ) { IOLink* link; // = ¤tModule->inputLinkVect.at(i); atp_( link, currentModule->inputLinkVect, i, 3 ); if ( !link ) { cout << "Link " << i << " is NULL at mapper.cpp:247" << endl; continue; } if ( link->fromModule >= 0 ) { currentLink = link; currentModule = getModule( currentLink->fromModule ); linkFound = true; break; } } // end for(i) if ( !linkFound ) { state = STATE_DRAW_REMAINING_LINKS; break; } } // end [else] : currentModule is not visible break; case STATE_DRAW_REMAINING_LINKS: /******************************************************************/ /* Part 1.2: Draw the remaining links. Interzone links will be */ /* Drawn in part 1.3, when all modules of the current */ /* column have been drawn. */ /******************************************************************/ if ( remainingLinkVect.size() < 1 ) { columnFinished = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -