/******************************************************************* * * DESCRIPTION: class CellCoordinator * * AUTHOR: Amir Barylko & Jorge Beyoglonian * Version 2: Daniel A. Rodriguez * * EMAIL: mailto://amir@dc.uba.ar * mailto://jbeyoglo@dc.uba.ar * mailto://drodrigu@dc.uba.ar * * DATE: 27/6/1998 * DATE: 27/2/1999 (v2) * *******************************************************************/ // ** include files **// #include "coorcell.h" // class header #include "coupcell.h" // class CupledCell #include "msgadm.h" // SingleMsgAdmin // ** public data ** // // ** private data ** // // ** public ** // /******************************************************************* * Function Name: CellCoordinator * Description: ********************************************************************/ CellCoordinator::CellCoordinator( CoupledCell *cell ) : Coordinator( cell ) {} /******************************************************************* * Function Name: receive * Description: ********************************************************************/ Processor &CellCoordinator::receive( const InternalMessage &msg ) { doneCount(0) ; InternalMessage internal( msg.time(), this->Processor::id() ) ; Inminents::iterator cursor = inminents.find( msg.time() ); for( ; cursor != inminents.end() && cursor->first == msg.time() ; cursor++ , this->donecount++ ) SingleMsgAdm::Instance().send( internal, cursor->second ) ; inminents.erase( inminents.find( msg.time() ), cursor ); return *this ; } /******************************************************************* * Function Name: receive * Description: ********************************************************************/ Processor &CellCoordinator::receive( const OutputMessage &msg ) { Coupled &coupled( static_cast< Coupled & >( model() ) ); const InfluenceList &influList( msg.port().influences() ); InfluenceList::const_iterator cursor( influList.begin() ); OutputMessage outMsg( msg ) ; outMsg.procId( this->Processor::id() ) ; ExternalMessage extMsg ; extMsg.time( msg.time() ) ; extMsg.procId( this->Processor::id() ) ; extMsg.value( msg.value() ) ; for( ; cursor != influList.end() ; cursor++ ) { // missing in the output list => must be treated as an external message if( coupled.outputPorts().find( (*cursor)->id() ) == coupled.outputPorts().end() ) { extMsg.port( * (*cursor) ) ; // send the message only once per model /* * if( influenced.find( (*cursor)->model() ) == influenced.end() ) { SingleMsgAdm::Instance().send( extMsg, (*cursor)->model() ) ; donecount++ ; } influenced.insert( (*cursor)->model() ) ; */ } else { outMsg.port( * (*cursor) ) ; SingleMsgAdm::Instance().send( outMsg, coupled.parentId() ) ; } } return *this ; } /******************************************************************* * Function Name: receive * Description: ********************************************************************/ Processor &CellCoordinator::receive( const DoneMessage &msg ) { Coupled &coupled( static_cast< Coupled & >( this->model() ) ) ; //Rami MASSERTMSG( this->doneCount() > 0, "Unexpected Done message!" ) ; Inminents::iterator cursor ; for( cursor = inminents.begin() ; cursor != inminents.end() && (*cursor).second != msg.procId() ; cursor++ ) ; if( cursor != inminents.end() ) inminents.erase( cursor ); if( msg.nextChange() != Time::Inf ) { Time t( msg.time() + msg.nextChange() ); Inminents::iterator cursor ; for( cursor = inminents.find( t ) ; cursor != inminents.end() && cursor->first == t && cursor->second > msg.procId() ; cursor ++ ) ; // the inminents list it's ordered by (time, procid) inminents.insert( cursor, Inminents::value_type( t, msg.procId() ) ) ; } //Rami donecount-- ; // if donecount == 0 then all the children already answered to they messages if( doneCount() == 0 ) { lastChange( msg.time() ) ; if( inminents.empty() ) { nextChange( Time::Inf ) ; inminentChild( Processor::InvalidId ) ; } else { cursor = inminents.begin() ; // nextchange relative nextChange( cursor->first - msg.time() ) ; inminentChild( cursor->second ) ; } // the set must be erased influenced.erase( influenced.begin(), influenced.end() ) ; DoneMessage doneMsg( msg.time(), this->Processor::id(), coupled.nextChange() ) ; SingleMsgAdm::Instance().send( doneMsg, coupled.parentId() ) ; } return *this ; }