tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 707HTML 660Markdown 12TOML 62344 Definiciones

Load of small fixes, updates API, and added tests

af085fac4e4ada54f216cf49aa28d6a55e86be76 · por Emil Sjölander · (hace 7 años) · padre d4ae260ba · ver el árbol en este commit

Delta semántico · 27

src/node.rs

tests/measure.rs

tests/node.rs

5 archivos · +167 −51

diff --git a/.circleci/config.yml b/.circleci/config.yml
index cf5487e91..0e5050e4f 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,7 +1,7 @@
 version: 2
 
 jobs:
-  build:
+  core:
     docker:
       - image: rust:1
 
@@ -23,4 +23,100 @@ jobs:
           key: target-cache
           paths:
             - ~/.cargo
-            - ./target
\ No newline at end of file
+            - ./target
+
+  android:
+    docker:
+      - image: circleci/android:api-28
+    
+    environment:
+      _JAVA_OPTIONS: "-Xmx3200m -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:ParallelGCThreads=2 -XX:ConcGCThreads=2 -XX:ParallelGCThreads=2 -Djava.util.concurrent.ForkJoinPool.common.parallelism=2"
+
+    steps:
+      - checkout
+      - restore_cache:
+          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "stretch/build.gradle" }}
+      - run: yes | sdkmanager --update || true
+      - run: cd android && ./gradlew androidDependencies --no-daemon --max-workers 2
+      - save_cache:
+          paths:
+            - ~/.gradle
+          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "stretch/build.gradle" }}
+      - run:
+          name: Setup emulator
+          command: sdkmanager "system-images;android-16;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-16;default;armeabi-v7a"
+      - run:
+          name: Launch emulator
+          command: export LD_LIBRARY_PATH=${ANDROID_HOME}/emulator/lib64:${ANDROID_HOME}/emulator/lib64/qt/lib && emulator64-arm -avd test -noaudio -no-boot-anim -no-window -accel auto -verbose
+          background: true
+      - run:
+          name: Wait emulator
+          command: |
+            # wait for it to have booted
+            circle-android wait-for-boot
+            # unlock the emulator screen
+            sleep 30
+            adb shell input keyevent 82
+      - run:
+          name: Run tests
+          command: ./gradlew connectedAndroidTest
+      - store_artifacts:
+          path: stretch/build/reports
+          destination: reports
+      - store_test_results:
+          path: stretch/build/test-results
+
+workflows:
+  version: 2
+  test_all:
+    jobs:
+      - android
+      - core
+
+
+version: 2
+jobs:
+  build:
+    working_directory: ~/code
+    docker:
+      # Android the primary container
+      - image: circleci/android:api-26-alpha
+    environment:
+      JVM_OPTS: -Xmx3200m
+    steps:
+      - checkout
+      - restore_cache:
+          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
+      - run:
+          name: Download Dependencies
+          command: ./gradlew androidDependencies
+      - save_cache:
+          paths:
+            - ~/.gradle
+          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
+      - run:
+          name: Run UnitTest
+          command: ./gradlew testDemoDebugUnitTest
+      - run:
+          name: Setup emulator
+          command: sdkmanager "system-images;android-16;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-16;default;armeabi-v7a"
+      - run:
+          name: Launch emulator
+          command: export LD_LIBRARY_PATH=${ANDROID_HOME}/emulator/lib64:${ANDROID_HOME}/emulator/lib64/qt/lib && emulator64-arm -avd test -noaudio -no-boot-anim -no-window -accel auto -verbose
+          background: true
+      - run:
+          name: Wait emulator
+          command: |
+            # wait for it to have booted
+            circle-android wait-for-boot
+            # unlock the emulator screen
+            sleep 30
+            adb shell input keyevent 82
+      - run:
+          name: Run EspressoTests
+          command: ./gradlew connectedDemoDebugAndroidTest
+      - store_artifacts:
+          path: app/build/reports
+          destination: reports
+      - store_test_results:
+          path: app/build/test-results
diff --git a/Cargo.toml b/Cargo.toml
index 7041f4984..abdddc80e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "stretch"
-version = "0.2.1"
+version = "0.2.2"
 authors = ["Emil Sjölander <emil@visly.app>"]
 edition = "2018"
 include = ["src/**/*", "Cargo.toml"]
