diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index b28a60163a..ce73d11f47 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -115,6 +115,8 @@ public: double timeout, std::string preScript = "", std::string postScript = ""); void removeRepeatedScript(std::string_view identifier); + void scheduleScript(std::string script, double delay); + std::vector allLuaFunctions() const; const std::vector& allLuaLibraries() const; @@ -158,6 +160,15 @@ private: }; std::vector _repeatedScripts; + struct ScheduledScriptInfo { + // The script that should be executed + std::string script; + + // The application timestamp at which time the script should be executed + double timestamp = 0.0; + }; + std::vector _scheduledScripts; + // Logging variables bool _logFileExists = false; bool _logScripts = true; diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 0b1878a9b8..f8b1915e2e 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -572,6 +572,15 @@ void ScriptEngine::postSync(bool isMaster) { info.lastRun = now; } } + + for (size_t i = 0; i < _scheduledScripts.size(); i++) { + const ScheduledScriptInfo& info = _scheduledScripts[i]; + if (now > info.timestamp) { + runScript({ info.script }); + _scheduledScripts.erase(_scheduledScripts.begin() + i); + i--; + } + } } void ScriptEngine::queueScript(Script script) { @@ -636,6 +645,14 @@ void ScriptEngine::removeRepeatedScript(std::string_view identifier) { } } +void ScriptEngine::scheduleScript(std::string script, double delay) { + double now = + global::sessionRecordingHandler->isSavingFramesDuringPlayback() ? + global::sessionRecordingHandler->currentApplicationInterpolationTime() : + global::windowDelegate->applicationTime(); + _scheduledScripts.emplace_back(std::move(script), now + delay); +} + void ScriptEngine::addBaseLibrary() { ZoneScoped; @@ -715,7 +732,8 @@ void ScriptEngine::addBaseLibrary() { codegen::lua::DirectoryForPath, codegen::lua::UnzipFile, codegen::lua::RegisterRepeatedScript, - codegen::lua::RemoveRepeatedScript + codegen::lua::RemoveRepeatedScript, + codegen::lua::ScheduleScript } }; addLibrary(lib); diff --git a/src/scripting/scriptengine_lua.inl b/src/scripting/scriptengine_lua.inl index 8c038f308d..0e24921205 100644 --- a/src/scripting/scriptengine_lua.inl +++ b/src/scripting/scriptengine_lua.inl @@ -312,6 +312,15 @@ std::vector walkCommon(const std::filesystem::path& path, openspace::global::scriptEngine->removeRepeatedScript(identifier); } +/** + * Schedules a `script` to be run in `delay` seconds. The delay is measured in wallclock + * time, which is seconds that occur in the real world, not in relation to the in-game + * time. + */ +[[codegen::luawrap]] void scheduleScript(std::string script, double delay) { + openspace::global::scriptEngine->scheduleScript(std::move(script), delay); +} + #include "scriptengine_lua_codegen.cpp" } // namespace