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 }
Documentation generated on Mon Jun 9 11:45:56 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |