#include <widget_bridge.hpp>
Classes | |
| struct | EmbeddedAsset |
| One file compiled into the plug-in beside its editor script. More... | |
| struct | DamageLedger |
| What the tree had marked when a batch of script work started, so the bridge can tell whether that work already asked for exactly the repaints it needs (see View::damage_request_count()). More... | |
Public Types | |
| using | DeadlineCheck = std::function<void()> |
| using | TimeSource = std::function<std::chrono::steady_clock::time_point()> |
| Clock for script timers, performance.now() and the rAF timestamp (default steady_clock::now; Date.now() never follows it). | |
Public Member Functions | |
| WidgetBridge (ScriptEngine &engine, View &root, state::StateStore &store, render::GpuSurface *gpu_surface=nullptr, CapabilitySet granted_capabilities=CapabilitySet::all()) | |
| ~WidgetBridge () | |
| void | attach_gpu_surface (render::GpuSurface *gpu_surface) |
| render::GpuSurface * | gpu_surface () const noexcept |
| void | set_value_channels (ValueChannelSet *channels) |
| Attach stable channels, or leased access for a reloadable processor. | |
| void | set_value_channel_access (ValueChannelAccess access) |
| void | visit_value_channels (const ValueChannelVisitor &visitor) const |
| The visitor must not retain a channel set or source after it returns. | |
| void | set_imported_text_scale (float scale) noexcept |
| Multiplies every font size an imported UI asks for through setFontSize. | |
| float | imported_text_scale () const noexcept |
| CapabilitySet | granted_capabilities () const noexcept |
| bool | has_native_gpu_bridge () const noexcept |
| void | load_script (const std::string &code) |
| Load and execute a UI script. | |
| bool | frame_pump_live () const noexcept |
| void | dispatch_native_message (std::string_view receiver, std::string_view type, const choc::value::Value &payload, std::string_view id={}, std::string_view context="native message dispatch") |
| Deliver one typed host-owned message to a named receiver in this UI realm. | |
| void | set_asset_roots (std::vector< std::filesystem::path > roots) |
| Set reviewed local roots used by JS asset loading for relative URLs. | |
| const std::vector< std::filesystem::path > & | asset_roots () const noexcept |
| void | set_embedded_assets (std::vector< EmbeddedAsset > assets) |
| Install the files embedded beside the script. | |
| const std::vector< EmbeddedAsset > & | embedded_assets () const noexcept |
| const EmbeddedAsset * | embedded_asset (std::string_view path) const noexcept |
| The embedded file a script-relative path names, or nullptr. | |
| std::string | embedded_asset_data_uri (const EmbeddedAsset &asset) const |
| data:<mime>;base64,... for an embedded file, which is how an image widget draws bytes that have no file behind them. | |
| void | set_storage_identity (std::string identity) |
| Identity of this bridge's persisted stores (widget storage, style presets). | |
| std::string | storage_identity () const |
| The identity the persisted stores hash: set_storage_identity()'s value when set, else the script base directory, else empty (no store). | |
| std::string | font_weight_scope () const |
| Process-local identity for declarations owned by this bridge lifetime. | |
| void | set_script_base_dir (std::filesystem::path dir) |
| Preferred directory for resolving RELATIVE filesystem paths handed to path-taking bridge APIs. | |
| const std::filesystem::path & | script_base_dir () const noexcept |
| void | set_allow_unreviewed_file_paths (bool allow) noexcept |
| Whether path-taking bridge APIs (setImageSource, registerFont, loadFont, sprite strips, loadAssetSync) may open a file that lies outside the script directory and the reviewed asset roots. | |
| bool | allow_unreviewed_file_paths () const noexcept |
| bool | permits_file_path (const std::filesystem::path &path) const |
| Whether a script may open path, an absolute filesystem path. | |
| std::string | resolve_script_relative (const std::string &path) const |
| Resolve a file a script named against the script directory or a reviewed asset root, for a caller that will open the result. | |
| void | load_script (const std::string &code, const std::string &script_id) |
| load_script overload that retains a script identifier. | |
| void | set_active_script_id (const std::string &script_id) |
| Set the active script identifier without re-evaluating a script. | |
| const std::string & | active_script_id () const noexcept |
| View * | widget (const std::string &id) |
| ScrollView * | scroll_wrapper (const std::string &id) const noexcept |
| View * | style_target (const std::string &id) noexcept |
| void | sync_from_store () |
| void | clear (const DeadlineCheck &deadline_check={}) |
| void | clear_for_realm_replacement (const DeadlineCheck &deadline_check={}) |
| std::string_view | bounded_realm_retirement_denial () const noexcept |
| Empty when the current tree can be retired by Runtime.evaluate's bounded reset; otherwise describes the structural blocker. | |
| void | clear_quarantined_realm () |
| void | force_retire_root_for_owner_teardown () noexcept |
| void | quarantine_realm () noexcept |
| void | forward_key_event (int key_code, uint16_t modifiers, bool is_down) |
| void | snapshot_values (WidgetReloadSnapshot &out, const DeadlineCheck &deadline_check={}, bool include_custom_state=true) const |
| void | snapshot_values (std::unordered_map< std::string, float > &out) const |
| void | restore_values (const WidgetReloadSnapshot &snapshot, const DeadlineCheck &deadline_check={}, bool include_custom_state=true) |
| void | restore_values (const std::unordered_map< std::string, float > &snapshot) |
| void | poll_async_results () |
| void | service_frame_callbacks () |
| int | pending_runtime_settle_rounds () const noexcept |
| void | service_param_bindings () |
| void | service_shader_value_bindings () |
| std::size_t | param_binding_count () const noexcept |
| std::size_t | owned_widget_identity_count () const noexcept |
| std::size_t | widget_cache_count () const noexcept |
| std::uint64_t | bridge_call_count () const noexcept |
| void | reset_bridge_call_count () noexcept |
| void | service_param_subscriptions () |
| std::size_t | param_subscription_count () const noexcept |
| void | service_event_bindings () |
| std::size_t | event_binding_count () const noexcept |
| void | install_runtime_import_handlers () |
| void | set_repaint_callback (std::function< void()> cb) |
| DamageLedger | damage_ledger () const |
| void | request_repaint_after (const DamageLedger &ledger) |
| The repaint owed after a batch of script work that requested none itself, decided from what it marked (see DamageLedger). | |
| void | request_frame () |
| Ask for a frame without marking damage (View::request_frame()). | |
| void | set_ai_cli_command (std::string cmd) |
| void | set_host_kind (std::string kind) |
| const std::string & | host_kind () const |
| void | set_time_source (TimeSource source) |
| std::chrono::steady_clock::time_point | time_now () const |
| CanvasWidget::NativeGpuTextureFrame | describe_native_canvas_frame (const std::string &canvas_id) const |
| CanvasWidget::NativeGpuTextureFrame | describe_native_texture_frame (const std::string &texture_id) const |
| CssKeyframesRegistry & | css_keyframes_registry () |
| const CssKeyframesRegistry & | css_keyframes_registry () const |
| const std::vector< BindingAttempt > & | binding_attempts () const noexcept |
| Binding attempts in call order, bound or not (binding_diagnostics.hpp). | |
| std::vector< std::string > | unbound_params () const |
| Declared parameters no attempt reached — the UI cannot change them. | |
| bool | record_binding_attempt (const std::string &widget_id, const std::string ¶m_name, BindingTarget target, BindingOutcome outcome) |
| Record a binding attempt from an extension API such as shader uniforms. | |
| bool | parameter_id_for_name (const std::string &name, state::ParamID &out) const |
| void | clear_shader_uniform_bindings (const std::string &widget_id) |
Static Public Member Functions | |
| static std::string | loaded_script_source (const std::string &code) |
| What load_script() evaluates for code – what a prewarm must compile. | |
| static bool | dispatch_key_for_root (View &root, int key_code, uint16_t modifiers, bool is_down) |
| Deliver a key only to the live bridge attached to root. | |
| static void | dispatch_global_key (int key_code, uint16_t modifiers, bool is_down) |
| static void | dispatch_document_event (const std::string &event_type, const std::string &event_json_literal) |
Friends | |
| struct | BridgeRegistrars |
| using pulp::view::WidgetBridge::DeadlineCheck = std::function<void()> |
| using pulp::view::WidgetBridge::TimeSource = std::function<std::chrono::steady_clock::time_point()> |
Clock for script timers, performance.now() and the rAF timestamp (default steady_clock::now; Date.now() never follows it).
| pulp::view::WidgetBridge::WidgetBridge | ( | ScriptEngine & | engine, |
| View & | root, | ||
| state::StateStore & | store, | ||
| render::GpuSurface * | gpu_surface = nullptr, | ||
| CapabilitySet | granted_capabilities = CapabilitySet::all() ) |
| pulp::view::WidgetBridge::~WidgetBridge | ( | ) |
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
| void pulp::view::WidgetBridge::attach_gpu_surface | ( | render::GpuSurface * | gpu_surface | ) |
|
inlinenoexcept |
Binding attempts in call order, bound or not (binding_diagnostics.hpp).
Reset per bridge, so this is the log for the loaded script.
|
noexcept |
Empty when the current tree can be retired by Runtime.evaluate's bounded reset; otherwise describes the structural blocker.
|
inlinenoexcept |
| void pulp::view::WidgetBridge::clear | ( | const DeadlineCheck & | deadline_check = {} | ) |
| void pulp::view::WidgetBridge::clear_for_realm_replacement | ( | const DeadlineCheck & | deadline_check = {} | ) |
| void pulp::view::WidgetBridge::clear_quarantined_realm | ( | ) |
| void pulp::view::WidgetBridge::clear_shader_uniform_bindings | ( | const std::string & | widget_id | ) |
|
inline |
|
inline |
| DamageLedger pulp::view::WidgetBridge::damage_ledger | ( | ) | const |
| CanvasWidget::NativeGpuTextureFrame pulp::view::WidgetBridge::describe_native_canvas_frame | ( | const std::string & | canvas_id | ) | const |
| CanvasWidget::NativeGpuTextureFrame pulp::view::WidgetBridge::describe_native_texture_frame | ( | const std::string & | texture_id | ) | const |
|
static |
|
static |
|
static |
Deliver a key only to the live bridge attached to root.
Returns whether a shortcut or JS listener consumed the event. Plugin hosts use this instead of process-wide dispatch so one editor can never deliver navigation into another editor in the same host process.
| void pulp::view::WidgetBridge::dispatch_native_message | ( | std::string_view | receiver, |
| std::string_view | type, | ||
| const choc::value::Value & | payload, | ||
| std::string_view | id = {}, | ||
| std::string_view | context = "native message dispatch" ) |
Deliver one typed host-owned message to a named receiver in this UI realm.
Arguments cross the engine binding directly; no JavaScript source is generated or evaluated. This pumps microtasks and ensures the host has one repaint request, without duplicating a request already made by the receiver, but deliberately leaves requestAnimationFrame callbacks for the host's next frame tick. The receiver must be a global function with the shape (type, payload, id).
|
noexcept |
The embedded file a script-relative path names, or nullptr.
A leading ./ is ignored; .. segments, absolute paths (including a leading /) and URIs (including file://) never match, so an embedded file answers only names resolve_script_relative() treats as relative. Matching is exact on the normalized name.
| std::string pulp::view::WidgetBridge::embedded_asset_data_uri | ( | const EmbeddedAsset & | asset | ) | const |
data:<mime>;base64,... for an embedded file, which is how an image widget draws bytes that have no file behind them.
|
inlinenoexcept |
|
noexcept |
| std::string pulp::view::WidgetBridge::font_weight_scope | ( | ) | const |
Process-local identity for declarations owned by this bridge lifetime.
Unlike storage_identity(), this must never be shared by two bridges.
|
noexcept |
| void pulp::view::WidgetBridge::forward_key_event | ( | int | key_code, |
| uint16_t | modifiers, | ||
| bool | is_down ) |
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
|
noexcept |
|
inline |
|
inlinenoexcept |
| void pulp::view::WidgetBridge::install_runtime_import_handlers | ( | ) |
| void pulp::view::WidgetBridge::load_script | ( | const std::string & | code | ) |
Load and execute a UI script.
Pending rAF callbacks are flushed only until the host first calls service_frame_callbacks(); after that they wait for the next frame tick. Push per-tick data with dispatch_native_message() instead.
| void pulp::view::WidgetBridge::load_script | ( | const std::string & | code, |
| const std::string & | script_id ) |
load_script overload that retains a script identifier.
script_id is recorded as active_script_id_ and threaded into every rAF callback registered while the script is active so motion.publishValue(...) calls from inside an rAF body emit events tagged with source_kind="rAF", source_id="<script_id>:<callback_id>". The legacy overload continues to work unchanged.
|
static |
What load_script() evaluates for code – what a prewarm must compile.
|
inlinenoexcept |
|
inlinenoexcept |
|
noexcept |
| bool pulp::view::WidgetBridge::parameter_id_for_name | ( | const std::string & | name, |
| state::ParamID & | out ) const |
|
inlinenoexcept |
| bool pulp::view::WidgetBridge::permits_file_path | ( | const std::filesystem::path & | path | ) | const |
Whether a script may open path, an absolute filesystem path.
True when the realm holds Filesystem AND either unreviewed paths are allowed or the canonicalized path stays inside the script directory or a reviewed asset root. Pure; opens nothing.
| void pulp::view::WidgetBridge::poll_async_results | ( | ) |
|
noexcept |
| bool pulp::view::WidgetBridge::record_binding_attempt | ( | const std::string & | widget_id, |
| const std::string & | param_name, | ||
| BindingTarget | target, | ||
| BindingOutcome | outcome ) |
Record a binding attempt from an extension API such as shader uniforms.
Keeping it on the bridge preserves one diagnostic stream for all declarative binding surfaces.
| void pulp::view::WidgetBridge::request_frame | ( | ) |
Ask for a frame without marking damage (View::request_frame()).
| void pulp::view::WidgetBridge::request_repaint_after | ( | const DamageLedger & | ledger | ) |
The repaint owed after a batch of script work that requested none itself, decided from what it marked (see DamageLedger).
|
inlinenoexcept |
| std::string pulp::view::WidgetBridge::resolve_script_relative | ( | const std::string & | path | ) | const |
Resolve a file a script named against the script directory or a reviewed asset root, for a caller that will open the result.
A file:// URL is judged as the path it names. A relative path resolves to an existing file inside the script directory or a root; candidates are canonicalized and must remain inside their root so symlinks and .. cannot escape it. An absolute path is returned unchanged only when permits_file_path() allows it. A file above AssetManager's per-file ceiling, any other URI scheme, and a relative name found under no root all resolve to the empty string, which the caller treats as a refusal; with allow_unreviewed_file_paths() the last two are returned unchanged.
| void pulp::view::WidgetBridge::restore_values | ( | const std::unordered_map< std::string, float > & | snapshot | ) |
| void pulp::view::WidgetBridge::restore_values | ( | const WidgetReloadSnapshot & | snapshot, |
| const DeadlineCheck & | deadline_check = {}, | ||
| bool | include_custom_state = true ) |
|
inlinenoexcept |
|
noexcept |
| void pulp::view::WidgetBridge::service_event_bindings | ( | ) |
| void pulp::view::WidgetBridge::service_frame_callbacks | ( | ) |
| void pulp::view::WidgetBridge::service_param_bindings | ( | ) |
| void pulp::view::WidgetBridge::service_param_subscriptions | ( | ) |
| void pulp::view::WidgetBridge::service_shader_value_bindings | ( | ) |
| void pulp::view::WidgetBridge::set_active_script_id | ( | const std::string & | script_id | ) |
Set the active script identifier without re-evaluating a script.
Useful when the same engine evaluates fragments from multiple sources and the caller wants subsequent rAF/timer callbacks to attribute to a different surface. Pass an empty string to clear.
| void pulp::view::WidgetBridge::set_ai_cli_command | ( | std::string | cmd | ) |
|
inlinenoexcept |
Whether path-taking bridge APIs (setImageSource, registerFont, loadFont, sprite strips, loadAssetSync) may open a file that lies outside the script directory and the reviewed asset roots.
Off by default: an absolute path or file:// URL is refused unless it resolves inside one of those roots, and __loadAssetSync__ never falls back to a raw filesystem read. A desktop tool that renders its own import output, or an app whose UI legitimately previews user-picked files, opts in; a DAW-hosted editor never should. The Filesystem capability is still required for the API group to exist at all.
|
inline |
Set reviewed local roots used by JS asset loading for relative URLs.
These are scoped to this bridge instance and are intended for post-review UI-kit assets copied under pulp-kits/<kit-id>/.
| void pulp::view::WidgetBridge::set_embedded_assets | ( | std::vector< EmbeddedAsset > | assets | ) |
Install the files embedded beside the script.
For an editor whose script was compiled into the image, these stand in for the script's directory: __loadAssetSync__, setImageSource, sprite strips and fonts resolve a relative path here first, before the asset roots.
|
inline |
|
inlinenoexcept |
Multiplies every font size an imported UI asks for through setFontSize.
An imported design carries its type sizes as literals — a panel authored at 9-11px is legible in a browser tab and small in a plugin window — and they are scattered across the authored source, so there is no single value a host can turn. This is that value. It is applied at the one bridge funnel every styled text size passes through, so a host or plugin can size an imported UI for its own context without editing (or re-editing, after each reimport) any authored literal.
Default 1.0 changes nothing. Values are clamped to a sane range so a bad number cannot make text invisible or unbounded.
| void pulp::view::WidgetBridge::set_repaint_callback | ( | std::function< void()> | cb | ) |
|
inline |
Preferred directory for resolving RELATIVE filesystem paths handed to path-taking bridge APIs.
Imported code emits assets/<file> beside its generated script; a host may instead keep the script in a scratch file and provide the durable artifact directory through set_asset_roots(). The script directory is tried first, followed by those reviewed roots.
|
inline |
Identity of this bridge's persisted stores (widget storage, style presets).
A path-backed script is keyed by its directory; an embedded script has no directory, so its host names it here (the plug-in's bundle id and script name) and the stores keep working across hosts.
| void pulp::view::WidgetBridge::set_time_source | ( | TimeSource | source | ) |
| void pulp::view::WidgetBridge::set_value_channel_access | ( | ValueChannelAccess | access | ) |
| void pulp::view::WidgetBridge::set_value_channels | ( | ValueChannelSet * | channels | ) |
Attach stable channels, or leased access for a reloadable processor.
| void pulp::view::WidgetBridge::snapshot_values | ( | std::unordered_map< std::string, float > & | out | ) | const |
| void pulp::view::WidgetBridge::snapshot_values | ( | WidgetReloadSnapshot & | out, |
| const DeadlineCheck & | deadline_check = {}, | ||
| bool | include_custom_state = true ) const |
| std::string pulp::view::WidgetBridge::storage_identity | ( | ) | const |
The identity the persisted stores hash: set_storage_identity()'s value when set, else the script base directory, else empty (no store).
|
noexcept |
| void pulp::view::WidgetBridge::sync_from_store | ( | ) |
| std::chrono::steady_clock::time_point pulp::view::WidgetBridge::time_now | ( | ) | const |
| std::vector< std::string > pulp::view::WidgetBridge::unbound_params | ( | ) | const |
Declared parameters no attempt reached — the UI cannot change them.
Excludes Bypass/Reset designations and triggers, which the host surfaces.
| void pulp::view::WidgetBridge::visit_value_channels | ( | const ValueChannelVisitor & | visitor | ) | const |
The visitor must not retain a channel set or source after it returns.
| View * pulp::view::WidgetBridge::widget | ( | const std::string & | id | ) |
|
inlinenoexcept |
|
friend |