History

make use of stl containers and RAII

The QTimer class automatically stops the timer, so no need to do it automatically.

RTUnreal committed 4 months ago

Commit b87aa041 parent 42bbbaf2 files · +12 −45Browse files

Showing the changes to libraries/script-engine/src/ScriptManager.cpp (1 of 2 files). Show all

Unified · Split

libraries/script-engine/src/ScriptManager.cpp+11−44
@@ -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 why1172// 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.
1173void ScriptManager::stopAllTimers() {1174void 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
1185void ScriptManager::stopAllTimersForEntityScript(const EntityItemID& entityID) {1179void 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 counter1182 // 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 it1238 // 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 exists1242 // 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 it1262 // 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-enum1268 // 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
1355void ScriptManager::stopTimer(int handle) {1325void 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 }