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

logo OpenMask

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

Generated with doxygen by Dimitri van Heesch ,   1997-2007