signal.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. use std::rc::{self};
  2. use std::cell::{RefCell};
  3. use std::any::{Any};
  4. use std::marker::{PhantomData};
  5. use weak_table::{PtrWeakKeyHashMap as WeakMap};
  6. //////////////////////////////////////////////////////////////////////////////////////////
  7. // Traits
  8. /// Event that produces event argument of type A when fired.
  9. pub trait Evt<A: ?Sized> {
  10. fn bind<S>(&self, sink: S) where S: Sink<A>;
  11. }
  12. /// Sink that may respond to events of type A.
  13. pub trait Sink<A: ?Sized> {
  14. fn bind_to_src(self, src: EvtSrc<A>);
  15. fn bind_to<E>(self, evt: &E) where E: Evt<A>, Self: Sized
  16. { evt.bind(self) }
  17. }
  18. pub trait Callback<T, A: ?Sized>: 'static {
  19. fn call(&mut self, state: &mut T, arg: &A);
  20. }
  21. //////////////////////////////////////////////////////////////////////////////////////////
  22. // EvtSrc
  23. /// Source of events with event arguments type A.
  24. pub struct EvtSrc<A: ?Sized>(PhantomData<A>, rc::Rc<()>);
  25. impl<A: ?Sized> EvtSrc<A> {
  26. /// Create a new event source.
  27. pub fn new() -> Self {
  28. EvtSrc(PhantomData, rc::Rc::new(()))
  29. }
  30. pub fn id(&self) -> &rc::Rc<()> { &self.1 }
  31. pub fn into_id(self) -> rc::Rc<()> { self.1 }
  32. }
  33. impl<A> Evt<A> for EvtSrc<A> {
  34. fn bind<S>(&self, sink: S) where S: Sink<A> {
  35. sink.bind_to_src(EvtSrc::clone(self))
  36. }
  37. }
  38. impl<A> Clone for EvtSrc<A> {
  39. fn clone(&self) -> Self {
  40. EvtSrc(PhantomData, rc::Rc::clone(&self.1))
  41. }
  42. }
  43. impl<A> PartialEq for EvtSrc<A> {
  44. fn eq(&self, _: &Self) -> bool { true }
  45. }
  46. impl<A> Eq for EvtSrc<A> {}
  47. //////////////////////////////////////////////////////////////////////////////////////////
  48. struct DynCallback<T, A: ?Sized>(rc::Rc<RefCell<dyn Callback<T, A>>>);
  49. // invariant:
  50. // all RHS bindings to this map should be type Callback<T, A> for some A
  51. type InternalCallbackMap =
  52. rc::Rc<RefCell<WeakMap<rc::Weak<()>, Vec<Box<dyn Any>>>>>; // yikes
  53. pub struct CallbackMap<T: 'static> {
  54. phantom: PhantomData<T>,
  55. map: InternalCallbackMap,
  56. }
  57. pub struct Dispatcher<'s, T: 'static> {
  58. state: &'s mut T,
  59. map: InternalCallbackMap,
  60. }
  61. pub struct Registrar<T: 'static> {
  62. phantom: PhantomData<T>,
  63. map: InternalCallbackMap,
  64. }
  65. //
  66. impl<T, A: ?Sized> DynCallback<T, A> {
  67. fn new<C>(cb: C) -> Self where C: Callback<T, A> {
  68. DynCallback(rc::Rc::new(RefCell::new(cb)))
  69. }
  70. }
  71. impl<T, A: ?Sized> Clone for DynCallback<T, A> {
  72. fn clone(&self) -> Self {
  73. DynCallback(self.0.clone())
  74. }
  75. }
  76. impl<T> CallbackMap<T> {
  77. /// Create a new Dispatcher with given initial state and no bound callbacks.
  78. pub fn new() -> Self {
  79. CallbackMap {
  80. phantom: PhantomData,
  81. map: rc::Rc::new(RefCell::new(WeakMap::new())),
  82. }
  83. }
  84. pub fn dispatcher<'s>(&mut self, state: &'s mut T) -> Dispatcher<'s, T> {
  85. Dispatcher { state, map: self.map.clone() }
  86. }
  87. pub fn registrar(&mut self) -> Registrar<T> {
  88. Registrar { phantom: PhantomData, map: self.map.clone() }
  89. }
  90. }
  91. impl<'s, T> Dispatcher<'s, T> {
  92. /// Fire a given event (source) with given event args passed to each callback.
  93. pub fn fire<A: ?Sized>(&mut self, evt: &EvtSrc<A>, arg: &A)
  94. where A: 'static {
  95. let Dispatcher { state, map } = self;
  96. let callbacks: Vec<DynCallback<_, _>> =
  97. map.borrow_mut()
  98. .get_mut(evt.id())
  99. .into_iter()
  100. .flat_map(|rhs| rhs.iter_mut())
  101. .flat_map(|erased| erased.downcast_mut::<DynCallback<T, A>>().cloned())
  102. .collect();
  103. for cb in callbacks {
  104. cb.0.borrow_mut().call(state, arg);
  105. }
  106. }
  107. }
  108. impl<T> Registrar<T> {
  109. /// Create a `Sink<A>` from a callback. The callback can mutate the internal state
  110. /// of the listener.
  111. pub fn sink_from_callback<A, C>(&self, callback: C) -> impl Sink<A>
  112. where A: ?Sized + 'static,
  113. C: Callback<T, A> {
  114. CallbackSink { phantom: PhantomData, map: self.map.clone(), callback }
  115. }
  116. }
  117. struct CallbackSink<T, C> {
  118. phantom: PhantomData<fn(&mut T)>,
  119. map: InternalCallbackMap,
  120. callback: C,
  121. }
  122. impl<T, A, C> Sink<A> for CallbackSink<T, C>
  123. where T: 'static,
  124. A: ?Sized + 'static,
  125. C: Callback<T, A> + 'static {
  126. fn bind_to_src(self, src: EvtSrc<A>) {
  127. bind(self.map, src, self.callback)
  128. }
  129. }
  130. fn bind<T, A, C>(map: InternalCallbackMap, src: EvtSrc<A>, cb: C)
  131. where T: 'static,
  132. A: ?Sized + 'static,
  133. C: Callback<T, A> {
  134. map.borrow_mut()
  135. .entry(src.into_id())
  136. .or_insert_with(Vec::new)
  137. .push(Box::new(DynCallback::new(cb)));
  138. }
  139. //////////////////////////////////////////////////////////////////////////////////////////
  140. #[cfg(test)]
  141. mod test {
  142. use super::*;
  143. use std::mem::{size_of};
  144. #[test]
  145. fn test_static_sizes() {
  146. let ptr_size = size_of::<*const i32>();
  147. assert_eq!(size_of::<EvtSrc<()>>(), ptr_size);
  148. assert_eq!(size_of::<Option<EvtSrc<()>>>(), ptr_size);
  149. }
  150. #[test]
  151. fn test_listener_callback() {
  152. let mut dsp = Dispatcher::new(vec![]);
  153. let evt = EvtSrc::new();
  154. dsp.callback(|state, &arg| state.push(arg))
  155. .bind_to(&evt);
  156. dsp.fire(&evt, 1);
  157. dsp.fire(&evt, 2);
  158. dsp.fire(&evt, 3);
  159. assert_eq!(dsp.state(), &[1, 2, 3])
  160. }
  161. #[test]
  162. fn test_listener_heterog() {
  163. let mut dsp = Dispatcher::new(String::from(""));
  164. let evt1 = EvtSrc::new();
  165. let evt2 = EvtSrc::new();
  166. dsp.callback(|s, &arg| s.push_str(arg))
  167. .bind_to(&evt1);
  168. dsp.callback(|s, &arg| s.push_str(&format!("[{:?}]", arg)))
  169. .bind_to(&evt2);
  170. dsp.fire(&evt1, "hi");
  171. dsp.fire(&evt2, 5);
  172. dsp.fire(&evt1, "world");
  173. assert_eq!(dsp.state(), "hi[5]world");
  174. }
  175. }