00001 #include "stdafx.h"
00002 #include "CommonSmart.h"
00003 #include "GMEGraph.h"
00004 #include "Gme.h"
00005
00006 GMEGraph::GMEGraph( IMgaProject *project, IMgaModel* model, IMgaMetaAspect* aspect )
00007 {
00008 CComObjPtr<IMgaParts> parts;
00009
00010 COMTHROW( model->get_AspectParts(aspect, 0, PutOut(parts)) );
00011
00012 fillNodes( project, parts );
00013 fillConnections( project, parts );
00014
00015 fillSubGraphField();
00016 }
00017
00018 GMEGraph::~GMEGraph()
00019 {
00020 for( unsigned int i=0; i<m_nodes.size(); ++i )
00021 {
00022 if( m_nodes[i]->m_fco != NULL )
00023 {
00024 m_nodes[i]->m_fco->Release();
00025 m_nodes[i]->m_fco = NULL;
00026 }
00027 for( unsigned int j=0; j<m_nodes[i]->m_ports.size(); ++j )
00028 {
00029 if( m_nodes[i]->m_ports[j]->m_fco != NULL )
00030 {
00031 m_nodes[i]->m_ports[j]->m_fco->Release();
00032 m_nodes[i]->m_ports[j]->m_fco = NULL;
00033 }
00034 }
00035 }
00036
00037 clear();
00038 }
00039
00040
00041 void GMEGraph::fillNodes( IMgaProject *project, IMgaParts* parts )
00042 {
00043 long n;
00044
00045 COMTHROW( parts->get_Count(&n) );
00046 for( int i=0; i<n; ++i )
00047 {
00048 CComObjPtr<IMgaPart> part;
00049 CComObjPtr<IMgaFCO> fco;
00050 CComObjPtr<IMgaMetaPart> metaPart;
00051 objtype_enum type;
00052 CComBSTR icon;
00053 long x,y,sx,sy;
00054
00055 COMTHROW( parts->get_Item(i+1, PutOut(part)) );
00056 COMTHROW( part->get_FCO(PutOut(fco)) );
00057 COMTHROW( part->get_Meta(PutOut(metaPart)) );
00058 COMTHROW( fco->get_ObjType(&type) );
00059 COMTHROW( part->GetGmeAttrs(&icon,&x,&y) );
00060
00061
00062 if( type == OBJTYPE_ATOM || type == OBJTYPE_MODEL || type == OBJTYPE_REFERENCE )
00063 {
00064 CComBSTR decoratorProgID;
00065 COMTHROW( fco->get_RegistryValue(L"decorator",&decoratorProgID) );
00066
00067 CComObjPtr<IMgaDecorator> decorator;
00068 CComPtr<IMgaElementDecorator> newDecorator;
00069 if (decoratorProgID.Length() == 0)
00070 decoratorProgID = L"Mga.BoxDecorator";
00071
00072 try {
00073 HRESULT hres = newDecorator.CoCreateInstance(PutInBstr(decoratorProgID));
00074 if (FAILED(hres) && hres != CO_E_CLASSSTRING) {
00075 hres = decorator.CoCreateInstance(PutInBstr(decoratorProgID));
00076 }
00077 if (hres == S_OK && newDecorator)
00078 decorator = CComQIPtr<IMgaDecorator>(newDecorator);
00079 if (hres == S_OK && decorator) {
00080 if (newDecorator)
00081 COMTHROW(newDecorator->InitializeEx(project, metaPart, fco, NULL, (ULONGLONG)GetDesktopWindow()));
00082 else
00083 COMTHROW(decorator->Initialize(project, metaPart, fco));
00084
00085 COMTHROW( decorator->GetPreferredSize( &sx, &sy ) );
00086
00087 sx = (sx + GME_GRID_SIZE - 1) / GME_GRID_SIZE * GME_GRID_SIZE;
00088 sy = (sy + GME_GRID_SIZE - 1) / GME_GRID_SIZE * GME_GRID_SIZE;
00089 COMTHROW( decorator->SetLocation( x, y, x+sx, y+sy ) );
00090
00091 Node * node = new Node( sx, sy );
00092 node->m_x = x;
00093 node->m_y = y;
00094 node->m_fco = fco;
00095 node->m_fco->AddRef();
00096
00097 CComObjPtr<IMgaFCOs> fcos;
00098 COMTHROW( decorator->GetPorts(PutOut(fcos)) );
00099 long fcoNum = 0;
00100 if( fcos!=NULL )
00101 COMTHROW( fcos->get_Count(&fcoNum) );
00102 for( int j=0; j<fcoNum; ++j )
00103 {
00104 CComObjPtr<IMgaFCO> port_fco;
00105 COMTHROW( fcos->get_Item(j+1, PutOut(port_fco)) );
00106
00107 long port_sx, port_sy, port_ex, port_ey;
00108 COMTHROW( decorator->GetPortLocation( port_fco, &port_sx, &port_sy, &port_ex, &port_ey ) );
00109
00110 int x1 = port_ex;
00111 int x2 = port_sx;
00112 if( x2 < x1 )
00113 {
00114 x1 = port_sx;
00115 x2 = port_ex;
00116 }
00117 int y1 = port_ey;
00118 int y2 = port_sy;
00119 if( y2 < y1 )
00120 {
00121 y1 = port_sy;
00122 y2 = port_ey;
00123 }
00124
00125 Node * port = new Node( node, x1, y1, x2-x1, y2-y1 );
00126 port->m_fco = port_fco;
00127 port->m_fco->AddRef();
00128 node->m_ports.push_back( port );
00129 }
00130 m_nodes.push_back( node );
00131 }
00132 }
00133 catch (hresult_exception&) {
00134 }
00135 if (decorator) {
00136 decorator->Destroy();
00137 }
00138 }
00139 }
00140 }
00141
00142 void GMEGraph::fillConnections( IMgaProject *project, IMgaParts* parts )
00143 {
00144 long n;
00145
00146 COMTHROW( parts->get_Count(&n) );
00147 for( int i=0; i<n; ++i )
00148 {
00149 CComObjPtr<IMgaPart> part;
00150 CComObjPtr<IMgaFCO> fco;
00151 objtype_enum type;
00152
00153 COMTHROW( parts->get_Item(i+1, PutOut(part)) );
00154 COMTHROW( part->get_FCO(PutOut(fco)) );
00155 COMTHROW( fco->get_ObjType(&type) );
00156
00157 if( type == OBJTYPE_CONNECTION )
00158 {
00159 CComObjPtr<IMgaSimpleConnection> conn( (IMgaSimpleConnection*)fco.p );
00160
00161 CComObjPtr<IMgaFCO> fco_from;
00162 CComObjPtr<IMgaFCO> fco_to;
00163
00164 COMTHROW( conn->get_Src(PutOut(fco_from)) );
00165 COMTHROW( conn->get_Dst(PutOut(fco_to)) );
00166
00167 Node * nodeFrom = findFCO( fco_from.p );
00168 Node * nodeTo = findFCO( fco_to.p );
00169
00170 if( nodeFrom != NULL && nodeTo != NULL )
00171 {
00172 Edge * e = new Edge( nodeFrom, nodeTo );
00173
00174 CComBSTR prefs;
00175 COMTHROW( fco->get_RegistryValue( L"autorouterPref", &prefs ) );
00176 CString prefs2(prefs);
00177 setRoutingPrefs(e,prefs2);
00178
00179 m_edges.push_back( e );
00180 nodeFrom->m_edges.push_back( e );
00181 if( nodeFrom->m_parent != NULL )
00182 nodeFrom->m_parent->m_edges.push_back(e);
00183 if( nodeFrom != nodeTo )
00184 {
00185 nodeTo->m_edges.push_back( e );
00186 if( nodeTo->m_parent != NULL )
00187 nodeTo->m_parent->m_edges.push_back(e);
00188 }
00189 }
00190 }
00191 }
00192 }
00193
00194 Node * GMEGraph::findFCO( IMgaFCO * fco )
00195 {
00196 for( unsigned int i=0; i<m_nodes.size(); ++i )
00197 {
00198 Node * n = m_nodes[i];
00199 if( n->m_fco == fco )
00200 return n;
00201 for( unsigned int j=0; j<n->m_ports.size(); ++j )
00202 {
00203 Node * p = n->m_ports[j];
00204 if( p->m_fco == fco )
00205 return p;
00206 }
00207 }
00208 return NULL;
00209 }
00210
00211 void GMEGraph::setRoutingPrefs( Edge * e, CString connPrefs )
00212 {
00213 bool nodeFromIsPort = (e->m_nodeFrom->m_parent != NULL);
00214 bool nodeToIsPort = (e->m_nodeTo->m_parent != NULL);
00215
00216 if( nodeFromIsPort )
00217 {
00218 if( e->m_nodeFrom->m_x < e->m_nodeFrom->m_parent->m_sx/2 )
00219 e->cannotStartToEast = true;
00220 else
00221 e->cannotStartToWest = true;
00222 }
00223 else
00224 {
00225 CComBSTR prefs;
00226 COMTHROW( e->m_nodeFrom->m_fco->get_RegistryValue( CComBSTR(L"autorouterPref"), &prefs ) );
00227 CString prefs2(prefs);
00228 if( connPrefs.GetLength() > 0 )
00229 prefs2 = connPrefs;
00230 if( prefs2.GetLength() > 0 )
00231 {
00232 bool N = prefs2.Find(_T("N"))!=-1;
00233 bool E = prefs2.Find(_T("E"))!=-1;
00234 bool S = prefs2.Find(_T("S"))!=-1;
00235 bool W = prefs2.Find(_T("W"))!=-1;
00236
00237 if( !N && !E && S && !W ) e->cannotStartToNorth = true;
00238 if( !N && !E && !S && W ) e->cannotStartToEast = true;
00239 if( N && !E && !S && !W ) e->cannotStartToSouth = true;
00240 if( !N && E && !S && !W ) e->cannotStartToWest = true;
00241 }
00242 }
00243
00244 if( nodeToIsPort )
00245 {
00246 if( e->m_nodeTo->m_x < e->m_nodeTo->m_parent->m_sx/2 )
00247 e->cannotEndFromEast = true;
00248 else
00249 e->cannotEndFromWest = true;
00250 }
00251 else
00252 {
00253 CComBSTR prefs;
00254 COMTHROW( e->m_nodeTo->m_fco->get_RegistryValue( CComBSTR(L"autorouterPref"), &prefs ) );
00255 CString prefs2(prefs);
00256 if( connPrefs.GetLength() > 0 )
00257 prefs2 = connPrefs;
00258 if( prefs2.GetLength() > 0 )
00259 {
00260 bool N = prefs2.Find(_T("n"))!=-1;
00261 bool E = prefs2.Find(_T("e"))!=-1;
00262 bool S = prefs2.Find(_T("s"))!=-1;
00263 bool W = prefs2.Find(_T("w"))!=-1;
00264
00265 if( !N && !E && S && !W ) e->cannotEndFromNorth = true;
00266 if( !N && !E && !S && W ) e->cannotEndFromEast = true;
00267 if( N && !E && !S && !W ) e->cannotEndFromSouth = true;
00268 if( !N && E && !S && !W ) e->cannotEndFromWest = true;
00269 }
00270 }
00271 }