use self::{
fractional_index::{FractionalIndex, FractionalIndexType},
inner::{Action, SignalInner},
};
use super::{IntoWeak, Key, KeyCell, Meta, Rw};
use std::{borrow::Borrow, rc::Rc};
mod fractional_index;
mod inner;
#[cfg(test)]
mod tests;
type Handler<T> = dyn Fn(&mut Key, &T) -> Action;
struct Receiver<T> {
handler: Rc<Handler<T>>,
relative_index: FractionalIndexType,
id: u64,
}
trait Disconnectable {
fn disconnect(&self, key: &mut Key, id: u64, relative_index: FractionalIndexType);
}
impl<T: 'static> Disconnectable for KeyCell<SignalInner<T>> {
fn disconnect(&self, key: &mut Key, id: u64, relative_index: FractionalIndexType) {
self.rw(key).disconnect(id, relative_index);
}
}
pub struct Connection {
inner: Rc<dyn Disconnectable>,
relative_index: FractionalIndexType,
id: u64,
}
impl Connection {
pub fn disconnect(self, key: &mut Key) {
self.inner.disconnect(key, self.id, self.relative_index);
}
}
pub struct Signal<T> {
inner: Rc<KeyCell<SignalInner<T>>>,
index: FractionalIndex,
}
impl<T: 'static> Signal<T> {
pub fn new() -> Self {
Signal {
inner: Rc::new(KeyCell::new(SignalInner::new(), ())),
index: FractionalIndex::new(),
}
}
pub fn before(&self, key: &mut Key) -> Self {
if let Some(index) = self.index.left() {
Self {
inner: self.inner.clone(),
index,
}
} else {
self.subsignal_at(key, self.index.value() - 1)
}
}
pub fn after(&self, key: &mut Key) -> Self {
if let Some(index) = self.index.right() {
Self {
inner: self.inner.clone(),
index,
}
} else {
self.subsignal_at(key, self.index.value() + 1)
}
}
pub fn connect<R, I, F>(&self, key: &mut Key, receiver: &I, handler: F) -> Connection
where
R: Meta + 'static,
I: IntoWeak<R>,
F: Fn(Rw<R>, &T) + 'static,
{
let receiver = receiver.into();
let id = self
.inner
.rw(key)
.connect(receiver, self.index.value(), handler);
Connection {
inner: self.inner.clone(),
relative_index: self.index.value(),
id,
}
}
pub fn subsignal(&self, key: &mut Key) -> Self {
let index = self.index.value();
let inner = self.inner.rw(key).subsignal(index);
Self {
inner,
index: FractionalIndex::new(),
}
}
fn subsignal_at(&self, key: &mut Key, index: FractionalIndexType) -> Self {
debug_assert!(index % 2 == 1);
if let Some(subsignal) = self.inner.rw(key).preexisting_subsignal(index) {
return subsignal;
}
let inner = self.inner.rw(key).subsignal(index);
let subsignal = Self {
inner,
index: FractionalIndex::new(),
};
self.inner
.rw(key)
.register_subsignal(subsignal.clone(), index);
subsignal
}
pub fn emit<B>(&self, key: &mut Key, item: B)
where
B: Borrow<T>,
{
self.inner.rw(key).emit(item.borrow());
}
#[cfg(test)]
const fn test_ordering_depth() -> u32 {
FractionalIndexType::BITS - 1
}
#[cfg(test)]
pub fn test_subscriber_count(&self, key: &mut Key) -> usize {
self.inner.ro(key).len()
}
#[cfg(test)]
fn test_ordering_subsignal_count(&self, key: &mut Key) -> usize {
self.inner.ro(key).ordering_subsignals()
}
}
impl<T> Clone for Signal<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
index: self.index,
}
}
}
impl<T: 'static> Default for Signal<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: 'static> Eq for Signal<T> {}
impl<T: 'static> PartialEq for Signal<T> {
fn eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.inner, &other.inner) && self.index.value() == other.index.value()
}
}