Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PsController.cxx

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 <PsController.h>
00019 #include <PsObjectDescriptor.h>
00020 #include <PsnDoubleList.h>
00021 #include <PsnSequentialSemaphore.h>
00022 #include <math.h>
00023 #include <PsObjectDescriptor.h>
00024 #include <PsSimulatedObject.h>
00025 #include <PsnSvmLink.h>
00026 #include <typeinfo>
00027 #include <PsDuplicatedObject.h>
00028 #include "PsName.h"
00029 #include "PsNameServer.h"
00030 #include "PsnScheduler.h"
00031 #include "PsnFrameScheduler.h"
00032 
00033 #include <unistd.h>
00034 #include "PsEvent.h"
00035 #include "PsSystemEventIdentifier.h"
00036 #include "PsUserException.h"
00037 #include "PsNullOutputCreator.h"
00038 
00039 PsDate PsController::initialSimulationDate = 0 ;
00040 PsController::WarningLevels PsController::warningLevel = PsController::NoWarnings ;
00041 
00042 PsKernelObjectAbstractFactory * PsController::kernelObjectFactory = NULL ;
00043 
00044 bool PsController::setKernelObjectFactory ( PsKernelObjectAbstractFactory * aFactory )
00045 {
00046    if ( kernelObjectFactory != NULL ) 
00047       {
00048          kernelObjectFactory = aFactory ;
00049          return true ;
00050       }
00051    else 
00052       {
00053          return false ;
00054       }
00055 }
00056 
00057 PsKernelObjectAbstractFactory * PsController::getKernelObjectFactory ( ) 
00058 {
00059    if ( kernelObjectFactory == NULL ) 
00060       {
00061          kernelObjectFactory = new PsKernelObjectClassicFactory () ;
00062       }
00063 
00064    return kernelObjectFactory ;
00065 }
00066 
00067 //--------------------------------------------------------
00068 
00069 PsController::PsController(PsObjectDescriptor & initialObjects,
00070                            const PsDate & initialDate )   :  
00071    PsSimulatedObject(*this, initialObjects ), 
00072    _simulationTree ( initialObjects ),
00073    _nbStepsByCycle ( 0 ),
00074    _controledObjectsSignalsDispatcher( *this ),
00075    _numberOfSimulatedSteps ( 0 ),
00076    _showDateAndStepNumber ( false ),
00077    _scheduler (NULL),
00078    _forcedCompute (false)
00079 {
00080 
00081    PsNullOutputCreator::setController(this) ;
00082 
00083    initialSimulationDate = initialDate ;
00084 
00085    //as a controller created throught this constructor has no controller, create the illusion of being handled
00086    _objectHandle = createReferenceObjectHandle( *this ) ;
00087    _computeStatePointer = const_cast<PsnReferenceObjectHandle::SimulatedObjectComputingState *>(&(dynamic_cast<PsnReferenceObjectHandle *>(_objectHandle)->getComputingState () )) ;
00088    
00089    //connect the object description to the controller
00090    _simulationTree._pointerToSimulatedObject = this ;
00091    _simulationTree._destroySimulatedObject =  false ;
00092 
00093   //create data structures for system events managed by the controller
00094   _systemEventsList [ 0 ] = new list <PsEvent *> () ;
00095   _systemEventsList [ 1 ] = new list <PsEvent *> () ;
00096   _currentWritableSystemEventsList = 0 ;
00097 
00098   //create data structures to keep track of objects needing activation because they have pending events
00099   _objectsNeedingActivationList[0]=new list<PsnReferenceObjectHandle *> () ;
00100   _objectsNeedingActivationList[1]=new list<PsnReferenceObjectHandle *> () ;
00101   _currentListOfObjectsNeedingActivation = 0 ;
00102 
00103    // initialisation de l'état du controleur
00104   assert ( _computeStatePointer != NULL ) ;
00105    *_computeStatePointer = PsnReferenceObjectHandle::initial ;
00106 }
00107 
00108 void PsController::finish()
00109 {
00110 #ifdef _DEBUGEXEC
00111    cerr<<"PsController::finish()"<<endl;
00112 #endif
00113    //call destroyObject on all the sons
00114    for ( PsObjectDescriptor::SonsContainerType::iterator i = _simulationTree.getSons().begin() ;
00115          i !=  _simulationTree.getSons().end() ;
00116          ++i )
00117       {
00118          assert ( (*i) != NULL ) ;
00119          destroyObject ( (*i)->getName() ,true ) ;
00120       }
00121 }
00122 
00123 
00124 PsController::~PsController() 
00125 {
00126   int i;
00127   int minor;
00128   
00129   if ( _scheduler != NULL ) 
00130      {
00131         delete _scheduler ;
00132         _scheduler = NULL ;
00133      }
00134 
00135   // destruction of data structures related to event handling
00136   for(i=0;i<2;i++) 
00137      {
00138         if ( _systemEventsList[i] != NULL ) delete  _systemEventsList[i] ;
00139         if ( _objectsNeedingActivationList[i] != NULL) delete _objectsNeedingActivationList[i];
00140      }
00141 
00142   purgeMemoryFromOldEvents ( _date + _stepPeriod ) ;
00143   
00144   // destruction of pending registrations
00145   for ( map<PsName, PsnSignalDispatcher *>::iterator i = _pendingRegistrationRequests.begin() ;
00146         i != _pendingRegistrationRequests.end() ;
00147         ++i )
00148      {
00149         // delete the signal dispatcher
00150         delete i->second ;
00151         
00152         // removal from the map omitted, because automatic at destruction of the data member
00153      }
00154   
00155 
00156   if ( _objectHandle != NULL ) delete _objectHandle ;
00157 }
00158 
00159 
00160 
00161 void PsController::createControlledObjects( const PsObjectDescriptor * subTree ) 
00162 {
00163    assert ( subTree != NULL ) ;
00164    //go through the simulation tree to find all objects that have to be created
00165    list<PsObjectDescriptor *>::const_iterator i = subTree->getSons()->begin() ;
00166 
00167    while ( i != subTree->getSons()->end() )
00168       {
00169          assert ( *i != NULL ) ;
00170 #ifdef _DEBUGOBJECTCREATION
00171          cerr<<"Creating "<< (*i)->getName() << endl ;
00172 #endif
00173          //create the object
00174          createReferenceObject ( *i ) ;
00175          
00176          //create the subTree of that object
00177          createControlledObjects ( *i ) ;
00178          
00179 #ifdef _DEBUGOBJECTCREATION
00180          cerr<<"Created "<< (*i)->getName() << endl ;
00181 #endif
00182          ++i ;
00183       }
00184 }
00185 
00186 
00187 
00188 void PsController::computeScheduling(bool fromOriginal)
00189 {
00190    //cerr<<"PsController::computeScheduling at date "<<_date<<endl;
00191   
00192    list<PsObjectDescriptor * > objectDescriptorList ;
00193    int freq;
00194    
00195    _simulationTree.getDescendants( &objectDescriptorList );
00196    
00197    list<PsObjectDescriptor * >::iterator i ;
00198  
00199    //remove objects with no frequency from the list
00200    i = objectDescriptorList.begin () ;
00201 
00202    while ( i != objectDescriptorList.end() )
00203       {
00204          if ( fromOriginal )
00205             {
00206                if ((*i)->getOriginalFrequency() == 0 )
00207                   {
00208                      i = objectDescriptorList.erase ( i ) ;
00209                   }
00210                else
00211                   {
00212                      ++i ;
00213                   }
00214             }
00215          else
00216             {
00217                if ( (*i)->getFrequency() == 0 )
00218                   {
00219                      i = objectDescriptorList.erase ( i ) ;
00220                   }
00221                else
00222                   {
00223                      ++i ;
00224                   }
00225             }
00226       }
00227 
00228     i = objectDescriptorList.begin () ;
00229    
00230    if ( i == objectDescriptorList.end() ) 
00231       {
00232          //no objects need regular activation
00233          if ( fromOriginal )
00234             {
00235                _stepFrequency = _simulationTree.getOriginalFrequency() ;
00236             }
00237          else 
00238             {
00239                _stepFrequency = _simulationTree.getFrequency() ;
00240             }
00241          if ( _stepFrequency == 0 ) 
00242             {
00243                warning ("Controller needs a frequency: assigning 1", SomeWarnings) ;
00244                _stepFrequency = 1 ;
00245            }
00246         setCycleFrequency(_stepFrequency) ;
00247      }
00248   else 
00249      {
00250         //initialise the loop with coherant values
00251         if (fromOriginal)
00252            {
00253               setCycleFrequency ( (*i)->getOriginalFrequency() ) ;
00254            }
00255         else
00256            {
00257               setCycleFrequency ( (*i)->getFrequency() ) ; 
00258            }
00259         _stepFrequency = 1 ;
00260      }
00261   
00262   while ( i != objectDescriptorList.end() )
00263     {
00264        if (fromOriginal)
00265           {
00266              freq = (*i)->getOriginalFrequency() ;
00267 
00268              if ( freq != (*i)->getFrequency() ) //the objects frequency has changed previously,
00269                 {
00270                    //reset it:
00271                    (*i)->setFrequency ( freq ) ;
00272                    
00273                    //send MaskChangeObjectFrequency to the object
00274                    PsnReferenceObjectHandle * referenceObjectHandle = _referenceObjectsMap.getObjectOfIndex ((*i)->getName() ) ;
00275                    if ( referenceObjectHandle != NULL )
00276                       {
00277                          //use receive event is sub optimal, because MaskChangeObjectFrequency is a system event, thus implying a copy is sent back to the controller, whithout effect
00278                          referenceObjectHandle->receiveEvent ( new PsValuedEvent<PsFrequency> (PsSystemEventIdentifier::MaskChangeObjectFrequency,
00279                                                                                                _date,
00280                                                                                                getName(),
00281                                                                                                (*i)->getName(),
00282                                                                                                (*i)->getFrequency() ) );
00283                       }            
00284                 }
00285           }
00286        else
00287           {
00288              freq = (*i)->getFrequency() ; 
00289           }
00290 
00291 
00292       if (freq != 0) 
00293          {
00294             setCycleFrequency ( gcd( freq, getCycleFrequency() ) ) ;
00295             _stepFrequency=(int)((freq*_stepFrequency)/gcd(freq,_stepFrequency));  //lcm(freq,_stepFrequency);
00296          }
00297 
00298       ++ i ;
00299     }
00300 
00301   assert ( _stepFrequency != 0 ) ;
00302   
00303   if ( _stepFrequency != _simulationTree.getFrequency() )
00304      {//the controller has changed frequency
00305         
00306         _simulationTree.setFrequency( _stepFrequency ) ;
00307 
00308         fireSignal(PsSystemEventIdentifier::MaskControllerFrequencyChange) ;
00309      }
00310   
00311   _stepPeriod = int(1000./_stepFrequency);
00312 
00313   _nbStepsByCycle = _stepFrequency/getCycleFrequency() ;
00314 
00315   if ( _scheduler != NULL ) delete _scheduler ;
00316   
00317   _scheduler = createScheduler() ;
00318   
00319 }
00320 
00321 
00322 
00323 PsnScheduler * PsController::createScheduler () {
00324 
00325    return new PsnFrameScheduler ( _nbStepsByCycle ) ;
00326 
00327 }
00328 
00329 
00330 
00331 void PsController::scheduleControlledObjects() 
00332 {
00333    PsNameToPointerMap<PsnReferenceObjectHandle>::iterator pTab;
00334 
00335    //for all controlled objects
00336    for (pTab=_referenceObjectsMap.begin(); pTab!= _referenceObjectsMap.end(); pTab++)
00337       {
00338          if ((*pTab).second != getObjectHandle() ) //a controller shouldn't schedule itself. 
00339             {
00340                //schedule object correctly on the each frame of a cycle
00341                scheduleObject((*pTab).second);
00342             } 
00343       } 
00344 }
00345 
00346 
00347 
00348 void PsController::scheduleObject(PsnReferenceObjectHandle* ref) {
00349 
00350    assert (_scheduler != NULL) ;
00351    
00352    int objectFrequency = ref->getSimulatedObject().getObjectDescriptor().getFrequency() ;
00353 
00354 #ifndef NDEBUG
00355    int adaptedFrequency = computeAdequateFrequency ( objectFrequency ) ;
00356    assert ( (objectFrequency == adaptedFrequency) || ( objectFrequency == 0 ) ) ;
00357 #endif
00358 
00359    if ( objectFrequency != 0 ) 
00360      {
00361         int nbFramesARaterPlusUn=int(_controller._stepFrequency/objectFrequency);
00362         
00363         for(int minor=0;minor<_nbStepsByCycle;minor++) 
00364            {
00365               if (minor%nbFramesARaterPlusUn==0) 
00366                  {  //earliest execution 
00367                     _scheduler->addToScheduable( ref , minor );
00368                  }
00369            }
00370         if ( ref->getComputingState() == PsnReferenceObjectHandle::running ) 
00371            {
00372               _scheduler->schedule ( ref ) ;
00373            }   
00374      }
00375 }
00376 
00377 
00378 
00379 PsFrequency PsController::computeAdequateFrequency(const PsFrequency & suggestedFrequency) {
00380    PsFrequency result ;
00381    list <PsFrequency> listOfAvailableFrequencies ;
00382 
00383    // construct the list of frequencies that can be scheduled without changing the frame structure
00384    for ( int i = 1 ; i <= _nbStepsByCycle ; ++i )
00385       {
00386          if ( _stepFrequency % i == 0 )
00387             {
00388                listOfAvailableFrequencies.push_back(_stepFrequency / i ) ;
00389             }
00390       }
00391 
00392    // find the closest frequency in listOfAvailableFrequencies to suggestedFrequency
00393 
00394    list<PsFrequency>::const_iterator frequencyIterator = listOfAvailableFrequencies.begin() ;
00395    while ( frequencyIterator != listOfAvailableFrequencies.end() && 
00396            ( suggestedFrequency <= *frequencyIterator ) )
00397       {
00398          ++frequencyIterator ;
00399       }
00400    
00401    if (frequencyIterator == listOfAvailableFrequencies.end() )
00402       { //the suggested frequency is < _cycleFrequency
00403          result = getCycleFrequency() ; //cannot schedule object slower than _cycleFrequency
00404       }
00405    else 
00406       { 
00407          if ( frequencyIterator == listOfAvailableFrequencies.begin() )
00408             { // *(listOfAvailableFrequencies.begin()) == _stepFrequency < suggestedFrequency
00409                result = _stepFrequency ; //cannot scheduleObject faster the _stepFrequency
00410             }
00411          else 
00412             { // *(frequencyIterator) < suggestedFrequency <= *(frequencyIterator--)
00413                PsFrequency lowerEstimate = *frequencyIterator ;
00414                -- frequencyIterator ;
00415                PsFrequency higherEstimate = *frequencyIterator ;
00416 
00417                // lowerEstimate < suggestedFrequency <= higherEstimate
00418                if ( (suggestedFrequency - lowerEstimate) < (higherEstimate - suggestedFrequency) )
00419                   {
00420                      result = lowerEstimate ;
00421                   }
00422                else
00423                   {
00424                      result = higherEstimate ;
00425                   }
00426             }
00427       }
00428    return result ;
00429 }
00430 
00431 
00432 
00433 void PsController::init() 
00434 {
00435 
00436    PsNameToPointerMap<PsnReferenceObjectHandle>::iterator pTab;
00437    
00438    computeScheduling(true) ;
00439 
00440 #ifdef _USESSTREAM
00441    ostringstream warningMessage ;
00442    warningMessage << "PsController::init : controler's cycle frequency : " << getCycleFrequency() <<" Hz"<< endl ;
00443    warningMessage << "PsController::init : controler's step frequency : " << _stepFrequency <<" Hz"<< endl ;
00444    warning ( warningMessage.str() , AllWarnings ) ;
00445 #else   
00446    ostrstream warningMessage ;
00447    warningMessage << "PsController::init : controler's cycle frequency : " << getCycleFrequency() <<" Hz"<< endl ;
00448    warningMessage << "PsController::init : controler's step frequency : " << _stepFrequency <<" Hz"<< endl ;
00449    warningMessage.put('\0');
00450    warning ( warningMessage.str() , AllWarnings ) ;
00451    delete warningMessage.str() ;
00452 #endif
00453 
00454    createControlledObjects ( &_simulationTree ) ;
00455          
00456    scheduleControlledObjects() ;
00457 
00458    _referenceObjectsMap.addObjectWithIndex (getName(), (PsnReferenceObjectHandle *)getObjectHandle());
00459 
00460    PsNameToPointerMap<PsInputNT>::iterator i;
00461 
00462    //pretend init order was sent just before initialsimulationDate
00463    _date = PsController::initialSimulationDate - _stepPeriod ;
00464    
00465    //all initial simulation objects are started
00466    for ( pTab = _referenceObjectsMap.begin();
00467          pTab != _referenceObjectsMap.end(); 
00468          pTab++ )
00469       {
00470          sendInitialEventsTo ( *(*pTab).second, _date ) ;
00471       }
00472 
00473    advanceSimulatedDate() ;
00474 
00475    //only if initialisation happens at a different simulation date than the first simulation step
00476    //reactToControlledObjectsSystemEvents(); 
00477 }
00478 
00479 
00480 void PsController::run()
00481 {
00482    PsnReferenceObjectHandle * objectHandle = dynamic_cast<PsnReferenceObjectHandle *> ( _objectHandle ) ;
00483    assert ( objectHandle != NULL ) ;
00484    *_computeStatePointer = PsnReferenceObjectHandle::running ;
00485    while(*_computeStatePointer == PsnReferenceObjectHandle::running) 
00486       {
00487          runControllersStep (objectHandle) ;
00488       }//while
00489 }
00490 
00491 
00492 void PsController::runControllersStep(PsnReferenceObjectHandle * objectHandle)
00493 {
00494 #ifdef _DEBUGEXEC
00495    cerr<<"PsController::runControllersStep"<<endl;
00496 #endif
00497    assert ( objectHandle != NULL );
00498    _forcedCompute = true ;
00499 
00500    //the controller has to process system events adressed to itself
00501    objectHandle->processEvents() ;
00502 
00503    //the controller has schedule itself
00504    if( (*_computeStatePointer == PsnReferenceObjectHandle::running) ||
00505        _forcedCompute ) 
00506       {
00507          objectHandle->compute();
00508       }
00509    _forcedCompute = false ;
00510 }
00511 
00512 void PsController::compute ()
00513 {
00514    computeNextSimulationStep();
00515    purgeMemoryFromOldEvents ( getPurgeDate() ) ;
00516    advanceSimulatedDate();
00517 }
00518 
00519 
00520 
00521 PsDate PsController::getPurgeDate()
00522 {
00523    return _date - _stepPeriod ;
00524 }
00525 
00526 
00527 void PsController::purgeMemoryFromOldEvents ( const PsDate & dateOfOldestKept )
00528 {
00529    // purge old events with no known receiver
00530    map<PsName, list <PsEvent *> >::iterator pendingEventsMapIterator = _pendingEventsList.begin() ;
00531    while ( pendingEventsMapIterator != _pendingEventsList.end() )
00532       {
00533         list<PsEvent *>::iterator eventListIterator = pendingEventsMapIterator->second.begin() ;
00534         while ( eventListIterator != pendingEventsMapIterator->second.end() )
00535            {
00536               if ( (*eventListIterator)->date < dateOfOldestKept )
00537                  {
00538                     delete *eventListIterator ;
00539                     eventListIterator = pendingEventsMapIterator->second.erase ( eventListIterator ) ;
00540                  }
00541               else 
00542                  {
00543                     ++ eventListIterator ;
00544                  }
00545            }
00546          if ( pendingEventsMapIterator->second.empty() )
00547             {
00548                _pendingEventsList.erase ( pendingEventsMapIterator++ ) ;
00549             }
00550          else
00551             {
00552                pendingEventsMapIterator++ ;
00553             }
00554       }
00555 
00556 
00557    //purge deleted objects, objects handles and object descriptors
00558    bool disposableElements = !_deletedObjectHandles.empty() ;
00559    pair <PsDate, PsnObjectHandle *> examinedObjectHandle ;
00560    while ( disposableElements )
00561       {
00562          examinedObjectHandle = _deletedObjectHandles.front() ;
00563          if ( examinedObjectHandle.first < dateOfOldestKept )
00564             {
00565 #ifdef _DEBUGEXEC
00566                cerr<<"PsDistributedController::eventsProcessed: deleting "<<examinedObjectHandle.second->getSimulatedObject().getName()<<endl;
00567 #endif
00568                deleteObjectHandle ( examinedObjectHandle.second ) ;
00569                _deletedObjectHandles.pop_front() ;
00570                disposableElements = !_deletedObjectHandles.empty() ;
00571             }
00572          else 
00573             {
00574                disposableElements = false ;
00575             }
00576       }
00577 }
00578 
00579 void PsController::advanceSimulatedDate() 
00580 {
00581    
00582    _numberOfSimulatedSteps++;  
00583       
00584    _date = _date + _stepPeriod;  
00585 
00586    if (_showDateAndStepNumber) 
00587       {
00588          cout<< "Controller starting simulation step number : "<< _numberOfSimulatedSteps
00589              << " with date being "<<_date<<endl;
00590       }
00591 }
00592 
00593 void PsController::computeNextSimulationStep () 
00594 {
00595 #ifdef _DEBUGEXEC
00596    cerr<<"PsController::computeNextSimulationStep"<<endl;
00597    cerr<<"calling reactToControlledObjectsSystemEvents ";
00598 #endif
00599    reactToControlledObjectsSystemEvents () ;
00600 #ifdef _DEBUGEXEC
00601    cerr<<"done "<<endl;
00602 #endif
00603    _scheduler->runStep( (_numberOfSimulatedSteps - 1) % _nbStepsByCycle ) ;
00604 
00605    processEventsOfSuspendedObjects () ;
00606 
00607 #ifdef _VERIFCOHERANCE
00608    //fast coded trace generator for the default controller
00609    PsString nomFich("/tmp/simul.") ;
00610    nomFich<<date;
00611    ofstream fichier(nomFich.getCString());
00612    assert ( fichier.good() ) ;
00613    processEventsOfSuspendedObjects () ;
00614    PsList<PsName> * maListe = listDescendantsOfType( TYPEINFO(PsSimulatedObject) );
00615    PsList<PsName>::iterator i = maListe->begin();
00616    for(;i!=maListe->end(); ++i) {
00617       try {
00618          fichier<<getPointerToSimulatedObjectNamed(*i)->getName()<<" "<<*getPointerToSimulatedObjectNamed(*i)<<";"<<endl;
00619       }
00620       catch (PsException e) {
00621          fichier<<";"<<endl;
00622       }
00623    }
00624    fichier<<"_____________"<<endl;
00625    fichier.close() ;
00626    delete maListe ;   
00627 #endif
00628 #ifdef _DEBUGEXEC
00629    cerr<<"PsController::computeNextSimulationStep done"<<endl;
00630 #endif
00631 }
00632 
00633 
00634 void 
00635 PsController::createObject(const PsObjectDescriptor & newObjectDescription, const PsName & fathersName )
00636 {
00637   PsValuedEvent<PsPair<PsObjectDescriptor,PsName> > creationEvent(PsSystemEventIdentifier::MaskNewObject,
00638                                                                   getSimulatedDate(),
00639                                                                   getName(),
00640                                                                   getName(),
00641                                                                   PsPair<PsObjectDescriptor,PsName>(newObjectDescription,
00642                                                                                                     fathersName) );
00643   sendEvent (creationEvent) ;
00644 }
00645 
00646 
00647 void
00648 PsController::destroyObject(const PsName & name, bool recursively )  // name of the object to destroy
00649 {
00650    PsObjectDescriptor * objectDescriptor = _simulationTree.findDescendantNamed ( name ) ;
00651    
00652    if( objectDescriptor != NULL )
00653       {
00654          if ( recursively ) 
00655             {
00656                for ( PsObjectDescriptor::SonsContainerType::iterator i = objectDescriptor->getSons().begin() ;
00657                      i !=  objectDescriptor->getSons().end() ;
00658                      ++i )
00659                   {
00660                      assert ( (*i) != NULL ) ;
00661                      destroyObject ( (*i)->getName() ,true ) ;
00662                   }
00663             }
00664          sendEvent(name, PsSystemEventIdentifier::MaskStop);
00665          sendEvent(name, PsSystemEventIdentifier::MaskDelete);
00666       }
00667    else 
00668       {
00669 #ifdef _USESSTREAM
00670          ostringstream warningMessage ;
00671          warningMessage<<"PsController::destroyObject "<<name<<" not found"<<endl;
00672          PsName::getNameServer()->printToStream(warningMessage,"\n") ;
00673          warning (warningMessage.str(), SomeWarnings) ;
00674 #else
00675          ostrstream warningMessage ;
00676          warningMessage<<"PsController::destroyObject "<<name<<" not found"<<endl;
00677          PsName::getNameServer()->printToStream(warningMessage,"\n") ;
00678          warningMessage.put ('\0') ;
00679          warning (warningMessage.str(), SomeWarnings) ;
00680          delete warningMessage.str() ;
00681 #endif
00682       }
00683 }
00684 
00685 
00686 
00687 void PsController::changeObjectsFather (PsObjectDescriptor * object, PsObjectDescriptor * newFather)
00688 {
00689    assert ( object != NULL ) ;
00690    assert ( newFather != NULL ) ;
00691    object->setFathersDescription( newFather ) ;
00692 }
00693 
00694 
00695 
00696 void PsController::changeObjectsFather (const PsName & name, const PsName & newFather)
00697 {
00698    PsObjectDescriptor * object = _simulationTree.findDescendantNamed ( name ) ;
00699    if ( object != NULL )
00700       {
00701          PsObjectDescriptor * father = _simulationTree.findDescendantNamed ( newFather ) ;
00702          if (father != NULL) 
00703             {
00704                object->setFathersDescription( father ) ;
00705             }
00706          else
00707             {
00708 #ifdef _USESSTREAM
00709                ostringstream warningMessage ; 
00710                warningMessage<<"PsController::changeObjectsFather new father ("<<newFather
00711                              <<") for object "<<name<<"doesn't exist"<<endl;
00712                warning (warningMessage.str(), SomeWarnings) ;
00713 #else
00714                ostrstream warningMessage ; 
00715                warningMessage<<"PsController::changeObjectsFather new father ("<<newFather
00716                              <<") for object "<<name<<"doesn't exist"<<endl;
00717                warningMessage.put('\0') ;
00718                warning (warningMessage.str(), SomeWarnings) ;
00719                delete warningMessage.str() ;
00720 #endif
00721             }
00722       }
00723    else
00724       {
00725 #ifdef _USESSTREAM
00726          ostringstream warningMessage ; 
00727          warningMessage<<"PsController::changeObjectsFather object "<<name<<"doesn't exist"<<endl;
00728          warning (warningMessage.str(), SomeWarnings) ;
00729 #else
00730          ostrstream warningMessage ; 
00731          warningMessage<<"PsController::changeObjectsFather object "<<name<<"doesn't exist"<<endl;
00732          warningMessage.put ('\0') ;
00733          warning (warningMessage.str(), SomeWarnings) ;
00734          delete warningMessage.str() ;
00735 #endif
00736       }
00737 }
00738 
00739 
00740 
00741 bool PsController::addToPendingRegistrations(const PsEventIdentifier & sig, 
00742                                              const PsName & producer,
00743                                              const PsEventIdentifier & eventId,
00744                                              const PsName & registrant)
00745 {
00746    _mutexPendingDataStructures.protect() ;
00747    map<PsName, PsnSignalDispatcher *>::iterator i = _pendingRegistrationRequests.find (producer) ;
00748    if ( i == _pendingRegistrationRequests.end() )
00749       {
00750          i = _pendingRegistrationRequests.insert ( pair <PsName,PsnSignalDispatcher *> (producer,
00751                                                                                        new PsnSignalDispatcher(*this) ) ).first ;
00752       }
00753 
00754    i->second->registerForSignal( sig, registrant, eventId ) ;
00755 
00756    _mutexPendingDataStructures.unprotect() ;
00757 
00758    return true ;
00759 }
00760 
00761 bool PsController::removeFromPendingRegistrations ( const PsEventIdentifier & sig,
00762                                                     const PsName & producer,
00763                                                     const PsName & registrant)
00764 {
00765    bool result ;
00766    _mutexPendingDataStructures.protect() ;
00767    map<PsName, PsnSignalDispatcher *>::iterator i = _pendingRegistrationRequests.find (producer) ;
00768    if ( i == _pendingRegistrationRequests.end() )
00769       {
00770          result = false ;
00771       }
00772    else 
00773       {
00774          result = i->second->cancelRegistrationForSignal ( sig, registrant ) ;
00775       }
00776 
00777    _mutexPendingDataStructures.unprotect() ;
00778 
00779    return result ;
00780 }
00781 
00782 
00783 
00784 void PsController::addToPendingEvents (PsEvent * event) 
00785 {
00786    if (event != NULL)
00787       {
00788 #ifdef _USESSTREAM
00789          ostringstream warningMessage ;
00790          warningMessage<<"PsController::addToPendingEvents : Adding "<<*event<<" to pending events"
00791                        <<" of yet unexisting object: "<<event->receiver<<endl;
00792          warning ( warningMessage.str() , AllWarnings ) ;
00793 #else
00794          ostrstream warningMessage ;
00795          warningMessage<<"PsController::addToPendingEvents : Adding "<<*event<<" to pending events"
00796                        <<" of yet unexisting object: "<<event->receiver<<endl;
00797          warningMessage.put('\0') ;
00798          warning ( warningMessage.str() , AllWarnings ) ;
00799          delete warningMessage.str() ;
00800 #endif
00801          _mutexPendingDataStructures.protect() ;
00802          map<PsName, list <PsEvent *> >::iterator pendingEventsMapIterator = _pendingEventsList.find( event->receiver ) ;
00803          if ( pendingEventsMapIterator != _pendingEventsList.end() )
00804             {
00805                pendingEventsMapIterator->second.push_back(event) ;
00806             }
00807          else
00808             {
00809                _pendingEventsList.insert (pair<PsName, list<PsEvent *> > (event->receiver, list<PsEvent *>(1,event) ) ) ;
00810             }
00811          _mutexPendingDataStructures.unprotect() ;
00812       }
00813 }
00814 
00815 
00816 void PsController::sendInitialEventsTo ( PsnReferenceObjectHandle & objectHandle, const PsDate & dateOfMaskStart )
00817 { 
00818    if (&objectHandle.getSimulatedObject() != this )
00819       {
00820 #ifdef _DEBUGEXEC
00821         cerr<<"Sending init event to "<<objectHandle.getSimulatedObject().getObjectDescriptor().getName()<<endl; 
00822 #endif
00823         PsEvent * startEvent = new PsEvent(PsSystemEventIdentifier::MaskStart, 
00824                                            dateOfMaskStart,
00825                                            getName(),
00826                                            objectHandle.getSimulatedObject().getObjectDescriptor().getName() ) ;
00827          sendEvent ( startEvent ) ;
00828 
00829          //objects whose frequency is 0 must be suspended
00830          if( objectHandle.getSimulatedObject().getObjectDescriptor().getFrequency() == 0 ) 
00831             {
00832                sendEvent(&objectHandle.getSimulatedObject(),PsSystemEventIdentifier::MaskSuspend);
00833             }
00834          
00835          //send any pending events 
00836 
00837          /* no mutex protection needed, because this is only called during controller's system event processing */
00838 
00839          map<PsName, list <PsEvent *> >::iterator pendingEvents = _pendingEventsList.find(objectHandle.getSimulatedObject().getObjectDescriptor().getName() ) ;
00840          if ( pendingEvents != _pendingEventsList.end() )
00841             {
00842 #ifdef _DEBUGEXEC
00843                cerr<<"Found pending events for "<<objectHandle.getSimulatedObject().getObjectDescriptor().getName()<<endl;
00844 #endif
00845                for ( list <PsEvent *>::iterator pendingEventsListIterator = pendingEvents->second.begin() ;
00846                      pendingEventsListIterator != pendingEvents->second.end() ;
00847                      ++pendingEventsListIterator)
00848                   {
00849 #ifdef _DEBUGEXEC
00850                      cerr<<"sent "<<**pendingEventsListIterator<< "to "<<objectHandle.getSimulatedObject().getObjectDescriptor().getName()<<endl;
00851 #endif
00852                      objectHandle.getSimulatedObject().sendEvent(*pendingEventsListIterator) ; 
00853                   }
00854                _pendingEventsList.erase ( pendingEvents ) ;
00855             }
00856       }
00857    
00858 }
00859 
00860 
00861 
00862 PsnObjectHandle *
00863 PsController::removeObjectFromDataStructures(const PsName & nom) {
00864     PsnReferenceObjectHandle * referentiel = NULL ;
00865 
00866     referentiel = _referenceObjectsMap.getObjectOfIndex(nom);
00867     //Purge all data structures related to event management
00868     for(int i=0;i<2;i++) 
00869        {
00870           _objectsNeedingActivationList[i]->remove( referentiel );
00871        }
00872 
00873     _listOfObjectsWithPostPonedEvents.remove ( referentiel ) ;
00874 
00875     _referenceObjectsMap.erase(nom);
00876 
00877     _scheduler->unschedule( referentiel ) ;
00878 
00879     _scheduler->removeFromScheduable( referentiel ) ;
00880     
00881     return referentiel;
00882 }
00883 
00884 
00885 void PsController::deleteObjectHandle ( PsnObjectHandle * objectHandle )
00886 {
00887    
00888    PsObjectDescriptor * objectDescriptor  = const_cast<PsObjectDescriptor *>(& objectHandle->getSimulatedObject().getObjectDescriptor() ) ;
00889 
00890    delete objectHandle ;
00891 
00892    //The object description is referenced by the simulation tree and the simulated object
00893    //delete the object description only if it isn't referenced by its simulated object 
00894    if ( objectDescriptor->_pointerToSimulatedObject == NULL ) 
00895       {
00896 #ifdef _DEBUGEXEC
00897          cerr<<"PsController::deleteObject: deleting object descriptor of object "<<objectDescriptor->getName()<<endl;
00898 #endif
00899          delete objectDescriptor;
00900       }
00901 }
00902 
00903 void 
00904 PsController::deleteObject( PsObjectDescriptor * objectDescriptor )
00905 {
00906 #ifdef _DEBUGEXEC
00907    cerr <<"PsController::deleteObject "<<objectDescriptor->getName()<<endl;
00908 #endif
00909 
00910    if (objectDescriptor != &getObjectDescriptor() )
00911       //shouldn't delete oneself !
00912       {   
00913          assert ( objectDescriptor != NULL) ;
00914          
00915          // remove from the kernel's data structures
00916          PsnObjectHandle * toDelete = removeObjectFromDataStructures( objectDescriptor->getName() ) ;
00917          
00918          //remove the object descriptor from the simulation tree
00919          if ( objectDescriptor->getFathersObjectDescriptor() != objectDescriptor )
00920             {
00921                objectDescriptor->getFathersObjectDescriptor()->removeSon ( objectDescriptor ) ;
00922             }
00923 
00924          if ( toDelete != NULL )
00925             {
00926                //put the object handle in the list of object to be deleted
00927                _deletedObjectHandles.push_back ( make_pair ( _date, toDelete) ) ;
00928             }
00929       }
00930 }
00931 
00932 //******************************************************
00933 
00934 PsSimulatedObject * PsController::createDescribedObject(const PsObjectDescriptor * description ) 
00935 {
00936    PsSimulatedObject * obj = description->createDescribedObject() ;
00937 
00938    return obj;
00939 }
00940 
00941 
00942 //--------------------------------------------------------
00943 void PsController::processNewObjectDeclaration ( PsObjectDescriptor & declaration, const PsDate & declarationDate )
00944 {
00945    PsnReferenceObjectHandle * objectHandle = createReferenceObject (  & declaration ) ;
00946    assert ( objectHandle != NULL ) ;
00947    if ( declaration.getFrequency() != computeAdequateFrequency ( declaration.getFrequency() ) )
00948       {
00949          //the whole scheduling data structure needs recalculating
00950          computeScheduling ( false ) ;
00951          
00952          //the new object will therefore be scheduled with all the others
00953          scheduleControlledObjects() ;
00954       }
00955    else
00956       {
00957          scheduleObject ( objectHandle ) ;
00958       }
00959    sendInitialEventsTo ( *objectHandle, declarationDate ) ;
00960 }
00961 
00962 
00963 PsnReferenceObjectHandle *
00964 PsController::createReferenceObject (const PsObjectDescriptor * objectDescription)
00965      
00966 {
00967    assert (objectDescription != NULL );
00968 #ifdef _DEBUGOBJECTCREATION
00969    cerr<<"PsController::createReferenceObject "<<endl;
00970 #endif
00971    PsnReferenceObjectHandle * result = NULL ;
00972 
00973    PsSimulatedObject * createdObject = createDescribedObject ( objectDescription ) ;
00974 
00975    if (createdObject != NULL) 
00976       {
00977          result = createReferenceObjectHandle (*createdObject);
00978          
00979          _referenceObjectsMap.addObjectWithIndex (objectDescription->getName(), result);
00980          
00981       }
00982    else
00983       {
00984          cerr<<"PsController::createReferenceObject unable to create"<<*objectDescription<<endl;
00985       }
00986 #ifdef _DEBUGOBJECTCREATION
00987          cerr<<"PsController::createReferenceObject ended"<<endl;
00988 #endif
00989    return result;
00990 }
00991 
00992 PsDuplicatedObject *
00993 PsController::getPointerToDuplicatedObjectNamed (const PsName & nom) 
00994 {
00995    PsString messErreur="PsController::getPointerToDuplicatedObjectNamed ";
00996    PsSimulatedObject * resultatPossible;
00997    PsDuplicatedObject * resul;  
00998    //Soit l'objet est déjà un référentiel, soit il faut en faire un référentiel
00999    resultatPossible=getPointerToSimulatedObjectNamed(nom);
01000    if (resultatPossible==NULL) {
01001       PsnReferenceObjectHandle * refe = _referenceObjectsMap.getObjectOfIndex(nom);
01002       if (refe==NULL) {
01003          messErreur=messErreur+"\n Pas d'objet "+nom+" dans le processus";
01004          PsController::error(messErreur.getCString());
01005       }   
01006    }
01007    else {
01008       resul=dynamic_cast<PsDuplicatedObject *>(resultatPossible);
01009       if (resul==NULL) {
01010          messErreur=messErreur+": Impossible d'obtenir un pointeur sur l'objet : ";
01011          messErreur=messErreur+nom+": Ce n'est pas un objet duplicable";
01012          PsController::error(messErreur.getCString());
01013       }
01014    }
01015    return resul;
01016 }
01017 
01018 PsSimulatedObject *
01019 PsController::getPointerToSimulatedObjectNamed (const PsName & nom) 
01020 {
01021    PsSimulatedObject * resul;  
01022    //Soit l'objet est déjà un référentiel, soit il faut en faire un référentiel
01023    PsnReferenceObjectHandle * refe = _referenceObjectsMap.getObjectOfIndex(nom);
01024    if (refe==NULL) {
01025       if ( nom == getName() ) {
01026          resul = this ;
01027       }
01028       else 
01029          {
01030             resul = NULL;
01031          }
01032    }
01033    else {
01034       resul=&refe->getSimulatedObject();  
01035    }
01036   return resul;
01037 }
01038 
01039 const PsObjectDescriptor & PsController::getObjectDescriptorOfObject(const PsName & objectName) 
01040 {
01041    if (_simulationTree.findDescendantNamed(objectName) != NULL )
01042       {
01043          return *(_simulationTree.findDescendantNamed(objectName));
01044       }
01045    else 
01046       {
01047          //the object might have just been deleted : look for it in _deletedObjectHandles
01048          list <pair <PsDate, PsnObjectHandle *> >::iterator i = _deletedObjectHandles.begin() ;
01049          while ( i != _deletedObjectHandles.end() )
01050             {
01051                if (i->second->getSimulatedObject().getName() == objectName )
01052                   {
01053                      return i->second->getSimulatedObject().getObjectDescriptor() ;
01054                   }
01055                ++i ;
01056             }
01057          PsUserException e("UnknownObject :") ; 
01058          e<<objectName ;
01059          throw e ;
01060       }
01061 }
01062    
01063 
01064 
01065 //**********************************************
01066 // aspects frequentiels
01067 const PsDate & 
01068 PsController::getSimulatedDate () const 
01069 {
01070     return _date;
01071 }
01072 
01073 void PsController::setCycleFrequency(int newFreq) 
01074 {
01075    _cycleFrequency = newFreq ;
01076    _cyclePeriod = 1000/newFreq ; 
01077 }
01078 
01079 int PsController::getCycleFrequency() const 
01080 {
01081    return _cycleFrequency ;
01082 }
01083 
01084 
01085 int PsController::getCyclePeriod() const 
01086 {
01087    return _cyclePeriod ;
01088 }
01089 
01090 
01091 
01092 int PsController::lcm (const int a, const int b) {
01093    return (a * b / gcd (a, b)) ;
01094 }
01095  
01096 int PsController::gcd (const int a, const int b) {
01097   int res = a ;
01098   if (b != 0) {
01099      res = gcd (b, a % b) ;
01100   }
01101   return res ;
01102 }
01103 
01104 
01105 //- affichage du pas -------------------------------------
01106 //
01107 void PsController::showDateAndStepNumber(bool show)
01108 {
01109   _showDateAndStepNumber = show;
01110 }
01111 
01112 
01113 void PsController::error (const char * Errormess) 
01114 {
01115    throw PsUserException(Errormess) ;
01116 }
01117 
01118 void PsController::warning ( const string & warningMessage, WarningLevels minWarningLevel )
01119 {
01120    assert ( minWarningLevel != NoWarnings ) ;
01121    if ( warningLevel >= minWarningLevel )
01122       {
01123          cerr<<warningMessage<<endl ;
01124       }
01125    if ( warningLevel == ExceptionOnWarnings )
01126       {
01127          throw warningMessage ;
01128       }
01129    if ( warningLevel == FatalWarnings )
01130       {
01131          exit ( -1 ) ;
01132       }
01133 }
01134 
01135 
01136 void PsController::switchSystemEventList() {
01137    _currentWritableSystemEventsList = 1 - _currentWritableSystemEventsList ;
01138 }
01139 
01140 void PsController::actOnSystemEvent ( PsEvent * event ) 
01141 {
01142    //do not send a copy of a system event to oneself (avoids redundancy), except if the controller is being controlled
01143    if (event->receiver != getName() )
01144       {
01145          _mutexSystemEventsList.protect() ;
01146          PsEvent::insertInList ( _systemEventsList[ _currentWritableSystemEventsList ],
01147                                  event->clone() );
01148          _mutexSystemEventsList.unprotect() ;
01149       }
01150    else if (this != & getController() )
01151       {
01152          //the controller is being controlled : send a copy of the event to the controllers controller
01153          getController().actOnSystemEvent ( event ) ;
01154       }
01155 }
01156  
01157 bool PsController::processEvent (PsEvent * event ) 
01158 {
01159    const PsEventIdentifier & eventId ( event->eventId ) ;
01160    if (eventId == PsSystemEventIdentifier::MaskRestart) 
01161       {
01162          if (*_computeStatePointer == PsnReferenceObjectHandle::stopped)
01163             {
01164                *_computeStatePointer = PsnReferenceObjectHandle::initial ;
01165                //implementation very difficult, because the original simulation tree has been modified
01166                init() ;
01167                assert (false) ; 
01168             }
01169          else
01170             {
01171                warning(" PsController::processEvent should be stopped before restarted", AllWarnings);
01172             }
01173       }
01174    else if ( eventId == PsSystemEventIdentifier::MaskResume ) 
01175       {
01176          *_computeStatePointer = PsnReferenceObjectHandle::running;
01177       } 
01178    else if ( eventId == PsSystemEventIdentifier::MaskSuspend ) 
01179       {
01180          if (*_computeStatePointer != PsnReferenceObjectHandle::suspended )
01181             {
01182                // moving in suspended mode
01183                // stop computations, even forced
01184                _forcedCompute = false ;
01185                *_computeStatePointer = PsnReferenceObjectHandle::suspended ;
01186             }
01187       } 
01188    else if ( eventId == PsSystemEventIdentifier::MaskStop ) 
01189       {
01190          if (*_computeStatePointer != PsnReferenceObjectHandle::stopped )
01191             {
01192                *_computeStatePointer=PsnReferenceObjectHandle::stopped ;
01193                
01194                finish() ;
01195             }
01196          
01197       } 
01198    else if ( eventId == PsSystemEventIdentifier::MaskStart ) 
01199       {
01200       
01201          *_computeStatePointer=PsnReferenceObjectHandle::running;
01202          //this produces incorrect behaviour from the point of view of an object controlling the controller
01203          //if(_date==PsController::initialSimulationDate) advanceSimulatedDate();
01204          
01205       } 
01206    else if (eventId == PsSystemEventIdentifier::MaskDelete ) 
01207       {
01208          *_computeStatePointer=PsnReferenceObjectHandle::destroyed;
01209       } 
01210    else if ( eventId == PsSystemEventIdentifier::MaskNewObject ) 
01211       {
01212          PsValuedEvent <PsPair <PsObjectDescriptor,PsName> > * creationEvent = dynamic_cast<PsValuedEvent <PsPair <PsObjectDescriptor,PsName> >* > ( event ) ;
01213          
01214          assert (creationEvent != NULL ) ;
01215          
01216          // add the described object in the simulation tree : this is a declaration
01217          PsObjectDescriptor * objectDescriptor = _simulationTree.findDescendantNamed( creationEvent->value.first.getName() );
01218          if ( objectDescriptor == NULL )
01219             {
01220                PsObjectDescriptor * newObjectDescriptor = new PsObjectDescriptor(creationEvent->value.first) ;
01221                PsObjectDescriptor * fathersDescription = _simulationTree.findDescendantNamed ( creationEvent->value.second ) ;
01222                if (fathersDescription == NULL)
01223                   {
01224                      fathersDescription = & _simulationTree ;
01225 #ifdef _USESSTREAM
01226                      ostringstream warningMessage ;
01227                      warningMessage<<"Attached new object named "<<newObjectDescriptor->getName()<<" to "<<getName()
01228                                    <<" because object "<<creationEvent->value.second<<"is unknown"<<endl;
01229                      warning ( warningMessage.str() , SomeWarnings ) ;
01230 #else
01231                      ostrstream warningMessage ;
01232                      warningMessage<<"Attached new object named "<<newObjectDescriptor->getName()<<" to "<<getName()
01233                                    <<" because object "<<creationEvent->value.second<<"is unknown"<<endl;
01234                      warningMessage.put ('\0') ;
01235                      warning ( warningMessage.str() , SomeWarnings ) ;
01236                      delete warningMessage.str() ;
01237 #endif
01238                   }
01239                changeObjectsFather (newObjectDescriptor, fathersDescription) ;
01240 
01241                //create the described object
01242                processNewObjectDeclaration ( *newObjectDescriptor, event->date ) ;
01243                
01244                // notify other objects that an object has been created
01245                fireValuedSignal(PsSystemEventIdentifier::MaskObjectCreated,creationEvent->value.first.getName() ) ;
01246             }
01247          else
01248             {
01249 #ifdef _USESSTREAM
01250                ostringstream warningMessage ;
01251                warningMessage<<"WARNING: an object of name "<<creationEvent->value.first.getName()<<" already exists"<<endl;
01252                warning ( warningMessage.str() , SomeWarnings ) ;
01253 #else
01254                ostrstream warningMessage ;
01255                warningMessage<<"WARNING: an object of name "<<creationEvent->value.first.getName()<<" already exists"<<endl;
01256                warningMessage.put ('\0') ;
01257                warning ( warningMessage.str() , SomeWarnings ) ;
01258                delete warningMessage.str() ;
01259 #endif
01260             }
01261       }
01262    else if ( eventId == PsSystemEventIdentifier::MaskRecomputeScheduling)
01263       {
01264          computeScheduling( true ) ;
01265 
01266          scheduleControlledObjects() ;
01267       }
01268    else 
01269       {
01270 #ifdef _USESSTREAM
01271          ostringstream warningMessage ;
01272          warningMessage<<"WARNING:PsController::traiterEvt événement système non géré"<<endl;
01273          warning ( warningMessage.str() , SomeWarnings ) ;
01274 #else
01275          ostrstream warningMessage ;
01276          warningMessage<<"WARNING:PsController::traiterEvt événement système non géré"<<endl;
01277          warningMessage.put('\0') ;
01278          warning ( warningMessage.str() , SomeWarnings ) ;
01279          delete warningMessage.str() ;
01280 #endif
01281       } 
01282    return true ;
01283 }
01284 
01285 
01286 
01287 void PsController::processStartEventOf(PsnReferenceObjectHandle * objectHandle) 
01288 {
01289 
01290    if(objectHandle->getComputingState() == PsnReferenceObjectHandle::initial) 
01291       {
01292          setComputingState (objectHandle, PsnReferenceObjectHandle::running ) ;
01293          noActivationNeededFor ( objectHandle );
01294 #ifdef _DEBUGEVT
01295          cerr<<"PsController:: Init of "<<objectHandle->getSimulatedObject().getName()<<endl;
01296 #endif
01297          objectHandle->init() ;
01298 #ifdef _DEBUGEVT
01299          cerr<<"PsController:: end of init of "<<objectHandle->getSimulatedObject().getName()<<endl;
01300 #endif
01301          
01302          _scheduler->schedule( objectHandle );
01303 
01304    }
01305 }
01306 
01307 
01308 
01309 void PsController::processDeleteEventOf(PsnReferenceObjectHandle * objectHandle) 
01310 {
01311 #ifdef _DEBUGEXEC
01312    cerr<<" PsController::processDeleteEventOf() "<<objectHandle->getSimulatedObject().getName()<<endl;
01313 #endif
01314    if(objectHandle->getComputingState() == PsnReferenceObjectHandle::stopped) 
01315       {
01316          fireValuedSignal( PsSystemEventIdentifier::MaskObjectDestroyed, objectHandle->getSimulatedObject().getObjectDescriptor().getName() ) ;
01317          setComputingState ( objectHandle, PsnReferenceObjectHandle::destroyed );
01318          deleteObject(const_cast<PsObjectDescriptor *>(&objectHandle->getSimulatedObject().getObjectDescriptor()) );
01319       }         
01320 }
01321 
01322 
01323 void PsController::reactToControlledObjectsSystemEvents() {
01324 
01325    PsSimulatedObject * receiverObject ;
01326    PsnReferenceObjectHandle * receiverReferential ;
01327    PsEvent * currentEvent ;
01328 
01329    switchSystemEventList() ;
01330    list< PsEvent * > & myEventList = *_systemEventsList [ 1 - _currentWritableSystemEventsList ] ;
01331    list< PsEvent * >::iterator i = myEventList.begin() ;
01332    list< PsEvent * >::iterator toErase ;
01333    while ( i != myEventList.end() ) {
01334 
01335       receiverObject = getPointerToSimulatedObjectNamed( (*i)->receiver ) ;
01336       currentEvent = (*i) ;
01337 
01338       if ( receiverObject == NULL ) 
01339          {
01340 #ifdef _USESSTREAM
01341             ostringstream warningMessage ;
01342             warningMessage<<"WARNING : object "
01343                           << currentEvent ->receiver.getCString() 
01344                           <<", who has received event "
01345                           << *currentEvent 
01346                           <<"  doesn't exist (anymore)"<<endl;
01347             warning ( warningMessage.str() , AllWarnings ) ;
01348 #else
01349             ostrstream warningMessage ;
01350             warningMessage<<"WARNING : object "
01351                           << currentEvent ->receiver.getCString() 
01352                           <<", who has received event "
01353                           << *currentEvent 
01354                           <<"  doesn't exist (anymore)"<<endl;
01355             warningMessage.put('\0') ;
01356             warning ( warningMessage.str() , AllWarnings ) ;
01357             delete warningMessage.str() ;
01358 #endif
01359          }
01360       else {
01361          receiverReferential = dynamic_cast<PsnReferenceObjectHandle *>(receiverObject->getObjectHandle() );
01362          assert (receiverReferential != NULL) ;
01363 #if defined (_DEBUGEXEC) || defined (_DEBUGEVT) 
01364          cerr<<*currentEvent<<" received by "<<receiverObject->getName() <<endl;
01365 #endif
01366          if ( currentEvent->eventId == PsSystemEventIdentifier::MaskStart ) 
01367             {
01368                processStartEventOf ( receiverReferential );
01369             }
01370 
01371          else if ( currentEvent->eventId == PsSystemEventIdentifier::MaskStop ) {
01372 #ifdef _DEBUGEVT
01373             cout<< currentEvent->receiver <<" will be stopped "<<endl;
01374 #endif
01375           if((receiverReferential->getComputingState() == PsnReferenceObjectHandle::running)||
01376              (receiverReferential->getComputingState() == PsnReferenceObjectHandle::suspended)) 
01377              {
01378                 setComputingState (receiverReferential, PsnReferenceObjectHandle::stopped );
01379                 receiverReferential->processEvents () ;
01380                 receiverObject -> finish() ;
01381                 _scheduler->unschedule( receiverReferential ); 
01382              } 
01383          }
01384          else if ( currentEvent->eventId == PsSystemEventIdentifier::MaskSuspend ) {
01385 #ifdef _DEBUGEVT
01386           cout<<currentEvent->receiver <<" will be suspended "<<endl;
01387 #endif
01388           if(receiverReferential->getComputingState() == PsnReferenceObjectHandle::running) 
01389              {
01390              setComputingState (receiverReferential, PsnReferenceObjectHandle::suspended ) ;
01391              hasEventsToProcess (receiverReferential) ; // à la fin du pas de temps l'événement MaskSuspend sera traité, ainsi que d'autres événements éventuels
01392              _scheduler->unschedule ( receiverReferential ); 
01393              }      
01394           else
01395              {
01396                 assert ( false ) ;
01397              }
01398          }
01399          else if ( currentEvent->eventId == PsSystemEventIdentifier::MaskResume ) 
01400             {
01401 #ifdef _DEBUGEVT
01402                cout<<currentEvent->receiver <<" will resume execution"<<endl;
01403 #endif
01404                if ( receiverReferential -> getComputingState() == PsnReferenceObjectHandle::suspended ) 
01405                   {
01406                      setComputingState (receiverReferential, PsnReferenceObjectHandle::running );
01407                      // inutile de traiter l'événement : les compute à venir le feront
01408                      noActivationNeededFor ( receiverReferential );
01409                      
01410                      _scheduler->schedule( (PsnReferenceObjectHandle *)receiverObject -> getObjectHandle() );
01411                   }
01412          }
01413          else if ( currentEvent->eventId == PsSystemEventIdentifier::MaskDelete ) 
01414             {
01415                processDeleteEventOf ( receiverReferential ) ;
01416             }
01417          else if ( currentEvent->eventId == PsSystemEventIdentifier::MaskRestart ) {
01418 #ifdef _DEBUGEVT
01419           cout<<currentEvent->receiver <<" will be restarted"<<endl;
01420 #endif
01421           if (receiverReferential->getComputingState() == PsnReferenceObjectHandle::stopped) 
01422              {
01423                 setComputingState(receiverReferential, PsnReferenceObjectHandle::running) ;
01424                 // inutile de traiter l'événement : les compute à venir le feront
01425                 noActivationNeededFor( receiverReferential );
01426                 
01427                 receiverObject->init();
01428                 //on sait que c'est un référentiel 
01429                 _scheduler->schedule( receiverReferential ) ;
01430              }
01431          }
01432          else if ( currentEvent->eventId == PsSystemEventIdentifier::MaskChangeObjectFrequency ) 
01433             {
01434                PsValuedEvent<PsFrequency> * realEvent ;
01435                realEvent = dynamic_cast<PsValuedEvent<PsFrequency> *> (currentEvent ) ;
01436                assert (realEvent != NULL) ;
01437                PsObjectDescriptor * objectDescription = _simulationTree.findDescendantNamed (realEvent->receiver) ;
01438                if (objectDescription != NULL)
01439                   {
01440                      objectDescription->setFrequency ( realEvent->value ) ;
01441                      if ( realEvent->value == computeAdequateFrequency ( realEvent->value ) )
01442                         {
01443                            PsnReferenceObjectHandle * referenceObjectHandle = _referenceObjectsMap.getObjectOfIndex (realEvent->receiver) ;
01444                            if ( referenceObjectHandle != NULL )
01445                               {
01446                                  _scheduler->unschedule( referenceObjectHandle ) ;
01447                                  
01448                                  _scheduler->removeFromScheduable( referenceObjectHandle ) ;
01449 
01450                                  scheduleObject ( _referenceObjectsMap.getObjectOfIndex (realEvent->receiver) ) ;
01451                               }
01452                         }
01453                      else 
01454                         {
01455                            computeScheduling ( false ) ; //false necessary because otherwise no change would happen
01456                            scheduleControlledObjects () ;
01457                         }
01458                   }
01459                else
01460                   {
01461 #ifdef _USESSTREAM
01462                      ostringstream warningMessage ;
01463                      warningMessage<<"PsController received MaskChangeObjectFrequency for "<<realEvent->receiver<<" which is unknown "<<endl;
01464                      warning ( warningMessage.str() , SomeWarnings ) ;
01465 #else
01466                      ostrstream warningMessage ;
01467                      warningMessage<<"PsController received MaskChangeObjectFrequency for "<<realEvent->receiver<<" which is unknown "<<endl;
01468                      warningMessage.put('\0') ;
01469                      warning ( warningMessage.str() , SomeWarnings ) ;
01470                      delete warningMessage.str() ;
01471 #endif
01472                   }
01473             }
01474       }
01475       toErase = i ;
01476       i++ ;
01477       myEventList.erase ( toErase ) ;
01478    }
01479 }
01480 
01481 void PsController::noActivationNeededFor (PsnReferenceObjectHandle * refObjet) {
01482    _objectsNeedingActivationList[ _currentListOfObjectsNeedingActivation ]->remove( refObjet );
01483    refObjet->_isInObjectNeedingActivationList[ _currentListOfObjectsNeedingActivation ] = false ;
01484    assert ( refObjet->_isInObjectNeedingActivationList[ 1 - _currentListOfObjectsNeedingActivation ] == false );
01485 }
01486 
01487 void PsController::hasEventsToProcess(PsnReferenceObjectHandle * refObjet) 
01488 {
01489    // the object handle should be correct (because this member function is called by it)
01490   assert ( dynamic_cast<PsnReferenceObjectHandle *>(_objectHandle) != NULL ) ;
01491 
01492   //the controller shouldn't try and schedule itself if it isn't controlled
01493   if (refObjet != _objectHandle)
01494      {
01495         
01496         if (!refObjet->_isInObjectNeedingActivationList[ _currentListOfObjectsNeedingActivation ]) 
01497            {
01498 #ifdef _DEBUGEVT
01499               cerr<<"PsController::hasEventsToProcess of "
01500                   << refObjet->getSimulatedObject().getName() 
01501                   << " at date "<< _date + _stepPeriod << endl;
01502 #endif
01503               _objectsNeedingActivationList[ _currentListOfObjectsNeedingActivation ]->push_back ( refObjet );
01504               refObjet->_isInObjectNeedingActivationList[ _currentListOfObjectsNeedingActivation ] = true ;
01505            } 
01506 #ifdef _DEBUGEVT
01507         else 
01508            {
01509               cerr<< "PsController::hasEventsToProcess of " << refObjet->getSimulatedObject().getName() << " at date "<< _date + _stepPeriod << " not necessary "<< endl;
01510            }
01511 #endif
01512      }
01513   else if ( & getController() != this )
01514      {
01515         getController().hasEventsToProcess( refObjet ) ;
01516      }
01517 }
01518 
01519 void PsController::postponeEventProcessing ( PsnReferenceObjectHandle * refObjet ) {
01520    _listOfObjectsWithPostPonedEvents.push_back(refObjet) ;
01521 }
01522 
01523 void PsController::processEventsOfSuspendedObjects() 
01524 {   
01525 #ifdef _DEBUGEVT
01526     cerr<<"PsController::processEventsOfSuspendedObjects "<< _date << endl;
01527 #endif
01528     while ( ! _objectsNeedingActivationList[ _currentListOfObjectsNeedingActivation ]->empty() ) {
01529        //using a iteration to be able to process ASAP events generated throught this phase
01530        int indiceFile = _currentListOfObjectsNeedingActivation ;
01531        _currentListOfObjectsNeedingActivation = 1 - _currentListOfObjectsNeedingActivation ;
01532        PsnReferenceObjectHandle * courant;
01533        list<PsnReferenceObjectHandle *>::iterator i;
01534        i=_objectsNeedingActivationList[indiceFile]->begin();
01535        while(i!=_objectsNeedingActivationList[indiceFile]->end()) {
01536           list<PsnReferenceObjectHandle *>::iterator needsDelete;
01537           courant=(*i);
01538           courant->processEvents () ;
01539           courant->_isInObjectNeedingActivationList[indiceFile]= false ;
01540           needsDelete=i;
01541           i++; 
01542           _objectsNeedingActivationList[indiceFile]->erase(needsDelete);
01543        }
01544     }
01545     list < PsnReferenceObjectHandle * >::iterator j =  _listOfObjectsWithPostPonedEvents.begin() ;
01546     list < PsnReferenceObjectHandle * >::iterator toErase ;
01547     while ( j != _listOfObjectsWithPostPonedEvents.end() ) {
01548        hasEventsToProcess (*j) ;
01549        toErase = j ;
01550        j++ ;
01551        _listOfObjectsWithPostPonedEvents.erase( toErase ) ;
01552     }
01553 #ifdef _DEBUGEVT
01554    cerr<<"PsController::processEventsOfSuspendedObjects fin "<< _date <<endl;
01555 #endif
01556 }
01557 
01558 
01559 
01560 int PsController::getOutputHistorySize(void) {
01561   // each output keeps an history to enable polations
01562   // _nbStepsByCycle * 4 --> the minimum history lenght for the default max extrapolation to work  
01563   // + 1 because of uncertainty about relative order of simulated object activation
01564 
01565    int result ;
01566    char * environementValue = getenv("MaskHISTORYLENGTH");
01567    if (environementValue == NULL ) 
01568       {
01569          result = _nbStepsByCycle*4+1 ;
01570       }
01571    else 
01572       {
01573          result = atoi (environementValue) ;
01574       }
01575    return result ;
01576 }  
01577 
01578 
01579 void PsController::broadcastEventsForSignal (PsEvent & event, const PsEventIdentifier & sigId) 
01580 {
01581    //cerr<<"PsController::broadcastEventsForSignal "<<sigId<<endl;
01582    _controledObjectsSignalsDispatcher.sendEventsForSignal( event , sigId ) ;
01583 }
01584 
01585 
01586 bool PsController::receiveRegistrationForSignal(const PsEventIdentifier & sig,
01587                                                 const PsName & registrant, 
01588                                                 const PsEventIdentifier & eventId)
01589 {
01590    //cerr<<"PsController::receiveRegistrationForSignal "<<sig<<" "<<registrant<<" "<<eventId<<endl;
01591    return _controledObjectsSignalsDispatcher.registerForSignal(sig , registrant , eventId) ;
01592 }
01593 
01594 
01595 bool PsController::receiveCancellationForSignal ( const PsEventIdentifier & sigId , const PsName & registrant ) {
01596    return _controledObjectsSignalsDispatcher.cancelRegistrationForSignal (sigId , registrant) ;
01597 }
01598 
01599 
01600 
01601 
01602 PsnReferenceObjectHandle * PsController::newPsnReferenceObjectHandle(PsSimulatedObject & object, 
01603                                                                      PsController & controller,
01604                                                                      PsnSignalDispatcher * signalDispatcher)
01605 {
01606    return new PsnReferenceObjectHandle(object, controller, signalDispatcher) ;
01607 }
01608 
01609 
01610 
01611 PsnReferenceObjectHandle * PsController::createReferenceObjectHandle(PsSimulatedObject & obj) 
01612 {
01613    /* no mutex protection needed, because this member function is only called by the controller during system event processing */
01614 #ifdef _DEBUGOBJECTCREATION
01615   cerr<<"PsController::createReferenceObjectHandle"<<endl;
01616 #endif 
01617    PsnReferenceObjectHandle * result ;
01618    map<PsName, PsnSignalDispatcher *>::iterator i = _pendingRegistrationRequests.find( obj.getName() ) ;
01619    if ( i == _pendingRegistrationRequests.end() )
01620       {
01621          result = newPsnReferenceObjectHandle(obj,*this, new PsnSignalDispatcher (*this) );
01622       }
01623    else 
01624       {
01625          result = newPsnReferenceObjectHandle(obj,*this, i->second) ;
01626          _pendingRegistrationRequests.erase ( i ) ;
01627       }
01628 #ifdef _DEBUGOBJECTCREATION
01629   cerr<<"PsController::createReferenceObjectHandle ended"<<endl;
01630 #endif 
01631    return result ;
01632 }
01633 
01634 
01635 void PsController::setComputingState(PsnReferenceObjectHandle * handle, 
01636                                      PsnReferenceObjectHandle::SimulatedObjectComputingState state) const 
01637 {
01638    handle->_computingState = state ;
01639 }
01640 
01641 
01642 PsMultipleConfigurationParameter * PsController::getSchedulingParametersOfObject(PsObjectDescriptor & objectDescription ) 
01643 {
01644    return objectDescription.getSchedulingParameters () ;
01645 }
01646 
01647 void PsController::setProcessOfDescriptor ( PsObjectDescriptor & objectDescription, const PsName & newProcessName ) 
01648 {
01649    objectDescription.setProcess ( newProcessName ) ;
01650 }

logo OpenMask

Documentation generated on Mon Nov 25 15:24:59 2002

Generated with doxygen 1.2.12 by Dimitri van Heesch ,   1997-2001