use std::sync::{Arc, Mutex, RwLock};
use bitflags::bitflags;
use pipewire_native_spa as spa;
use crate::{
core::Core,
new_refcounted,
properties::Properties,
proxy::{HasProxy, Proxy},
refcounted, types, HookId, Id,
};
refcounted! {
pub struct Module {
proxy: RwLock<Option<Proxy<Module>>>,
hooks: Arc<Mutex<spa::hook::HookList<ModuleEvents>>>,
}
}
bitflags! {
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ModuleChangeMask : u32 {
const PROPS = (1 << 0);
}
}
pub struct ModuleInfo<'a> {
pub id: Id,
pub name: &'a str,
pub file_name: &'a str,
pub args: Option<&'a str>,
pub mask: ModuleChangeMask,
pub props: &'a Properties,
}
#[allow(clippy::type_complexity)]
#[derive(Default)]
pub struct ModuleEvents {
pub info: Option<Box<dyn FnMut(&ModuleInfo<'_>) + Send>>,
}
impl HasProxy for Module {
fn type_(&self) -> types::ObjectType {
types::interface::MODULE
}
fn version(&self) -> u32 {
3
}
fn proxy(&self) -> Proxy<Self> {
self.inner
.proxy
.read()
.unwrap()
.as_ref()
.expect("Module proxy should be initialised on creation")
.clone()
}
}
impl Module {
pub(crate) fn new(core: &Core) -> Self {
let this = Self {
inner: new_refcounted(InnerModule::new()),
};
let id = core.next_proxy_id();
this.inner
.proxy
.write()
.unwrap()
.replace(Proxy::new(id, &this));
core.add_proxy(&this, id);
this
}
pub fn add_listener(&self, events: ModuleEvents) -> HookId {
self.inner.hooks.lock().unwrap().append(events)
}
pub fn remove_listener(&self, hook_id: HookId) {
self.inner.hooks.lock().unwrap().remove(hook_id);
}
pub(crate) fn events(&self) -> Arc<Mutex<spa::hook::HookList<ModuleEvents>>> {
self.inner.hooks.clone()
}
}
impl InnerModule {
fn new() -> Self {
Self {
proxy: RwLock::new(None),
hooks: spa::hook::HookList::new(),
}
}
}