Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extend the traversal interface to support passing a value from parent…

…s to children.
  • Loading branch information...
commit 0b7d020174197e40a27107fd45e1c8657c618874 1 parent 1663461
mmeyerho mmeyerho authored
Showing with 52 additions and 13 deletions.
  1. +52 −13 src/servo/layout/traverse.rs
65 src/servo/layout/traverse.rs
View
@@ -6,6 +6,8 @@ import intrinsic::tydesc;
export full_traversal;
export top_down_traversal;
export bottom_up_traversal;
+export extended_full_traversal;
+export extended_top_down_traversal;
// The underlying representation of an @T. We don't actually care
// what it is, just that we can transform to and from this
@@ -35,18 +37,25 @@ fn rewrap_box(-b : *shared_box<Box>) -> @Box unsafe {
Iterate down and then up a tree of layout boxes in parallel and apply
the given functions to each box. Each box applies the first function,
-spawns a task to complete all of its children in parallel, waits for
-them to finish, and then applies the second function.
+spawns a task to complete all of its children in parallel, passing
+each child the result of the ifrst funciton. It waits for them to
+finish, and then applies the second function to the current box.
# Arguments
-* `root` - The current top of the tree, the functions will be applied to it and its children.
-* `top-down` - A function that is applied to each node after it is applied to that node's parent.
-* `bottom-up` - A function that is applied to each node after it is applied to that node's
- children
+* `root` - The current top of the tree, the functions will be applied
+ to it and its children.
+* `returned` - The value returned by applying top_down to the parent
+ of the current box, or a passed in default
+* `top_down` - A function that is applied to each node after it is
+ applied to that node's parent.
+* `bottom_up` - A function that is applied to each node after it is
+ applied to that node's children
+
"]
-fn traverse_helper(-root : @Box, -top_down : fn~(@Box), -bottom_up : fn~(@Box)) {
- top_down(root);
+fn traverse_helper<T : copy send>(-root : @Box, returned : T, -top_down : fn~(+T, @Box) -> T,
+ -bottom_up : fn~(@Box)) {
+ let returned = top_down(returned, root);
do listen |ack_chan| {
let mut count = 0;
@@ -74,7 +83,7 @@ fn traverse_helper(-root : @Box, -top_down : fn~(@Box), -bottom_up : fn~(@Box))
// Retrieve the original @Box and recurse
let new_kid = rewrap_box(option::unwrap(swapped_in));
- traverse_helper(new_kid, copy top_down, copy bottom_up);
+ traverse_helper(new_kid, copy returned, copy top_down, copy bottom_up);
ack_chan.send(());
}
@@ -92,13 +101,20 @@ fn nop(_box : @Box) {
return;
}
+#[doc= "
+ A wrapper to change a function that only acts on a box to one that
+ threasds a unit through to match travserse_helper
+"]
+fn unit_wrapper(-fun : fn~(@Box)) -> fn~(+(), @Box) {
+ fn~(+_u : (), box : @Box) { fun(box); }
+}
+
#[doc="
Iterate in parallel over the boxes in a tree, applying one function
to a parent before recursing on its children and one after.
"]
-
fn full_traversal(+root : @Box, -top_down : fn~(@Box), -bottom_up : fn~(@Box)) {
- traverse_helper(root, top_down, bottom_up);
+ traverse_helper(root, (), unit_wrapper(top_down), bottom_up);
}
#[doc="
@@ -106,7 +122,7 @@ fn full_traversal(+root : @Box, -top_down : fn~(@Box), -bottom_up : fn~(@Box)) {
function to a parent before its children.
"]
fn top_down_traversal(+root : @Box, -top_down : fn~(@Box)) {
- traverse_helper(root, top_down, nop);
+ traverse_helper(root, (), unit_wrapper(top_down), nop);
}
#[doc="
@@ -114,5 +130,28 @@ fn top_down_traversal(+root : @Box, -top_down : fn~(@Box)) {
function to a parent after its children.
"]
fn bottom_up_traversal(+root : @Box, -bottom_up : fn~(@Box)) {
- traverse_helper(root, nop, bottom_up);
+ traverse_helper(root, (), unit_wrapper(nop), bottom_up);
+}
+
+#[doc="
+ Iterate in parallel over the boxes in a tree, applying the given
+ function to a parent before its children, the value returned by the
+ function is passed to each child when they are recursed upon. As
+ the recursion unwinds, the second function is applied to first the
+ children in parallel, and then the parent.
+"]
+fn extended_full_traversal<T : copy send>(+root : @Box, first_val : T,
+ -top_down : fn~(+T, @Box) -> T,
+ -bottom_up : fn~(@Box)) {
+ traverse_helper(root, first_val, top_down, bottom_up);
+}
+
+#[doc="
+ Iterate in parallel over the boxes in a tree, applying the given
+ function to a parent before its children, the value returned by the
+ function is passed to each child when they are recursed upon.
+"]
+fn extended_top_down_traversal<T : copy send>(+root : @Box, first_val : T,
+ -top_down : fn~(+T, @Box) -> T) {
+ traverse_helper(root, first_val, top_down, nop);
}
Please sign in to comment.
Something went wrong with that request. Please try again.