The QTimer class automatically stops the timer, so no need to do it automatically.
Showing the changes to libraries/script-engine/src/ScriptManager.cpp (1 of 2 files). Show all
Unified · Split
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include "ScriptManager.h" |
| 15 | 15 | |
| 16 | 16 | #include <chrono> |
| 17 | +#include <memory> | |
| 17 | 18 | #include <thread> |
| 18 | 19 | |
| 19 | 20 | #include <QtCore/QCoreApplication> |
| @@ -1171,40 +1172,12 @@ void ScriptManager::run() { · 1151 unmodified lines | ||
| 1171 | 1172 | // NOTE: This is private because it must be called on the same thread that created the timers, which is why |
| 1172 | 1173 | // we want to only call it in our own run "shutdown" processing. |
| 1173 | 1174 | void ScriptManager::stopAllTimers() { |
| 1174 | − for (const auto& pair : _timerFunctionMap) { | |
| 1175 | − QTimer* timer = std::get<0>(pair); | |
| 1176 | − | |
| 1177 | − timer->stop(); | |
| 1178 | − delete timer; | |
| 1179 | − } | |
| 1180 | − | |
| 1181 | 1175 | _timerFunctionMap.clear(); |
| 1182 | 1176 | _timerHandleCounter = 1; |
| 1183 | 1177 | } |
| 1184 | 1178 | |
| 1185 | 1179 | void ScriptManager::stopAllTimersForEntityScript(const EntityItemID& entityID) { |
| 1186 | − std::vector<int> toDelete = {}; | |
| 1187 | − | |
| 1188 | − for ( | |
| 1189 | − auto i = _timerFunctionMap.constKeyValueBegin(); | |
| 1190 | − i != _timerFunctionMap.constKeyValueEnd(); | |
| 1191 | − ++i | |
| 1192 | − ) { | |
| 1193 | − const auto& handle = i->first; | |
| 1194 | − const auto& [timer, callbackData] = i->second; | |
| 1195 | − | |
| 1196 | − if (callbackData.definingEntityIdentifier != entityID) { continue; } | |
| 1197 | − | |
| 1198 | − timer->stop(); | |
| 1199 | − delete timer; | |
| 1200 | − | |
| 1201 | − toDelete.push_back(handle); | |
| 1202 | − } | |
| 1203 | − | |
| 1204 | − for (auto handle : toDelete) { | |
| 1205 | − _timerFunctionMap.remove(handle); | |
| 1206 | − } | |
| 1207 | − | |
| 1180 | + std::erase_if(_timerFunctionMap, [entityID](auto& i) { return i.second.second.definingEntityIdentifier == entityID; }); | |
| 1208 | 1181 | // the timer map is potentially shared across multiple entity scripts, |
| 1209 | 1182 | // so don't clear it or reset the handle counter |
| 1210 | 1183 | } |
| @@ -1257,12 +1230,13 @@ void ScriptManager::timerFired(int handle) { · 46 unmodified lines | ||
| 1257 | 1230 | return; |
| 1258 | 1231 | } |
| 1259 | 1232 | |
| 1260 | − auto [timer, data] = _timerFunctionMap.value(handle); | |
| 1233 | + auto& functionPair = _timerFunctionMap[handle]; | |
| 1234 | + auto& timer = functionPair.first; | |
| 1235 | + auto data = functionPair.second; | |
| 1261 | 1236 | |
| 1262 | 1237 | if (!timer->isActive()) { |
| 1263 | 1238 | // this timer is done, we can kill it |
| 1264 | − _timerFunctionMap.remove(handle); | |
| 1265 | − delete timer; | |
| 1239 | + _timerFunctionMap.erase(handle); | |
| 1266 | 1240 | } |
| 1267 | 1241 | |
| 1268 | 1242 | // call the associated JS function, if it exists |
| @@ -1286,7 +1260,9 @@ int ScriptManager::setupTimerWithInterval(const ScriptValue& function, int inter · 17 unmodified lines | ||
| 1286 | 1260 | int handle = _timerHandleCounter++; |
| 1287 | 1261 | |
| 1288 | 1262 | // create the timer, add it to the map, and start it |
| 1289 | − QTimer* newTimer = new QTimer(this); | |
| 1263 | + CallbackData timerData = { function, currentEntityIdentifier, currentSandboxURL }; | |
| 1264 | + auto& newTimer = | |
| 1265 | + _timerFunctionMap.emplace(handle, std::make_pair(std::make_unique<QTimer>(), timerData)).first->second.first; | |
| 1290 | 1266 | newTimer->setSingleShot(isSingleShot); |
| 1291 | 1267 | |
| 1292 | 1268 | // The default timer type is not very accurate below about 200ms http://doc.qt.io/qt-5/qt.html#TimerType-enum |
| @@ -1295,13 +1271,7 @@ int ScriptManager::setupTimerWithInterval(const ScriptValue& function, int inter · 2 unmodified lines | ||
| 1295 | 1271 | newTimer->setTimerType(Qt::PreciseTimer); |
| 1296 | 1272 | } |
| 1297 | 1273 | |
| 1298 | − connect(newTimer, &QTimer::timeout, [this, handle]() { timerFired(handle); }); | |
| 1299 | − | |
| 1300 | − // make sure the timer stops when the script does | |
| 1301 | − connect(this, &ScriptManager::scriptEnding, newTimer, &QTimer::stop); | |
| 1302 | − | |
| 1303 | − CallbackData timerData = { function, currentEntityIdentifier, currentSandboxURL }; | |
| 1304 | − _timerFunctionMap.insert(handle, { newTimer, timerData }); | |
| 1274 | + connect(newTimer.get(), &QTimer::timeout, [this, handle]() { timerFired(handle); }); | |
| 1305 | 1275 | |
| 1306 | 1276 | if (intervalMS < 0) { |
| 1307 | 1277 | int lineNumber = -1; |
| @@ -1354,10 +1324,7 @@ int ScriptManager::setTimeout(const ScriptValue& function, int timeoutMS) { · 46 unmodified lines | ||
| 1354 | 1324 | |
| 1355 | 1325 | void ScriptManager::stopTimer(int handle) { |
| 1356 | 1326 | if (_timerFunctionMap.contains(handle)) { |
| 1357 | − auto [timer, callbackData] = _timerFunctionMap.value(handle); | |
| 1358 | − timer->stop(); | |
| 1359 | − _timerFunctionMap.remove(handle); | |
| 1360 | − delete timer; | |
| 1327 | + _timerFunctionMap.erase(handle); | |
| 1361 | 1328 | } else { |
| 1362 | 1329 | qCDebug(scriptengine) << "stopTimer -- not in _timerFunctionMap" << handle; |
| 1363 | 1330 | } |