peggle two
This commit is contained in:
parent
58ef3e956c
commit
dbd209f904
4 changed files with 90 additions and 50 deletions
|
@ -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),
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue