#ifndef __TRANSPORT_DELAY_ATOMIC_CELL_H #define __TRANSPORT_DELAY_ATOMIC_CELL_H #include #include #include "atomcell.h" // base class header #include "JackyDebugStream.h" //jacky-debug-mode & jacky-sync #define TRANSPORT_DELAY_CELL_NAME "TransportDelayCell" class TDCellState : public AtomicCellState { public: typedef pair< string, Real > QueueValue ; //Jacky: portName = value //Jacky: add a field to record the schedule of the internal event. "change further" and "change back" is // based on this "schedule time" rather than the "output time" as we did before! typedef pair< QueueValue, VTime > QueueValueWithScheduleTime ; //QueueElement => pair< outputTime, pair< pair< outputPortName, outputValue >, scheduleTime > > typedef pair< VTime, QueueValueWithScheduleTime > QueueElement ; //this is for the TransientQueue. //TransientValue => pair< pair< outputPortName, outputValue >, flag > typedef pair< QueueValue, bool > QueueValueWithFlag ; Queue queueVal ; //Nov. 29, 2005 //add a flag to identify value generated from external event (input) typedef list< QueueValueWithFlag > TransientQueue; //a list of (portName = value / flag) TransientQueue transientVal ; // [2006-01-06] // We need to record the simulation time to set the flag in the TransientValue // Flags in TQ are associated with a particular simulation time (RT). When ever the simulation time, // i.e. the time of the MessageBag in the externalFunction(), changes, we will update the flags in TQ // (reset the flag to FALSE for this new simulation time) // Whether the value of the cell will change depends on the flag in T for a given time: // 1. if flag = FALSE, state change/change further/change back are allowed // 2. if flag = TRUE, change further/change back are NOT allowed VTime recordTime; // RT for detecting a time change in externalFunction() //add a StateVars here to record the values of the state variables at the beginning of Round 0 //[see macro JACKY_STATE_VAR in JackyDebugStream.h for more information] StateVars vars_round0; TDCellState(){}; virtual ~TDCellState(){}; TDCellState& operator=(TDCellState& thisState); //Assignment void copyState(BasicState *); int getSize() const; bool isAtomic(); bool isAtomic() const; }; class TransportDelayCell: public AtomicCell { public: TransportDelayCell( const CellPosition& cellPos, const string & = TRANSPORT_DELAY_CELL_NAME , const LocalTransAdmin::Function &fn = LocalTransAdmin::InvalidFn ) ; string className() const; protected: Model &initFunction(); Model &internalFunction( const InternalMessage & ) ; Model &externalFunction( const MessageBag & ) ; Model &outputFunction( const CollectMessage & ) ; ModelState* allocateState() { return new TDCellState;} void initializeCell(); private: //Real Quantum; // GW //AT: Quantum is now part of AtomicCellState //const Real & QuantumValue() const; // GW //AT: This is part of AtomicCell //function to get the Queue, a list of QueueValueWithScheduleTime TDCellState::Queue &queueVal() const; //function to get the TransientQueue, a list of QueueValueWithFlag TDCellState::TransientQueue &transientVal() const; //TransportDelayCell & updateTransientQueue(const list& ); //function to get the transient value (T) at a given output port const Real &getTransientValue(const string &portName) const; //function to set the TransientValue (T), the flag in it defaults to FALSE void setTransientValue(const string &portName, const Real &value, const bool &flag = false); //function to get the flag in the transient value at a given output port const bool getTransientValueFlag(const string &portName) const; // [2006-01-06] //function to reset all flags in the transient queue to FALSE, values in the transient queue are not changed void resetTransientFlags( TDCellState::TransientQueue & ); //No need to use this function since PORT_IN_FIRST is based on the flag in the transient value //rather than the flag in the Queue element [2006-01-06] //function to get the flag in the Queue element for the same port & time //const bool getQueueElementFlag(const VTime &time, const string &portName); // [2006-01-06] // function to get/set the recordTime (RT) in the state const VTime &getRecordTime() const; void setRecordTime( const VTime& ); //get the StateVars in the AtomicCellState class StateVars &cellStateVariables(); //get the StateVars in the TDCellState class //this is a record of the StateVars in AtomicCellState at the beginning of Round 0 StateVars &recordStateVariables(); const VTime & firstQueuedTime() const; const Real & firstQueuedValue() const; const string & firstQueuedPort() const; TransportDelayCell & updateRemainingTime( const VTime & ); TransportDelayCell & insertByTime( const VTime &, const string &, const Real & ); } ; // TransportDelayCell /** inline **/ inline string TransportDelayCell::className() const { return TRANSPORT_DELAY_CELL_NAME; } inline TDCellState::Queue &TransportDelayCell::queueVal() const { return ((TDCellState *) getCurrentState())->queueVal; } inline TDCellState::TransientQueue &TransportDelayCell::transientVal() const{ return ((TDCellState *) getCurrentState())->transientVal; } inline const VTime &TransportDelayCell::getRecordTime() const{ return ((TDCellState*)getCurrentState())->recordTime; } inline void TransportDelayCell::setRecordTime( const VTime& newTime){ ((TDCellState*)getCurrentState())->recordTime = newTime; } //get the StateVars in the AtomicCellState class inline StateVars &TransportDelayCell::cellStateVariables(){ return ((TDCellState*)getCurrentState())->variables; } //get the StateVars in the TDCellState class, which is a record of the StateVars in AtomicCellState //at the beginning of Round 0 inline StateVars &TransportDelayCell::recordStateVariables(){ return ((TDCellState*)getCurrentState())->vars_round0; } #endif // __TRANSPORT_DELAY_ATOMIC_CELL_H