mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 19:19:39 -06:00
Add ability to schedule Lua scripts (#3416)
This commit is contained in:
@@ -102,7 +102,6 @@ public:
|
||||
void addLibrary(LuaLibrary library);
|
||||
bool hasLibrary(const std::string& name);
|
||||
|
||||
|
||||
virtual void preSync(bool isMaster) override;
|
||||
virtual void encode(SyncBuffer* syncBuffer) override;
|
||||
virtual void decode(SyncBuffer* syncBuffer) override;
|
||||
@@ -111,6 +110,11 @@ public:
|
||||
void queueScript(Script script);
|
||||
void queueScript(std::string script);
|
||||
|
||||
// Runs the `script` every `timeout` seconds wallclock time
|
||||
void registerRepeatedScript(std::string identifier, std::string script,
|
||||
double timeout, std::string preScript = "", std::string postScript = "");
|
||||
void removeRepeatedScript(std::string_view identifier);
|
||||
|
||||
std::vector<std::string> allLuaFunctions() const;
|
||||
const std::vector<LuaLibrary>& allLuaLibraries() const;
|
||||
|
||||
@@ -141,6 +145,19 @@ private:
|
||||
|
||||
std::vector<std::string> _scriptsToSync;
|
||||
|
||||
struct RepeatedScriptInfo {
|
||||
/// This script is run everytime `timeout` seconds have passed
|
||||
std::string script;
|
||||
|
||||
/// This script is run when the repeated script is unregistered
|
||||
std::string postScript;
|
||||
|
||||
std::string identifier;
|
||||
double timeout = 0.0;
|
||||
double lastRun = 0.0;
|
||||
};
|
||||
std::vector<RepeatedScriptInfo> _repeatedScripts;
|
||||
|
||||
// Logging variables
|
||||
bool _logFileExists = false;
|
||||
bool _logScripts = true;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/util/syncbuffer.h>
|
||||
@@ -103,6 +104,12 @@ void ScriptEngine::deinitialize() {
|
||||
ZoneScoped;
|
||||
|
||||
_registeredLibraries.clear();
|
||||
for (const RepeatedScriptInfo& info : _repeatedScripts) {
|
||||
if (info.postScript.empty()) {
|
||||
queueScript(info.postScript);
|
||||
}
|
||||
}
|
||||
_repeatedScripts.clear();
|
||||
}
|
||||
|
||||
void ScriptEngine::initializeLuaState(lua_State* state) {
|
||||
@@ -553,6 +560,17 @@ void ScriptEngine::postSync(bool isMaster) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double now =
|
||||
global::sessionRecording->isSavingFramesDuringPlayback() ?
|
||||
global::sessionRecording->currentApplicationInterpolationTime() :
|
||||
global::windowDelegate->applicationTime();
|
||||
for (RepeatedScriptInfo& info : _repeatedScripts) {
|
||||
if (now - info.lastRun >= info.timeout) {
|
||||
runScript({ info.script });
|
||||
info.lastRun = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::queueScript(Script script) {
|
||||
@@ -568,6 +586,55 @@ void ScriptEngine::queueScript(std::string script) {
|
||||
queueScript({ .code = std::move(script) });
|
||||
}
|
||||
|
||||
void ScriptEngine::registerRepeatedScript(std::string identifier, std::string script,
|
||||
double timeout, std::string preScript,
|
||||
std::string postScript)
|
||||
{
|
||||
auto it = std::find_if(
|
||||
_repeatedScripts.begin(),
|
||||
_repeatedScripts.end(),
|
||||
[&identifier](const RepeatedScriptInfo& info) {
|
||||
return info.identifier == identifier;
|
||||
}
|
||||
);
|
||||
if (it != _repeatedScripts.end()) {
|
||||
throw ghoul::RuntimeError(
|
||||
std::format("Script with identifier '{}' already registered", identifier),
|
||||
"ScriptEngine"
|
||||
);
|
||||
}
|
||||
|
||||
if (!preScript.empty()) {
|
||||
runScript({ std::move(preScript) });
|
||||
}
|
||||
_repeatedScripts.emplace_back(
|
||||
std::move(script),
|
||||
std::move(postScript),
|
||||
std::move(identifier),
|
||||
timeout
|
||||
);
|
||||
}
|
||||
|
||||
void ScriptEngine::removeRepeatedScript(std::string_view identifier) {
|
||||
auto it = std::find_if(
|
||||
_repeatedScripts.begin(),
|
||||
_repeatedScripts.end(),
|
||||
[&identifier](const RepeatedScriptInfo& info) {
|
||||
return info.identifier == identifier;
|
||||
}
|
||||
);
|
||||
if (it != _repeatedScripts.end()) {
|
||||
if (!it->postScript.empty()) {
|
||||
queueScript(it->postScript);
|
||||
}
|
||||
|
||||
_repeatedScripts.erase(it);
|
||||
}
|
||||
else {
|
||||
LERROR(std::format("Could not find script with identifier '{}'", identifier));
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::addBaseLibrary() {
|
||||
ZoneScoped;
|
||||
|
||||
@@ -645,7 +712,9 @@ void ScriptEngine::addBaseLibrary() {
|
||||
codegen::lua::WalkDirectoryFiles,
|
||||
codegen::lua::WalkDirectoryFolders,
|
||||
codegen::lua::DirectoryForPath,
|
||||
codegen::lua::UnzipFile
|
||||
codegen::lua::UnzipFile,
|
||||
codegen::lua::RegisterRepeatedScript,
|
||||
codegen::lua::RemoveRepeatedScript
|
||||
}
|
||||
};
|
||||
addLibrary(lib);
|
||||
|
||||
@@ -279,6 +279,39 @@ std::vector<std::filesystem::path> walkCommon(const std::filesystem::path& path,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function registers another Lua script that will be periodically executed as long
|
||||
* as the application is running. The `identifier` is used to later remove the script. The
|
||||
* `script` is being executed every `timeout` seconds. This timeout is only as accurate as
|
||||
* the framerate at which the application is running. Optionally the `preScript` Lua
|
||||
* script is run when registering the repeated script and the `postScript` is run when
|
||||
* unregistering it or when the application closes.
|
||||
* If the `timeout` is 0, the script will be executed every frame.
|
||||
* The `identifier` has to be a unique name that cannot have been used to register a
|
||||
* repeated script before. A registered script is removed with the #removeRepeatedScript
|
||||
* function.
|
||||
*/
|
||||
[[codegen::luawrap]] void registerRepeatedScript(std::string identifier,
|
||||
std::string script, double timeout = 0.0,
|
||||
std::string preScript = "",
|
||||
std::string postScript = "")
|
||||
{
|
||||
openspace::global::scriptEngine->registerRepeatedScript(
|
||||
std::move(identifier),
|
||||
std::move(script),
|
||||
timeout,
|
||||
std::move(preScript),
|
||||
std::move(postScript)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a previously registered repeated script (see #registerRepeatedScript)
|
||||
*/
|
||||
[[codegen::luawrap]] void removeRepeatedScript(std::string identifier) {
|
||||
openspace::global::scriptEngine->removeRepeatedScript(identifier);
|
||||
}
|
||||
|
||||
#include "scriptengine_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user