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