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 | #include "ScriptManager.h" | 14 | #include "ScriptManager.h" |
| 15 | 15 | ||
| 16 | #include <chrono> | 16 | #include <chrono> |
| 17 | #include <memory> | ||
| 17 | #include <thread> | 18 | #include <thread> |
| 18 | 19 | ||
| 19 | #include <QtCore/QCoreApplication> | 20 | #include <QtCore/QCoreApplication> |
| @@ -1171,40 +1172,12 @@ void ScriptManager::run() { · 1151 unmodified lines | |||
| 1171 | // NOTE: This is private because it must be called on the same thread that created the timers, which is why | 1172 | // NOTE: This is private because it must be called on the same thread that created the timers, which is why |
| 1172 | // we want to only call it in our own run "shutdown" processing. | 1173 | // we want to only call it in our own run "shutdown" processing. |
| 1173 | void ScriptManager::stopAllTimers() { | 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 | _timerFunctionMap.clear(); | 1175 | _timerFunctionMap.clear(); |
| 1182 | _timerHandleCounter = 1; | 1176 | _timerHandleCounter = 1; |
| 1183 | } | 1177 | } |
| 1184 | 1178 | ||
| 1185 | void ScriptManager::stopAllTimersForEntityScript(const EntityItemID& entityID) { | 1179 | void ScriptManager::stopAllTimersForEntityScript(const EntityItemID& entityID) { |
| 1186 | std::vector<int> toDelete = {}; | 1180 | std::erase_if(_timerFunctionMap, [entityID](auto& i) { return i.second.second.definingEntityIdentifier == entityID; }); |
| 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 | |||
| 1208 | // the timer map is potentially shared across multiple entity scripts, | 1181 | // the timer map is potentially shared across multiple entity scripts, |
| 1209 | // so don't clear it or reset the handle counter | 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 | return; | 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 | if (!timer->isActive()) { | 1237 | if (!timer->isActive()) { |
| 1263 | // this timer is done, we can kill it | 1238 | // this timer is done, we can kill it |
| 1264 | _timerFunctionMap.remove(handle); | 1239 | _timerFunctionMap.erase(handle); |
| 1265 | delete timer; | ||
| 1266 | } | 1240 | } |
| 1267 | 1241 | ||
| 1268 | // call the associated JS function, if it exists | 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 | int handle = _timerHandleCounter++; | 1260 | int handle = _timerHandleCounter++; |
| 1287 | 1261 | ||
| 1288 | // create the timer, add it to the map, and start it | 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 | newTimer->setSingleShot(isSingleShot); | 1266 | newTimer->setSingleShot(isSingleShot); |
| 1291 | 1267 | ||
| 1292 | // The default timer type is not very accurate below about 200ms http://doc.qt.io/qt-5/qt.html#TimerType-enum | 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 | newTimer->setTimerType(Qt::PreciseTimer); | 1271 | newTimer->setTimerType(Qt::PreciseTimer); |
| 1296 | } | 1272 | } |
| 1297 | 1273 | ||
| 1298 | connect(newTimer, &QTimer::timeout, [this, handle]() { timerFired(handle); }); | 1274 | connect(newTimer.get(), &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 }); | ||
| 1305 | 1275 | ||
| 1306 | if (intervalMS < 0) { | 1276 | if (intervalMS < 0) { |
| 1307 | int lineNumber = -1; | 1277 | int lineNumber = -1; |
| @@ -1354,10 +1324,7 @@ int ScriptManager::setTimeout(const ScriptValue& function, int timeoutMS) { · 46 unmodified lines | |||
| 1354 | 1324 | ||
| 1355 | void ScriptManager::stopTimer(int handle) { | 1325 | void ScriptManager::stopTimer(int handle) { |
| 1356 | if (_timerFunctionMap.contains(handle)) { | 1326 | if (_timerFunctionMap.contains(handle)) { |
| 1357 | auto [timer, callbackData] = _timerFunctionMap.value(handle); | 1327 | _timerFunctionMap.erase(handle); |
| 1358 | timer->stop(); | ||
| 1359 | _timerFunctionMap.remove(handle); | ||
| 1360 | delete timer; | ||
| 1361 | } else { | 1328 | } else { |
| 1362 | qCDebug(scriptengine) << "stopTimer -- not in _timerFunctionMap" << handle; | 1329 | qCDebug(scriptengine) << "stopTimer -- not in _timerFunctionMap" << handle; |
| 1363 | } | 1330 | } |