uniui_core 0.0.4

Basic structures like Signal and Slot for uniui_* crates familiy
Documentation
use crate::{
	Slot,
	SlotProxy,
};

/// [Signal] can be used to inform others that new data is available.
///
/// There is two generic ways to subscribe for new data notificaitons:
/// * callback - the callback (FnMut) will be triggered every time new data
/// value will be emitted,
/// * [Slot] - new data will be added to the [Slot]'s queue. The [Slot] have to
/// be pulled to obtain queued data.
#[derive(Default)]
pub struct Signal<T> {
	listeners: Vec<Box<dyn FnMut(&T)>>,
	senders: Vec<SlotProxy<T>>,
}

impl<T: 'static + Clone> Signal<T> {
	/// Creates new instance
	pub fn new() -> Signal<T> {
		return Signal {
			listeners: Vec::new(),
			senders: Vec::new(),
		};
	}

	/// Connect callback to the Signal
	pub fn connect_func<F: 'static + FnMut(&T)>(
		&mut self,
		f: F,
	) {
		self.listeners.push(Box::new(f));
	}

	/// Connect [Slot] to the Signal
	pub fn connect_slot(
		&mut self,
		slot: &dyn Slot<T>,
	) {
		self.senders.push(slot.proxy());
	}

	/// Emit signal. During the call all related callbacks will be activated and
	/// data will be pushed to [Slot]s' queues.
	pub fn emit(
		&mut self,
		t: T,
	) {
		self.listeners.iter_mut().for_each(|l| {
			l.as_mut()(&t);
		});

		self.senders.iter().for_each(|s| {
			match s.exec_for(t.clone()) {
				true => trace!("sended to slot"),
				false => warn!("send to slot err"),
			}
		});
	}

	/// Shows if signal connected to any callback and/or [Slot].
	pub fn has_connections(&self) -> bool {
		return (self.listeners.len() + self.senders.len()) > 0;
	}
}