소스 검색

fix widgets in tui

Evan Almloff 2 년 전
부모
커밋
db04550fc8
5개의 변경된 파일73개의 추가작업 그리고 51개의 파일을 삭제
  1. 0 9
      packages/native-core/src/lib.rs
  2. 17 12
      packages/tui/examples/driven.rs
  3. 20 12
      packages/tui/src/dioxus.rs
  4. 32 16
      packages/tui/src/lib.rs
  5. 4 2
      packages/tui/src/query.rs

+ 0 - 9
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<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
 pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>;
 pub type SendAnyMap = anymap::Map<dyn Any + Send + Sync + 'static>;
-
-pub trait Renderer<E, V: FromAnyValue + Send + Sync = ()> {
-    fn render(&mut self, root: NodeMut<V>);
-    fn handle_event(&mut self, node: NodeMut<V>, event: &str, value: E, bubbles: bool);
-    fn poll_async(&mut self) -> Pin<Box<dyn Future<Output = ()> + '_>>;
-}

+ 17 - 12
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<Rc<EventData>> for Test {
-    fn render(&mut self, mut root: dioxus_native_core::NodeMut) {
+impl Renderer for Test {
+    fn render(&mut self, rdom: &Arc<RwLock<RealDom>>) {
+        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<Rc<EventData>> for Test {
 
     fn handle_event(
         &mut self,
-        node: dioxus_native_core::NodeMut<()>,
-        event: &str,
-        value: Rc<EventData>,
-        bubbles: bool,
+        rdom: &Arc<RwLock<RealDom>>,
+        id: NodeId,
+        _: &str,
+        _: Rc<EventData>,
+        _: bool,
     ) {
+        let rdom = rdom.read().unwrap();
+        let node = rdom.get(id).unwrap();
         if let Some(parent) = node.parent() {
             let child_number = parent
                 .child_ids()

+ 20 - 12
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<dioxus_hot_reload::HotReloadMsg>,
 }
 
-impl Renderer<Rc<EventData>> 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<RwLock<RealDom>>) {
         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<RwLock<RealDom>>,
+        id: NodeId,
         event: &str,
         value: Rc<EventData>,
         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);
         }

+ 32 - 16
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<R: Renderer<Rc<EventData>>>(
+pub fn render<R: Renderer>(
     cfg: Config,
     create_renderer: impl FnOnce(
         &Arc<RwLock<RealDom>>,
@@ -116,11 +119,10 @@ pub fn render<R: Renderer<Rc<EventData>>>(
     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<R: Renderer<Rc<EventData>>>(
                         })?;
                         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<R: Renderer<Rc<EventData>>>(
 
                 {
                     {
-                        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<RwLock<RealDom>>);
+    fn handle_event(
+        &mut self,
+        rdom: &Arc<RwLock<RealDom>>,
+        id: NodeId,
+        event: &str,
+        value: Rc<EventData>,
+        bubbles: bool,
+    );
+    fn poll_async(&mut self) -> Pin<Box<dyn Future<Output = ()> + '_>>;
+}

+ 4 - 2
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,
         )
     }