diff --git a/src/node.rs b/src/node.rs
index e9369b1a7..5221c464a 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -26,12 +26,12 @@ pub(crate) struct InternalNode {
 pub struct Node(Rc<RefCell<InternalNode>>);
 
 impl Node {
-    pub fn new_leaf(style: Style, measure: Option<MeasureFunc>) -> Node {
+    pub fn new_leaf(style: Style, measure: MeasureFunc) -> Node {
         Node(Rc::new(RefCell::new(InternalNode {
             style,
             parents: Vec::with_capacity(1),
             children: Vec::with_capacity(0),
-            measure,
+            measure: Some(measure),
             layout_cache: None,
             is_dirty: true,
         })))
@@ -55,6 +55,11 @@ impl Node {
         parent
     }
 
+    pub fn set_measure(&mut self, measure: Option<MeasureFunc>) {
+        self.0.borrow_mut().measure = measure;
+        self.mark_dirty();
+    }
+
     pub fn add_child(&mut self, child: &Node) {
         child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
         self.0.borrow_mut().children.push(Rc::clone(&child.0));
@@ -117,6 +122,11 @@ impl Node {
         node.children.iter().map(|child| Node(Rc::clone(child))).collect()
     }
 
+    pub fn child_count(&self) -> usize {
+        let node = self.0.borrow_mut();
+        node.children.len()
+    }
+
     pub fn set_style(&mut self, style: Style) {
         self.0.borrow_mut().style = style;
         self.mark_dirty();
diff --git a/tests/measure.rs b/tests/measure.rs
index afed43f61..a5f3fb7f0 100644
--- a/tests/measure.rs
+++ b/tests/measure.rs
@@ -6,12 +6,12 @@ mod measure {
     fn measure_root() {
         let layout = stretch::node::Node::new_leaf(
             stretch::style::Style { ..Default::default() },
-            Some(Box::new(|constraint| {
+            Box::new(|constraint| {
                 Ok(stretch::geometry::Size {
                     width: constraint.width.or_else(100.0),
                     height: constraint.height.or_else(100.0),
                 })
-            })),
+            }),
         )
         .compute_layout(stretch::geometry::Size::undefined())
         .unwrap();
@@ -26,12 +26,12 @@ mod measure {
             stretch::style::Style { ..Default::default() },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { ..Default::default() },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(100.0),
                         height: constraint.height.or_else(100.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -53,12 +53,12 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { ..Default::default() },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(100.0),
                         height: constraint.height.or_else(100.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -86,12 +86,12 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { ..Default::default() },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(100.0),
                         height: constraint.height.or_else(100.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -124,12 +124,12 @@ mod measure {
                 ),
                 &stretch::node::Node::new_leaf(
                     stretch::style::Style { flex_grow: 1.0, ..Default::default() },
-                    Some(Box::new(|constraint| {
+                    Box::new(|constraint| {
                         Ok(stretch::geometry::Size {
                             width: constraint.width.or_else(10.0),
                             height: constraint.height.or_else(50.0),
                         })
-                    })),
+                    }),
                 ),
             ],
         )
@@ -161,12 +161,12 @@ mod measure {
                 ),
                 &stretch::node::Node::new_leaf(
                     stretch::style::Style { ..Default::default() },
-                    Some(Box::new(|constraint| {
+                    Box::new(|constraint| {
                         Ok(stretch::geometry::Size {
                             width: constraint.width.or_else(100.0),
                             height: constraint.height.or_else(50.0),
                         })
-                    })),
+                    }),
                 ),
             ],
         )
@@ -198,11 +198,11 @@ mod measure {
                 ),
                 &stretch::node::Node::new_leaf(
                     stretch::style::Style { flex_grow: 1.0, ..Default::default() },
-                    Some(Box::new(|constraint| {
+                    Box::new(|constraint| {
                         let width = constraint.width.or_else(10.0);
                         let height = constraint.height.or_else(width * 2.0);
                         Ok(stretch::geometry::Size { width, height })
-                    })),
+                    }),
                 ),
             ],
         )
@@ -235,11 +235,11 @@ mod measure {
                 ),
                 &stretch::node::Node::new_leaf(
                     stretch::style::Style { ..Default::default() },
-                    Some(Box::new(|constraint| {
+                    Box::new(|constraint| {
                         let width = constraint.width.or_else(100.0);
                         let height = constraint.height.or_else(width * 2.0);
                         Ok(stretch::geometry::Size { width, height })
-                    })),
+                    }),
                 ),
             ],
         )
@@ -262,11 +262,11 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { ..Default::default() },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     let height = constraint.height.or_else(50.0);
                     let width = constraint.width.or_else(height);
                     Ok(stretch::geometry::Size { width, height })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -288,12 +288,12 @@ mod measure {
                     },
                     ..Default::default()
                 },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(100.0),
                         height: constraint.height.or_else(100.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -315,12 +315,12 @@ mod measure {
                     },
                     ..Default::default()
                 },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(100.0),
                         height: constraint.height.or_else(100.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -355,12 +355,12 @@ mod measure {
                         flex_grow: 1.0,
                         ..Default::default()
                     },
-                    Some(Box::new(|constraint| {
+                    Box::new(|constraint| {
                         Ok(stretch::geometry::Size {
                             width: constraint.width.or_else(100.0),
                             height: constraint.height.or_else(100.0),
                         })
-                    })),
+                    }),
                 ),
             ],
         )
@@ -385,12 +385,12 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { ..Default::default() },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(50.0),
                         height: constraint.height.or_else(50.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -412,12 +412,12 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { position_type: stretch::style::PositionType::Absolute, ..Default::default() },
-                Some(Box::new(|constraint| {
+                Box::new(|constraint| {
                     Ok(stretch::geometry::Size {
                         width: constraint.width.or_else(50.0),
                         height: constraint.height.or_else(50.0),
                     })
-                })),
+                }),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -439,7 +439,7 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { flex_grow: 1.0, ..Default::default() },
-                Some(Box::new(|_| Ok(stretch::geometry::Size { width: 200.0, height: 200.0 }))),
+                Box::new(|_| Ok(stretch::geometry::Size { width: 200.0, height: 200.0 })),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined())
@@ -460,13 +460,13 @@ mod measure {
                 stretch::style::Style { ..Default::default() },
                 vec![&stretch::node::Node::new_leaf(
                     stretch::style::Style { ..Default::default() },
-                    Some(Box::new(move |constraint| {
+                    Box::new(move |constraint| {
                         unsafe { (*num_measure_ptr) += 1 };
                         Ok(stretch::geometry::Size {
                             width: constraint.width.or_else(50.0),
                             height: constraint.height.or_else(50.0),
                         })
-                    })),
+                    }),
                 )],
             )],
         )
