Raxol.UI.Rendering.Pipeline (Raxol v0.4.0)
View SourceManages the rendering pipeline for the UI as a GenServer.
Pipeline Stages (Planned)
- Diffing: Compare the new UI tree to the previous one and compute minimal changes.
DELEGATED TO:
Raxol.UI.Rendering.TreeDiffer
- Layout: Calculate positions and sizes for all UI elements.
- Composition: Build a render tree or command list from the layout.
- Paint: Convert the render tree into draw commands or buffer updates.
- Commit: Send the final output to the Renderer process for display.
Data Flow
- UI state changes or events call
update_tree/1
(orupdate_tree/2
) to submit a new UI tree. - The pipeline stores the latest tree, may batch or debounce rapid updates, and triggers a render via the Renderer process.
- The GenServer holds pipeline state (current tree, previous tree, pending updates, etc.).
Extension Points
- Custom diffing or batching strategies
- Animation frame scheduling
- Hooks for custom renderers or output backends
TODO
- Implement diffing and minimal update computation (DELEGATED:
TreeDiffer
handles core diffing. Layout stage has partial diff-awareness. Compose and Paint stages now reuse previous results if their respective inputs are unchanged, providing a level of minimal update.) - Add batching/debouncing of rapid updates (partially implemented with send_after for debouncing)
- Integrate animation frame scheduling (request_animation_frame now uses GenServer.call with deferred reply from :animation_tick; this is more robust.)
- Store and manage pipeline state (previous tree, pending updates, etc.) (GenServer state has current_tree, previous_tree)
- Connect to the real rendering backend (commit stage calls a renderer module)
Summary
Functions
Applies animation settings (delegates to Renderer).
Child spec for supervision trees.
Commits the final output to the Renderer process for display. This is where the pipeline would send the output (a list of paint operations) to the configured renderer.
Computes the minimal set of changes (diff) between two UI trees.
Gets the current renderer module (default: Raxol.UI.Rendering.Renderer).
Requests notification on the next animation frame. The caller will receive {:animation_frame, ref}. Returns a unique reference for the request.
Schedules a render to occur on the next animation frame. Only one render will be scheduled per frame, regardless of how many times this is called before the next frame.
Sets the renderer module to use for output (default: Raxol.UI.Rendering.Renderer). This allows for custom renderers or output backends.
Starts the rendering pipeline GenServer. Registers under the module name by default.
Triggers a render with the current UI tree (or provided data).
Updates the UI tree in the pipeline and triggers a render.
Functions
@spec apply_animation_settings( atom() | nil, String.t() | nil, pos_integer(), boolean(), float(), float(), float(), :fit | :fill | :stretch ) :: :ok
Applies animation settings (delegates to Renderer).
Child spec for supervision trees.
Commits the final output to the Renderer process for display. This is where the pipeline would send the output (a list of paint operations) to the configured renderer.
@spec diff_trees(old_tree :: map() | nil, new_tree :: map() | nil) :: :no_change | {:replace, map()} | {:update, [integer()], any()}
Computes the minimal set of changes (diff) between two UI trees.
Returns:
- :no_change if trees are identical
- if the root node differs
- for subtree updates (path is a list of indices)
TODO: Support keyed children, reordering, and more granular diffs.
@spec get_renderer() :: module()
Gets the current renderer module (default: Raxol.UI.Rendering.Renderer).
Requests notification on the next animation frame. The caller will receive {:animation_frame, ref}. Returns a unique reference for the request.
@spec schedule_render_on_next_frame() :: :ok
Schedules a render to occur on the next animation frame. Only one render will be scheduled per frame, regardless of how many times this is called before the next frame.
@spec set_renderer(module()) :: :ok
Sets the renderer module to use for output (default: Raxol.UI.Rendering.Renderer). This allows for custom renderers or output backends.
Starts the rendering pipeline GenServer. Registers under the module name by default.
@spec trigger_render(data :: any()) :: :ok
Triggers a render with the current UI tree (or provided data).
@spec update_tree(tree :: map()) :: :ok
Updates the UI tree in the pipeline and triggers a render.