History

punish slow scripts and don't send updates while physics is still loading

Brad Hefta-Gaub committed 10 years ago

Commit 83dc9ea1 parent cb848364 files · +38 −4Browse files

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

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+27−4
@@ -828,24 +828,42 @@ void ScriptEngine::run() { · 827 unmodified lines
828828
829829 _lastUpdate = usecTimestampNow();
830830
831+ qint64 totalSleepFor = 0;
832+ std::chrono::microseconds totalUpdates;
833+ auto lastLoopStart = clock::now();
834+
831835 // TODO: Integrate this with signals/slots instead of reimplementing throttling for ScriptEngine
832836 while (!_isFinished) {
837+ auto thisLoopStart = clock::now();
838+
833839 // Throttle to SCRIPT_FPS
834840 const std::chrono::microseconds FRAME_DURATION(USECS_PER_SECOND / SCRIPT_FPS + 1);
841+ const std::chrono::microseconds MINIMUM_SLEEP { FRAME_DURATION / 2 };
842+
843+ auto beforeSleep = clock::now();
835844 clock::time_point sleepTime(startTime + thisFrame++ * FRAME_DURATION);
845+ auto wouldSleep = (sleepTime - clock::now());
846+ auto avgUpdates = totalUpdates / thisFrame;
847+
848+ if (wouldSleep < avgUpdates) {
849+ sleepTime = beforeSleep + avgUpdates;
850+ }
851+
836852 std::this_thread::sleep_until(sleepTime);
837853
838854 #ifdef SCRIPT_DELAY_DEBUG
839855 {
840− auto now = clock::now();
841− uint64_t seconds = std::chrono::duration_cast<std::chrono::seconds>(now - startTime).count();
856+ auto sleptTill = clock::now();
857+ uint64_t seconds = std::chrono::duration_cast<std::chrono::seconds>(sleptTill - startTime).count();
842858 if (seconds > 0) { // avoid division by zero and time travel
843859 uint64_t fps = thisFrame / seconds;
844860 // Overreporting artificially reduces the reported rate
845861 if (thisFrame % SCRIPT_FPS == 0) {
846862 qCDebug(scriptengine) <<
847863 "Frame:" << thisFrame <<
848− "Slept (us):" << std::chrono::duration_cast<std::chrono::microseconds>(now - sleepTime).count() <<
864+ "Slept (us):" << std::chrono::duration_cast<std::chrono::microseconds>(sleptTill - beforeSleep).count() <<
865+ "Avg Updates (us):" << avgUpdates.count() <<
866+ "Last loop time (us):" << std::chrono::duration_cast<std::chrono::microseconds>(thisLoopStart - lastLoopStart).count() <<
849867 "FPS:" << fps;
850868 }
851869 }
@@ -874,16 +892,21 @@ void ScriptEngine::run() { · 22 unmodified lines
874892 qint64 now = usecTimestampNow();
875893
876894 // we check for 'now' in the past in case people set their clock back
877− if (_lastUpdate < now) {
895+ if (_isPhysicsEnabledFunc() && _lastUpdate < now) {
878896 float deltaTime = (float) (now - _lastUpdate) / (float) USECS_PER_SECOND;
879897 if (!_isFinished) {
898+ auto preUpdate = clock::now();
880899 emit update(deltaTime);
900+ auto postUpdate = clock::now();
901+ auto elapsed = (postUpdate - preUpdate);
902+ totalUpdates += std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
881903 }
882904 }
883905 _lastUpdate = now;
884906
885907 // Debug and clear exceptions
886908 hadUncaughtExceptions(*this, _fileNameString);
909+ lastLoopStart = thisLoopStart;
887910 }
888911
889912 qCDebug(scriptengine) << "Script Engine stopping:" << getFilename();