Skip to content

Commit e830b00

Browse files
author
Gauthier Quesnel
committed
devs: allows negative time in time advance
If a vle::devs::Dynamics::timeAdvance returns a negative value, VLE kernel will interpret this value as an absolute date instead of a duration. Seems to be useful to (re)synchronize model with integer dates and permits to reduce real representation problems. (closes: vle-forge#241).
1 parent 13d1b8b commit e830b00

File tree

4 files changed

+237
-102
lines changed

4 files changed

+237
-102
lines changed

src/vle/devs/Dynamics.hpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,16 @@ class VLE_API Dynamics
100100

101101
/**
102102
* @brief Process the initialization of the model by initializing the
103-
* initial state and return the duration (or timeAdvance) of the initial
104-
* state.
103+
* initial state and return the duration of the initial state.
104+
*
105+
* If @e init returns 0 or a positive real, this value means the
106+
* duration of the current state. But, if @e init returns a negative
107+
* real, this value means an absolute value.
108+
*
105109
* @param time the time of the creation of this model.
106-
* @return duration of the initial state.
110+
*
111+
* @return duration of the initial state ([0, +oo{) or an absolute
112+
* date (]-oo, 0[).
107113
*/
108114
virtual Time init(Time /* time */)
109115
{
@@ -121,6 +127,24 @@ class VLE_API Dynamics
121127
/**
122128
* @brief Process the time advance function: compute the duration of the
123129
* current state.
130+
*
131+
* If @e timeAdvance returns 0 or a positive real, this value means
132+
* the duration of the current state. But, if @e timeAdvance returns a
133+
* negative real, this value means an absolute value.
134+
*
135+
* @code
136+
* class Model : public vle::devs::Dynamics
137+
* {
138+
* void timeAdvance() const
139+
* {
140+
* return 0.1; // Wake up me in current time + 0.1.
141+
*
142+
* return -123.456; // Wake up me at date 123.456.
143+
* }
144+
* }
145+
*
146+
* @endcode
147+
*
124148
* @return duration of the current state.
125149
*/
126150
virtual Time timeAdvance() const

src/vle/devs/Simulator.cpp

+47-19
Original file line numberDiff line numberDiff line change
@@ -129,59 +129,87 @@ void Simulator::output(Time time)
129129
m_dynamics->output(time, m_result);
130130
}
131131

132-
Time Simulator::timeAdvance()
133-
{
134-
Time tn = m_dynamics->timeAdvance();
135-
136-
if (tn < 0.0)
137-
throw utils::ModellingError(
138-
(fmt(_("Negative time advance in '%1%' (%2%)"))
139-
% getName() % tn).str());
140-
141-
return tn;
142-
}
143-
144132
Time Simulator::init(Time time)
145133
{
146134
Time tn = m_dynamics->init(time);
147135

148-
if (tn < 0.0)
136+
if (tn >= 0)
137+
return m_tn = tn + time;
138+
139+
if (-tn < time)
149140
throw utils::ModellingError(
150-
(fmt(_("Negative init function in '%1%' (%2%)"))
151-
% getName() % tn).str());
141+
_("Bad absolute date: %f must be greater than the current date %f"),
142+
tn, time);
143+
144+
m_tn = -tn;
152145

153-
m_tn = tn + time;
154146
return m_tn;
155147
}
156148

157149
Time Simulator::confluentTransitions(Time time)
158150
{
159151
assert(not m_external_events.empty() and "Simulator d-conf error");
160152
assert(m_have_internal == true and "Simulator d-conf error");
153+
161154
m_dynamics->confluentTransitions(time, m_external_events);
162155
m_external_events.clear();
163156

164-
m_tn = timeAdvance() + time;
157+
Time tn = m_dynamics->timeAdvance();
158+
159+
if (tn >= 0)
160+
return m_tn = tn + time;
161+
162+
if (-tn < time)
163+
throw utils::ModellingError(
164+
_("Bad absolute date: %f must be greater than the current date %f"),
165+
tn, time);
166+
167+
m_tn = -tn;
168+
165169
return m_tn;
166170
}
167171

168172
Time Simulator::internalTransition(Time time)
169173
{
170174
assert(m_have_internal == true and "Simulator d-int error");
175+
171176
m_dynamics->internalTransition(time);
172177
m_have_internal = false;
173178

174-
m_tn = timeAdvance() + time;
179+
Time tn = m_dynamics->timeAdvance();
180+
181+
if (tn >= 0)
182+
return m_tn = tn + time;
183+
184+
if (-tn < time)
185+
throw utils::ModellingError(
186+
_("Bad absolute date: %f must be greater than the current date %f"),
187+
tn, time);
188+
189+
m_tn = -tn;
190+
175191
return m_tn;
176192
}
177193

178194
Time Simulator::externalTransition(Time time)
179195
{
180196
assert(not m_external_events.empty() and "Simulator d-ext error");
197+
181198
m_dynamics->externalTransition(m_external_events, time);
182199
m_external_events.clear();
183200

184-
m_tn = timeAdvance() + time;
201+
Time tn = m_dynamics->timeAdvance();
202+
203+
if (tn >= 0)
204+
return m_tn = tn + time;
205+
206+
if (-tn < time)
207+
throw utils::ModellingError(
208+
_("Bad absolute date: %f must be greater than the current date %f"),
209+
tn, time);
210+
211+
m_tn = -tn;
212+
185213
return m_tn;
186214
}
187215

src/vle/devs/Simulator.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ class VLE_LOCAL Simulator
136136
/*-*-*-*-*-*-*-*-*-*/
137137

138138
Time init(Time time);
139-
Time timeAdvance();
140139
void finish();
141140
void output(Time time);
142141
Time internalTransition(Time time);

0 commit comments

Comments
 (0)