GME  13
AutoRouter.cpp
Go to the documentation of this file.
00001 
00002 #include "stdafx.h"
00003 
00004 #include "../GuiMeta.h"
00005 #include "../GuiObject.h"
00006 #include "AutoRouterGraph.h"
00007 #include "AutoRouterPort.h"
00008 #include "AutoRouter.h"
00009 
00010 #include "../GMEView.h"
00011 
00013 
00014 CAutoRouter::CAutoRouter()
00015 {
00016         router = new CAutoRouterGraph();
00017         ASSERT( router != NULL );
00018         routeret = 1;
00019 }
00020 
00021 CAutoRouter::~CAutoRouter()
00022 {
00023         ASSERT( router != NULL );
00024 
00025         router->Destroy();
00026         delete router;
00027 }
00028 
00029 bool CAutoRouter::AutoRoute(long aspect)
00030 {
00031         if (CGMEView::IsHugeModel())
00032                 return true;
00033 
00034         long res = router->AutoRoute(aspect);
00035         bool wereThereDeletion = RemoveDeletedCustomPathDataFromGuiConnections();
00036         routeret = res;
00037         return wereThereDeletion;
00038 }
00039 
00040 void CAutoRouter::AutoRoute(CGuiFcoList& fcos, long aspect)
00041 {
00042         if (CGMEView::IsHugeModel())
00043                 return;
00044         bool wereThereDeletion = false;
00045         do {
00046                 Fill(fcos);
00047                 wereThereDeletion = AutoRoute(aspect);
00048         } while (routeret == -2 && wereThereDeletion);
00049 }
00050 
00051 void CAutoRouter::Fill(CGuiFcoList& fcos)
00052 {
00053         Clear(fcos);
00054         AddObjects(fcos);
00055 }
00056 
00057 void CAutoRouter::Clear(CGuiFcoList& fcos)
00058 {
00059         router->DeleteAll(true);
00060 
00061         POSITION pos = fcos.GetHeadPosition();
00062         while (pos) {
00063                 CGuiFco* fco = fcos.GetNext(pos);
00064                 ASSERT(fco != NULL);
00065                 CGuiConnection* conn = fco->dynamic_cast_CGuiConnection();
00066                 if (conn) {
00067                         conn->SetRouterPath(NULL);
00068                 } else {
00069                         CGuiObject* obj = fco->dynamic_cast_CGuiObject();
00070                         VERIFY(obj);
00071                         if (obj->IsVisible()) {
00072                                 obj->SetRouterBox(NULL);
00073                                 obj->SetRouterNameBox(NULL);
00074                                 POSITION ppos = obj->GetPorts().GetHeadPosition();
00075                                 while (ppos) {
00076                                         obj->GetPorts().GetNext(ppos)->SetRouterPort(NULL) ;
00077                                 }
00078                         }
00079                 }
00080         }
00081 }
00082 
00083 void CAutoRouter::AddObjects(CGuiFcoList& fcos)
00084 {
00085         if (CGMEView::IsHugeModel())
00086                 return;
00087         CGuiConnectionList conns;
00088         POSITION pos = fcos.GetHeadPosition();
00089         while (pos) {
00090                 CGuiFco* fco = fcos.GetNext(pos);
00091                 ASSERT(fco != NULL);
00092                 if (fco->IsVisible()) {
00093                         CGuiConnection* conn = fco->dynamic_cast_CGuiConnection();
00094                         if (conn)
00095                                 conns.AddTail(conn);
00096                         else
00097                                 AddFco(fco);
00098                 }
00099         }
00100         pos = conns.GetHeadPosition();
00101         while (pos)
00102                 AddFco(conns.GetNext(pos));
00103 }
00104 
00105 void CAutoRouter::SetPortPreferences(CAutoRouterPort* portBox, CGuiPort* port)
00106 {
00107 
00108         if (CGMEView::IsHugeModel())
00109                 return;
00110         
00111         unsigned long attr = 0;
00112         
00113         if (port->GetARPref(GME_START_NORTH))
00114                 attr |= ARPORT_StartOnTop;
00115         if (port->GetARPref(GME_START_SOUTH))
00116                 attr |= ARPORT_StartOnBottom;
00117         if (port->GetARPref(GME_START_EAST))
00118                 attr |= ARPORT_StartOnRight;
00119         if (port->GetARPref(GME_START_WEST))
00120                 attr |= ARPORT_StartOnLeft;
00121 
00122         if (port->GetARPref(GME_END_NORTH))
00123                 attr |= ARPORT_EndOnTop;
00124         if (port->GetARPref(GME_END_SOUTH))
00125                 attr |= ARPORT_EndOnBottom;
00126         if (port->GetARPref(GME_END_EAST))
00127                 attr |= ARPORT_EndOnRight;
00128         if (port->GetARPref(GME_END_WEST))
00129                 attr |= ARPORT_EndOnLeft;
00130 
00131         portBox->SetAttributes(attr);
00132 }
00133 
00134 void CAutoRouter::SetPathPreferences(CAutoRouterPath* path, CGuiConnection* conn)
00135 {
00136         if(CGMEView::IsHugeModel())
00137                 return;
00138 
00139         ASSERT( path != NULL );
00140         unsigned int arpath_start = ARPATH_Default, arpath_end = ARPATH_Default;
00141 
00142         if (conn->GetARPref(GME_START_NORTH))
00143                 arpath_start |= ARPATH_StartOnTop;
00144         if (conn->GetARPref(GME_START_SOUTH))
00145                 arpath_start |= ARPATH_StartOnBottom;
00146         if (conn->GetARPref(GME_START_EAST))
00147                 arpath_start |= ARPATH_StartOnRight;
00148         if (conn->GetARPref(GME_START_WEST))
00149                 arpath_start |= ARPATH_StartOnLeft;
00150 
00151         if (conn->GetARPref(GME_END_NORTH))
00152                 arpath_end |= ARPATH_EndOnTop;
00153         if (conn->GetARPref(GME_END_SOUTH))
00154                 arpath_end |= ARPATH_EndOnBottom;
00155         if (conn->GetARPref(GME_END_EAST))
00156                 arpath_end |= ARPATH_EndOnRight;
00157         if (conn->GetARPref(GME_END_WEST))
00158                 arpath_end |= ARPATH_EndOnLeft;
00159 
00160 
00161         ASSERT( (arpath_start & (~ARPATH_StartMask)) == 0 );
00162         ASSERT( (arpath_end & (~ARPATH_EndMask)) == 0 );
00163 
00164         path->SetStartDir(arpath_start);
00165         path->SetEndDir(arpath_end);
00166 
00167         // Load the customized edge data which corresponds to the needed aspect
00168         std::vector<CustomPathData> cpd = conn->GetCurrentPathCustomizations();
00169         path->SetCustomPathData(cpd);
00170 }
00171 
00172 bool CAutoRouter::RemoveDeletedCustomPathDataFromGuiConnections(void)
00173 {
00174         bool wereThereDeletion = false;
00175 
00176         const CAutoRouterPathList& pathList = router->GetPathList();
00177 
00178         CAutoRouterPathList::const_iterator ii = pathList.begin();
00179         while (ii != pathList.end()) {
00180                 CAutoRouterPath* path = (*ii);
00181                 if (path->AreThereDeletedPathCustomizations()) {
00182                         std::vector<CustomPathData> cpd;
00183                         path->GetDeletedCustomPathData(cpd);
00184                         CGuiConnection* conn = (CGuiConnection*)path->GetExtPtr();
00185                         conn->RemoveDeletedPathCustomizations(cpd);
00186                         wereThereDeletion = true;
00187                 }
00188                 ++ii;
00189         }
00190 
00191         return wereThereDeletion;
00192 }
00193 
00194 void CAutoRouter::AddFco(CGuiFco* fco)
00195 {
00196         if (CGMEView::IsHugeModel())
00197                 return;
00198         ASSERT(fco != NULL);
00199         CGuiConnection* conn = fco->dynamic_cast_CGuiConnection();
00200         if (conn) {
00201                 AddConnection(conn);
00202         } else {
00203                 CGuiObject* obj = fco->dynamic_cast_CGuiObject();
00204                 VERIFY(obj);
00205                 AddObject(obj);
00206         }
00207 }
00208 
00209 void CAutoRouter::AddObject(CGuiObject* object)
00210 {
00211         if (CGMEView::IsHugeModel())
00212                 return;
00213 
00214         CAutoRouterBox* box = router->CreateBox();
00215 
00216         CRect loc = object->GetLocation();
00217         box->SetRect(loc);
00218 
00219         CAutoRouterBox* nameBox = NULL;
00220         if (theApp.labelAvoidance) {
00221                 nameBox = router->CreateBox();
00222                 nameBox->SetRect(object->GetNameLocation());
00223         }
00224 
00225         CGuiPortList& ports = object->GetPorts();
00226         POSITION pos = ports.GetHeadPosition();
00227         while (pos) {
00228                 CGuiPort* port = ports.GetNext(pos);
00229                 CAutoRouterPort* portBox = box->CreatePort();
00230                 // real ports most obey the rule that the only dir allowed is
00231                 // the one on which side of their parent they are laid out
00232                 portBox->SetLimitedDirs(port->IsRealPort());
00233                 CRect r = port->GetLocation() + loc.TopLeft();
00234                 portBox->SetRect(r);
00235                 SetPortPreferences(portBox, port);
00236                 port->SetRouterPort(portBox);
00237                 box->AddPort(portBox);
00238         }
00239 
00240         object->SetRouterBox(box);
00241         if (theApp.labelAvoidance)
00242                 object->SetRouterNameBox(nameBox);
00243 
00244         router->AddBox(box);
00245 
00246         if (theApp.labelAvoidance)
00247                 router->AddBox(nameBox);
00248 }
00249 
00250 void CAutoRouter::AddConnections(CGuiConnectionList& connList)
00251 {
00252         if (CGMEView::IsHugeModel())
00253                 return;
00254         POSITION pos = connList.GetHeadPosition();
00255         while (pos)
00256                 AddConnection(connList.GetNext(pos));
00257 }
00258 
00259 void CAutoRouter::AddConnection(CGuiConnection* conn)
00260 {
00261         if (CGMEView::IsHugeModel())
00262                 return;
00263         if (!conn->IsVisible())
00264                 return;
00265         if (!conn->srcPort || !conn->dstPort)
00266                 return;
00267 
00268         CAutoRouterPort* asrc = conn->srcPort->GetRouterPort();
00269         CAutoRouterPort* adst = conn->dstPort->GetRouterPort();
00270 
00271         CAutoRouterPath* path = router->AddPath(conn->IsAutoRouted(), asrc, adst);
00272 
00273         SetPathPreferences(path, conn);
00274         conn->SetRouterPath(path);
00275         // hack no 1: this is a little hack: 
00276         // only the address is needed, thus it should be void*
00277         path->SetExtPtr(conn);
00278 }
00279 
00280 void CAutoRouter::DeleteObjects(CGuiObjectList &objs)
00281 {
00282         if (CGMEView::IsHugeModel())
00283                 return;
00284         POSITION pos = objs.GetHeadPosition();
00285         while (pos) {
00286                 CGuiObject *obj = objs.GetNext(pos);
00287                 if (obj && obj->IsVisible()) {
00288                         DeleteObject(obj);
00289                 }
00290         }
00291 }
00292 
00293 void CAutoRouter::DeleteObject(CGuiObject *object)
00294 {
00295         if (CGMEView::IsHugeModel())
00296                 return;
00297         if (object->IsVisible()) {
00298                 router->DeleteBox(object->GetRouterBox());
00299 
00300                 if (theApp.labelAvoidance) {
00301                         CAutoRouterBox* nameBox = object->GetRouterNameBox();
00302                         if (nameBox != NULL) {
00303                                 router->DeleteBox(nameBox);
00304                         }
00305                 }
00306 
00307                 object->SetRouterBox(NULL);
00308                 object->SetRouterNameBox(NULL);
00309                 ClearRouterPorts(object->GetPorts());
00310         }
00311 }
00312 
00313 void CAutoRouter::ClearRouterPorts(CGuiPortList &portList)
00314 {
00315         POSITION pos = portList.GetHeadPosition();
00316         while (pos)
00317                 portList.GetNext(pos)->SetRouterPort(NULL);
00318 }
00319 
00320 void CAutoRouter::DeleteConnection(CGuiConnection *conn)
00321 {
00322         if (CGMEView::IsHugeModel())
00323                 return;
00324 
00325         if (conn->GetRouterPath() != NULL) {
00326                 CAutoRouterPath* currPath = conn->GetRouterPath();
00327                 router->DeletePath(currPath);
00328                 conn->SetRouterPath(NULL);
00329         }
00330 }
00331 
00332 CGuiConnection* CAutoRouter::FindConnection(CPoint& pt) const
00333 {
00334         if (CGMEView::IsHugeModel())
00335                 return 0;
00336 
00337         CAutoRouterPath* path = router->GetPathAt(pt, 3);
00338 
00339         if (path != NULL)
00340         {
00341                 // hack no 2: this is the same hack as in hack no 1.
00342                 void* address = path->GetExtPtr();
00343                 return (CGuiConnection*)(address);
00344         }
00345         else
00346         {
00347                 return NULL;
00348         }
00349 }
00350 
00351 void CAutoRouter::NudgeObjects(CGuiObjectList& objectList, int right, int down, long aspect)
00352 {
00353         if (CGMEView::IsHugeModel())
00354                 return;
00355         CPoint offs = CPoint(right * GME_GRID_SIZE, down * GME_GRID_SIZE);
00356         POSITION pos = objectList.GetHeadPosition();
00357         while(pos) {
00358                 CGuiObject* obj = objectList.GetNext(pos);
00359 
00360                 router->ShiftBoxBy(obj->GetRouterBox(), offs);
00361 
00362                 if (theApp.labelAvoidance) {
00363                         CAutoRouterBox* nameBox = obj->GetRouterNameBox();
00364                         if (nameBox) {
00365                                 router->ShiftBoxBy(nameBox, offs);
00366                         }
00367                         
00368                 }
00369         }
00370         AutoRoute(aspect);
00371 }