00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 #include <OMKDoubleList.h> 00019 #include <OMKDoubleListElement.h> 00020 #include "OMKReferenceObjectHandle.h" 00021 #include "OMKTracer.h" 00022 using namespace std ; 00023 using namespace OMK ; 00024 00025 00026 DoubleList::DoubleList() 00027 : _startOfSuperList( 0 ), 00028 _lastOfSuperList( 0 ), 00029 _start( 0 ), 00030 _last( 0 ) 00031 { 00032 } 00033 00034 00035 bool DoubleList::push_front(ReferenceObjectHandle * M) { 00036 DoubleListElement * elem=new DoubleListElement(M); 00037 00038 //1 Gestion de la liste complète 00039 //chainage dans le sens suivant; 00040 elem->nextInSuperList=_startOfSuperList; 00041 //chainage dans le sens précédent 00042 elem->previousInSuperList=NULL; 00043 if (_startOfSuperList!=NULL) {//la liste n'est pas vide 00044 _startOfSuperList->previousInSuperList=elem; 00045 } 00046 else { 00047 _lastOfSuperList=elem; 00048 } 00049 _startOfSuperList=elem; 00050 return false ; 00051 } 00052 00053 bool DoubleList::push_back(ReferenceObjectHandle * M) { 00054 DoubleListElement * elem=new DoubleListElement(M); 00055 00056 //1 Gestion de la liste complète 00057 //chainage dans le sens prec; 00058 elem->previousInSuperList=_lastOfSuperList; 00059 //chainage dans le sens suivant 00060 elem->nextInSuperList=NULL; 00061 if (_lastOfSuperList!=NULL) {//la liste n'est pas vide 00062 _lastOfSuperList->nextInSuperList=elem; 00063 } 00064 else { 00065 _startOfSuperList=elem; 00066 } 00067 _lastOfSuperList=elem; 00068 return false; 00069 } 00070 00071 bool DoubleList::insert(ReferenceObjectHandle * M) 00072 { 00073 DoubleListElement * elem = new DoubleListElement(M); 00074 DoubleListElement * pcour = _startOfSuperList; 00075 DoubleListElement * prec = NULL; 00076 enum{ON_BOUCLE,FIN_LISTE,PLACE_TROUVEE} etatBoucle; 00077 etatBoucle=ON_BOUCLE; 00078 00079 while(etatBoucle==ON_BOUCLE) 00080 { 00081 if (pcour==NULL) 00082 { 00083 etatBoucle=FIN_LISTE; 00084 } 00085 else 00086 { 00087 if (*pcour->listeElem >= *M) 00088 { 00089 etatBoucle=PLACE_TROUVEE; 00090 } 00091 else 00092 { 00093 prec=pcour; 00094 pcour=pcour->nextInSuperList; 00095 } 00096 } 00097 } 00098 /* ici on sait que 00099 * si prec != NULL , *prec->listeElem < *M 00100 * soit pcour == NULL ou *M <= *pcour->listeElem 00101 * Il faut donc refaire le chainage 00102 */ 00103 elem->nextInSuperList=pcour; 00104 elem->previousInSuperList=prec; 00105 if (prec==NULL) {//insertion de l'élément au début 00106 if (pcour!=NULL) {//la liste n'est pas vide 00107 pcour->previousInSuperList=elem; 00108 } 00109 else { 00110 _lastOfSuperList=elem; 00111 } 00112 _startOfSuperList=elem; 00113 } 00114 else { 00115 prec->nextInSuperList=elem; 00116 if (pcour==NULL) {//on ajoute à la fin 00117 _lastOfSuperList=elem; 00118 } 00119 else { 00120 pcour->previousInSuperList=elem; 00121 } 00122 } 00123 //test intergrity of data 00124 if ( _lastOfSuperList != NULL ) 00125 OMASSERTM( findInSuperList ( _lastOfSuperList->listeElem ) == _lastOfSuperList, "" ) ; 00126 if ( _last != NULL ) 00127 OMASSERTM( find ( _last->listeElem) == _last, "" ) ; 00128 return false; 00129 } 00130 00131 bool DoubleList::remove(ReferenceObjectHandle * M) 00132 { 00133 DoubleListElement * elem = findInSuperList(M) ; 00134 if( elem != NULL ) 00135 {//l'objet n'est pas déjà détruit 00136 if( ( elem->nextInActiveList != NULL ) || 00137 ( elem->previousInActiveList != NULL ) || 00138 ( _start == elem) ) 00139 { 00140 //l'objet est encore dans la liste des objets à exécuter : on ne le détruit pas 00141 return true; 00142 } 00143 else 00144 { 00145 DoubleListElement * prec=elem->previousInSuperList; 00146 DoubleListElement * suiv=elem->nextInSuperList; 00147 if(prec!=NULL) 00148 { 00149 prec->nextInSuperList=suiv; 00150 } 00151 else 00152 {//l'élément détruit était en tete 00153 _startOfSuperList=suiv; 00154 } 00155 if(suiv!=NULL) 00156 { 00157 suiv->previousInSuperList=prec; 00158 } 00159 else 00160 {//l'élement détruit était en queue 00161 _lastOfSuperList=prec; 00162 } 00163 delete elem; 00164 } 00165 } 00166 //test intergrity of data 00167 if ( _lastOfSuperList != NULL ) 00168 OMASSERTM( findInSuperList ( _lastOfSuperList->listeElem ) == _lastOfSuperList, "" ) ; 00169 if ( _last != NULL ) 00170 OMASSERTM( find ( _last->listeElem) == _last, "" ) ; 00171 return false; 00172 } 00173 00174 00175 bool DoubleList::activate(ReferenceObjectHandle * M, DoubleListElement ** elemExecPrec) 00176 { 00177 bool result ; 00178 DoubleListElement * pcour = _startOfSuperList; 00179 DoubleListElement * resul = NULL; 00180 DoubleListElement * execSuiv = _start; 00181 DoubleListElement * execPrec = NULL; 00182 //on commence par chercher M dans la liste complète en gardant la trace du dernier élément qui appartient à la liste des exécutables. 00183 while((pcour!=NULL)&&(resul==NULL)) 00184 { 00185 if( pcour->listeElem == M ) 00186 { 00187 OMASSERTM( pcour->_isActive == false, "" ) ; 00188 resul = pcour; 00189 } 00190 else 00191 { 00192 if( pcour->_isActive ) 00193 {//l'élément courant est dans la liste des exec 00194 execPrec = pcour ; 00195 execSuiv = pcour->nextInActiveList; 00196 } 00197 pcour = pcour->nextInSuperList; 00198 } 00199 } 00200 //rendu ici, pcour contient un pointeur sur l'élément ou NULL si l'élément n'est pas dans la liste 00201 //execPrec, le précédant de pcour dans la liste des exécutables 00202 //execSuiv, le suivant de pcour dans la liste des exécutables 00203 if (pcour==NULL) 00204 { 00205 if(elemExecPrec != NULL) *elemExecPrec = execPrec; 00206 result = false; 00207 } 00208 else 00209 { 00210 pcour->_isActive = true ; 00211 if ( execPrec == NULL ) 00212 { 00213 //premier dans la liste des executables 00214 _start = pcour; 00215 } 00216 else 00217 { 00218 execPrec->nextInActiveList = pcour ; 00219 } 00220 if( execSuiv == NULL ) 00221 { 00222 //dernier dans la liste des executables 00223 _last = pcour; 00224 } 00225 else 00226 { 00227 execSuiv->previousInActiveList = pcour; 00228 } 00229 pcour->previousInActiveList = execPrec ; 00230 OMASSERTM( pcour != execPrec, "" ) ; 00231 00232 pcour->nextInActiveList = execSuiv; 00233 OMASSERTM( pcour != execSuiv, "" ) ; 00234 00235 if(elemExecPrec!=NULL) *elemExecPrec=execPrec; 00236 result = true ; 00237 } 00238 //test integrity of data 00239 if ( _lastOfSuperList != NULL ) 00240 OMASSERTM( findInSuperList ( _lastOfSuperList->listeElem ) == _lastOfSuperList, "" ) ; 00241 if ( _last != NULL ) 00242 OMASSERTM( find ( _last->listeElem) == _last, "" ) ; 00243 return result ; 00244 } 00245 00246 bool DoubleList::suspend(ReferenceObjectHandle * M) 00247 { 00248 DoubleListElement * elem = find(M); 00249 if( elem != NULL ) 00250 {//l'objet n'est pas déjà détruit ou est une entité 00251 DoubleListElement * prec=elem->previousInActiveList; 00252 DoubleListElement * suiv=elem->nextInActiveList; 00253 if(prec!=NULL) { 00254 prec->nextInActiveList=suiv; 00255 } 00256 else {//l'élément détruit était en tete 00257 _start=suiv; 00258 }; 00259 if(suiv!=NULL) { 00260 suiv->previousInActiveList=prec; 00261 } 00262 else { 00263 _last=prec; 00264 }; 00265 //l'élément n'appartient plus à la liste des modules à exécuter 00266 elem->previousInActiveList=NULL; 00267 elem->nextInActiveList=NULL; 00268 elem->_isActive = false ; 00269 return false; 00270 } 00271 else { 00272 return true; 00273 } 00274 } 00275 00276 DoubleListElement * DoubleList::findInSuperList(ReferenceObjectHandle * p) 00277 { 00278 DoubleListElement * pcour=_startOfSuperList; 00279 DoubleListElement * resul=NULL; 00280 while( ( pcour != NULL ) && 00281 ( resul == NULL) ) 00282 { 00283 if( pcour->listeElem == p ) 00284 { 00285 resul=pcour; 00286 } 00287 OMASSERTM( pcour != pcour->nextInSuperList, "" ) ; 00288 pcour = pcour->nextInSuperList ; 00289 } 00290 return resul; 00291 } 00292 00293 DoubleListElement * DoubleList::find(ReferenceObjectHandle * p) 00294 { 00295 DoubleListElement * pcour = _start; 00296 DoubleListElement * resul = NULL; 00297 while( ( pcour != NULL ) && 00298 ( resul == NULL ) ) 00299 { 00300 if(pcour->listeElem==p) 00301 { 00302 resul = pcour; 00303 } 00304 OMASSERTM( pcour != pcour->nextInActiveList, "" ) ; 00305 pcour = pcour->nextInActiveList; 00306 } 00307 return resul; 00308 } 00309 00310 DoubleListElement * DoubleList::superListBegin() 00311 { 00312 return _startOfSuperList; 00313 } 00314 00315 DoubleListElement * DoubleList::superListNext(DoubleListElement * pcour) 00316 { 00317 if(pcour == NULL) 00318 { 00319 cerr<<"DoubleList::superListNext WARNING:Suivant de NULL inexistant"<<endl; 00320 return NULL; 00321 } 00322 else 00323 { 00324 OMASSERTM( pcour->nextInSuperList != pcour, "" ) ; 00325 return pcour->nextInSuperList ; 00326 } 00327 } 00328 00329 DoubleListElement * DoubleList::begin() 00330 { 00331 return _start; 00332 } 00333 00334 DoubleListElement * DoubleList::next(DoubleListElement * pcour) 00335 { 00336 if(pcour == NULL) 00337 { 00338 cerr<<"DoubleList::next WARNING:Suivant de NULL inexistant"<<endl; 00339 return NULL; 00340 } 00341 else 00342 { 00343 OMASSERTM( pcour->nextInActiveList != pcour, "" ) ; 00344 return pcour->nextInActiveList; 00345 } 00346 } 00347
Documentation generated on Mon Jun 9 11:45:56 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |