Compare commits

..

3 commits

Author SHA1 Message Date
57b6024845 state machine 2024-11-10 16:45:56 +01:00
129281ea4a another sanity check 2024-11-10 15:57:03 +01:00
a0be95189b remove volume, mute, pause watches
these shouldn't even change from the mpv side anyways
2024-11-10 15:54:47 +01:00

View file

@ -11,10 +11,22 @@ mod imp {
use tracing::{event, span, Level}; use tracing::{event, span, Level};
use zbus::object_server::InterfaceRef; use zbus::object_server::InterfaceRef;
#[derive(Debug, Copy, Clone)]
enum State {
Idle,
FileLoading,
FileLoaded,
Active,
FileEnded,
Seeking,
}
#[derive(gtk::CompositeTemplate, glib::Properties)] #[derive(gtk::CompositeTemplate, glib::Properties)]
#[template(resource = "/eu/callcc/audrey/window.ui")] #[template(resource = "/eu/callcc/audrey/window.ui")]
#[properties(wrapper_type = super::Window)] #[properties(wrapper_type = super::Window)]
pub struct Window { pub struct Window {
state: Cell<State>,
#[template_child] #[template_child]
pub(super) playbar: TemplateChild<crate::ui::Playbar>, pub(super) playbar: TemplateChild<crate::ui::Playbar>,
@ -83,9 +95,6 @@ mod imp {
mpv.set_property("vid", false).unwrap(); mpv.set_property("vid", false).unwrap();
mpv.set_property("prefetch-playlist", true).unwrap(); mpv.set_property("prefetch-playlist", true).unwrap();
mpv.observe_property(0, "volume").unwrap();
mpv.observe_property(1, "mute").unwrap();
mpv.observe_property(2, "pause").unwrap();
mpv.observe_property(3, "playlist-pos").unwrap(); mpv.observe_property(3, "playlist-pos").unwrap();
mpv.observe_property(4, "idle-active").unwrap(); mpv.observe_property(4, "idle-active").unwrap();
mpv.observe_property(6, "playlist-count").unwrap(); mpv.observe_property(6, "playlist-count").unwrap();
@ -95,6 +104,8 @@ mod imp {
mpv.add_hook(0, "on_before_start_file", 0).unwrap(); mpv.add_hook(0, "on_before_start_file", 0).unwrap();
Self { Self {
state: Cell::new(State::Idle),
playbar: Default::default(), playbar: Default::default(),
play_queue: Default::default(), play_queue: Default::default(),
can_click_shuffle_all: Cell::new(false), can_click_shuffle_all: Cell::new(false),
@ -371,7 +382,9 @@ mod imp {
} }
fn playlist_count(&self) -> i64 { fn playlist_count(&self) -> i64 {
self.mpv.get_property::<i64>("playlist-count").unwrap() let count = self.mpv.get_property::<i64>("playlist-count").unwrap();
assert_eq!(count as u32, self.playlist_model.n_items());
count
} }
fn song(&self) -> Option<Song> { fn song(&self) -> Option<Song> {
@ -420,21 +433,6 @@ mod imp {
fn on_property_change(&self, event: crate::mpv::event::PropertyEvent) { fn on_property_change(&self, event: crate::mpv::event::PropertyEvent) {
match event.reply_userdata { match event.reply_userdata {
0 => {
assert_eq!(event.name, "volume");
self.obj().notify("volume");
}
1 => {
assert_eq!(event.name, "mute");
self.obj().notify("mute");
}
2 => {
assert_eq!(event.name, "pause");
self.obj().notify("pause");
}
3 => { 3 => {
assert_eq!(event.name, "playlist-pos"); assert_eq!(event.name, "playlist-pos");
self.obj().notify("playlist-pos"); self.obj().notify("playlist-pos");
@ -443,6 +441,9 @@ mod imp {
4 => { 4 => {
assert_eq!(event.name, "idle-active"); assert_eq!(event.name, "idle-active");
self.obj().notify("idle-active"); self.obj().notify("idle-active");
if self.obj().idle_active() {
self.on_idle_active();
}
} }
6 => { 6 => {
@ -503,7 +504,25 @@ mod imp {
}; };
} }
fn on_idle_active(&self) {
match self.state.get() {
State::Idle => {}
State::FileEnded => {}
other => panic!("invalid state transition: IdleActive from {other:?}"),
}
self.state.set(State::Idle);
}
fn on_start_file(&self) { fn on_start_file(&self) {
match self.state.get() {
State::Idle => {}
State::FileEnded => {}
other => panic!("invalid state transition: StartFile from {other:?}"),
}
self.state.set(State::FileLoading);
event!(Level::INFO, "StartFile"); event!(Level::INFO, "StartFile");
self.obj().notify("song"); self.obj().notify("song");
self.buffering_start(); self.buffering_start();
@ -542,6 +561,13 @@ mod imp {
} }
fn on_file_loaded(&self) { fn on_file_loaded(&self) {
match self.state.get() {
State::FileLoading => {}
other => panic!("invalid state transition: FileLoaded from {other:?}"),
}
self.state.set(State::FileLoaded);
event!(Level::INFO, "FileLoaded"); event!(Level::INFO, "FileLoaded");
// sanity check // sanity check
// i think "path" is only available after this event is dispatched // i think "path" is only available after this event is dispatched
@ -553,10 +579,27 @@ mod imp {
fn on_seek(&self) { fn on_seek(&self) {
event!(Level::INFO, "Seek"); event!(Level::INFO, "Seek");
match self.state.get() {
State::Active => {}
State::Seeking => {}
other => panic!("invalid state transition: Seek from {other:?}"),
}
self.state.set(State::Seeking);
self.buffering_start(); self.buffering_start();
} }
fn on_playback_restart(&self) { fn on_playback_restart(&self) {
match self.state.get() {
State::FileLoaded => {}
State::Seeking => {}
other => panic!("invalid state transition: PlaybackRestart from {other:?}"),
}
self.state.set(State::Active);
event!(Level::INFO, "PlaybackRestart"); event!(Level::INFO, "PlaybackRestart");
self.buffering_end(); self.buffering_end();
self.obj().notify("time-pos"); self.obj().notify("time-pos");
@ -570,6 +613,16 @@ mod imp {
fn on_end_file(&self, event: crate::mpv::event::EndFileEvent) { fn on_end_file(&self, event: crate::mpv::event::EndFileEvent) {
event!(Level::INFO, "EndFile: {event:?}"); event!(Level::INFO, "EndFile: {event:?}");
match self.state.get() {
State::Active => {}
State::FileLoading => {}
State::Seeking => {}
other => panic!("invalid state transition: EndFile from {other:?}"),
}
self.state.set(State::FileEnded);
self.obj().notify("song"); self.obj().notify("song");
self.buffering_end(); self.buffering_end();