StorageFrom VLEThe storage model is to replicate the input to output with a lag. If an input is present before the replication to output, so this input is ignored. Code explanationModel's attributs private: enum State { PASSIVE, RESPOND }; // parameter double mDuration; // state double mStorage; double mSigma; State mState; vd::Time mLastTime; As the model Generator,mDuration is a parameter that will allow us to store the time step between the reception of an event and its replication. The attributemStorage store entrance to replicate. In our example, an entry is represented by a real. mSigma will allow us to calculate the remaining time between each event received to continue to replicate the first entry received. mState will serve to situate us in the state of the model : if it's waiting for input or if it's in the process of replicating. And finally, mLastTime, as in the model Generator used to store the date of the last event.
Storage(const vd::DynamicsInit& init, const vd::InitEventList& events) : vd::Dynamics(init, events) { mDuration = vv::toDouble(events.get("duration")); } virtual ~Storage() { } There are exactly the same as for the model Generator, the constructor retrieves the duration parameter, and the destructor is empty but obligatory.
virtual vd::Time init(const vd::Time& time) { mSigma = mDuration; mLastTime = time; mState = PASSIVE; return vd::Time::infinity; } We init the attribute mSigma at parameter duration, mLastime at the start. At the begining of the simulation, we wait an input so we init mState to PASSIVE. Finaly, we return infinity to wait indefinitely until a reception of an entry. Output virtual void output(const vd::Time& /* time */, vd::ExternalEventList& output) const { vd::ExternalEvent* event = new vd::ExternalEvent("out"); event << vd::attribute("in", mStorage); output.addEvent(event); } We xant replicate what we have recieved in entry. First we create an event nammed event which will be sent on the port out. We add at this new event the attribute mStorage (which contains what must be replicated) and which will be send on the port out. Finaly we add the event which will be sent by the output function.
TimeAdvance (Ta) virtual vd::Time timeAdvance() const { switch (mState) { case PASSIVE : return vd::Time::infinity; case RESPOND : return mSigma; } } If we waiting en event in model's entry, we wait indefinitely. If we replicating an entry (RESPOND state), we return the time remaining before sending the replicated entry.
virtual void internalTransition(const vd::Time& time) { mLastTime = time; mSigma = mDuration; mState = PASSIVE; }
virtual void externalTransition(const vd::ExternalEventList& events, const vd::Time& time ) { switch (mState) { case PASSIVE: vd::ExternalEventList::const_iterator it = events.begin(); while (it != events.end()) { mStorage = (*it)->getDoubleAttributeValue("in"); ++it; } mSigma = mDuration; mLastTime = time; mState = RESPOND; break; case RESPOND: mSigma -= time - mLastTime; mLastTime = time; break; } } First, we watch if we are in a stay state (PASSIVE) or if we yet have an entry to replicate (RESPOND). If we waiting an entry, we retrieve this entry on the port in with : vd::ExternalEventList::const_iterator it = events.begin(); while (it != events.end()) { mStorage = (*it)->getDoubleAttributeValue("in"); ++it; } We then reset mSigma to the parameter duration, update mLastTime an set instate of replication (RESPOND)
virtual void confluentTransitions(const vd::Time& time, const vd::ExternalEventList& /* event */ ) { internalTransition(time); } As the model [[Generator], this function say that when a conflict arises, we ignore external events and we do the internal transition only.
|