diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cfbaee7ade..9b38e95c2d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5419,6 +5419,15 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri return !entityServerNode || isPhysicsEnabled(); }); + scriptEngine->setGetTargetUpdateRateFunction([this]() { + auto displayPlugin = _displayPlugin; + if (displayPlugin) { + auto targetUpdateRate = displayPlugin->getTargetFrameRate(); + return targetUpdateRate; + } + return 60.0f; + }); + // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so // we can use the same ones from the application. auto entityScriptingInterface = DependencyManager::get(); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 2191d45d45..19ab19abb8 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -898,14 +898,14 @@ void ScriptEngine::run() { while (!_isFinished) { auto beforeSleep = clock::now(); - // Throttle to SCRIPT_FPS - // We'd like to try to keep the script at a solid SCRIPT_FPS update rate. And so we will + // Throttle to _targetUpdateRate + // We'd like to try to keep the script at a solid _targetUpdateRate update rate. And so we will // calculate a sleepUntil to be the time from our start time until the original target // sleepUntil for this frame. This approach will allow us to "catch up" in the event // that some of our script udpates/frames take a little bit longer than the target average // to execute. // NOTE: if we go to variable SCRIPT_FPS, then we will need to reconsider this approach - const std::chrono::microseconds TARGET_SCRIPT_FRAME_DURATION(USECS_PER_SECOND / SCRIPT_FPS + 1); + const std::chrono::microseconds TARGET_SCRIPT_FRAME_DURATION(static_cast(USECS_PER_SECOND / _getTargetUpdateRate()) + 1); clock::time_point targetSleepUntil(startTime + (thisFrame++ * TARGET_SCRIPT_FRAME_DURATION)); // However, if our sleepUntil is not at least our average update and timer execution time diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 32d81b9511..c0c1f7ac96 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -41,11 +41,9 @@ #include "ScriptUUID.h" #include "Vec3.h" -class QScriptEngineDebugger; - static const QString NO_SCRIPT(""); -static const int SCRIPT_FPS = 60; +class QScriptEngineDebugger; class CallbackData { public: @@ -56,6 +54,7 @@ public: typedef QList CallbackList; typedef QHash RegisteredEventHandlers; +using GetTargetUpdateRateFunction = std::function; class EntityScriptDetails { public: @@ -201,6 +200,8 @@ public: bool getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const; + void setGetTargetUpdateRateFunction(GetTargetUpdateRateFunction function) { _getTargetUpdateRate = function; } + public slots: void callAnimationStateHandler(QScriptValue callback, AnimVariantMap parameters, QStringList names, bool useNames, AnimVariantResultHandler resultHandler); void updateMemoryCost(const qint64&); @@ -270,6 +271,8 @@ protected: std::atomic _isUserLoaded { false }; bool _isReloading { false }; + GetTargetUpdateRateFunction _getTargetUpdateRate { []() { return 60.0f; } }; + ArrayBufferClass* _arrayBufferClass; AssetScriptingInterface _assetScriptingInterface{ this };