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

PsDistributedController.cxx

Go to the documentation of this file.
00001 /*
00002  * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software
00003  * 
00004  * The Software has been developped within the Siames Project. 
00005  * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights
00006  * 
00007  * The Software has been registered with the Agence pour la Protection des
00008  * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200
00009  *
00010  * This file may be distributed under the terms of the Q Public License
00011  * version 1.0 as defined by Trolltech AS of Norway and appearing in the file
00012  * LICENSE.QPL included in the packaging of this file.
00013  *
00014  * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 
00015  * for the software may use this file in accordance with that specific license 
00016  *
00017  */
00018 #include <PsDistributedController.h>
00019 #include <PsDuplicatedObject.h>
00020 #include <PsnMirrorObjectHandle.h>
00021 #include <PsnDuplicatedObjectHandle.h>
00022 #include <PsObjectDescriptor.h>
00023 #include "PsSystemEventIdentifier.h"
00024 #include "PsUnInitialisedAttributeException.h"
00025 #include "PsnCurrentActiveObject.h"
00026 
00027 //------------------------------------------------------------------------------
00028 
00029 PsDistributedController::PsDistributedController( PsObjectDescriptor & initialObjects, const PsDate & initialDate ) 
00030    : PsController(initialObjects, initialDate),
00031      _processName (initialObjects.getProcess())
00032 {
00033 }
00034 
00035 //------------------------------------------------------------------------------
00036 
00037 PsDistributedController::~PsDistributedController() 
00038 {
00039   purgeMemoryFromOldEvents ( _date + _stepPeriod ) ;
00040 }
00041 
00042 
00043 PsnDuplicatedObjectHandle * PsDistributedController::createDuplicatedObject( PsObjectDescriptor * objectDescription ) 
00044 {
00045    PsnDuplicatedObjectHandle * result ;
00046 
00047    PsSimulatedObject * createdObject = createDescribedObject(objectDescription) ;
00048 
00049    if (createdObject == NULL) 
00050       {
00051          cerr<<"PsController::createReferenceObject: unable to create "<<*objectDescription<<endl;
00052       }
00053    else
00054       {
00055          result = newPsnDuplicatedObjectHandle(*createdObject) ;
00056          
00057          _referenceObjectsMap.addObjectWithIndex (objectDescription->getName(), result);
00058          _duplicatedObjectsMap.addObjectWithIndex (objectDescription->getName(),result);
00059       }
00060    return result ;
00061 }
00062 
00063 //------------------------------------------------------------------------------
00064 
00065 PsSimulatedObject * PsDistributedController::getPointerToSimulatedObjectNamed (const PsName & nom) {
00066    //in case of dynamic creation of objects
00067    PsnCurrentActiveObject context ( NULL ) ;   
00068 
00069    PsSimulatedObject * resultat = NULL ;
00070    // On verifie que l'objet est un referentiel
00071    //cerr<<"PsDistributedController::getPointerToSimulatedObjectNamed("<<nom<<")"<<endl;
00072    if (nom == getName() ) 
00073       {
00074          resultat = this ;
00075       }
00076    else if (_referenceObjectsMap.find (nom) != _referenceObjectsMap.end ()) 
00077       {
00078          // On recupere le referentiel
00079          resultat = & _referenceObjectsMap.getObjectOfIndex (nom)->getSimulatedObject() ;
00080       } 
00081    else 
00082       {
00083          MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.find (nom) ;
00084          if ( i != _mirrorObjectsMap.end ()) 
00085             {
00086                // On recupere le miroir
00087                resultat = & ( i->second->getSimulatedObject() ) ;
00088             } 
00089          else if (_duplicatedObjectsMap.find (nom) != _duplicatedObjectsMap.end()) 
00090             {
00091                //this shouldn't happen, as duplicate objects are also in the referenceObjectMap
00092                cout<<"PsPvmController::getPointerToSimulatedObjectNamed : found in _duplicatedObjectsMap: problem"<<endl;
00093                resultat = &_duplicatedObjectsMap.getObjectOfIndex (nom)->getSimulatedObject() ;
00094             }
00095          else {
00096             PsObjectDescriptor * objectDescription = _simulationTree.findDescendantNamed (nom) ;
00097             if ( objectDescription != NULL ) 
00098                {
00099                   PsSimulatedObject * obj = createDescribedObject ( objectDescription ) ;
00100                   
00101                   PsDuplicatedObject * objDup = dynamic_cast<PsDuplicatedObject *>(obj);
00102                   
00103                   if( objDup == NULL ) 
00104                      {
00105                         createMirrorObject ( objectDescription ) ;
00106                      }
00107                   else 
00108                      {
00109                         PsnDuplicatedObjectHandle * newObjectHandle = createDuplicatedObject ( objectDescription );   
00110                         
00111                         if ( objectDescription->getFrequency() != computeAdequateFrequency (objectDescription->getFrequency()) )
00112                            {
00113                               //the whole scheduling data structure needs recalculating
00114                               computeScheduling ( false ) ;
00115                               
00116                               //the new object will therefore be scheduled with all the others
00117                               scheduleControlledObjects() ;
00118                            }
00119                         else
00120                            {
00121                               scheduleObject ( newObjectHandle ) ;
00122                            }
00123                         
00124                         sendInitialEventsTo ( *newObjectHandle, _date ) ; 
00125                         fireValuedSignal(PsSystemEventIdentifier::MaskObjectCreated,nom ) ;
00126                         
00127                         //here, nothing is done for creation process coherence. It might be usefull to initialise the object for duplicated objects
00128                      }
00129                   resultat = obj ;
00130                }
00131          }
00132       }
00133    return resultat ;
00134 }
00135 
00136 
00137 //------------------------------------------------------------------------------
00138 
00139 void PsDistributedController::processStartEventOf(PsnReferenceObjectHandle * objectHandle)
00140 {
00141   try 
00142     {
00143       PsController::processStartEventOf ( objectHandle ) ;
00144       tableDesInitialises.addObjectWithIndex ( objectHandle->getSimulatedObject ().getName (), 
00145                                                objectHandle) ;
00146 #ifdef _DEBUGDISTRIBUTEDINIT
00147       cerr<<"PsDistributedController::processStartEventOf init of "
00148           << objectHandle->getSimulatedObject ().getName ()
00149           <<" successfull"<<endl;
00150 #endif
00151     }
00152   catch (PsUnInitialisedAttributeException & e) 
00153     {
00154 #ifdef _DEBUGDISTRIBUTEDINIT
00155       cerr<<"PsDistributedController::processStartEventOf init of "
00156           << objectHandle->getSimulatedObject ().getName ()
00157           <<" failed"<<endl;
00158 #endif
00159       setComputingState (objectHandle, PsnReferenceObjectHandle::initial ) ;
00160       tableDesNonInitialises.addObjectWithIndex ( objectHandle->getSimulatedObject ().getName () , 
00161                                                   objectHandle) ;
00162     }
00163 }
00164 
00165 
00166 //------------------------------------------------------------------------------
00167 
00168 void PsDistributedController::dispatchEvent(PsEvent * event) {
00169 #ifdef _DEBUGEVT
00170    cerr<<"PsDistributedController::dispatchEvent pour "<<event->receiver<<endl;
00171 #endif
00172    PsNameToPointerMap<PsnReferenceObjectHandle>::iterator i = _referenceObjectsMap.find(event->receiver);
00173    assert(i!=_referenceObjectsMap.end());
00174    (*i).second->receiveEvent( event );
00175 #ifdef _DEBUGEVT
00176          cerr<<"PsDistributedController::dispatchEvent fin"<<endl;
00177 #endif
00178 } 
00179 
00180 //------------------------------------------------------------------------------
00181 
00182 PsnMirrorObjectHandle * PsDistributedController::createMirrorObject(PsObjectDescriptor * objectDescription) 
00183 {
00184    PsnMirrorObjectHandle * result = NULL ;
00185    PsSimulatedObject * obj = createDescribedObject( objectDescription ) ;
00186    if ( obj == NULL )
00187       {
00188          cerr<<"PsController::createReferenceObject: unable to create "<<*objectDescription<<endl;
00189       }
00190    else
00191       {
00192          result = newPsnMirrorObjectHandle(*obj) ;
00193                  
00194          _mirrorObjectsMap.insert ( MirrorObjectsContainerType::value_type(objectDescription->getName (), result ) ) ;
00195       }
00196    return result ;   
00197 }
00198 
00199 //------------------------------------------------------------------------------
00200 
00201 void PsDistributedController::createControlledObjects( const PsObjectDescriptor * subTree ) 
00202 {
00203    //go through the simulation tree to find all objects that have to be created
00204    PsObjectDescriptor::SonsContainerType::const_iterator i = subTree->getSons()->begin() ;
00205    while ( i != subTree->getSons()->end() )
00206       {
00207          if ( (*i)->getProcess() == _processName ) 
00208             {
00209                cerr<<"Creating "<< (*i)->getName() << endl ;
00210                //create the object
00211                createReferenceObject ( (*i) ) ;
00212             }    
00213          else 
00214             {
00215                cerr<<"Not Creating "<< (*i)->getName() 
00216                    <<" of process "<< (*i)->getProcess()
00217                    <<endl ;
00218             }
00219          //create the subTree of that object
00220          createControlledObjects ( *i ) ;
00221          
00222          ++i ;
00223       }
00224 }
00225 
00226 void PsDistributedController::processNewObjectDeclaration ( PsObjectDescriptor & declaration, const PsDate & declarationDate )
00227 {
00228   //cerr<<"PsDistributedController::processNewObjectDeclaration "<<_processName<<" "<<declaration.getProcess()<<endl;
00229    if ( _processName == declaration.getProcess() ) 
00230       {
00231          PsController::processNewObjectDeclaration ( declaration, declarationDate ) ;
00232       }
00233    else
00234       {
00235          map<PsName, list <PsEvent *> >::iterator pendingEvents = _pendingEventsList.find( declaration.getName() ) ;
00236          if ( pendingEvents != _pendingEventsList.end() )
00237             {
00238 #ifdef _DEBUGEXEC
00239                cerr<<"Found pending events for "<<declaration.getName()<<endl;
00240 #endif
00241                for ( list <PsEvent *>::iterator pendingEventsListIterator = pendingEvents->second.begin() ;
00242                      pendingEventsListIterator != pendingEvents->second.end() ;
00243                      ++pendingEventsListIterator)
00244                   {
00245 #ifdef _DEBUGEXEC
00246                      cerr<<"sent "<<**pendingEventsListIterator<< "to "<<declaration.getName()<<endl;
00247 #endif
00248                      assert ( getPointerToSimulatedObjectNamed(declaration.getName()) != NULL ) ;
00249                      getPointerToSimulatedObjectNamed(declaration.getName())->sendEvent(*pendingEventsListIterator) ; 
00250                   }
00251                _pendingEventsList.erase ( pendingEvents ) ;
00252             }
00253       }
00254 }
00255 
00256    
00257 bool PsDistributedController::processEvent ( PsEvent * event )
00258 {
00259    bool result ;
00260    if ( event->eventId == PsSystemEventIdentifier::MaskRegisterForSignal )
00261       {
00262          PsValuedEvent<RegistrationData> * realEvent = dynamic_cast<PsValuedEvent<RegistrationData> *>( event ) ;
00263          assert (realEvent != NULL ) ;
00264          
00265          cerr<<"PsDistributedController::processEvent received registration from "<<realEvent->value._registrant<<endl;
00266 
00267          _controledObjectsSignalsDispatcher.registerForSignal(realEvent->value._sig , 
00268                                                               realEvent->value._registrant , 
00269                                                               realEvent->value._eventId) ;
00270 
00271          result = true ;
00272 
00273          //find out if an allready broadcasted signal should sent to the registrant
00274          for ( list<pair<PsEventIdentifier, pair <PsEvent *, PsDate> > >::iterator i = _broadcastedSignals.begin() ;
00275                i != _broadcastedSignals.end() ;
00276                ++i )
00277             {
00278                if ( i->first == realEvent->value._sig )
00279                   {
00280         
00281                      if ( i->second.second >= realEvent->date )
00282                         {
00283                            PsEvent * sentEvent = i->second.first->clone() ;
00284                            sentEvent->eventId = realEvent->value._eventId ;
00285                            sentEvent->receiver = realEvent->value._registrant ;
00286                            sendEvent ( sentEvent ) ;
00287                         }
00288                   }
00289             }
00290 
00291       }
00292    else if ( event->eventId == PsSystemEventIdentifier::MaskCancelRegistrationForSignal )
00293       {
00294          PsValuedEvent<CancellationData> * realEvent = dynamic_cast<PsValuedEvent<CancellationData> *>( event ) ;
00295 
00296          assert (realEvent != NULL ) ;
00297 
00298          _controledObjectsSignalsDispatcher.cancelRegistrationForSignal (realEvent->value._sigId , 
00299                                                                          realEvent->value._registrant) ;
00300          result = true ;
00301       }
00302    else if (event->eventId == PsSystemEventIdentifier::MaskObjectDestroyed)
00303       {
00304          PsValuedEvent<PsName> * realEvent = dynamic_cast<PsValuedEvent<PsName> *>( event ) ;
00305 
00306          assert ( realEvent != NULL ) ;
00307 
00308          PsObjectDescriptor * objectDescriptor = _simulationTree.findDescendantNamed ( realEvent->value ) ;
00309 
00310          if (objectDescriptor != NULL )
00311             {
00312                deleteObject( objectDescriptor ) ;
00313             }
00314          result = PsController::processEvent ( event ) ;
00315       } 
00316    else
00317       {
00318          result = PsController::processEvent ( event ) ;
00319       }
00320    return result ;
00321 }
00322  
00323 
00324 
00325 void PsDistributedController::deleteObjectHandle ( PsnObjectHandle * objectHandle )
00326 {
00327    _deletedObjectHandles.push_back ( make_pair ( _date,objectHandle ) ) ;
00328 }
00329 
00330 
00331 
00332 void PsDistributedController::createObject(const PsObjectDescriptor & newObjectDescription, const PsName & fathersName)
00333 {
00334    PsName noProcess ;
00335    if ( newObjectDescription.getProcess() == noProcess )
00336       {
00337          PsObjectDescriptor modifiableObjectDescription ( newObjectDescription ) ;
00338          modifiableObjectDescription.setProcess ( _processName ) ;
00339          PsController::createObject( modifiableObjectDescription, fathersName ) ;
00340       }
00341    else
00342       {
00343          PsController::createObject( newObjectDescription, fathersName ) ;
00344       }
00345 }
00346 
00347 void PsDistributedController::purgeMemoryFromOldEvents ( const PsDate & dateOfOldestKept )
00348 {
00349    PsController::purgeMemoryFromOldEvents ( dateOfOldestKept ) ;
00350    //purge the list of old broadcasted signals. 2 * _stepPeriod is arbitrary. The effective distributed controller should redefine this according to it's latency
00351    pair<PsEventIdentifier, pair <PsEvent *, PsDate> > examinedPair ;
00352    bool disposableElements = !_broadcastedSignals.empty() ;
00353    while ( disposableElements )
00354       {
00355          examinedPair = _broadcastedSignals.front() ;
00356          if ( examinedPair.second.second < dateOfOldestKept )
00357             {
00358                delete examinedPair.second.first ;
00359                _broadcastedSignals.pop_front() ;
00360                disposableElements = !_broadcastedSignals.empty() ;
00361             }
00362          else 
00363             {
00364                disposableElements = false ;
00365             }
00366       }
00367 
00368 }
00369 
00370 void PsDistributedController::broadcastEventsForSignal ( PsEvent & event, const PsEventIdentifier & sigId )
00371 {
00372    PsController::broadcastEventsForSignal ( event, sigId ) ;
00373 
00374    //remember the broadcasted signal to be able to send it to objects whose registration is still under way
00375    _broadcastedSignals.push_back ( make_pair ( sigId, make_pair (event.clone(), _date) ) ) ;
00376 
00377 }
00378 
00379 bool PsDistributedController::receiveRegistrationForSignal(const PsEventIdentifier & sig,
00380                                                            const PsName & registrant, 
00381                                                            const PsEventIdentifier & eventId)
00382 {
00383    PsValuedEvent<RegistrationData> * event ;
00384    event= new PsValuedEvent<RegistrationData> (PsSystemEventIdentifier::MaskRegisterForSignal, _date, getName(), getName() ,RegistrationData (sig, registrant, eventId) ) ;
00385    sendEvent (event) ;
00386    return true ;
00387 }
00388 
00389 
00390 bool PsDistributedController::receiveCancellationForSignal ( const PsEventIdentifier & sigId , const PsName & registrant ) {
00391    PsValuedEvent<CancellationData> * event ;
00392    event= new PsValuedEvent<CancellationData> (PsSystemEventIdentifier::MaskCancelRegistrationForSignal, _date, getName(), getName() ,CancellationData (sigId, registrant) ) ;
00393    sendEvent (event) ;
00394    return true ;
00395 }
00396 
00397 PsDistributedController::RegistrationData::RegistrationData (const PsEventIdentifier & sig,
00398                                                                   const PsName & registrant, 
00399                                                              const PsEventIdentifier & eventId) :
00400    _sig ( sig ),
00401    _registrant (registrant),
00402    _eventId (eventId)
00403 {
00404 }
00405 
00406 PsDistributedController::RegistrationData::~RegistrationData ()
00407 {
00408 }
00409 void PsDistributedController::RegistrationData::unpack (PsIncomingSynchronisationMessage & in ) 
00410 {
00411    in>>_sig>>_registrant>>_eventId ;  
00412 }
00413 
00414 void PsDistributedController::RegistrationData::pack (PsOutgoingSynchronisationMessage & out) const 
00415 {
00416    out<<_sig<<_registrant<<_eventId;
00417 }
00418 
00419 void PsDistributedController::RegistrationData::extract (istream & in ) 
00420 {
00421    in>>_sig>>_registrant>>_eventId ;  
00422 }
00423 
00424 void PsDistributedController::RegistrationData::insertInStream (ostream &  out) const 
00425 {
00426    out<<_sig<<" "<<_registrant<<" "<<_eventId<<" ";
00427 }
00428 
00429 
00430 
00431 PsPolatorNT * PsDistributedController::RegistrationData::createPolator() 
00432 {
00433    return new PsPolator<RegistrationData>() ;
00434 }
00435 PsPolatorNT * PsDistributedController::CancellationData::createPolator() 
00436 {
00437    return new PsPolator<CancellationData>() ;
00438 }
00439 PsDistributedController::CancellationData::CancellationData (const PsEventIdentifier & sigId,
00440                                                              const PsName & registrant ) :
00441    _sigId ( sigId ),
00442    _registrant (registrant)
00443 {
00444 }
00445 
00446 PsDistributedController::CancellationData::~CancellationData ()
00447 {
00448 }
00449 void PsDistributedController::CancellationData::unpack (PsIncomingSynchronisationMessage & in ) 
00450 {
00451    in>>_sigId>>_registrant;  
00452 }
00453 
00454 void PsDistributedController::CancellationData::pack (PsOutgoingSynchronisationMessage & out) const 
00455 {
00456    out<<_sigId<<_registrant;
00457 }
00458 
00459 void PsDistributedController::CancellationData::extract (istream & in ) 
00460 {
00461    in>>_sigId>>_registrant;  
00462 }
00463 
00464 void PsDistributedController::CancellationData::insertInStream (ostream &  out) const 
00465 {
00466    out<<_sigId<<" "<<_registrant<<" ";
00467 }
00468 

logo OpenMask

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

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