Refactor PA to handle interior mutability / ref counting itself
This commit is contained in:
parent
9f3803fedc
commit
a431457468
2 changed files with 79 additions and 38 deletions
|
|
@ -1,11 +1,19 @@
|
|||
use futures::{channel::oneshot, future::poll_fn, task::Poll};
|
||||
use libpulse_binding::{
|
||||
callbacks::ListResult,
|
||||
context::{introspect::SinkInfo, Context},
|
||||
context::{
|
||||
introspect::{Introspector, SinkInfo},
|
||||
subscribe::{Facility, InterestMaskSet, Operation},
|
||||
Context, FlagSet, State,
|
||||
},
|
||||
error::PAErr,
|
||||
volume::ChannelVolumes,
|
||||
};
|
||||
use libpulse_glib_binding::Mainloop;
|
||||
use std::rc::Rc;
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
pub struct DeviceInfo {
|
||||
pub name: Option<String>,
|
||||
|
|
@ -18,22 +26,66 @@ pub struct ServerInfo {
|
|||
pub default_source_name: Option<String>,
|
||||
}
|
||||
|
||||
pub struct PA {
|
||||
struct PAInner {
|
||||
main_loop: Mainloop,
|
||||
pub context: Context,
|
||||
pub context: RefCell<Context>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PA(Rc<PAInner>);
|
||||
|
||||
impl PA {
|
||||
pub fn new() -> Option<Self> {
|
||||
let main_loop = Mainloop::new(None)?;
|
||||
let context = Context::new(&main_loop, "com.system76.cosmic.applets.audio")?;
|
||||
Some(Self { main_loop, context })
|
||||
Some(Self(Rc::new(PAInner {
|
||||
main_loop,
|
||||
context: RefCell::new(context),
|
||||
})))
|
||||
}
|
||||
|
||||
pub fn set_state_callback<F: Fn(&Self, State) + 'static>(&self, cb: F) {
|
||||
let pa = self.clone(); // TODO: weak ref?
|
||||
self.0
|
||||
.context
|
||||
.borrow_mut()
|
||||
.set_state_callback(Some(Box::new(move || {
|
||||
let state = pa.0.context.borrow().get_state();
|
||||
cb(&pa, state);
|
||||
})));
|
||||
}
|
||||
|
||||
// TODO: builder pattern?
|
||||
pub fn set_subscribe_callback<F: FnMut(Option<Facility>, Option<Operation>, u32) + 'static>(
|
||||
&self,
|
||||
cb: F,
|
||||
) {
|
||||
self.0
|
||||
.context
|
||||
.borrow_mut()
|
||||
.set_subscribe_callback(Some(Box::new(cb)));
|
||||
}
|
||||
|
||||
pub fn subscribe(&self, mask: InterestMaskSet) {
|
||||
// XXX cb; operation; async
|
||||
self.0.context.borrow_mut().subscribe(mask, |_| {});
|
||||
}
|
||||
|
||||
pub fn connect(&self) -> Result<(), PAErr> {
|
||||
self.0
|
||||
.context
|
||||
.borrow_mut()
|
||||
.connect(None, FlagSet::empty(), None)
|
||||
}
|
||||
|
||||
fn introspect(&self) -> Introspector {
|
||||
self.0.context.borrow().introspect()
|
||||
}
|
||||
|
||||
pub async fn get_server_info(&self) -> ServerInfo {
|
||||
let (sender, receiver) = oneshot::channel();
|
||||
let mut sender = Some(sender);
|
||||
self.context.introspect().get_server_info(move |info| {
|
||||
self.introspect().get_server_info(move |info| {
|
||||
sender.take().unwrap().send(ServerInfo {
|
||||
default_sink_name: info.default_sink_name.clone().map(|x| x.into_owned()),
|
||||
default_source_name: info.default_source_name.clone().map(|x| x.into_owned()),
|
||||
|
|
@ -46,8 +98,7 @@ impl PA {
|
|||
let (sender, receiver) = oneshot::channel();
|
||||
let mut sender = Some(sender);
|
||||
let mut items = Some(Vec::new());
|
||||
self.context
|
||||
.introspect()
|
||||
self.introspect()
|
||||
.get_sink_info_list(move |result| match result {
|
||||
ListResult::Item(item) => items.as_mut().unwrap().push(DeviceInfo {
|
||||
name: item.name.clone().map(|x| x.into_owned()),
|
||||
|
|
@ -74,8 +125,7 @@ impl PA {
|
|||
let (sender, receiver) = oneshot::channel();
|
||||
let mut sender = Some(sender);
|
||||
let mut sink = None;
|
||||
self.context
|
||||
.introspect()
|
||||
self.introspect()
|
||||
.get_sink_info_by_name(&name, move |result| match result {
|
||||
ListResult::Item(item) => {
|
||||
sink = Some(DeviceInfo {
|
||||
|
|
@ -97,7 +147,7 @@ impl PA {
|
|||
/*
|
||||
// XXX async wait and handle error
|
||||
pub fn set_default_sink(&mut self, name: &str) {
|
||||
self.context.set_default_sink(name, |_| {});
|
||||
self.0.context.set_default_sink(name, |_| {});
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
@ -105,8 +155,7 @@ impl PA {
|
|||
let (sender, receiver) = oneshot::channel();
|
||||
let mut sender = Some(sender);
|
||||
let mut items = Some(Vec::new());
|
||||
self.context
|
||||
.introspect()
|
||||
self.introspect()
|
||||
.get_source_info_list(move |result| match result {
|
||||
ListResult::Item(item) => items.as_mut().unwrap().push(DeviceInfo {
|
||||
name: item.name.clone().map(|x| x.into_owned()),
|
||||
|
|
@ -133,8 +182,7 @@ impl PA {
|
|||
let (sender, receiver) = oneshot::channel();
|
||||
let mut sender = Some(sender);
|
||||
let mut source = None;
|
||||
self.context
|
||||
.introspect()
|
||||
self.introspect()
|
||||
.get_source_info_by_name(&name, move |result| match result {
|
||||
ListResult::Item(item) => {
|
||||
source = Some(DeviceInfo {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue