wip
This commit is contained in:
122
src/ui/ui.gleam
Normal file
122
src/ui/ui.gleam
Normal file
@@ -0,0 +1,122 @@
|
||||
import gleam/erlang/process.{type Name, type Subject}
|
||||
import gleam/otp/actor
|
||||
import gleam/result
|
||||
import gleam/string
|
||||
|
||||
import input/key.{type Key}
|
||||
import mpv/control as mpv_control
|
||||
import ui/control as ui_control
|
||||
|
||||
pub type State(ui_mpv, mpv_ui, ui_input_keys, ui_input_stream, exit) {
|
||||
State(
|
||||
ui_mpv: Subject(mpv_control.Control),
|
||||
mpv_ui: Subject(ui_control.Control),
|
||||
ui_input_keys: Subject(Key),
|
||||
ui_input_stream: Subject(List(String)),
|
||||
exit: Subject(Nil),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
ui_mpv_name: Name(mpv_control.Control),
|
||||
mpv_ui_name: Name(ui_control.Control),
|
||||
ui_input_keys_name: Name(Key),
|
||||
ui_input_stream_name: Name(List(String)),
|
||||
exit: Subject(Nil),
|
||||
) -> Result(Nil, String) {
|
||||
let ui_mpv: Subject(mpv_control.Control) = process.named_subject(ui_mpv_name)
|
||||
let mpv_ui: Subject(ui_control.Control) = process.named_subject(mpv_ui_name)
|
||||
|
||||
let ui_input_keys: Subject(Key) = process.named_subject(ui_input_keys_name)
|
||||
let ui_input_stream: Subject(List(String)) =
|
||||
process.named_subject(ui_input_stream_name)
|
||||
|
||||
case
|
||||
actor.new(State(ui_mpv, mpv_ui, ui_input_keys, ui_input_stream, exit))
|
||||
|> actor.on_message(handle_message)
|
||||
|> actor.start
|
||||
{
|
||||
Error(start_error) ->
|
||||
Error("Could not start ui: " <> string.inspect(start_error))
|
||||
Ok(actor.Started(data: ui, ..)) -> {
|
||||
echo "ui started"
|
||||
|
||||
process.spawn(fn() {
|
||||
let assert Ok(_) = process.register(process.self(), ui_input_keys_name)
|
||||
handle_key(ui, ui_input_keys)
|
||||
})
|
||||
|
||||
process.spawn(fn() {
|
||||
let assert Ok(_) = process.register(process.self(), mpv_ui_name)
|
||||
handle_mpv_control(ui, mpv_ui)
|
||||
})
|
||||
|
||||
process.spawn(fn() {
|
||||
let assert Ok(_) =
|
||||
process.register(process.self(), ui_input_stream_name)
|
||||
temp_input_stream(ui_input_stream)
|
||||
})
|
||||
|
||||
Ok(Nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_message(
|
||||
state: State(ui_mpv, mpv_ui, ui_input_keys, ui_input_stream, exit),
|
||||
control: ui_control.Control,
|
||||
) -> actor.Next(
|
||||
State(ui_mpv, mpv_ui, ui_input_keys, ui_input_stream, exit),
|
||||
ui_control.Control,
|
||||
) {
|
||||
case control {
|
||||
ui_control.Ack -> {
|
||||
echo "ack! use this to re-render?"
|
||||
actor.continue(state)
|
||||
}
|
||||
ui_control.TogglePlayPause -> {
|
||||
process.send(state.mpv_ui, ui_control.TogglePlayPause)
|
||||
case process.receive(state.mpv_ui, 5000) {
|
||||
Error(_) -> echo "mpv not responding: could not toggle pause :("
|
||||
Ok(_) -> echo "toggled pause"
|
||||
}
|
||||
|
||||
actor.continue(state)
|
||||
}
|
||||
ui_control.Exit -> {
|
||||
// TODO call `mpv` to exit, wait for response
|
||||
process.send(state.exit, Nil)
|
||||
actor.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `handle_key` listens to a subject onto which `input` will send messages with
|
||||
/// parsed `Key`s which will be mapped to `Control`s (if possible)
|
||||
fn handle_key(
|
||||
ui: Subject(ui_control.Control),
|
||||
ui_input_keys: Subject(Key),
|
||||
) -> Nil {
|
||||
let _ =
|
||||
process.receive_forever(ui_input_keys)
|
||||
|> ui_control.from_key
|
||||
|> result.map(process.send(ui, _))
|
||||
|
||||
handle_key(ui, ui_input_keys)
|
||||
}
|
||||
|
||||
fn handle_mpv_control(
|
||||
ui: Subject(ui_control.Control),
|
||||
mpv_ui: Subject(ui_control.Control),
|
||||
) {
|
||||
let control = process.receive_forever(mpv_ui)
|
||||
process.send(ui, control)
|
||||
|
||||
handle_mpv_control(ui, mpv_ui)
|
||||
}
|
||||
|
||||
fn temp_input_stream(ui_input_stream: Subject(List(String))) -> Nil {
|
||||
let stream = process.receive_forever(ui_input_stream)
|
||||
echo "input stream: " <> string.inspect(stream)
|
||||
temp_input_stream(ui_input_stream)
|
||||
}
|
||||
Reference in New Issue
Block a user