use super::{ConnectionHandle, ConnectionScope, GenericSignal, Priority};
use crate::compat::HashMap;
use crate::compat::Mutex;
pub struct CustomSignalHub {
signals: Mutex<HashMap<String, GenericSignal>>,
}
impl CustomSignalHub {
pub fn new() -> Self {
Self { signals: Mutex::new(HashMap::new()) }
}
pub fn define(&self, name: impl Into<String>) {
self.signals.lock().unwrap_or_else(|e| e.into_inner()).entry(name.into()).or_default();
}
pub fn emit(&self, name: &str) {
if let Some(signal) = self.signals.lock().unwrap_or_else(|e| e.into_inner()).get(name) {
signal.emit();
}
}
pub fn connect<F>(&self, name: impl Into<String>, slot: F) -> ConnectionHandle
where
F: FnMut() + Send + Sync + 'static,
{
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.entry(name.into())
.or_default()
.connect(slot)
}
pub fn disconnect(&self, name: &str, handle: ConnectionHandle) -> bool {
let signals = self.signals.lock().unwrap_or_else(|e| e.into_inner());
if let Some(signal) = signals.get(name) {
signal.disconnect(handle)
} else {
false
}
}
pub fn disconnect_all(&self, name: &str) {
if let Some(signal) = self.signals.lock().unwrap_or_else(|e| e.into_inner()).get(name) {
signal.disconnect_all();
}
}
pub fn remove(&self, name: &str) -> bool {
self.signals.lock().unwrap_or_else(|e| e.into_inner()).remove(name).is_some()
}
pub fn contains(&self, name: &str) -> bool {
self.signals.lock().unwrap_or_else(|e| e.into_inner()).contains_key(name)
}
pub fn signal_count(&self) -> usize {
self.signals.lock().unwrap_or_else(|e| e.into_inner()).len()
}
pub fn is_empty(&self) -> bool {
self.signals.lock().unwrap_or_else(|e| e.into_inner()).is_empty()
}
pub fn clear(&self) {
self.signals.lock().unwrap_or_else(|e| e.into_inner()).clear();
}
pub fn block(&self, name: &str, handle: ConnectionHandle) -> bool {
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(name)
.map(|s| s.block(handle))
.unwrap_or(false)
}
pub fn unblock(&self, name: &str, handle: ConnectionHandle) -> bool {
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(name)
.map(|s| s.unblock(handle))
.unwrap_or(false)
}
pub fn is_blocked(&self, name: &str, handle: ConnectionHandle) -> Option<bool> {
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(name)
.and_then(|s| s.is_blocked(handle))
}
pub fn set_priority(&self, name: &str, handle: ConnectionHandle, priority: Priority) -> bool {
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(name)
.map(|s| s.set_priority(handle, priority))
.unwrap_or(false)
}
pub fn connect_once<F>(&self, name: impl Into<String>, slot: F) -> ConnectionHandle
where
F: FnMut() + Send + Sync + 'static,
{
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.entry(name.into())
.or_default()
.connect_once(slot)
}
pub fn connect_with_priority<F>(
&self,
name: impl Into<String>,
slot: F,
priority: Priority,
) -> ConnectionHandle
where
F: FnMut() + Send + Sync + 'static,
{
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.entry(name.into())
.or_default()
.connect_with_priority(slot, priority)
}
pub fn connect_scoped<F>(
&self,
name: impl Into<String>,
owner: &ConnectionScope,
slot: F,
) -> ConnectionHandle
where
F: FnMut() + Send + Sync + 'static,
{
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.entry(name.into())
.or_default()
.connect_scoped(owner, slot)
}
pub fn connect_once_scoped<F>(
&self,
name: impl Into<String>,
owner: &ConnectionScope,
slot: F,
) -> ConnectionHandle
where
F: FnMut() + Send + Sync + 'static,
{
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.entry(name.into())
.or_default()
.connect_once_scoped(owner, slot)
}
pub fn slot_count(&self, name: &str) -> usize {
self.signals
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(name)
.map(|s| s.slot_count())
.unwrap_or(0)
}
}
impl Default for CustomSignalHub {
fn default() -> Self {
Self::new()
}
}