This commit is contained in:
Erica Z 2024-11-02 20:57:12 +01:00
parent 8ab1e1e1fa
commit 859e1ca527
4 changed files with 38 additions and 20 deletions

View file

@ -2,10 +2,11 @@ mod imp {
use crate::{mpv, ui}; use crate::{mpv, ui};
use adw::{prelude::*, subclass::prelude::*}; use adw::{prelude::*, subclass::prelude::*};
use gtk::glib; use gtk::glib;
use std::rc::Rc;
#[derive(Default)] #[derive(Default)]
pub struct Application { pub struct Application {
mpv: mpv::Handle, mpv: Rc<mpv::Handle>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -36,14 +37,13 @@ mod imp {
self.mpv.set_property("gapless-audio", true).unwrap(); self.mpv.set_property("gapless-audio", true).unwrap();
// TODO: observe properties // TODO: observe properties
let self_weak = self.obj().downgrade(); let mpv_weak = Rc::downgrade(&self.mpv);
glib::spawn_future_local(async move { glib::spawn_future_local(async move {
while let Some(app) = self_weak.upgrade() { while let Some(mpv) = mpv_weak.upgrade() {
// this song and dance is required so the strong reference to app match mpv.tick() {
// isn't uselessly preserved during the await None => break,
let future = app.imp().mpv.tick(); Some(listener) => listener.await,
drop(app); }
future.await;
} }
}); });

View file

@ -17,6 +17,8 @@ pub use playbin::Playbin;
pub mod subsonic; pub mod subsonic;
pub mod subsonic_vala; pub mod subsonic_vala;
mod playbin2;
use gettextrs::{bind_textdomain_codeset, bindtextdomain, setlocale, textdomain, LocaleCategory}; use gettextrs::{bind_textdomain_codeset, bindtextdomain, setlocale, textdomain, LocaleCategory};
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};

View file

@ -44,7 +44,7 @@ impl fmt::Debug for Error {
impl std::error::Error for Error {} impl std::error::Error for Error {}
use event_listener::{Event, IntoNotification}; use event_listener::{Event, EventListener, IntoNotification};
use std::cell::RefCell; use std::cell::RefCell;
use std::pin::Pin; use std::pin::Pin;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -87,7 +87,10 @@ impl Handle {
} }
// set up verbose logging for now // set up verbose logging for now
Error::from_return_code(unsafe { ffi::mpv_request_log_messages(inner.as_ptr(), c"v".as_ptr()) }).unwrap(); Error::from_return_code(unsafe {
ffi::mpv_request_log_messages(inner.as_ptr(), c"v".as_ptr())
})
.unwrap();
// TODO: maybe we need to set something before initialization, but idk // TODO: maybe we need to set something before initialization, but idk
// also wed need a builder, since "Note that you should avoid doing concurrent accesses on the uninitialized client handle." // also wed need a builder, since "Note that you should avoid doing concurrent accesses on the uninitialized client handle."
@ -111,9 +114,16 @@ impl Handle {
}) })
} }
fn drain_event_queue(&self) { // TODO: return None on SHUTDOWN possibly?
pub fn tick(&self) -> Option<EventListener> {
// take listener before we drain the event queue, so we don't miss any notifications
let listener = self.wakeup.listen();
let borrowed = self
.wait_event_cell
.try_borrow_mut()
.expect("Mpv::tick is not reentrant");
loop { loop {
let borrowed = self.wait_event_cell.borrow_mut();
let event = unsafe { &*ffi::mpv_wait_event(self.inner.as_ptr(), 0.0) }; let event = unsafe { &*ffi::mpv_wait_event(self.inner.as_ptr(), 0.0) };
match event.event_id { match event.event_id {
@ -126,26 +136,31 @@ impl Handle {
let level = unsafe { CStr::from_ptr(data.level) }.to_str().unwrap(); let level = unsafe { CStr::from_ptr(data.level) }.to_str().unwrap();
let text = unsafe { CStr::from_ptr(data.text) }.to_str().unwrap(); let text = unsafe { CStr::from_ptr(data.text) }.to_str().unwrap();
print!("[{prefix}] {level}: {text}"); print!("[{prefix}] {level}: {text}");
}, }
11 => { /* deprecated, ignore */ } 11 => { /* deprecated, ignore */ }
_ => todo!("event {}", event.event_id), _ => todo!("event {}", event.event_id),
} }
drop(borrowed); // make sure the borrow is held until here
}
} }
pub fn tick(&self) -> impl std::future::Future<Output = ()> { drop(borrowed); // make sure the borrow is held until here
// take listener before we drain the event queue, so we don't miss any notifications Some(listener)
let listener = self.wakeup.listen();
self.drain_event_queue();
listener
} }
} }
impl Drop for Handle { impl Drop for Handle {
fn drop(&mut self) { fn drop(&mut self) {
// let any executor ticking tasks know we're ded
self.wakeup.notify(u32::MAX.relaxed());
// just in case
unsafe {
ffi::mpv_wait_async_requests(self.inner.as_ptr());
}
// drain event queue (we're &mut so we know we have exclusive access)
self.tick();
unsafe { unsafe {
ffi::mpv_destroy(self.inner.as_ptr()); ffi::mpv_destroy(self.inner.as_ptr());
} }

1
src/playbin2.rs Normal file
View file

@ -0,0 +1 @@
mod imp {}