peggle two

This commit is contained in:
Erica Z 2024-11-03 13:41:02 +01:00
parent 58ef3e956c
commit dbd209f904
4 changed files with 90 additions and 50 deletions

View file

@ -1,10 +1,9 @@
use super::Error; use super::Error;
use std::borrow::Cow;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Event<'a> { pub enum Event {
Shutdown, Shutdown,
LogMessage(LogMessageEvent<'a>), LogMessage(LogMessageEvent),
//GetPropertyReply(PropertyEvent), TODO //GetPropertyReply(PropertyEvent), TODO
//SetPropertyReply(PropertyEvent), TODO //SetPropertyReply(PropertyEvent), TODO
//CommandReply(CommandEvent), TODO //CommandReply(CommandEvent), TODO
@ -16,7 +15,7 @@ pub enum Event<'a> {
AudioReconfig, AudioReconfig,
//Seek, //Seek,
PlaybackRestart, PlaybackRestart,
PropertyChange(PropertyEvent<'a>), PropertyChange(PropertyEvent),
//QueueOverflow, //QueueOverflow,
//Hook, //Hook,
Unknown(u32), Unknown(u32),
@ -45,25 +44,25 @@ pub struct EndFileEvent {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LogMessageEvent<'a> { pub struct LogMessageEvent {
pub prefix: &'a str, pub prefix: String,
pub level: &'a str, pub level: String,
pub text: &'a str, pub text: String,
//log_level: i32, //log_level: i32,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PropertyEvent<'a> { pub struct PropertyEvent {
pub reply_userdata: u64, pub reply_userdata: u64,
pub name: &'a str, pub name: String,
pub value: PropertyEventValue<'a>, pub value: PropertyEventValue,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum PropertyEventValue<'a> { pub enum PropertyEventValue {
None, None,
String(Cow<'a, str>), String(String),
OsdString(&'a str), OsdString(String),
Flag(bool), Flag(bool),
Int64(i64), Int64(i64),
Double(f64), Double(f64),

View file

@ -3,6 +3,7 @@ use event::{
EndFileEvent, EndFileReason, LogMessageEvent, PropertyEvent, PropertyEventValue, StartFileEvent, EndFileEvent, EndFileReason, LogMessageEvent, PropertyEvent, PropertyEventValue, StartFileEvent,
}; };
use event_listener::{Event, EventListener, IntoNotification}; use event_listener::{Event, EventListener, IntoNotification};
use std::cell::{RefCell, RefMut};
use std::ffi::{c_char, c_void, CStr, CString}; use std::ffi::{c_char, c_void, CStr, CString};
use std::fmt; use std::fmt;
use std::pin::Pin; use std::pin::Pin;
@ -11,6 +12,7 @@ use std::ptr::NonNull;
pub struct Handle { pub struct Handle {
inner: NonNull<ffi::mpv_handle>, inner: NonNull<ffi::mpv_handle>,
wakeup: Pin<Box<Event>>, // the wakeup callback holds a pointer to this wakeup: Pin<Box<Event>>, // the wakeup callback holds a pointer to this
wait_event_cell: RefCell<()>,
} }
// The client API is generally fully thread-safe, unless otherwise noted. // The client API is generally fully thread-safe, unless otherwise noted.
@ -61,7 +63,11 @@ impl Handle {
Error::from_return_code(unsafe { ffi::mpv_initialize(inner.as_ptr()) }) Error::from_return_code(unsafe { ffi::mpv_initialize(inner.as_ptr()) })
.expect("could not initialize mpv handle"); .expect("could not initialize mpv handle");
Self { inner, wakeup } Self {
inner,
wakeup,
wait_event_cell: RefCell::new(()),
}
} }
pub fn client_name(&self) -> &str { pub fn client_name(&self) -> &str {
@ -122,8 +128,11 @@ impl Handle {
self.wakeup.listen() self.wakeup.listen()
} }
pub fn wait_event(&mut self, timeout: f64) -> Option<MpvEvent<'_>> { pub fn wait_event(&self, timeout: f64) -> Option<MpvEvent> {
let event = unsafe { &*ffi::mpv_wait_event(self.inner.as_ptr(), timeout) }; // use refcell to ensure exclusive access
let event = RefMut::map(self.wait_event_cell.borrow_mut(), |()| unsafe {
&mut *ffi::mpv_wait_event(self.inner.as_ptr(), timeout)
});
match event.event_id { match event.event_id {
ffi::mpv_event_id_MPV_EVENT_NONE => None, ffi::mpv_event_id_MPV_EVENT_NONE => None,
@ -134,9 +143,15 @@ impl Handle {
let data = unsafe { &*(event.data as *mut ffi::mpv_event_log_message) }; let data = unsafe { &*(event.data as *mut ffi::mpv_event_log_message) };
// TODO: actual logging? // TODO: actual logging?
Some(MpvEvent::LogMessage(LogMessageEvent { Some(MpvEvent::LogMessage(LogMessageEvent {
prefix: unsafe { CStr::from_ptr(data.prefix) }.to_str().unwrap(), prefix: unsafe { CStr::from_ptr(data.prefix) }
level: unsafe { CStr::from_ptr(data.level) }.to_str().unwrap(), .to_string_lossy()
text: unsafe { CStr::from_ptr(data.text) }.to_str().unwrap(), .into(),
level: unsafe { CStr::from_ptr(data.level) }
.to_string_lossy()
.into(),
text: unsafe { CStr::from_ptr(data.text) }
.to_string_lossy()
.into(),
})) }))
} }
@ -178,7 +193,9 @@ impl Handle {
let data = unsafe { &*(event.data as *mut ffi::mpv_event_property) }; let data = unsafe { &*(event.data as *mut ffi::mpv_event_property) };
Some(MpvEvent::PropertyChange(PropertyEvent { Some(MpvEvent::PropertyChange(PropertyEvent {
reply_userdata: event.reply_userdata, reply_userdata: event.reply_userdata,
name: unsafe { CStr::from_ptr(data.name) }.to_str().unwrap(), name: unsafe { CStr::from_ptr(data.name) }
.to_string_lossy()
.into(),
value: match data.format { value: match data.format {
ffi::mpv_format_MPV_FORMAT_NONE => PropertyEventValue::None, ffi::mpv_format_MPV_FORMAT_NONE => PropertyEventValue::None,
ffi::mpv_format_MPV_FORMAT_INT64 => { ffi::mpv_format_MPV_FORMAT_INT64 => {

View file

@ -1 +1,43 @@
mod imp {} use crate::mpv;
use event_listener::EventListener;
pub struct Playbin {
mpv: mpv::Handle,
}
impl Default for Playbin {
fn default() -> Self {
let mpv = mpv::Handle::new();
mpv.set_property("audio-client-name", "audrey").unwrap();
mpv.set_property("user-agent", crate::USER_AGENT).unwrap();
mpv.set_property("video", false).unwrap();
mpv.set_property("prefetch-playlist", true).unwrap();
mpv.set_property("gapless-audio", true).unwrap();
mpv.command(["loadfile", "https://www.youtube.com/watch?v=19y8YTbvri8"])
.unwrap();
Self { mpv }
}
}
impl Playbin {
pub fn tick(&self) -> EventListener {
let listener = self.mpv.wakeup_listener();
while let Some(event) = self.mpv.wait_event(0.0) {
self.handle_event(event);
}
listener
}
fn handle_event(&self, event: mpv::Event) {
println!("mpv event {:?}", event);
}
}
impl Drop for Playbin {
fn drop(&mut self) {
println!("dropping Playbin2");
self.mpv.command(["quit"]).unwrap();
}
}

View file

@ -1,5 +1,4 @@
mod imp { mod imp {
use crate::mpv;
use adw::prelude::*; use adw::prelude::*;
use adw::subclass::prelude::*; use adw::subclass::prelude::*;
use glib::subclass::InitializingObject; use glib::subclass::InitializingObject;
@ -28,7 +27,8 @@ mod imp {
pub(super) setup: crate::ui::Setup, pub(super) setup: crate::ui::Setup,
pub(super) api: RefCell<Option<crate::subsonic_vala::Client>>, pub(super) api: RefCell<Option<crate::subsonic_vala::Client>>,
pub(super) mpv: Rc<RefCell<mpv::Handle>>,
playbin2: Rc<crate::playbin2::Playbin>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -52,36 +52,19 @@ mod imp {
fn constructed(&self) { fn constructed(&self) {
self.parent_constructed(); self.parent_constructed();
// set up mpv let playbin = Rc::downgrade(&self.playbin2);
let mpv = self.mpv.borrow(); glib::spawn_future_local(glib::clone!(async move {
mpv.set_property("audio-client-name", "audrey").unwrap();
mpv.set_property("user-agent", crate::USER_AGENT).unwrap();
mpv.set_property("video", false).unwrap();
mpv.set_property("prefetch-playlist", true).unwrap();
mpv.set_property("gapless-audio", true).unwrap();
mpv.observe_property_i64(0, "duration").unwrap();
mpv.command(["loadfile", "https://www.youtube.com/watch?v=19y8YTbvri8"])
.unwrap();
let mpv_weak = Rc::downgrade(&self.mpv);
glib::spawn_future_local(async move {
loop { loop {
let mpv = match mpv_weak.upgrade() { match playbin.upgrade() {
Some(mpv) => mpv,
None => break, None => break,
}; Some(playbin) => {
{ let listener = playbin.tick();
let mut mpv_ref = mpv.borrow_mut(); drop(playbin);
let listener = mpv_ref.wakeup_listener(); listener.await;
while let Some(event) = mpv_ref.wait_event(0.0) {
println!("mpv event {:?}", event);
} }
listener
} }
.await
} }
}); }));
// set up mpris // set up mpris
let window = self.obj().clone(); let window = self.obj().clone();
@ -194,7 +177,6 @@ mod imp {
impl Drop for Window { impl Drop for Window {
fn drop(&mut self) { fn drop(&mut self) {
println!("dropping AudreyUiWindow"); println!("dropping AudreyUiWindow");
self.mpv.borrow().command(["quit"]).unwrap();
} }
} }
} }