diff --git a/src/servo/layout/traverse.rs b/src/servo/layout/traverse.rs index 3f7748bd6d9..13339fc7b14 100644 --- a/src/servo/layout/traverse.rs +++ b/src/servo/layout/traverse.rs @@ -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 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(-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(+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(+root : @Box, first_val : T, + -top_down : fn~(+T, @Box) -> T) { + traverse_helper(root, first_val, top_down, nop); }