OMKDoubleList.cpp

Go to the documentation of this file.
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 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:56 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007