1
0

util.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. use std::{
  2. cell::{RefCell, RefMut},
  3. rc::Rc,
  4. vec::Drain,
  5. };
  6. use futures_util::StreamExt;
  7. use crate::innerlude::*;
  8. #[derive(PartialEq, Debug, Clone, Default)]
  9. pub struct EventQueue {
  10. pub queue: Rc<RefCell<Vec<HeightMarker>>>,
  11. }
  12. impl EventQueue {
  13. pub fn new_channel(&self, height: u32, idx: ScopeIdx) -> Rc<dyn Fn()> {
  14. let inner = self.clone();
  15. let marker = HeightMarker { height, idx };
  16. Rc::new(move || {
  17. log::debug!("channel updated {:#?}", marker);
  18. inner.queue.as_ref().borrow_mut().push(marker)
  19. })
  20. }
  21. pub fn sort_unstable(&self) {
  22. self.queue.borrow_mut().sort_unstable()
  23. }
  24. pub fn borrow_mut(&self) -> RefMut<Vec<HeightMarker>> {
  25. self.queue.borrow_mut()
  26. }
  27. }
  28. /// A helper type that lets scopes be ordered by their height
  29. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  30. pub struct HeightMarker {
  31. pub idx: ScopeIdx,
  32. pub height: u32,
  33. }
  34. impl Ord for HeightMarker {
  35. fn cmp(&self, other: &Self) -> std::cmp::Ordering {
  36. self.height.cmp(&other.height)
  37. }
  38. }
  39. impl PartialOrd for HeightMarker {
  40. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  41. Some(self.cmp(other))
  42. }
  43. }
  44. /// The `RealDomNode` is an ID handle that corresponds to a foreign DOM node.
  45. ///
  46. /// "u64" was chosen for two reasons
  47. /// - 0 cost hashing
  48. /// - use with slotmap and other versioned slot arenas
  49. #[derive(Clone, Copy, Debug, PartialEq)]
  50. pub struct RealDomNode(pub u64);
  51. impl RealDomNode {
  52. pub fn new(id: u64) -> Self {
  53. Self(id)
  54. }
  55. pub const fn empty() -> Self {
  56. Self(u64::MIN)
  57. }
  58. }
  59. pub struct DebugDom {
  60. counter: u64,
  61. logging: bool,
  62. }
  63. impl DebugDom {
  64. pub fn new() -> Self {
  65. Self {
  66. counter: 0,
  67. logging: false,
  68. }
  69. }
  70. pub fn with_logging_enabled() -> Self {
  71. Self {
  72. counter: 0,
  73. logging: true,
  74. }
  75. }
  76. }
  77. impl<'a> RealDom<'a> for DebugDom {
  78. fn push(&mut self, root: RealDomNode) {}
  79. fn pop(&mut self) {}
  80. fn append_children(&mut self, many: u32) {}
  81. fn replace_with(&mut self, many: u32) {}
  82. fn remove(&mut self) {}
  83. fn remove_all_children(&mut self) {}
  84. fn create_text_node(&mut self, text: &str) -> RealDomNode {
  85. self.counter += 1;
  86. RealDomNode::new(self.counter)
  87. }
  88. fn create_element(&mut self, tag: &str, ns: Option<&'a str>) -> RealDomNode {
  89. self.counter += 1;
  90. RealDomNode::new(self.counter)
  91. }
  92. fn create_placeholder(&mut self) -> RealDomNode {
  93. self.counter += 1;
  94. RealDomNode::new(self.counter)
  95. }
  96. fn new_event_listener(
  97. &mut self,
  98. event: &str,
  99. scope: ScopeIdx,
  100. element_id: usize,
  101. realnode: RealDomNode,
  102. ) {
  103. }
  104. fn remove_event_listener(&mut self, event: &str) {}
  105. fn set_text(&mut self, text: &str) {}
  106. fn set_attribute(&mut self, name: &str, value: &str, namespace: Option<&str>) {}
  107. fn remove_attribute(&mut self, name: &str) {}
  108. fn raw_node_as_any_mut(&self) -> &mut dyn std::any::Any {
  109. todo!()
  110. }
  111. }
  112. async fn launch_demo(app: FC<()>) {
  113. let mut dom = VirtualDom::new(app);
  114. let mut real_dom = DebugDom::new();
  115. dom.rebuild(&mut real_dom).unwrap();
  116. while let Some(evt) = dom.tasks.next().await {
  117. //
  118. log::debug!("Event triggered! {:#?}", evt);
  119. }
  120. }
  121. // #[cfg(test)]
  122. // mod tests {
  123. // use super::*;
  124. // use crate as dioxus;
  125. // use std::{pin::Pin, time::Duration};
  126. // use crate::builder::DioxusElement;
  127. // use dioxus::prelude::*;
  128. // use futures::Future;
  129. // #[async_std::test]
  130. // async fn async_tick() {
  131. // static App: FC<()> = |cx| {
  132. // // let mut count = use_state(cx, || 0);
  133. // let mut fut = cx.use_hook(
  134. // move || {
  135. // Box::pin(async {
  136. // //
  137. // let mut tick: i32 = 0;
  138. // loop {
  139. // async_std::task::sleep(Duration::from_millis(250)).await;
  140. // log::debug!("ticking forward... {}", tick);
  141. // tick += 1;
  142. // // match surf::get(ENDPOINT).recv_json::<DogApi>().await {
  143. // // Ok(_) => (),
  144. // // Err(_) => (),
  145. // // }
  146. // }
  147. // }) as Pin<Box<dyn Future<Output = ()> + 'static>>
  148. // },
  149. // |h| h,
  150. // |_| {},
  151. // );
  152. // cx.submit_task(fut);
  153. // cx.render(LazyNodes::new(move |f| {
  154. // f.text(format_args!("it's sorta working"))
  155. // }))
  156. // };
  157. // std::env::set_var("RUST_LOG", "debug");
  158. // env_logger::init();
  159. // launch_demo(App).await;
  160. // }
  161. // }