GME
13
|
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 }