servo: Extend the traversal interface to support passing a value from parents to children.

Source-Repo: https://github.com/servo/servo
Source-Revision: 0b7d020174197e40a27107fd45e1c8657c618874
This commit is contained in:
Margaret Meyerhofer 2012-08-09 17:53:20 -07:00
Родитель c6b3cd02df
Коммит 41cc094b74
1 изменённых файлов: 52 добавлений и 13 удалений

Просмотреть файл

@ -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);
}