ScriptHost.h header
#include <ew/app/ScriptHost.h>
Namespace ew::app
ScriptHost class
class ew::app::ScriptHost
A sandboxed JavaScript host for user macros and automation (DESIGN §4.16 "embedded scripting" / §6.11 extensibility host; the language is DECIDED as JavaScript via Qt's QJSEngine, §9/§482).
It evaluates a script string against a persistent QJSEngine and returns its result or a clear error, never throwing out to the caller. A per-run time budget interrupts a runaway script (an accidental infinite loop) so a bad macro cannot hang the application. Host objects registered with registerGlobal() – most importantly the project "world" bridge layered on top – become global objects the script can call, so a macro can read and (through the undoable command stack) modify the project. QJSEngine already sandboxes scripts from the filesystem, network, and process, so a script can only reach what the host explicitly exposes.
The engine is thread-affine: construct and call a ScriptHost on one thread (the GUI thread for the desktop console), where any registered world bridge also lives, so a script's mutations run on the thread that owns the project. Globals persist across evaluate() calls on the same host, so a later macro can build on definitions an earlier one made.
Members
ew::app::scripting::ScriptHost::ScriptHost()
Constructs a host with a fresh, empty JavaScript engine.
ew::app::scripting::ScriptHost::~ScriptHost()
Destroys the host and its engine.
ew::app::scripting::ScriptHost::ScriptHost(const ScriptHost &)=delete
Not copyable.
ScriptHost & ew::app::scripting::ScriptHost::operator=(const ScriptHost &)=delete
Not copyable.
ew::app::scripting::ScriptHost::ScriptHost(ScriptHost &&)=delete
Not movable.
ScriptHost & ew::app::scripting::ScriptHost::operator=(ScriptHost &&)=delete
Not movable.
ScriptResult ew::app::scripting::ScriptHost::evaluate(const QString &script)
Evaluates script and returns its result as text, or an error. A syntax error, an uncaught thrown value, or a run that exceeds the time budget (see setTimeoutMs) all come back as ScriptResult{ok=false, error=...} rather than an exception. The engine is reset to a non-interrupted state before each run, so a host stays usable after a timeout.
void ew::app::scripting::ScriptHost::registerGlobal(const QString &name, QObject *object)
Exposes object to scripts under the global name name: its Q_INVOKABLE methods and Q_PROPERTYs become a JavaScript object at globalThis[name]. The host does NOT take ownership – object must outlive the host (or be re-registered). A no-op for a null object or an empty name.
void ew::app::scripting::ScriptHost::setTimeoutMs(int timeoutMs)
Sets the runaway time budget in milliseconds: a single evaluate() whose script runs longer is interrupted and reported as an error. Defaults to 5000 ms. A non-positive value disables the guard (use only for trusted callers) – an infinite loop then hangs the calling thread.
int ew::app::scripting::ScriptHost::timeoutMs() const
The current runaway time budget in milliseconds (see setTimeoutMs).
ScriptResult struct
struct ew::app::ScriptResult
The outcome of running a script through a ScriptHost: whether it completed without error, its result rendered as text (the value the script evaluated to), and a human-readable error message when it failed.
Members
bool ew::app::scripting::ScriptResult::ok = false
True when the script ran to completion without throwing (and without being interrupted).
QString ew::app::scripting::ScriptResult::value
The script's result as text – the string form of the value the last statement evaluated to, or empty when that value is undefined. Meaningful only when ok is true.
QString ew::app::scripting::ScriptResult::error
A human-readable error ("Name: message (line N)") when ok is false: a syntax error, a thrown/uncaught runtime error, or the interruption of a script that ran past the timeout.
QString ew::app::scripting::ScriptResult::consoleOutput
Everything the script printed via console.log/info/debug/warn/error during this run, one message per line (warnings/errors prefixed [warn] /[error] ), with no trailing newline. Empty when the script printed nothing. Captured whether or not ok is true, so a macro that logs progress before throwing still shows its output.
Bounded at one million characters, after which it ends with a [output truncated at …] line. The time budget limits how long a runaway macro runs, not how much it produces while running – a logging loop reaches hundreds of megabytes in a fraction of a second, and this string is returned to the caller and then rendered, so leaving it unbounded would move the hang to just past the point the budget stopped protecting anything.
bool operator==(const ScriptResult &, const ScriptResult &)=default
Results compare equal when every field matches.