/******************************************************************* * * DESCRIPTION: class InertialDelayCell * * AUTHOR: Amir Barylko & Jorge Beyoglonian * Version 2: Daniel Rodriguez. * * EMAIL: mailto://amir@dc.uba.ar * mailto://jbeyoglo@dc.uba.ar * mailto://drodrigu@dc.uba.ar * * DATE: 27/6/1998 * DATE: 17/9/1999 (v2) * *******************************************************************/ // ** include files **// #include "idcell.h" // header class #include "message.h" // ExternalMessage #include "coupcell.h" // CoupledCell #include "realfunc.h" // calculateWithQuantum Model &InertialDelayCell::initFunction() { this->actualValue = value(); holdIn(active, Time::Zero); return *this; } /******************************************************************* * Method: externalFunction ********************************************************************/ //Model &InertialDelayCell::externalFunction( const ExternalMessage &msg ) Model &InertialDelayCell::externalFunction( const MessageBag &msgs ) { Time delay( static_cast( parent() ).defaultDelay() ) ; Time actualTime( msgs.time() ); localTransitionConfluent(msgs); bool executedLocal = false; if (actualTime == Time::Zero) actualValue = value(); Real tv ; ////////////////////////////////////////////////////////////////////// // if the message come from an external port we must set the value for (MessageBag::iterator cursor = msgs.begin(); cursor != msgs.end() ; cursor++) { ExternalMessage msg = *((ExternalMessage*)(*cursor)); if( !executedLocal && inputPort().find(msg.port().id()) != inputPort().end()) { string functionName = inputPortFunction()[ msg.port().name() ]; if (functionName == DEFAULT_FUNCTION_InPort) tv = msg.value() ; else { VirtualPortList *vpl = new VirtualPortList; getOutPorts(vpl); tv = SingleLocalTransAdmin::Instance().evaluate( functionName, neighborhood(), &(inputPortValues()), delay, actualTime, vpl, this, msg.port().name() ) ; delete vpl; } executedLocal = true ; } else if ( executedLocal && ( inputPort().find( msg.port().id() ) != inputPort().end() ) ) { cerr << "At : " << msg.time() << endl; cerr << "Warning: current implementation can Not handle multiple external messages !" ; } } if(!executedLocal) { VirtualPortList *vpl = new VirtualPortList; getOutPorts(vpl); tv = SingleLocalTransAdmin::Instance().evaluate( localFunction(), neighborhood(), NULL, delay, actualTime, vpl, this ) ; delete vpl; } /* // if come from a neighbor if( !executedLocal && msg.port() == neighborPort() ){ VirtualPortList *vpl = new VirtualPortList; getOutPorts(vpl); tv = SingleLocalTransAdmin::Instance().evaluate( localFunction(), neighborhood(), NULL, delay, actualTime, vpl, this ) ; delete vpl; } else // else the message come from an IN port { string functionName = inputPortFunction()[ msg.port().name() ]; // first we set the new port value in the list of PortValues // setPortValue( msg.port().name(), msg.value() ); if (functionName == DEFAULT_FUNCTION_InPort) tv = msg.value() ; else { // sino es un PortInTransition valido VirtualPortList *vpl = new VirtualPortList; getOutPorts(vpl); tv = SingleLocalTransAdmin::Instance().evaluate( functionName, neighborhood(), &(inputPortValues()), delay, actualTime, vpl, this, msg.port().name() ) ; delete vpl; } } */ /////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// if (UseQuantum().Active()) tv = valueWithQuantum(tv, Real(UseQuantum().Value())); ///////////////////////////////////////////////////////////////////// if( actualValue != tv ) { actualValue = tv; /* El nuevo estado es el recien calculado */ if( state() == passive ) holdIn( active, delay ) ; else // the coupled sets sigma to the reminder time until the next internal transition if( nextChange() > Time::Zero && futureValue != tv) holdIn( active, delay ) ; futureValue = tv; } return *this ; } /******************************************************************* * Method: outputFunction ********************************************************************/ //Model &InertialDelayCell::outputFunction( const InternalMessage &msg ) Model &InertialDelayCell::outputFunction( const CollectMessage &msg ) { value( actualValue ); this->sendOutput( msg.time(), outputPort(), this->value().value() ); return *this; }