The Runtime
After reading this guide, you will know:
-
What
Rooibos.rundoes when you call it -
In what order the runtime calls Init, View, and Update
-
How a command result finds its way back to Update
-
How the
Rooibosruntime compares to orchestrators in Rails, React, and BubbleTea
Context
You have defined a Model, written an Update, built a View, and learned how to return Commands. These are the pieces of your application.
Problem
None of these pieces do anything on their own. Model is data. Update, View, and Init are lambdas. Commands are instructions, not actions. Something has to call Init at startup, call View to render the screen, call Update when the user presses a key, and execute the commands that Update returns.
Solution
The runtime ties everything together. Pass it your application module and Rooibos does the rest.
Rooibos.run(MyApp)
Starting Up
The runtime sets up the terminal, then calls Init. Init returns a model and optionally a command.
The Loop
After Init, the runtime enters a loop. Each pass has three steps: render, check for events, and check for messages from commands.
The runtime calls View with the current model and renders the widget tree to the terminal. View runs on every pass, whether or not anything has changed.
The runtime checks for terminal events. If one has arrived, the runtime calls Update with the event and the current model. The runtime keeps the new model for the next View call and dispatches any returned command in the background.
The runtime also checks for messages from completed commands. If a timer has finished, an HTTP response has arrived, or any other command has produced a message, the runtime calls Update with it. Several messages can arrive between renders, and the runtime calls Update with each one separately. Each call receives the model returned by the previous call, so changes accumulate.
Stopping
The loop runs until Update returns Command.exit. When it does, the runtime asks any background commands to stop, waits briefly for them to finish, restores the terminal, and returns.
If You Know Other Frameworks
Every framework has an orchestrator. You write application code. The orchestrator decides when to call it.
In Rails, the orchestrator is Rack. It receives an HTTP request and hands it to Rails. The router finds a controller, Rails calls the action, and renders a response. State is rebuilt from the database on every request.
In React, the orchestrator is the render-and-commit cycle. React calls your component when props or state change, diffs the virtual DOM, and patches the real DOM. State lives in hooks or a store.
In Vue, the orchestrator is the component lifecycle. Vue compiles templates into render functions, mounts them to the DOM, and patches the DOM when reactive state changes. State lives in reactive refs or the Options API.
See Also
-
The Elm Architecture for the theory behind this design
-
Commands for the full list of built-in commands
-
Async Patterns for advanced topics like frame rate, animations, and the render loop internals