Bladeren bron

fixed race condition and zero sized node rendering

Evan Almloff 3 jaren geleden
bovenliggende
commit
7df8499da7
2 gewijzigde bestanden met toevoegingen van 21 en 14 verwijderingen
  1. 13 12
      src/lib.rs
  2. 8 2
      src/render.rs

+ 13 - 12
src/lib.rs

@@ -90,10 +90,6 @@ pub fn render_vdom(vdom: &mut VirtualDom, ctx: UnboundedSender<TermEvent>) -> Re
             terminal.clear().unwrap();
 
             loop {
-                let dims = terminal.size().unwrap();
-                let width = dims.width;
-                let height = dims.height;
-
                 /*
                 -> collect all the nodes with their layout
                 -> solve their layout
@@ -116,16 +112,21 @@ pub fn render_vdom(vdom: &mut VirtualDom, ctx: UnboundedSender<TermEvent>) -> Re
                 */
                 let node_id = root_node.try_mounted_id().unwrap();
                 let root_layout = nodes[&node_id].layout;
-                layout.compute_layout(
-                    root_layout,
-                    Size {
-                        width: stretch2::prelude::Number::Defined(width as f32),
-                        height: stretch2::prelude::Number::Defined(height as f32),
-                    },
-                )?;
 
                 terminal.draw(|frame| {
-                    //
+                    // size is guaranteed to not change when rendering
+                    let dims = frame.size();
+                    let width = dims.width;
+                    let height = dims.height;
+                    layout
+                        .compute_layout(
+                            root_layout,
+                            Size {
+                                width: stretch2::prelude::Number::Defined(width as f32),
+                                height: stretch2::prelude::Number::Defined(height as f32),
+                            },
+                        )
+                        .unwrap();
                     render::render_vnode(frame, &layout, &mut nodes, vdom, root_node);
                     assert!(nodes.is_empty());
                 })?;

+ 8 - 2
src/render.rs

@@ -86,13 +86,19 @@ pub fn render_vnode<'a>(
             let label = Label { text: t.text };
             let area = Rect::new(*x as u16, *y as u16, *width as u16, *height as u16);
 
-            frame.render_widget(label, area);
+            // the renderer will panic if a node is rendered out of range even if the size is zero
+            if area.width > 0 && area.height > 0 {
+                frame.render_widget(label, area);
+            }
         }
         VNode::Element(el) => {
             let block = Block::default().style(node.block_style);
             let area = Rect::new(*x as u16, *y as u16, *width as u16, *height as u16);
 
-            frame.render_widget(block, area);
+            // the renderer will panic if a node is rendered out of range even if the size is zero
+            if area.width > 0 && area.height > 0 {
+                frame.render_widget(block, area);
+            }
 
             for el in el.children {
                 render_vnode(frame, layout, layouts, vdom, el);