diff --git a/packages/native-core/src/lib.rs b/packages/native-core/src/lib.rs index 2e2ad14d8..a0e68e7ad 100644 --- a/packages/native-core/src/lib.rs +++ b/packages/native-core/src/lib.rs @@ -1,12 +1,9 @@ use std::any::Any; -use std::future::Future; use std::hash::BuildHasherDefault; -use std::pin::Pin; pub use node_ref::NodeMask; pub use passes::AnyMapLike; pub use passes::{Dependancy, Pass, TypeErasedPass}; -use prelude::FromAnyValue; pub use real_dom::{NodeMut, NodeRef, RealDom}; use rustc_hash::FxHasher; pub use tree::NodeId; @@ -34,9 +31,3 @@ pub mod prelude { pub type FxDashMap = dashmap::DashMap>; pub type FxDashSet = dashmap::DashSet>; pub type SendAnyMap = anymap::Map; - -pub trait Renderer { - fn render(&mut self, root: NodeMut); - fn handle_event(&mut self, node: NodeMut, event: &str, value: E, bubbles: bool); - fn poll_async(&mut self) -> Pin + '_>>; -} diff --git a/packages/tui/examples/driven.rs b/packages/tui/examples/driven.rs index 11ff7a6a8..1a258c3f6 100644 --- a/packages/tui/examples/driven.rs +++ b/packages/tui/examples/driven.rs @@ -2,14 +2,13 @@ use dioxus_html::EventData; use dioxus_native_core::{ node::{OwnedAttributeDiscription, OwnedAttributeValue, TextNode}, prelude::*, - real_dom::{ElementNodeMut, NodeImmutable, NodeTypeMut}, - NodeId, Renderer, + real_dom::{NodeImmutable, NodeTypeMut}, + NodeId, }; -use dioxus_tui::{self, render, Config}; +use dioxus_tui::{self, render, Config, Renderer}; use rustc_hash::FxHashSet; +use std::rc::Rc; use std::sync::{Arc, RwLock}; -use std::{rc::Rc, sync::Mutex}; -use taffy::Taffy; const SIZE: usize = 10; @@ -184,11 +183,14 @@ impl Test { } } -impl Renderer> for Test { - fn render(&mut self, mut root: dioxus_native_core::NodeMut) { +impl Renderer for Test { + fn render(&mut self, rdom: &Arc>) { + let mut rdom = rdom.write().unwrap(); + let root_id = rdom.root_id(); + let mut root = rdom.get_mut(root_id).unwrap(); for (x, y) in self.dirty.drain() { let row_id = root.child_ids().unwrap()[x]; - let mut rdom = root.real_dom_mut(); + let rdom = root.real_dom_mut(); let row = rdom.get(row_id).unwrap(); let node_id = row.child_ids().unwrap()[y]; let mut node = rdom.get_mut(node_id).unwrap(); @@ -216,11 +218,14 @@ impl Renderer> for Test { fn handle_event( &mut self, - node: dioxus_native_core::NodeMut<()>, - event: &str, - value: Rc, - bubbles: bool, + rdom: &Arc>, + id: NodeId, + _: &str, + _: Rc, + _: bool, ) { + let rdom = rdom.read().unwrap(); + let node = rdom.get(id).unwrap(); if let Some(parent) = node.parent() { let child_number = parent .child_ids() diff --git a/packages/tui/src/dioxus.rs b/packages/tui/src/dioxus.rs index 8c58d35bf..da83ce799 100644 --- a/packages/tui/src/dioxus.rs +++ b/packages/tui/src/dioxus.rs @@ -1,13 +1,17 @@ -use std::{ops::Deref, rc::Rc, sync::RwLock}; +use std::{ + ops::Deref, + rc::Rc, + sync::{Arc, RwLock}, +}; use dioxus_core::{Component, ElementId, VirtualDom}; use dioxus_html::EventData; use dioxus_native_core::{ dioxus::{DioxusState, NodeImmutableDioxusExt}, - NodeId, Renderer, + NodeId, RealDom, }; -use crate::{query::Query, render, Config, TuiContext}; +use crate::{query::Query, render, Config, Renderer, TuiContext}; pub fn launch(app: Component<()>) { launch_cfg(app, Config::default()) @@ -57,24 +61,28 @@ struct DioxusRenderer { hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver, } -impl Renderer> for DioxusRenderer { - fn render(&mut self, mut root: dioxus_native_core::NodeMut<()>) { - let rdom = root.real_dom_mut(); +impl Renderer for DioxusRenderer { + fn render(&mut self, rdom: &Arc>) { let muts = self.vdom.render_immediate(); - self.dioxus_state - .write() - .unwrap() - .apply_mutations(rdom, muts); + { + let mut rdom = rdom.write().unwrap(); + self.dioxus_state + .write() + .unwrap() + .apply_mutations(&mut rdom, muts); + } } fn handle_event( &mut self, - node: dioxus_native_core::NodeMut<()>, + rdom: &Arc>, + id: NodeId, event: &str, value: Rc, bubbles: bool, ) { - if let Some(id) = node.mounted_id() { + let id = { rdom.read().unwrap().get(id).unwrap().mounted_id() }; + if let Some(id) = id { self.vdom .handle_event(event, value.deref().clone().into_any(), id, bubbles); } diff --git a/packages/tui/src/lib.rs b/packages/tui/src/lib.rs index 49b4d3555..815264241 100644 --- a/packages/tui/src/lib.rs +++ b/packages/tui/src/lib.rs @@ -7,15 +7,18 @@ use crossterm::{ terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use dioxus_html::EventData; -use dioxus_native_core::{node_ref::NodeMaskBuilder, real_dom::NodeImmutable, Pass, Renderer}; +use dioxus_native_core::{node_ref::NodeMaskBuilder, real_dom::NodeImmutable, Pass}; use dioxus_native_core::{real_dom::RealDom, FxDashSet, NodeId, SendAnyMap}; use focus::FocusState; -use futures::{channel::mpsc::UnboundedSender, pin_mut, StreamExt}; +use futures::{channel::mpsc::UnboundedSender, pin_mut, Future, StreamExt}; use futures_channel::mpsc::unbounded; use layout::TaffyLayout; use prevent_default::PreventDefault; -use std::sync::{Arc, Mutex}; use std::{io, time::Duration}; +use std::{ + pin::Pin, + sync::{Arc, Mutex}, +}; use std::{rc::Rc, sync::RwLock}; use style_attributes::StyleModifier; use taffy::Taffy; @@ -77,7 +80,7 @@ impl TuiContext { } } -pub fn render>>( +pub fn render( cfg: Config, create_renderer: impl FnOnce( &Arc>, @@ -116,11 +119,10 @@ pub fn render>>( let mut renderer = create_renderer(&rdom, &taffy, event_tx_clone); { - let mut rdom = rdom.write().unwrap(); - let root_id = rdom.root_id(); - renderer.render(rdom.get_mut(root_id).unwrap()); + renderer.render(&rdom); let mut any_map = SendAnyMap::new(); any_map.insert(taffy.clone()); + let mut rdom = rdom.write().unwrap(); let _ = rdom.update_state(any_map, false); } @@ -201,7 +203,7 @@ pub fn render>>( })?; execute!(terminal.backend_mut(), RestorePosition, Show).unwrap(); } else { - let rdom = rdom.write().unwrap(); + let rdom = rdom.read().unwrap(); resize( Rect { x: 0, @@ -250,21 +252,22 @@ pub fn render>>( { { - let mut rdom = rdom.write().unwrap(); - let evts = handler - .get_events(&taffy.lock().expect("taffy lock poisoned"), &mut rdom); + let evts = { + handler.get_events( + &taffy.lock().expect("taffy lock poisoned"), + &mut rdom.write().unwrap(), + ) + }; updated |= handler.state().focus_state.clean(); for e in evts { - let node = rdom.get_mut(e.id).unwrap(); - renderer.handle_event(node, e.name, e.data, e.bubbles); + renderer.handle_event(&rdom, e.id, e.name, e.data, e.bubbles); } } - let mut rdom = rdom.write().unwrap(); // updates the dom's nodes - let root_id = rdom.root_id(); - renderer.render(rdom.get_mut(root_id).unwrap()); + renderer.render(&rdom); // update the style and layout + let mut rdom = rdom.write().unwrap(); let mut any_map = SendAnyMap::new(); any_map.insert(taffy.clone()); let (new_to_rerender, dirty) = rdom.update_state(any_map, false); @@ -297,3 +300,16 @@ pub enum InputEvent { UserInput(TermEvent), Close, } + +pub trait Renderer { + fn render(&mut self, rdom: &Arc>); + fn handle_event( + &mut self, + rdom: &Arc>, + id: NodeId, + event: &str, + value: Rc, + bubbles: bool, + ); + fn poll_async(&mut self) -> Pin + '_>>; +} diff --git a/packages/tui/src/query.rs b/packages/tui/src/query.rs index 40606e743..3a11d0f2d 100644 --- a/packages/tui/src/query.rs +++ b/packages/tui/src/query.rs @@ -48,9 +48,11 @@ pub struct Query { impl Query { pub fn get(&self, id: NodeId) -> ElementRef { + let rdom = self.rdom.read(); + let stretch = self.stretch.lock(); ElementRef::new( - self.rdom.read().expect("rdom lock poisoned"), - self.stretch.lock().expect("taffy lock poisoned"), + rdom.expect("rdom lock poisoned"), + stretch.expect("taffy lock poisoned"), id, ) }