18#include <unordered_map>
81#define PULP_VIEW_HAS_DEFERRED_DOCUMENT_LOAD 1
116 static bool& flag() noexcept {
117 static thread_local bool active =
false;
120 bool previous_ =
false;
128 std::function<std::string(std::string_view envelope_json)>;
142 return &root_ == &
view;
162 return document_load_pending_;
178 std::function<
void(
bool loaded, const
std::
string&
error)> cb) {
179 document_loaded_callback_ = std::move(cb);
214 const std::string&
host_kind()
const {
return host_kind_; }
258 return runtime_realm_quarantined_ ? nullptr : bridge_.get();
264 return bridge_ ? bridge_->granted_capabilities() : granted_capabilities_;
284 return inspector_port_.get();
287 std::uint64_t
identity() const noexcept {
return identity_; }
308 return probe_realm_evaluations_;
326 const std::filesystem::path&
script_path()
const {
return script_path_; }
327 const std::filesystem::path&
theme_path()
const {
return theme_path_; }
331 return script_path_.empty();
341 return reloader_ !=
nullptr;
344 return reloader_ && reloader_->has_pending_reload();
349 struct NativeMessageAttachment {
353 const std::uint64_t identity_;
356 std::filesystem::path script_path_;
357 std::filesystem::path theme_path_;
358 std::string script_source_;
359 std::string theme_source_;
360 std::string script_name_;
361 std::vector<WidgetBridge::EmbeddedAsset> embedded_assets_;
362 std::string storage_identity_;
363 std::string last_good_code_;
364 std::filesystem::path last_good_script_path_;
365 std::vector<std::filesystem::path> asset_roots_;
367 bool allow_unreviewed_file_paths_ =
false;
368 bool hot_reload_enabled_ =
false;
369 bool theme_reload_enabled_ =
false;
370 bool runtime_import_enabled_ =
false;
374 std::unique_ptr<ScriptEngine> engine_;
375 std::unique_ptr<WidgetBridge> bridge_;
376 struct RetiredRuntimeRealm {
377 std::unique_ptr<ScriptEngine> engine;
378 std::unique_ptr<WidgetBridge>
bridge;
380 struct RuntimeRealmTeardownOwner {
381 std::vector<RetiredRuntimeRealm> retired;
382 std::unique_ptr<ScriptEngine> current_engine;
383 std::unique_ptr<WidgetBridge> current_bridge;
388 std::vector<RetiredRuntimeRealm> retired_runtime_realms_;
392 std::shared_ptr<RuntimeRealmTeardownOwner> runtime_realm_teardown_owner_ =
393 std::make_shared<RuntimeRealmTeardownOwner>();
397 std::unique_ptr<ScriptInspectorPort> inspector_port_;
398 std::unique_ptr<HotReloader> reloader_;
399 bool root_released_ =
false;
400 std::function<void()> repaint_callback_;
401 std::string host_kind_ =
"unknown";
403 std::function<void()> post_evaluation_reset_callback_;
404 bool post_evaluation_reset_callback_pending_ =
false;
406 std::unordered_map<std::uint64_t, LogCallback> log_subscribers_;
407 std::unordered_map<std::string, std::shared_ptr<NativeMessageAttachment>>
408 native_message_handlers_;
409 std::uint64_t next_log_subscription_ = 0;
410 render::GpuSurface* gpu_surface_ =
nullptr;
413 Theme last_good_effective_theme_;
414 bool runtime_realm_quarantined_ =
false;
415 bool accessibility_retirement_pending_ =
false;
417 std::uint64_t probe_realm_evaluations_ = 0;
418 bool document_load_pending_ =
false;
419 int deferred_load_polls_ = 0;
420 std::function<void(
bool,
const std::string&)> document_loaded_callback_;
421 bool load_now(std::string*
error);
422 static constexpr double kBlockingLoadWarningMs = 50.0;
423 bool last_theme_exists_ =
false;
424 std::optional<std::filesystem::file_time_type> last_theme_write_time_;
428 std::string current_script_code(std::string*
error)
const;
429 bool rebuild_from_code(
430 const std::string& code,
const std::filesystem::path& source_path,
bool preserve_state,
432 std::optional<ScriptInspectorPort::EvaluationDeadline> deadline = std::nullopt);
433 bool apply_theme_override(std::string*
error);
438 bool resolve_theme_override(
const Theme& base, Theme& out_merged,
bool& out_exists,
439 std::optional<std::filesystem::file_time_type>& out_write_time,
440 std::string*
error)
const;
441 bool poll_theme_reload(std::string*
error);
442 void attach_inspector_port(ScriptEngine* engine) {
443 if (!inspector_port_)
447 inspector_port_->set_realm_capabilities(granted_capabilities_);
448 inspector_port_->attach(engine);
450 void detach_inspector_port() {
452 inspector_port_->detach();
456 void install_native_message_handlers(ScriptEngine& engine,
457 bool validation_realm)
const;
458 static void install_native_message_handler(
459 ScriptEngine& engine,
const std::string& name,
460 std::shared_ptr<NativeMessageAttachment> attachment,
461 bool validation_realm);
462 void dispatch_log(std::string_view level, std::string_view message);
464 static std::string read_text_file(
const std::filesystem::path&
path);
465 static std::string describe_exception();
A processor's declared channels.
Definition value_channel_set.hpp:61
Abstract GPU surface — a presentable rendering target backed by a native window/view.
Definition gpu_surface.hpp:112
Centralized parameter storage with lock-free value access.
Definition store.hpp:164
A granted-capability set.
Definition reload_capabilities.hpp:74
static CapabilitySet all()
Definition reload_capabilities.hpp:78
static bool active() noexcept
Whether a guard is alive on this thread.
Definition scripted_ui.hpp:108
~ScopedDeferredDocumentLoad()
Definition scripted_ui.hpp:102
ScopedDeferredDocumentLoad() noexcept
Definition scripted_ui.hpp:99
ScopedDeferredDocumentLoad(const ScopedDeferredDocumentLoad &)=delete
ScopedDeferredDocumentLoad & operator=(const ScopedDeferredDocumentLoad &)=delete
The engine-thread half of a runtime inspector, as ScriptedUiSession drives it.
Definition script_inspector_port.hpp:22
std::chrono::steady_clock::time_point EvaluationDeadline
Definition script_inspector_port.hpp:24
ScriptedEditorSession()=default
bool theme_reload_enabled() const
Definition scripted_ui.hpp:346
const ReloadMetrics & last_reload_metrics() const
Definition scripted_ui.hpp:301
void set_log_callback(LogCallback callback)
Replace the live JS console sink and retain it across hot reloads.
std::uint64_t add_log_callback(LogCallback callback)
Add a secondary console observer without replacing the primary sink.
bool uses_embedded_source() const noexcept
True when the document comes from ScriptedUiOptions::script_source rather than a file on disk.
Definition scripted_ui.hpp:330
bool document_load_pending() const noexcept override
True between a deferred load() and the poll() that evaluates it.
Definition scripted_ui.hpp:161
void set_document_loaded_callback(std::function< void(bool loaded, const std::string &error)> cb)
Called when a load() – immediate or deferred – finishes, with whether the document mounted and the er...
Definition scripted_ui.hpp:177
ScriptedUiSession(const ScriptedUiSession &)=delete
ScriptInspectorPort * script_inspector_port()
The runtime-inspector port for this session's JS engine, or nullptr.
Definition scripted_ui.hpp:283
bool borrows_root(const View &view) const noexcept override
True when view is this session's root.
Definition scripted_ui.hpp:141
bool reload_from(std::filesystem::path script_path, std::string *error=nullptr)
std::uint64_t probe_realm_evaluations() const noexcept
How many times this session evaluated a script on a throwaway probe realm.
Definition scripted_ui.hpp:307
std::string script_label() const
What log lines call this document: the script path, or the embedded script's name.
~ScriptedUiSession() override
void set_time_source(WidgetBridge::TimeSource source)
The clock script timers and performance.now() read (see WidgetBridge::set_time_source).
ScriptedUiSession(View &root, state::StateStore &store, ScriptedUiOptions options)
void attach_gpu_surface(render::GpuSurface *gpu_surface) override
See ScriptedUiSession::attach_gpu_surface().
WidgetBridge * bridge() const
Definition scripted_ui.hpp:257
bool reload(std::string *error=nullptr)
bool hot_reload_pending() const
Definition scripted_ui.hpp:343
bool complete_pending_load(std::string *error=nullptr) override
Evaluate a deferred document now (a harness that needs the mounted tree without pumping frames).
void release_root() noexcept override
Tear down everything that borrows the root – the realm, its engine and bridge, and the accessibility ...
bool load(std::string *error=nullptr)
Evaluate the script and mount it into the root now; bridge() is live when it returns true.
ScriptedUiSession & operator=(const ScriptedUiSession &)=delete
void attach_native_message_handler(std::string handler_name, NativeMessageHandler handler)
Attach a renderer-neutral native message endpoint to this session's JS realm.
const std::filesystem::path & theme_path() const
Definition scripted_ui.hpp:327
bool poll(std::string *error=nullptr) override
Advance one frame: discharge the realm reset a completed Runtime.evaluate owes, retire and destroy re...
void remove_log_callback(std::uint64_t token)
void detach_native_message_handler(std::string_view handler_name)
Remove a named native message endpoint from this and future realms.
bool hot_reload_watching() const noexcept
True once a loaded session owns a file watcher.
Definition scripted_ui.hpp:340
bool hot_reload_enabled() const
Definition scripted_ui.hpp:336
CapabilitySet granted_capabilities() const noexcept
Actual effectful API grants installed in the live bridge, or the grants that will be installed before...
Definition scripted_ui.hpp:263
bool load_deferrable(std::string *error=nullptr)
View-first load.
bool settling() const noexcept override
True while the mounted document still owes host frames to settle its commits (see WidgetBridge::pendi...
void set_host_kind(std::string kind) override
Declare where this editor lives, as its scripts read it through hostKind() ("plugin",...
const std::string & host_kind() const
Definition scripted_ui.hpp:214
double last_reload_ms() const
Convenience: total wall-clock of the last reload, ms.
Definition scripted_ui.hpp:311
std::function< std::string(std::string_view envelope_json)> NativeMessageHandler
Definition scripted_ui.hpp:127
void set_post_evaluation_reset_callback(std::function< void()> cb)
Install the host-owned rebind run after a successful deferred Runtime.evaluate realm reset.
std::uint64_t identity() const noexcept
Process-unique identity for borrowed-source lifetime/ABA checks.
Definition scripted_ui.hpp:287
void set_repaint_callback(std::function< void()> cb)
const std::filesystem::path & script_path() const
Definition scripted_ui.hpp:326
render::GpuSurface * gpu_surface() const noexcept
Definition scripted_ui.hpp:324
std::function< void(const ValueChannelVisitor &)> ValueChannelAccess
Definition value_channel_set.hpp:53
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ path
Definition anchor_strategy.hpp:42
constexpr std::size_t kDefaultJsMemoryLimitBytes
Definition js_engine.hpp:79
std::function< void(std::string_view level, std::string_view message)> LogCallback
Definition js_engine.hpp:25
@ error
Definition design_ir.hpp:697
Definition scripted_ui.hpp:25
std::vector< WidgetBridge::EmbeddedAsset > embedded_assets
Files compiled into the image beside an in-memory script.
Definition scripted_ui.hpp:63
std::vector< std::filesystem::path > asset_roots
Definition scripted_ui.hpp:28
std::size_t js_memory_limit_bytes
Heap ceiling for every realm this session creates, in bytes (0 = unlimited).
Definition scripted_ui.hpp:71
bool enable_runtime_import
Install the native runtime-design import endpoint before evaluating the session bundle.
Definition scripted_ui.hpp:46
ValueChannelSet * value_channels
Compatibility adapter for stable, non-reloadable processors.
Definition scripted_ui.hpp:33
bool allow_unreviewed_file_paths
Let path-taking bridge APIs open files outside the script directory and asset_roots (WidgetBridge::se...
Definition scripted_ui.hpp:75
std::filesystem::path script_path
Definition scripted_ui.hpp:26
std::filesystem::path theme_path
Definition scripted_ui.hpp:27
std::string theme_source
Theme override JSON applied over the root theme when theme_path is empty and script_source is in use.
Definition scripted_ui.hpp:55
bool enable_theme_reload
Definition scripted_ui.hpp:30
std::string script_source
In-memory script source.
Definition scripted_ui.hpp:52
std::string storage_identity
Identity of the session's persisted stores (widget storage, style presets) when the script has no dir...
Definition scripted_ui.hpp:67
CapabilitySet granted_capabilities
Native bridge APIs granted to this realm.
Definition scripted_ui.hpp:41
bool enable_hot_reload
Definition scripted_ui.hpp:29
ValueChannelAccess value_channel_access
Leased access to the hosting processor's named value channels.
Definition scripted_ui.hpp:36
std::string script_name
Diagnostic name for an in-memory script (ui.js); log lines and script_label() use it where a path-bac...
Definition scripted_ui.hpp:58
JS-axis reload timings, ms.
Definition scripted_ui.hpp:294
double snapshot_ms
snapshot the live widget values before the rebuild
Definition scripted_ui.hpp:296
double probe_ms
parse + build a probe bridge to validate the code
Definition scripted_ui.hpp:295
double restore_ms
restore preserved widget values into the new tree
Definition scripted_ui.hpp:298
double total_ms
end-to-end
Definition scripted_ui.hpp:299
double rebuild_ms
build the live bridge from the new code + apply theme
Definition scripted_ui.hpp:297