Monitor musicplayer actor and stop main process when actor stops

This commit is contained in:
Alexander Heldt
2025-11-29 14:59:49 +01:00
parent dd9468938d
commit 0877344a94
2 changed files with 10 additions and 13 deletions

View File

@@ -8,13 +8,14 @@ import musicplayer/ui/ui
pub fn main() -> Nil { pub fn main() -> Nil {
let input_keys_name: Name(Key) = process.new_name("input_keys") let input_keys_name: Name(Key) = process.new_name("input_keys")
input.new(input_keys_name) input.new(input_keys_name)
let assert Ok(ui) = ui.new() let assert Ok(ui) = ui.new()
let assert Ok(mpv) = mpv.new() let assert Ok(mpv) = mpv.new()
let assert Ok(musicplayer_pid) = musicplayer.new(ui, mpv, input_keys_name)
let exit = process.new_subject() let monitor = process.monitor(musicplayer_pid)
let assert Ok(_) = musicplayer.new(ui, mpv, input_keys_name, exit) process.new_selector()
process.receive_forever(exit) |> process.select_specific_monitor(monitor, fn(_) { Nil })
|> process.selector_receive_forever
} }

View File

@@ -1,4 +1,4 @@
import gleam/erlang/process.{type Name, type Subject} import gleam/erlang/process.{type Name, type Pid, type Subject}
import gleam/otp/actor import gleam/otp/actor
import gleam/result import gleam/result
import gleam/string import gleam/string
@@ -25,7 +25,6 @@ type State {
input: Input, input: Input,
ui: Subject(ui_control.Control), ui: Subject(ui_control.Control),
mpv: Subject(mpv_control.Control), mpv: Subject(mpv_control.Control),
exit: Subject(Nil),
) )
} }
@@ -33,20 +32,19 @@ pub fn new(
ui: Subject(ui_control.Control), ui: Subject(ui_control.Control),
mpv: Subject(mpv_control.Control), mpv: Subject(mpv_control.Control),
input_keys_name: Name(Key), input_keys_name: Name(Key),
exit: Subject(Nil), ) -> Result(Pid, String) {
) -> Result(Nil, String) {
let input_keys = process.named_subject(input_keys_name) let input_keys = process.named_subject(input_keys_name)
let input = Input(False, "") let input = Input(False, "")
case case
actor.new(State(Idle, input, ui, mpv, exit)) actor.new(State(Idle, input, ui, mpv))
|> actor.on_message(handle_message) |> actor.on_message(handle_message)
|> actor.start |> actor.start
{ {
Error(start_error) -> Error(start_error) ->
Error("Could not start actor: " <> string.inspect(start_error)) Error("Could not start actor: " <> string.inspect(start_error))
Ok(actor.Started(data: musicplayer, ..)) -> { Ok(actor.Started(pid:, data: musicplayer)) -> {
process.spawn(fn() { process.spawn(fn() {
let assert Ok(_) = process.register(process.self(), input_keys_name) let assert Ok(_) = process.register(process.self(), input_keys_name)
handle_key(musicplayer, input_keys) handle_key(musicplayer, input_keys)
@@ -54,7 +52,7 @@ pub fn new(
process.spawn(fn() { update_playback_time_loop(mpv, ui, 1000) }) process.spawn(fn() { update_playback_time_loop(mpv, ui, 1000) })
Ok(Nil) Ok(pid)
} }
} }
} }
@@ -117,8 +115,6 @@ fn handle_message(state: State, control: Control) -> actor.Next(State, Control)
// Reset terminal state (show cursor etc.) // Reset terminal state (show cursor etc.)
process.call(state.ui, 1000, fn(reply_to) { ui_control.Exit(reply_to) }) process.call(state.ui, 1000, fn(reply_to) { ui_control.Exit(reply_to) })
// End main process
process.send(state.exit, Nil)
actor.stop() actor.stop()
} }
} }