sure
This commit is contained in:
parent
8ab1e1e1fa
commit
859e1ca527
4 changed files with 38 additions and 20 deletions
|
@ -2,10 +2,11 @@ mod imp {
|
|||
use crate::{mpv, ui};
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gtk::glib;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Application {
|
||||
mpv: mpv::Handle,
|
||||
mpv: Rc<mpv::Handle>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -36,14 +37,13 @@ mod imp {
|
|||
self.mpv.set_property("gapless-audio", true).unwrap();
|
||||
// TODO: observe properties
|
||||
|
||||
let self_weak = self.obj().downgrade();
|
||||
let mpv_weak = Rc::downgrade(&self.mpv);
|
||||
glib::spawn_future_local(async move {
|
||||
while let Some(app) = self_weak.upgrade() {
|
||||
// this song and dance is required so the strong reference to app
|
||||
// isn't uselessly preserved during the await
|
||||
let future = app.imp().mpv.tick();
|
||||
drop(app);
|
||||
future.await;
|
||||
while let Some(mpv) = mpv_weak.upgrade() {
|
||||
match mpv.tick() {
|
||||
None => break,
|
||||
Some(listener) => listener.await,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ pub use playbin::Playbin;
|
|||
pub mod subsonic;
|
||||
pub mod subsonic_vala;
|
||||
|
||||
mod playbin2;
|
||||
|
||||
use gettextrs::{bind_textdomain_codeset, bindtextdomain, setlocale, textdomain, LocaleCategory};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{gio, glib};
|
||||
|
|
39
src/mpv.rs
39
src/mpv.rs
|
@ -44,7 +44,7 @@ impl fmt::Debug 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::pin::Pin;
|
||||
use std::ptr::NonNull;
|
||||
|
@ -87,7 +87,10 @@ impl Handle {
|
|||
}
|
||||
|
||||
// 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
|
||||
// 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 {
|
||||
let borrowed = self.wait_event_cell.borrow_mut();
|
||||
let event = unsafe { &*ffi::mpv_wait_event(self.inner.as_ptr(), 0.0) };
|
||||
|
||||
match event.event_id {
|
||||
|
@ -126,26 +136,31 @@ impl Handle {
|
|||
let level = unsafe { CStr::from_ptr(data.level) }.to_str().unwrap();
|
||||
let text = unsafe { CStr::from_ptr(data.text) }.to_str().unwrap();
|
||||
print!("[{prefix}] {level}: {text}");
|
||||
},
|
||||
}
|
||||
|
||||
11 => { /* deprecated, ignore */ }
|
||||
|
||||
_ => todo!("event {}", event.event_id),
|
||||
}
|
||||
drop(borrowed); // make sure the borrow is held until here
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&self) -> impl std::future::Future<Output = ()> {
|
||||
// take listener before we drain the event queue, so we don't miss any notifications
|
||||
let listener = self.wakeup.listen();
|
||||
self.drain_event_queue();
|
||||
listener
|
||||
drop(borrowed); // make sure the borrow is held until here
|
||||
Some(listener)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Handle {
|
||||
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 {
|
||||
ffi::mpv_destroy(self.inner.as_ptr());
|
||||
}
|
||||
|
|
1
src/playbin2.rs
Normal file
1
src/playbin2.rs
Normal file
|
@ -0,0 +1 @@
|
|||
mod imp {}
|
Loading…
Reference in a new issue