diff --git a/src/mpv/event.rs b/src/mpv/event.rs index 0177236..2586997 100644 --- a/src/mpv/event.rs +++ b/src/mpv/event.rs @@ -55,7 +55,12 @@ pub struct LogMessageEvent { pub struct PropertyEvent { pub reply_userdata: u64, pub name: String, - //pub value: PropertyEventValue, + pub value: Option, +} + +#[derive(Clone, Debug)] +pub enum PropertyEventValue { + Int64(i64), } #[derive(Clone, Debug)] diff --git a/src/mpv/handle.rs b/src/mpv/handle.rs index e80cce2..d8935b0 100644 --- a/src/mpv/handle.rs +++ b/src/mpv/handle.rs @@ -1,5 +1,6 @@ use super::event::{ - EndFileEvent, EndFileReason, HookEvent, LogMessageEvent, PropertyEvent, StartFileEvent, + EndFileEvent, EndFileReason, HookEvent, LogMessageEvent, PropertyEvent, PropertyEventValue, + StartFileEvent, }; use super::{ffi, Error, Event as MpvEvent, GetProperty, SetProperty}; use event_listener::{Event, EventListener, IntoNotification}; @@ -140,6 +141,18 @@ impl Handle { }) } + pub fn observe_property_i64(&self, reply_userdata: u64, name: &str) -> Result<(), Error> { + let name = CString::new(name).expect("null bytes in property name"); + Error::from_return_code(unsafe { + ffi::mpv_observe_property( + self.inner.as_ptr(), + reply_userdata, + name.as_ptr(), + ffi::mpv_format_MPV_FORMAT_INT64, + ) + }) + } + pub fn unobserve_property(&self, registered_reply_userdata: u64) -> Result { let rc = unsafe { ffi::mpv_unobserve_property(self.inner.as_ptr(), registered_reply_userdata) }; @@ -244,6 +257,15 @@ impl Handle { name: unsafe { CStr::from_ptr(data.name) } .to_string_lossy() .into(), + value: match data.format { + ffi::mpv_format_MPV_FORMAT_NONE => None, + ffi::mpv_format_MPV_FORMAT_INT64 => { + Some(PropertyEventValue::Int64(unsafe { + *(data.data as *mut i64) + })) + } + _ => todo!(), + }, })) } diff --git a/src/ui/window.rs b/src/ui/window.rs index 6bb713e..3491621 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -61,8 +61,8 @@ mod imp { _mute: (), #[property(type = bool, get = Self::pause, set = Self::set_pause)] _pause: (), - #[property(type = i64, get = Self::playlist_pos)] - _playlist_pos: (), + #[property(get)] + playlist_pos: Cell, #[property(type = f64, get = Self::time_pos)] _time_pos: (), #[property(type = f64, get = Self::duration)] @@ -97,7 +97,7 @@ mod imp { mpv.set_property("vid", false).unwrap(); mpv.set_property("prefetch-playlist", true).unwrap(); - mpv.observe_property(3, "playlist-pos").unwrap(); + mpv.observe_property_i64(3, "playlist-pos").unwrap(); mpv.observe_property(4, "idle-active").unwrap(); mpv.observe_property(6, "playlist-count").unwrap(); mpv.observe_property(7, "duration").unwrap(); @@ -126,7 +126,7 @@ mod imp { _volume: (), _mute: (), _pause: (), - _playlist_pos: (), + playlist_pos: Cell::new(-1), _time_pos: (), _duration: (), _idle_active: (), @@ -468,10 +468,6 @@ mod imp { self.mpv.set_property("pause", pause).unwrap(); } - fn playlist_pos(&self) -> i64 { - self.mpv.get_property("playlist-pos").unwrap() - } - fn time_pos(&self) -> f64 { if let Some(queued_seek) = self.queued_seek.get() { // counterfeit time-pos while the seek is ongoing @@ -556,9 +552,17 @@ mod imp { } fn on_property_change(&self, event: crate::mpv::event::PropertyEvent) { + use crate::mpv::event::PropertyEventValue; + match event.reply_userdata { 3 => { assert_eq!(event.name, "playlist-pos"); + let value = match event.value { + Some(PropertyEventValue::Int64(i)) => i, + _ => unreachable!(), + }; + self.playlist_pos.set(value); + event!(Level::TRACE, "playlist-pos is now {value}"); self.obj().notify("playlist-pos"); }