require "rooibos"
require_relative "messages"
require_relative "leaf"
module Panel
include Rooibos::Router
Command = Rooibos::Command
Model = Data.define(:top_leaf, :bottom_leaf, :count, :nested_resets, :name)
Init = -> (name:, top_leaf_name:, bottom_leaf_name:) {
Ractor.make_shareable Model.new(
top_leaf: Leaf::Init[name: top_leaf_name],
bottom_leaf: Leaf::Init[name: bottom_leaf_name],
count: 0, nested_resets: 0, name:
)
}
View = -> (model, tui, theme: :cyan) {
tui.layout(
direction: :vertical,
constraints: [tui.constraint_fill(1), tui.constraint_fill(1)],
children: [
tui.block(
title: "#{model.top_leaf.name} [#{model.top_leaf.count}]",
borders: [:all],
border_style: { fg: theme },
children: [Leaf::View.call(model.top_leaf, tui, theme:)]
),
tui.block(
title: "#{model.bottom_leaf.name} [#{model.bottom_leaf.count}]",
borders: [:all],
border_style: { fg: theme },
children: [Leaf::View.call(model.bottom_leaf, tui, theme:)]
),
]
)
}
route :top_leaf, to: Leaf
route :bottom_leaf, to: Leaf
receive_routed :panel_self,
-> (_, model) {
count = model.count + 1
case count
when 5
[model.with(count:), Command.deliver(Milestone.new(envelope: model.name, count:))]
when 10
[
model.with(count: 0, nested_resets: model.nested_resets + 1),
Command.bubble(PanelReset.new(envelope: model.name, count:)),
]
else
[model.with(count:), nil]
end
}
intercept_instances_of LeafReset,
-> (message, model) {
transformed = PanelChildReset.new(
envelope: model.name,
leaf: message.envelope,
count: message.count
)
[model.with(nested_resets: model.nested_resets + 1), Command.bubble(transformed)]
}
forward_routed :leaf_1, to: :top_leaf, as: :increment
forward_routed :leaf_2, to: :bottom_leaf, as: :increment
Update = from_router
end