@@ -488,7 +488,7 @@ mod measure {
             },
             vec![&stretch::node::Node::new_leaf(
                 stretch::style::Style { flex_grow: 1.0, ..Default::default() },
-                Some(Box::new(|_| Err(Box::new("")))),
+                Box::new(|_| Err(Box::new(""))),
             )],
         )
         .compute_layout(stretch::geometry::Size::undefined());
diff --git a/tests/node.rs b/tests/node.rs
index 1f29dddaf..ea35cb990 100644
--- a/tests/node.rs
+++ b/tests/node.rs
@@ -1,5 +1,6 @@
 #[cfg(test)]
 mod node {
+    use stretch::geometry::*;
     use stretch::node::Node;
     use stretch::style::*;
 
@@ -9,21 +10,30 @@ mod node {
         let child2 = Node::new(Style::default(), vec![]);
         let node = Node::new(Style::default(), vec![&child1, &child2]);
 
-        assert_eq!(node.children().len(), 2);
+        assert_eq!(node.child_count(), 2);
         assert_eq!(node.children()[0], child1);
         assert_eq!(node.children()[1], child2);
     }
 
+    #[test]
+    fn set_measure() {
+        let mut node = Node::new_leaf(Style::default(), Box::new(|_| Ok(Size { width: 200.0, height: 200.0 })));
+        assert_eq!(node.compute_layout(Size::undefined()).unwrap().size.width, 200.0);
+
+        node.set_measure(Some(Box::new(|_| Ok(Size { width: 100.0, height: 100.0 }))));
+        assert_eq!(node.compute_layout(Size::undefined()).unwrap().size.width, 100.0);
+    }
+
     #[test]
     fn add_child() {
         let mut node = Node::new(Style::default(), vec![]);
-        assert_eq!(node.children().len(), 0);
+        assert_eq!(node.child_count(), 0);
 
         node.add_child(&Node::new(Style::default(), vec![]));
-        assert_eq!(node.children().len(), 1);
+        assert_eq!(node.child_count(), 1);
 
         node.add_child(&Node::new(Style::default(), vec![]));
-        assert_eq!(node.children().len(), 2);
+        assert_eq!(node.child_count(), 2);
     }
 
     #[test]
@@ -32,14 +42,14 @@ mod node {
         let child2 = Node::new(Style::default(), vec![]);
 
         let mut node = Node::new(Style::default(), vec![&child1, &child2]);
-        assert_eq!(node.children().len(), 2);
+        assert_eq!(node.child_count(), 2);
 
         node.remove_child(&child1);
-        assert_eq!(node.children().len(), 1);
+        assert_eq!(node.child_count(), 1);
         assert_eq!(node.children()[0], child2);
 
         node.remove_child(&child2);
-        assert_eq!(node.children().len(), 0);
+        assert_eq!(node.child_count(), 0);
     }
 
     #[test]
@@ -48,14 +58,14 @@ mod node {
         let child2 = Node::new(Style::default(), vec![]);
 
         let mut node = Node::new(Style::default(), vec![&child1, &child2]);
-        assert_eq!(node.children().len(), 2);
+        assert_eq!(node.child_count(), 2);
 
         node.remove_child_at_index(0);
-        assert_eq!(node.children().len(), 1);
+        assert_eq!(node.child_count(), 1);
         assert_eq!(node.children()[0], child2);
 
         node.remove_child_at_index(0);
-        assert_eq!(node.children().len(), 0);
+        assert_eq!(node.child_count(), 0);
     }
 
     #[test]
@@ -64,11 +74,11 @@ mod node {
         let child2 = Node::new(Style::default(), vec![]);
 
         let mut node = Node::new(Style::default(), vec![&child1]);
-        assert_eq!(node.children().len(), 1);
+        assert_eq!(node.child_count(), 1);
         assert_eq!(node.children()[0], child1);
 
         node.replace_child_at_index(0, &child2);
-        assert_eq!(node.children().len(), 1);
+        assert_eq!(node.child_count(), 1);
         assert_eq!(node.children()[0], child2);
     }
 
@@ -78,7 +88,7 @@ mod node {
         let child2 = Node::new(Style::default(), vec![]);
         let mut node = Node::new(Style::default(), vec![&child1, &child2]);
 
-        assert_eq!(node.children().len(), 2);
+        assert_eq!(node.child_count(), 2);
         assert_eq!(node.children()[0], child1);
         assert_eq!(node.children()[1], child2);
 
@@ -86,7 +96,7 @@ mod node {
         let child4 = Node::new(Style::default(), vec![]);
         node.set_children(vec![&child3, &child4]);
 
-        assert_eq!(node.children().len(), 2);
+        assert_eq!(node.child_count(), 2);
         assert_eq!(node.children()[0], child3);
         assert_eq!(node.children()[1], child4);
     }