dioxus_application.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. use blitz_renderer_vello::BlitzVelloRenderer;
  2. use blitz_shell::{BlitzApplication, View};
  3. use dioxus_core::{ScopeId, VirtualDom};
  4. use dioxus_history::{History, MemoryHistory};
  5. use std::{
  6. cell::RefCell,
  7. collections::{HashMap, HashSet},
  8. rc::Rc,
  9. };
  10. use winit::application::ApplicationHandler;
  11. use winit::event::{StartCause, WindowEvent};
  12. use winit::event_loop::{ActiveEventLoop, EventLoopProxy};
  13. use winit::window::WindowId;
  14. use crate::{
  15. assets::DioxusNativeNetProvider, contexts::NativeDocument, mutation_writer::MutationWriter,
  16. BlitzShellEvent, DioxusDocument, DioxusNativeEvent, SharedNativeTexture, WindowConfig,
  17. };
  18. pub struct DioxusNativeApplication {
  19. pending_vdom: Option<VirtualDom>,
  20. // inner: BlitzApplication<DioxusDocument, BlitzVelloRenderer>,
  21. pub windows: HashMap<WindowId, View<DioxusDocument, BlitzVelloRenderer>>,
  22. proxy: EventLoopProxy<BlitzShellEvent>,
  23. }
  24. pub struct DioxusNativeWindow {}
  25. impl DioxusNativeApplication {
  26. pub fn new(proxy: EventLoopProxy<BlitzShellEvent>, vdom: VirtualDom) -> Self {
  27. Self {
  28. pending_vdom: Some(vdom),
  29. windows: HashMap::new(),
  30. proxy,
  31. // inner: BlitzApplication::new(proxy.clone()),
  32. }
  33. }
  34. fn handle_blitz_shell_event(
  35. &mut self,
  36. event_loop: &ActiveEventLoop,
  37. event: &DioxusNativeEvent,
  38. ) {
  39. match event {
  40. #[cfg(all(
  41. feature = "hot-reload",
  42. debug_assertions,
  43. not(target_os = "android"),
  44. not(target_os = "ios")
  45. ))]
  46. DioxusNativeEvent::DevserverEvent(event) => match event {
  47. dioxus_devtools::DevserverMsg::HotReload(hotreload_message) => {
  48. for window in self.windows.values_mut() {
  49. dioxus_devtools::apply_changes(&window.doc.vdom, hotreload_message);
  50. window.poll();
  51. }
  52. }
  53. dioxus_devtools::DevserverMsg::Shutdown => event_loop.exit(),
  54. dioxus_devtools::DevserverMsg::FullReloadStart => {}
  55. dioxus_devtools::DevserverMsg::FullReloadFailed => {}
  56. dioxus_devtools::DevserverMsg::FullReloadCommand => {}
  57. },
  58. DioxusNativeEvent::CreateHeadElement {
  59. name,
  60. attributes,
  61. contents,
  62. window,
  63. } => {
  64. if let Some(window) = self.windows.get_mut(window) {
  65. window.doc.create_head_element(name, attributes, contents);
  66. window.poll();
  67. }
  68. }
  69. // Suppress unused variable warning
  70. #[cfg(not(all(
  71. feature = "hot-reload",
  72. debug_assertions,
  73. not(target_os = "android"),
  74. not(target_os = "ios")
  75. )))]
  76. _ => {
  77. let _ = event_loop;
  78. let _ = event;
  79. }
  80. }
  81. }
  82. }
  83. impl ApplicationHandler<BlitzShellEvent> for DioxusNativeApplication {
  84. fn resumed(&mut self, event_loop: &ActiveEventLoop) {
  85. tracing::debug!("Injecting document provider into all windows");
  86. let vdom = self.pending_vdom.take().unwrap();
  87. #[cfg(feature = "net")]
  88. let net_provider = {
  89. let proxy = self.proxy.clone();
  90. let net_provider = DioxusNativeNetProvider::shared(proxy);
  91. Some(net_provider)
  92. };
  93. #[cfg(not(feature = "net"))]
  94. let net_provider = None;
  95. // Create document + window from the baked virtualdom
  96. let doc = DioxusDocument::new(vdom, net_provider);
  97. // let window = WindowConfig::new(doc);
  98. // little hack since View::init is not public - fix this once alpha-2 is out
  99. // let old_windows = self.inner.windows.keys().copied().collect::<HashSet<_>>();
  100. // self.inner.add_window(window);
  101. // self.inner.resumed(event_loop);
  102. // let new_windows = self.inner.windows.keys().cloned().collect::<HashSet<_>>();
  103. // todo(jon): we should actually mess with the pending windows instead of passing along the contexts
  104. // for window_id in new_windows.difference(&old_windows) {
  105. // let window = self.inner.windows.get_mut(window_id).unwrap();
  106. // window.doc.vdom.in_runtime(|| {
  107. // let document = Rc::new(NativeDocument::new(
  108. // self.proxy.clone(),
  109. // *window_id,
  110. // window.renderer.clone(),
  111. // ));
  112. // let shared: Rc<dyn dioxus_document::Document> = document.clone();
  113. // ScopeId::ROOT.provide_context(document);
  114. // ScopeId::ROOT.provide_context(shared);
  115. // });
  116. // // Add history
  117. // let history_provider: Rc<dyn History> = Rc::new(MemoryHistory::default());
  118. // window
  119. // .doc
  120. // .vdom
  121. // .in_runtime(|| ScopeId::ROOT.provide_context(history_provider));
  122. // // Queue rebuild
  123. // let mut writer = MutationWriter::new(&mut window.doc.inner, &mut window.doc.vdom_state);
  124. // window.doc.vdom.rebuild(&mut writer);
  125. // drop(writer);
  126. // // And then request redraw
  127. // window.request_redraw();
  128. // }
  129. }
  130. fn suspended(&mut self, event_loop: &ActiveEventLoop) {
  131. // self.inner.suspended(event_loop);
  132. }
  133. fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) {
  134. // self.inner.new_events(event_loop, cause);
  135. }
  136. fn window_event(
  137. &mut self,
  138. event_loop: &ActiveEventLoop,
  139. window_id: WindowId,
  140. event: WindowEvent,
  141. ) {
  142. // self.inner.window_event(event_loop, window_id, event);
  143. }
  144. fn user_event(&mut self, event_loop: &ActiveEventLoop, event: BlitzShellEvent) {
  145. // match event {
  146. // BlitzShellEvent::Embedder(event) => {
  147. // if let Some(event) = event.downcast_ref::<DioxusNativeEvent>() {
  148. // self.handle_blitz_shell_event(event_loop, event);
  149. // }
  150. // }
  151. // event => self.inner.user_event(event_loop, event),
  152. // }
  153. }
  154. }