lib.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. pub mod prelude;
  2. pub mod widgets;
  3. use std::{
  4. ops::Deref,
  5. rc::Rc,
  6. sync::{Arc, RwLock},
  7. };
  8. use dioxus_core::{Component, ElementId, VirtualDom};
  9. use dioxus_html::EventData;
  10. use dioxus_native_core::dioxus::{DioxusState, NodeImmutableDioxusExt};
  11. use dioxus_native_core::prelude::*;
  12. pub use rink::{query::Query, Config, RenderingMode, Size, TuiContext};
  13. use rink::{render, Driver};
  14. pub fn launch(app: Component<()>) {
  15. launch_cfg(app, Config::default())
  16. }
  17. pub fn launch_cfg(app: Component<()>, cfg: Config) {
  18. launch_cfg_with_props(app, (), cfg);
  19. }
  20. pub fn launch_cfg_with_props<Props: 'static>(app: Component<Props>, props: Props, cfg: Config) {
  21. render(cfg, |rdom, taffy, event_tx| {
  22. let dioxus_state = {
  23. let mut rdom = rdom.write().unwrap();
  24. DioxusState::create(&mut rdom)
  25. };
  26. let dioxus_state = Rc::new(RwLock::new(dioxus_state));
  27. let mut vdom = VirtualDom::new_with_props(app, props)
  28. .with_root_context(TuiContext::new(event_tx))
  29. .with_root_context(Query::new(rdom.clone(), taffy.clone()))
  30. .with_root_context(DioxusElementToNodeId {
  31. mapping: dioxus_state.clone(),
  32. });
  33. let muts = vdom.rebuild();
  34. let mut rdom = rdom.write().unwrap();
  35. dioxus_state
  36. .write()
  37. .unwrap()
  38. .apply_mutations(&mut rdom, muts);
  39. DioxusRenderer {
  40. vdom,
  41. dioxus_state,
  42. #[cfg(all(feature = "hot-reload", debug_assertions))]
  43. hot_reload_rx: {
  44. let (hot_reload_tx, hot_reload_rx) =
  45. tokio::sync::mpsc::unbounded_channel::<dioxus_hot_reload::HotReloadMsg>();
  46. dioxus_hot_reload::connect(move |msg| {
  47. let _ = hot_reload_tx.send(msg);
  48. });
  49. hot_reload_rx
  50. },
  51. }
  52. })
  53. .unwrap();
  54. }
  55. struct DioxusRenderer {
  56. vdom: VirtualDom,
  57. dioxus_state: Rc<RwLock<DioxusState>>,
  58. #[cfg(all(feature = "hot-reload", debug_assertions))]
  59. hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>,
  60. }
  61. impl Driver for DioxusRenderer {
  62. fn update(&mut self, rdom: &Arc<RwLock<RealDom>>) {
  63. let muts = self.vdom.render_immediate();
  64. {
  65. let mut rdom = rdom.write().unwrap();
  66. self.dioxus_state
  67. .write()
  68. .unwrap()
  69. .apply_mutations(&mut rdom, muts);
  70. }
  71. }
  72. fn handle_event(
  73. &mut self,
  74. rdom: &Arc<RwLock<RealDom>>,
  75. id: NodeId,
  76. event: &str,
  77. value: Rc<EventData>,
  78. bubbles: bool,
  79. ) {
  80. let id = { rdom.read().unwrap().get(id).unwrap().mounted_id() };
  81. if let Some(id) = id {
  82. self.vdom
  83. .handle_event(event, value.deref().clone().into_any(), id, bubbles);
  84. }
  85. }
  86. fn poll_async(&mut self) -> std::pin::Pin<Box<dyn futures::Future<Output = ()> + '_>> {
  87. #[cfg(all(feature = "hot-reload", debug_assertions))]
  88. return Box::pin(async {
  89. let hot_reload_wait = self.hot_reload_rx.recv();
  90. let mut hot_reload_msg = None;
  91. let wait_for_work = self.vdom.wait_for_work();
  92. tokio::select! {
  93. Some(msg) = hot_reload_wait => {
  94. #[cfg(all(feature = "hot-reload", debug_assertions))]
  95. {
  96. hot_reload_msg = Some(msg);
  97. }
  98. #[cfg(not(all(feature = "hot-reload", debug_assertions)))]
  99. let () = msg;
  100. }
  101. _ = wait_for_work => {}
  102. }
  103. // if we have a new template, replace the old one
  104. if let Some(msg) = hot_reload_msg {
  105. match msg {
  106. dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
  107. self.vdom.replace_template(template);
  108. }
  109. dioxus_hot_reload::HotReloadMsg::Shutdown => {
  110. std::process::exit(0);
  111. }
  112. }
  113. }
  114. });
  115. #[cfg(not(all(feature = "hot-reload", debug_assertions)))]
  116. Box::pin(self.vdom.wait_for_work())
  117. }
  118. }
  119. #[derive(Clone)]
  120. pub struct DioxusElementToNodeId {
  121. mapping: Rc<RwLock<DioxusState>>,
  122. }
  123. impl DioxusElementToNodeId {
  124. pub fn get_node_id(&self, element_id: ElementId) -> Option<NodeId> {
  125. self.mapping
  126. .read()
  127. .unwrap()
  128. .try_element_to_node_id(element_id)
  129. }
  130. }