Runtime

[中文]

Overview

This page covers:

  • the runtime resource model

  • the document_id + absolute_path API mapping

  • font/image resource queries

  • template instances

This page does not cover JSON field tables; for field details, see the per-module pages.

Runtime Resource Model

The parser ultimately resolves resources into a runtime Document:

  • a top-level screen -> Document.screens

  • a top-level non-screen view asset -> Document.templates

The Runtime also maintains three kinds of non-document global resources:

  • global font

  • global image

  • global theme

Then Runtime handles:

  • document registration

  • eager screen pre-creation

  • dynamic screen lazy creation

  • template instantiation

  • path indexing

  • events and bindings

Current bindings rules:

  • a bindings key uses a public camelCase dotted path

  • a bindings value is the local key in the current node path scope, without a prefix

  • the runtime actually locates a binding by document_id + absolute_path + local_key

  • prefer reading/writing via Runtime::set_binding_value(document_id, absolute_path, key, value), Runtime::set_binding_values(document_id, updates), or View::set_binding_value(key, value)

Current Public API Mapping of Protocols

Any Node Query

  • find_view(document_id, absolute_path)

  • View::find_view(path)

Notes:

  • find_view(document_id, absolute_path) can currently query any instantiated node

  • all public paths use Unix-style absolute paths, e.g. /about/header/title

Node Status and Runtime Operations

  • get_view_state(view, kind) / get_view_state(document_id, absolute_path, kind): read a node's runtime state (ViewStateKind)

  • scroll_view_to_visible(document_id, absolute_path, animated = true) / scroll_view_to_visible(view, animated = true): scroll the target node into the visible area

  • set_view_src(document_id, absolute_path, src): directly update an image node's src

  • process_backend(): drive one backend processing pass (events, animations, refresh, etc.); usually called periodically in the host main loop

Template Instance

  • create_view(document_id, template_id, parent_absolute_path, instance_id)

  • destroy_view(document_id, absolute_path)

Where:

  • template_id is the top-level template id

  • parent_absolute_path is the parent's absolute path

  • instance_id is explicitly provided by the caller

  • destroy_view(...) can only delete a non-screen subtree

Event Subscription

  • subscribe_event_action(document_id, action, handler)

  • subscribe_event_action_with_id(document_id, action, handler)

  • unsubscribe_subscription(subscription_id)

  • View::on_event(type, handler)

  • Button::on_click(handler)

Notes:

  • subscribe_event_action(...) uses exact document_id + action matching

  • subscribe_event_action_with_id(...) uses the same document_id + action routing and returns a SubscriptionId

  • within the same document, a statically declared non-empty action must be globally unique

  • multiple instances from a template definition can share the same action; tell sources apart via event.path / event.node_id

  • the new interface allows pre-registration: you can register before the target template instance has been created

  • subscribe_event_action(...) returns a ScopedConnection; the connection disconnects automatically on destruction

  • subscribe_event_action_with_id(...) returns a SubscriptionId; suitable when you need to record the subscription identity or disconnect explicitly later

  • unsubscribe_subscription(subscription_id) can explicitly disconnect a subscription obtained via with_id; it returns failure for an invalid or already-disconnected id

  • View::on_event(...) relies on a concrete, already-queryable instance and does no action string filtering

Runtime Animation

  • start_view_animation(document_id, absolute_path, animation, completed_handler = {})

  • start_view_animation_with_id(document_id, absolute_path, animation, completed_handler = {})

  • start_view_animation_with_result(document_id, absolute_path, animation, completed_handler = {})

  • start_view_animation(view, animation, completed_handler = {})

  • start_view_animation_with_id(view, animation, completed_handler = {})

  • start_view_animation_with_result(view, animation, completed_handler = {})

