1+ #include < QDateTime>
12#include < QRandomGenerator>
23#include " datasimulator.h"
34
78// /
89DataSimulator::DataSimulator (QObject* parent)
910 : QObject{parent}
10- ,_elapsed(0 )
1111{
12+ _timer.setSingleShot (true );
13+ _timer.setTimerType (Qt::PreciseTimer);
1214 connect (&_timer, &QTimer::timeout, this , &DataSimulator::on_timeout);
15+ _masterTimer.start ();
1316}
1417
1518// /
@@ -48,8 +51,8 @@ void DataSimulator::startSimulation(DataDisplayMode mode, quint8 deviceId, QModb
4851 }
4952
5053 _simulationMap[{ deviceId, type, addr}] = { mode, params, value };
51- resumeSimulations ();
5254
55+ scheduleNextRun ();
5356 emit simulationStarted (deviceId, type, addr);
5457}
5558
@@ -63,6 +66,8 @@ void DataSimulator::stopSimulation(quint8 deviceId, QModbusDataUnit::RegisterTyp
6366{
6467 _simulationMap.remove ({ deviceId, type, addr});
6568 emit simulationStopped (deviceId, type, addr);
69+
70+ scheduleNextRun ();
6671}
6772
6873// /
@@ -87,8 +92,7 @@ void DataSimulator::pauseSimulations()
8792// /
8893void DataSimulator::resumeSimulations ()
8994{
90- if (!_timer.isActive ())
91- _timer.start (_interval);
95+ scheduleNextRun ();
9296}
9397
9498// /
@@ -130,42 +134,78 @@ ModbusSimulationMap2 DataSimulator::simulationMap() const
130134 return map;
131135}
132136
137+ // /
138+ // / \brief DataSimulator::scheduleNextRun
139+ // /
140+ void DataSimulator::scheduleNextRun ()
141+ {
142+ if (_simulationMap.isEmpty ()) {
143+ _timer.stop ();
144+ return ;
145+ }
146+
147+ const qint64 currentTime = _masterTimer.elapsed ();
148+ qint64 minNextTime = -1 ;
149+
150+ for (auto it = _simulationMap.constBegin (); it != _simulationMap.constEnd (); ++it) {
151+ const qint64 nextTime = it.value ().NextRunTime ;
152+
153+ if (minNextTime == -1 || nextTime < minNextTime) {
154+ minNextTime = nextTime;
155+ }
156+ }
157+
158+ const qint64 delay = qMax<qint64>(0 , minNextTime - currentTime);
159+
160+ _timer.start (delay);
161+ }
162+
133163// /
134164// / \brief DataSimulator::on_timeout
135165// /
136166void DataSimulator::on_timeout ()
137167{
138- _elapsed++;
139- for (auto && key : _simulationMap.keys ())
168+ const qint64 currentTime = _masterTimer.elapsed ();
169+
170+ QMutableMapIterator it (_simulationMap);
171+ while (it.hasNext ())
140172 {
141- const auto mode = _simulationMap[key].Mode ;
142- const auto params = _simulationMap[key].Params ;
173+ it.next ();
174+
175+ auto & sim = it.value ();
176+ const auto & key = it.key ();
177+ const auto mode = sim.Mode ;
178+ const auto params = sim.Params ;
143179 const auto interval = params.Interval ;
144180
145- if ((_elapsed * _interval) % interval ) continue ;
181+ if (interval <= 0 || sim. NextRunTime > currentTime ) continue ;
146182
147183 switch (params.Mode )
148184 {
149185 case SimulationMode::Random:
150186 randomSimulation (mode, key.DeviceId , key.Type , key.Address , params.RandomParams );
151- break ;
187+ break ;
152188
153189 case SimulationMode::Increment:
154190 incrementSimulation (mode, key.DeviceId , key.Type , key.Address , params.IncrementParams );
155- break ;
191+ break ;
156192
157193 case SimulationMode::Decrement:
158194 decrementSimailation (mode, key.DeviceId , key.Type , key.Address , params.DecrementParams );
159- break ;
195+ break ;
160196
161197 case SimulationMode::Toggle:
162198 toggleSimulation (key.DeviceId , key.Type , key.Address );
163- break ;
199+ break ;
164200
165201 default :
166- break ;
202+ break ;
167203 }
204+
205+ sim.NextRunTime = currentTime + interval;
168206 }
207+
208+ scheduleNextRun ();
169209}
170210
171211
0 commit comments