///|
pub(all) enum Effect[Msg] {
NoEffect
Batch(Array[Effect[Msg]])
Send(Msg)
}
///|
pub(all) struct Program[Model, Msg] {
init : () -> (Model, Effect[Msg])
update : (Model, Msg) -> (Model, Effect[Msg])
view : (Model, ViewEnvironment) -> View[Msg]
}
///|
pub fn[Msg] Effect::none() -> Effect[Msg] {
NoEffect
}
///|
pub fn[Msg] Effect::batch(effects : Array[Effect[Msg]]) -> Effect[Msg] {
Batch(effects)
}
///|
pub fn[Msg] Effect::send(message : Msg) -> Effect[Msg] {
Send(message)
}
///|
pub fn[Model, Msg] Program::new(
init~ : () -> (Model, Effect[Msg]),
update~ : (Model, Msg) -> (Model, Effect[Msg]),
view~ : (Model) -> View[Msg],
) -> Program[Model, Msg] {
{ init, update, view: (model, _env) => view(model) }
}
///|
pub fn[Model, Msg] Program::new_with_environment(
init~ : () -> (Model, Effect[Msg]),
update~ : (Model, Msg) -> (Model, Effect[Msg]),
view~ : (Model, ViewEnvironment) -> View[Msg],
) -> Program[Model, Msg] {
{ init, update, view }
}
///|
pub fn[Model, Msg] Program::simple(
init~ : Model,
update~ : (Model, Msg) -> Model,
view~ : (Model) -> View[Msg],
) -> Program[Model, Msg] {
Program::new(
init=() => (init, Effect::none()),
update=(model, message) => (update(model, message), Effect::none()),
view~,
)
}
///|
pub fn[Model, Msg] Program::simple_with_environment(
init~ : Model,
update~ : (Model, Msg) -> Model,
view~ : (Model, ViewEnvironment) -> View[Msg],
) -> Program[Model, Msg] {
Program::new_with_environment(
init=() => (init, Effect::none()),
update=(model, message) => (update(model, message), Effect::none()),
view~,
)
}
///|
fn[Msg] run_effect(effect : Effect[Msg], dispatch : (Msg) -> Unit) -> Unit {
match effect {
NoEffect => ()
Batch(effects) =>
for effect in effects {
run_effect(effect, dispatch)
}
Send(message) => dispatch(message)
}
}