Notes:

  • this set of APIs starts a view animation directly at runtime, without relying on animations pre-declared in the node JSON.

  • currently recommended for: - placement.x - placement.y - placement.width - placement.height - imageProps.angle - imageProps.offsetX - imageProps.offsetY

  • animation.property reuses AnimationProperty; currently supports at least: - Opacity - X - Y - Width - Height - Scale - Angle - OffsetX - OffsetY

  • animation.easing reuses AnimationEasing; currently linear and easeIn cover common runtime scenarios.

  • start_view_animation(...) returns a ScopedConnection; the animation is canceled on destruction.

  • start_view_animation_with_id(...) returns a SubscriptionId; pair it with unsubscribe_subscription(subscription_id) to cancel actively.

  • start_view_animation_with_result(...) returns a RuntimeAnimationStartResult, bringing back both a SubscriptionId and start-result info, useful when the start fails or completes immediately.

  • a new animation of the same animation property on the same view overrides the previous one.

  • completed_handler fires only when the animation completes naturally; if the animation is canceled, the completion callback does not fire.

Resource Query

  • list_font_resources(document_id)

  • list_image_resources(document_id)

Notes:

  • a font query returns the Runtime's currently globally visible font resource set

  • list_supported_fonts(language = "") returns font ids, not full descriptors

  • an image query still returns, by document_id, the document's currently visible image resources, including the document imageSet and Runtime global images

  • a Runtime global image can be registered before load_file(); a ${image.<id>} in the document resolves to it during load validation

  • when size is not given explicitly, register_image(...) asks the backend to complete width / height from image metadata

  • during document load, the backend preload hook preloads the current document imageSet and Runtime global images; missing or invalid formats fail load_file() / load_json() rather than deferring failure to first display

  • unregister_image(id) removes the resource from the Runtime global image table and releases the backend's preload reference to that image

  • for image resources with the same name, the document imageSet is preferred, then the Runtime global image

Binding Batch Update and Incremental Apply

  • Runtime::set_binding_values(document_id, updates) can write multiple BindingValueUpdate groups at once.

  • the Runtime merges, per node, the props/style/layout/placement apply masks triggered by the batch; a node usually re-applies a given domain only once in a batch.

  • initial creation, document reload, and resource refresh still use a full apply; the high-frequency binding update path uses precise masks.

  • the animation API modifies backend node attributes directly and does not write back to the binding store. If the app layer caches binding values itself, invalidate the cache after the animation ends or is canceled, or force-write to overwrite the post-animation real state.

Delayed Update Policy for Languages and Themes

The Runtime's default API keeps immediate-update semantics:

  • set_language(language) validates the language, updates the Runtime's current language, and immediately reapplies style to all loaded documents

  • set_theme(theme_id) validates the theme, updates the Runtime's current theme, and immediately reapplies style to all loaded documents; a file-backed document using a Theme variant re-parses its root

  • update(document_id, file_path, environment) re-parses a single document; use it to let a new Environment affect variants, constant text, and initial binding values

If the app caches several loaded documents at once, a language or theme switch may not want to refresh all loaded pages synchronously on the display task. The caller can explicitly use Runtime lazy updates:

  • set_language(language, false) updates the Runtime's current language and the loaded tree's environment record, and marks environment_dirty inside the Runtime

  • set_theme(theme_id, false) updates the Runtime's current theme; an ordinary document is marked styles_dirty, while a file-backed document using a Theme variant is marked environment_dirty

  • before accessing a target document in mount_screen(...), find_view(...), create_view(...), subscribe_event_action(...), etc., the Runtime calls refresh_document_if_dirty(...) to honor dirty updates

  • refresh_document_if_dirty(...) handles only ``environment_dirty``: when environment_dirty is set, it runs an internal update(...) on a document loaded via load_file(...) and clears environment dirty on success

  • styles_dirty is not handled by the unified dirty pass: it is honored at specific access points; e.g. mount_screen(...) reapplies style only to the mounted subtree; it can also be honored explicitly by set_theme(theme_id) / reapply_styles(document_id)

  • a non-file-backed document has no re-parsable root file and cannot fully honor lazy environment updates; such documents need the default immediate API or an explicit update(...) by the caller

  • an unloaded document needs no dirty mark; the first load_file(...) directly uses the caller's current Environment and the Runtime theme