OMKReferenceObjectHandle.cpp

Go to the documentation of this file.
00001 /*
00002  * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software
00003  * 
00004  * The software has been developed 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 <OMKReferenceObjectHandle.h>
00019 #include <OMKSimulatedObject.h>
00020 #include <OMKController.h>
00021 #include <typeinfo>
00022 #include "OMKEventListener.h"
00023 
00024 #include "OMKCurrentActiveObject.h"
00025 #include <assert.h>
00026 #include <algorithm>
00027 using namespace std ;
00028 using namespace OMK ;
00029 
00030 
00031 //-----------------------------------------------------------------------------
00032 
00033 ReferenceObjectHandle::ReferenceObjectHandle( SimulatedObject & objet, 
00034                                                                             Controller & ctrl, 
00035                                                                             SignalDispatcher * signalDispatcher )
00036 : ObjectHandle ( objet ),
00037   _controller ( ctrl ),
00038   _signalDispatcher ( signalDispatcher ? signalDispatcher : new SignalDispatcher (ctrl) )
00039 {
00040    assert ( _signalDispatcher != NULL ) ;
00041 
00042    for( int i = 0 ; i<2 ; i++ ) 
00043    {
00044            _isInObjectNeedingActivationList[i]= false ;
00045    }
00046    _computingState = initial ;
00047    _dateOfLastEventManagement = Controller::initialSimulationDate - 1 ;
00048    _dateOfLastActivation = Controller::initialSimulationDate - 1 ;
00049 
00050    _eventList = new std::list <Event *> * [ 2 ] ;
00051    _eventList [ 0 ] = new std::list <Event *>() ;
00052    _eventList [ 1 ] = new std::list <Event *>() ;
00053    _currentWritableEventList = 0 ;
00054    
00055    // register the event listeners already added to the object
00056    const  list <EventListener *> & listOfEventListeners = _myObject.getEventListeners () ;
00057    for( list< EventListener * >::const_iterator eventListenersIterator = listOfEventListeners.begin() ;
00058         eventListenersIterator != listOfEventListeners.end() ;
00059         ++eventListenersIterator )
00060    {
00061            (*eventListenersIterator)->registerEvents() ;
00062    }
00063 }
00064 
00065 //-----------------------------------------------------------------------------
00066 
00067 ReferenceObjectHandle::~ReferenceObjectHandle () 
00068 {
00069    //cerr<<"ReferenceObjectHandle:"<<this<<":~ReferenceObjectHandle () "<<endl;
00070 
00071   delete _eventList[0] ;
00072   delete _eventList[1] ;
00073   delete [] _eventList ;
00074   for (virtualEventTableType::iterator i = _virtualEventTable.begin();
00075        i != _virtualEventTable.end();
00076        ++i )
00077      {
00078         delete (*i).second ;
00079      }
00080   assert (_signalDispatcher != NULL) ;
00081   delete _signalDispatcher ;
00082 }
00083 
00084 void ReferenceObjectHandle::init() 
00085 {
00086    CurrentActiveObject changeContext ( &_myObject ) ;
00087    OMTRACEID( OMK_DEBUG_OMK_EXEC, "init for " << debugMsg( &_myObject ) ) ;
00088    _myObject.init () ;
00089    OMTRACEID( OMK_DEBUG_OMK_EXEC, "init for " << debugMsg( &_myObject ) << " done" ) ;
00090    // do not treat init as an activation to enable init and compute in the same simulation step
00091 }
00092 
00094 void ReferenceObjectHandle::initAfterMorphose() 
00095 {
00096    CurrentActiveObject changeContext ( &_myObject ) ;
00097    _myObject.init () ;
00098 }
00099 
00100 void ReferenceObjectHandle::setMigrationCaseToTrue ()
00101 {
00102   _migrationCase = true ;
00103 }
00104 
00105 void ReferenceObjectHandle::setMorphosisPhaseTrue () 
00106 {
00107    OMASSERTM( false, "this code must not be called" ) ;
00108 }
00112 void ReferenceObjectHandle::compute() 
00113 {
00114    OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::compute() last activated at "<<_dateOfLastActivation<<", now is "
00115        <<_controller.getSimulatedDate() ) ;
00116 
00117    if ( _controller.getSimulatedDate() > _dateOfLastActivation ) 
00118    {
00119      
00120      _dateOfLastActivation = _controller.getSimulatedDate() ;
00121   
00122      CurrentActiveObject changeContext ( &_myObject ) ;
00123      OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::compute : processing events of " << debugMsg( &_myObject ) ) ;
00124      processEvents () ;
00125      OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::compute : events of " << debugMsg( &_myObject ) << " processed, now compute" ) ;
00126      _myObject.compute () ;
00127      OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::compute : computation finished for " << debugMsg( &_myObject ) ) ;
00128    }
00129    else
00130    {
00131            OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::compute : controller allready activated at "<<_controller.getSimulatedDate() ) ;
00132    }
00133 }
00134 
00135 void ReferenceObjectHandle::processEvents () 
00136 {
00137    bool eventsProcessed = false ;
00138    OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::processEvents () of " << debugMsg( &getSimulatedObject() ) << " last activated at " 
00139        << _dateOfLastEventManagement << ", now is " <<_controller.getSimulatedDate() ) ;
00140 
00141    if (_controller.getSimulatedDate() > _dateOfLastEventManagement ) 
00142       {
00143          switchEventList() ;
00144          list< Event * > & myEventList = getCurrentEventList() ;
00145          eventsProcessed = ! myEventList.empty() ;
00146          if ( eventsProcessed ) _myObject.prepareEventProcessing ( myEventList ) ; /*Mathias Lorente's suggestion*/
00147          list< Event * >::iterator i = myEventList.begin() ;
00148          list< Event * >::iterator toErase ;
00149          // if ( eventsProcessed ) _myObject.prepareEventProcessing ( myEventList ) ;
00150          while ( i != myEventList.end() ) 
00151             {
00152          OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::processEvents (): processing" << *(*i) ) ;
00153                virtualEventTableType::iterator listeners = _virtualEventTable.find ( (*i)->eventId ) ;
00154                bool finished = false ;
00155                if ( listeners != _virtualEventTable.end() ) 
00156                   {
00157                      list <EventListener * >::iterator aListener = listeners->second->begin() ;
00158                      while ( aListener != listeners->second->end() && ! finished )
00159                         {
00160                            (*aListener)->prepareEventProcessing ( myEventList , i ) ;
00161                            finished = (*aListener)->processEvent ( *i ) ;
00162                            ++aListener ;
00163                         }
00164                   }
00165                if ( ! finished ) 
00166                   {
00167                      if ( _myObject.processEvent ( *i ) ) {
00168                         delete (*i) ;
00169                      }
00170                   }
00171                else 
00172                   {
00173                      delete (*i) ;
00174                   }
00175                toErase = i ;
00176                i++ ;
00177                myEventList.erase ( toErase ) ;
00178             }
00179          if ( eventsProcessed ) _myObject.eventsProcessed ( myEventList ) ;
00180          _dateOfLastEventManagement = _controller.getSimulatedDate() ;      
00181       }  
00182    else 
00183       {
00184          //processEvents has already been called, and is called again 
00185    OMTRACEID( OMK_DEBUG_OMK_EXEC, "ReferenceObjectHandle::processEvents event processing postponed for " << debugMsg( &getSimulatedObject() ) ) ;
00186          _controller.postponeEventProcessing ( this ) ;
00187       }
00188 }
00189 
00190 
00191 
00192 bool OMK::operator < (const ReferenceObjectHandle & un,
00193                  const ReferenceObjectHandle & deux) 
00194 {   
00195    return un._myObject. getObjectDescriptor ().getName()<deux._myObject. getObjectDescriptor ().getName();
00196 }
00197 
00198 bool OMK::operator <= (const ReferenceObjectHandle & un,
00199                   const ReferenceObjectHandle & deux) 
00200 {
00201    return un._myObject.getObjectDescriptor ().getName()<=deux._myObject.getObjectDescriptor ().getName();
00202 }
00203 
00204 bool OMK::operator > (const ReferenceObjectHandle & un,
00205                  const ReferenceObjectHandle & deux)
00206 {
00207    return !(un<=deux);
00208 }
00209 
00210 bool OMK::operator >= (const ReferenceObjectHandle & un,
00211                   const ReferenceObjectHandle & deux)
00212 {
00213    return !(un<deux);
00214 }
00215 
00216 //-----------------------------------------------------------------------------
00217 
00218 void ReferenceObjectHandle::insertInStream (ostream & out) const {
00219    Controller::error ("insertInStream of ReferenceObjectHandle used");
00220 }
00221 
00222 void ReferenceObjectHandle::extract (istream & in) 
00223 {
00224    
00225 }
00226 
00227 
00228 
00229 //-----------------------------------------------------------------------------
00230 
00231 
00232 void ReferenceObjectHandle::receiveEvent (const Event & event) 
00233 {
00234 #ifdef _DEBUGEVT
00235    cerr<<"ReferenceObjectHandle::receiveEvent (const Event &"<<event<<")"<<endl;
00236 #endif
00237    receiveEvent ( event.clone() ) ;
00238 }
00239 
00240 void ReferenceObjectHandle::receiveEvent (Event * event) 
00241 {
00242   OMTRACEID( OMK_DEBUG_OMK_EVENT, "ReferenceObjectHandle::receiveEvent(Event *)" << std::endl 
00243      << "  \"" << event->receiver << "\" received event \"" << event->eventId << "\" at " << event->date ) ;
00244    //DM : a copy is sent only at reception , because only at reception is the correct controller known
00245    if ( (event->isSystem ()) && (event->receiver == _myObject.getName()) ) 
00246       {
00247          _controller.actOnSystemEvent (event) ;
00248       }  
00249    // if the receiving object is suspended, or has fast event processing activated
00250    // signal the reception to the controller
00251    if ( _computingState == suspended || _myObject.processEventsASAP () ) 
00252       {
00253          _controller.hasEventsToProcess (this) ;
00254       }
00255    if (  _computingState != stopped || event->isSystem () ) {
00256       //*event is owned by the object who has the responsibility to free it
00257 #ifdef _OMK_MUTEX_
00258       _mutexForListEvt.protect() ;
00259 #endif
00260       Event::insertInList (_eventList[_currentWritableEventList], event) ;
00261 #ifdef _OMK_MUTEX_
00262       _mutexForListEvt.unprotect() ;
00263 #endif
00264    }
00265    else {
00266       delete event ;
00267    }
00268 }
00269 
00270 // Modification 2007/05/11 Benoit Chanclou
00271 // Avoid twice registration of the same event handler
00272 void ReferenceObjectHandle::registerEventListenerForEvent( EventListener & eventListener, 
00273                                                                                                   const EventIdentifier & eventId )
00274 {
00275   // Look for an entry in the map for this event id
00276   virtualEventTableType::iterator i = _virtualEventTable.find( eventId ) ;
00277   if (i != _virtualEventTable.end() ) 
00278   {
00279     // Yes, the event id is already registered, add the listener to the list managed for it
00280     // To avoid twice registration of the same event handler
00281     list < EventListener *>* listeners = (*i).second ;
00282     if( find( listeners->begin(), listeners->end(), & eventListener ) == listeners->end() )
00283     {
00284       listeners->push_back( &eventListener ) ;
00285     }
00286   } 
00287   else
00288   {
00289     // No, must create the entry and add the listener
00290     _virtualEventTable[ eventId ] = new list< EventListener *>( 1, &eventListener ) ;
00291   }
00292 }
00293 void ReferenceObjectHandle::unregisterEventListener( EventListener & eventListener ) 
00294 {
00295   for( virtualEventTableType::iterator eventId = _virtualEventTable.begin() ;
00296        eventId != _virtualEventTable.end() ;
00297        eventId++ )
00298   {
00299     list < EventListener *>* listeners = (*eventId).second ;
00300     list < EventListener *>::iterator eventListenerPos = find( listeners->begin(), listeners->end(), & eventListener ) ;
00301     if( eventListenerPos != listeners->end() )
00302     {
00303       listeners->erase( eventListenerPos ) ;
00304     }
00305   }
00306 }
00307 
00308 list <Event *> & ReferenceObjectHandle::getCurrentEventList() {
00309    return *(_eventList[ 1 - _currentWritableEventList ] ) ;
00310 }
00311 
00312 void ReferenceObjectHandle::switchEventList () {
00313 #ifdef _OMK_MUTEX_
00314    _mutexForListEvt.protect() ;
00315 #endif
00316    _currentWritableEventList = 1 - _currentWritableEventList ;
00317 #ifdef _OMK_MUTEX_
00318    _mutexForListEvt.unprotect() ;
00319 #endif
00320 }
00321 
00322 const ReferenceObjectHandle::SimulatedObjectComputingState & ReferenceObjectHandle::getComputingState() const 
00323 {
00324    return _computingState ;
00325 }
00326 
00327 
00328 void ReferenceObjectHandle::sendEventsForSignal( Event & event , const EventIdentifier & sigId ) 
00329 {
00330    //cerr<<"ReferenceObjectHandle::sendEventsForSignal "<<sigId<<endl;
00331    _signalDispatcher->sendEventsForSignal ( event, sigId ) ;
00332    _controller.broadcastEventsForSignal ( event , sigId ) ;
00333 }
00334 
00335 bool ReferenceObjectHandle::receiveRegistrationForSignal ( const EventIdentifier & sigId, 
00336                                                               const Name & registrant, 
00337                                                               const EventIdentifier & eventId ) 
00338 {
00339    return _signalDispatcher->registerForSignal( sigId, registrant, eventId ) ;
00340 }
00341 
00342 
00343 
00344 bool ReferenceObjectHandle::cancelRegistrationForSignal ( const EventIdentifier & sigId, 
00345                                                    const Name & registrant ) 
00346 {
00347    return _signalDispatcher->cancelRegistrationForSignal ( sigId, registrant ) ;
00348 }
00349 

logo OpenMask

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

Generated with doxygen by Dimitri van Heesch ,   1997-2007