tiramisu/ui
Tiramisu-Lustre integration module.
This module provides bidirectional message passing between Tiramisu (game engine) and Lustre (web UI framework). Both systems communicate through a shared Bridge with a single message type.
Design
The bridge has ONE message type that both sides understand. Each side provides a wrapper function to convert bridge messages into their internal message type. This is similar to frontend/backend communication over websockets.
Example
// 1. Define a shared bridge message type
pub type BridgeMsg {
// Game → UI
UpdateScore(Int)
UpdateHealth(Float)
// UI → Game
SelectSlot(Int)
StartGame
}
// 2. Lustre side wraps bridge messages
pub type UIMsg {
FromBridge(BridgeMsg)
ButtonClicked
}
fn init(bridge) {
#(Model(bridge: bridge), ui.register_lustre(bridge, FromBridge))
}
fn update(model, msg) {
case msg {
FromBridge(UpdateScore(s)) -> #(Model(..model, score: s), effect.none())
ButtonClicked -> #(model, ui.send(model.bridge, SelectSlot(0)))
}
}
// 3. Game side wraps bridge messages
pub type GameMsg {
FromBridge(BridgeMsg)
Tick
}
fn update(model, msg, ctx) {
case msg {
FromBridge(SelectSlot(i)) -> // handle slot selection
Tick -> #(model, ui.send_to_ui(bridge, UpdateScore(10)), ...)
}
}
Types
Values
pub fn new_bridge() -> Bridge(bridge_msg)
Create a new bridge for Tiramisu-Lustre communication.
Example
let bridge = ui.new_bridge()
pub fn register_lustre(
bridge: Bridge(bridge_msg),
wrapper: fn(bridge_msg) -> lustre_msg,
) -> effect.Effect(lustre_msg)
Register Lustre’s dispatch with a wrapper function.
The wrapper converts bridge messages to Lustre’s internal message type.
Call this in your Lustre init function.
Example
pub type Msg {
FromBridge(BridgeMsg)
// ... other messages
}
fn init(bridge) {
#(Model(bridge: bridge), ui.register_lustre(bridge, FromBridge))
}
pub fn send(
bridge: Bridge(bridge_msg),
msg: bridge_msg,
) -> effect.Effect(lustre_msg)
Send a message across the bridge to the game.
Example
fn update(model, msg) {
case msg {
ButtonClicked -> #(model, ui.send(model.bridge, SelectSlot(0)))
}
}
pub fn send_to_ui(
bridge: Bridge(bridge_msg),
msg: bridge_msg,
) -> effect.Effect(game_msg)
Send a message across the bridge to the UI.
Example
fn update(model, msg, ctx) {
case msg {
Tick -> #(model, ui.send_to_ui(bridge, UpdateScore(10)), ...)
}
}