зеркало из https://github.com/mozilla/gecko-dev.git
servo: separate tree rd/wr ifaces, make them based on an ops object
the ops object is needed to make it so that dom node mutations go through the RCU store Source-Repo: https://github.com/servo/servo Source-Revision: bbc936dec423ba5acadcfb7ad67934d7e89a887f
This commit is contained in:
Родитель
5240195254
Коммит
a0ff56468e
|
@ -4,7 +4,7 @@ export content;
|
|||
import gfx::geom::*;
|
||||
import dom::rcu::*;
|
||||
import dom::base::*;
|
||||
import layout::base::tree; // method implementations of tree for box and node
|
||||
import layout::base::{rd_tree_ops, wr_tree_ops};
|
||||
|
||||
enum msg {
|
||||
exit
|
||||
|
|
|
@ -23,3 +23,23 @@ impl methods for scope<node_data, box> {
|
|||
kind: k}))
|
||||
}
|
||||
}
|
||||
|
||||
impl of tree::rd_tree_ops<node> for scope<node_data, box> {
|
||||
fn each_child(node: node, f: fn(node) -> bool) {
|
||||
tree::each_child(self, node, f)
|
||||
}
|
||||
|
||||
fn with_tree_fields<R>(node: node, f: fn(tree::fields<node>) -> R) -> R {
|
||||
f(self.rd(node) { |f| f.tree })
|
||||
}
|
||||
}
|
||||
|
||||
impl of tree::wr_tree_ops<node> for scope<node_data, box> {
|
||||
fn add_child(node: node, child: node) {
|
||||
tree::add_child(self, node, child)
|
||||
}
|
||||
|
||||
fn with_tree_fields<R>(node: node, f: fn(tree::fields<node>) -> R) -> R {
|
||||
f(self.wr(node) { |f| f.tree })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,12 @@ impl writer_methods<T:send,A> for scope<T,A> {
|
|||
self.layout_active = false;
|
||||
}
|
||||
|
||||
fn rd<U>(h: handle<T,A>, f: fn(T) -> U) -> U unsafe {
|
||||
// Use the wr_ptr, which may be more up to date than the
|
||||
// rd_ptr or may not
|
||||
f(*h.wr_ptr())
|
||||
}
|
||||
|
||||
fn wr<U>(h: handle<T,A>, f: fn(T) -> U) -> U unsafe {
|
||||
if self.layout_active {
|
||||
if h.rd_ptr() == h.wr_ptr() {
|
||||
|
|
|
@ -11,15 +11,35 @@ enum box = {
|
|||
mut bounds: geom::rect<au>
|
||||
};
|
||||
|
||||
impl of tree::tree for node {
|
||||
fn with_tree_fields<R>(f: fn(tree::fields<node>) -> R) -> R {
|
||||
f(self.rd { |f| f.tree })
|
||||
enum ntree { ntree }
|
||||
impl of tree::rd_tree_ops<node> for ntree {
|
||||
fn each_child(node: node, f: fn(node) -> bool) {
|
||||
tree::each_child(self, node, f)
|
||||
}
|
||||
|
||||
fn with_tree_fields<R>(n: node, f: fn(tree::fields<node>) -> R) -> R {
|
||||
n.rd { |n| f(n.tree) }
|
||||
}
|
||||
}
|
||||
|
||||
impl of tree::tree for @box {
|
||||
fn with_tree_fields<R>(f: fn(tree::fields<@box>) -> R) -> R {
|
||||
f(self.tree)
|
||||
enum btree { btree }
|
||||
impl of tree::rd_tree_ops<@box> for btree {
|
||||
fn each_child(node: @box, f: fn(&&@box) -> bool) {
|
||||
tree::each_child(self, node, f)
|
||||
}
|
||||
|
||||
fn with_tree_fields<R>(b: @box, f: fn(tree::fields<@box>) -> R) -> R {
|
||||
f(b.tree)
|
||||
}
|
||||
}
|
||||
|
||||
impl of tree::wr_tree_ops<@box> for btree {
|
||||
fn add_child(node: @box, child: @box) {
|
||||
tree::add_child(self, node, child)
|
||||
}
|
||||
|
||||
fn with_tree_fields<R>(b: @box, f: fn(tree::fields<@box>) -> R) -> R {
|
||||
f(b.tree)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +75,7 @@ fn reflow_block(root: @box, available_width: au) {
|
|||
}
|
||||
|
||||
let mut current_height = 0;
|
||||
for tree::each_child(root) {|c|
|
||||
for tree::each_child(btree, root) {|c|
|
||||
let mut blk_available_width = available_width;
|
||||
// FIXME subtract borders, margins, etc
|
||||
c.bounds.origin = {mut x: au(0), mut y: au(current_height)};
|
||||
|
@ -69,7 +89,8 @@ fn reflow_block(root: @box, available_width: au) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
import dom::base::{nk_img, node_data, node_kind, node, methods};
|
||||
import dom::base::{nk_img, node_data, node_kind, node, methods,
|
||||
wr_tree_ops};
|
||||
import dom::rcu::scope;
|
||||
|
||||
/*
|
||||
|
@ -90,7 +111,7 @@ mod test {
|
|||
|
||||
fn flat_bounds(root: @box) -> [geom::rect<au>] {
|
||||
let mut r = [];
|
||||
for tree::each_child(root) {|c|
|
||||
for tree::each_child(btree, root) {|c|
|
||||
r += flat_bounds(c);
|
||||
}
|
||||
ret r + [root.bounds];
|
||||
|
@ -105,18 +126,18 @@ mod test {
|
|||
let n2 = s.new_node(nk_img(size(au(10),au(20))));
|
||||
let n3 = s.new_node(nk_div);
|
||||
|
||||
tree::add_child(n3, n0);
|
||||
tree::add_child(n3, n1);
|
||||
tree::add_child(n3, n2);
|
||||
tree::add_child(s, n3, n0);
|
||||
tree::add_child(s, n3, n1);
|
||||
tree::add_child(s, n3, n2);
|
||||
|
||||
let b0 = linked_box(n0);
|
||||
let b1 = linked_box(n1);
|
||||
let b2 = linked_box(n2);
|
||||
let b3 = linked_box(n3);
|
||||
|
||||
tree::add_child(b3, b0);
|
||||
tree::add_child(b3, b1);
|
||||
tree::add_child(b3, b2);
|
||||
tree::add_child(btree, b3, b0);
|
||||
tree::add_child(btree, b3, b1);
|
||||
tree::add_child(btree, b3, b2);
|
||||
|
||||
reflow_block(b3, au(100));
|
||||
let fb = flat_bounds(b3);
|
||||
|
|
|
@ -13,7 +13,7 @@ import gfx::renderer;
|
|||
import dom::base::*;
|
||||
import display_list::*;
|
||||
import dom::rcu::scope;
|
||||
import base::tree;
|
||||
import base::{btree, rd_tree_ops, wr_tree_ops};
|
||||
|
||||
enum msg {
|
||||
build,
|
||||
|
@ -38,9 +38,9 @@ fn layout(renderer: chan<renderer::msg>) -> chan<msg> {
|
|||
int_to_au(r.next() as int % 800),
|
||||
int_to_au(r.next() as int % 200)
|
||||
)));
|
||||
tree::add_child(ndiv, node);
|
||||
s.add_child(ndiv, node);
|
||||
let b = base::linked_box(node);
|
||||
tree::add_child(bdiv, b);
|
||||
btree.add_child(bdiv, b);
|
||||
}
|
||||
|
||||
alt recv(po) {
|
||||
|
@ -63,7 +63,7 @@ fn layout(renderer: chan<renderer::msg>) -> chan<msg> {
|
|||
fn build_display_list(box: @base::box) -> display_list::display_list {
|
||||
let mut list = [box_to_display_item(box)];
|
||||
|
||||
for tree::each_child(box) {|c|
|
||||
for btree.each_child(box) {|c|
|
||||
list += build_display_list(c);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,20 +6,24 @@ type fields<T> = {
|
|||
mut next_sibling: option<T>
|
||||
};
|
||||
|
||||
iface tree {
|
||||
fn with_tree_fields<R>(f: fn(fields<self>) -> R) -> R;
|
||||
iface rd_tree_ops<T> {
|
||||
fn with_tree_fields<R>(T, f: fn(fields<T>) -> R) -> R;
|
||||
}
|
||||
|
||||
fn each_child<T:copy tree>(
|
||||
node: T, f: fn(T) -> bool) {
|
||||
iface wr_tree_ops<T> {
|
||||
fn with_tree_fields<R>(T, f: fn(fields<T>) -> R) -> R;
|
||||
}
|
||||
|
||||
let mut p = node.with_tree_fields { |f| f.first_child };
|
||||
fn each_child<T:copy,O:rd_tree_ops<T>>(
|
||||
ops: O, node: T, f: fn(T) -> bool) {
|
||||
|
||||
let mut p = ops.with_tree_fields(node) { |f| f.first_child };
|
||||
loop {
|
||||
alt p {
|
||||
none { ret; }
|
||||
some(c) {
|
||||
if !f(c) { ret; }
|
||||
p = c.with_tree_fields { |f| f.next_sibling };
|
||||
p = ops.with_tree_fields(c) { |f| f.next_sibling };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +37,10 @@ fn empty<T>() -> fields<T> {
|
|||
mut next_sibling: none}
|
||||
}
|
||||
|
||||
fn add_child<T:copy tree>(
|
||||
node: T, child: T) {
|
||||
fn add_child<T:copy,O:wr_tree_ops<T>>(
|
||||
ops: O, node: T, child: T) {
|
||||
|
||||
child.with_tree_fields { |child_tf|
|
||||
ops.with_tree_fields(child) { |child_tf|
|
||||
alt child_tf.parent {
|
||||
some(_) { fail "Already has a parent"; }
|
||||
none { child_tf.parent = some(node); }
|
||||
|
@ -45,14 +49,15 @@ fn add_child<T:copy tree>(
|
|||
assert child_tf.prev_sibling == none;
|
||||
assert child_tf.next_sibling == none;
|
||||
|
||||
node.with_tree_fields { |node_tf|
|
||||
ops.with_tree_fields(node) { |node_tf|
|
||||
alt node_tf.last_child {
|
||||
none {
|
||||
node_tf.first_child = some(child);
|
||||
}
|
||||
|
||||
some(lc) {
|
||||
lc.with_tree_fields { |lc_tf|
|
||||
let lc = lc; // satisfy alias checker
|
||||
ops.with_tree_fields(lc) { |lc_tf|
|
||||
assert lc_tf.next_sibling == none;
|
||||
lc_tf.next_sibling = some(child);
|
||||
}
|
||||
|
@ -72,9 +77,17 @@ mod test {
|
|||
value: uint
|
||||
};
|
||||
|
||||
impl of tree for dummy {
|
||||
fn with_tree_fields<R>(f: fn(fields<dummy>) -> R) -> R {
|
||||
f(self.fields)
|
||||
enum dtree { dtree }
|
||||
|
||||
impl of rd_tree_ops<dummy> for dtree {
|
||||
fn with_tree_fields<R>(d: dummy, f: fn(fields<dummy>) -> R) -> R {
|
||||
f(d.fields)
|
||||
}
|
||||
}
|
||||
|
||||
impl of wr_tree_ops<dummy> for dtree {
|
||||
fn with_tree_fields<R>(d: dummy, f: fn(fields<dummy>) -> R) -> R {
|
||||
f(d.fields)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +102,7 @@ mod test {
|
|||
let p = new_dummy(3u);
|
||||
|
||||
for vec::each(children) {|c|
|
||||
add_child(p, c);
|
||||
add_child(dtree, p, c);
|
||||
}
|
||||
|
||||
ret {p: p, children: children};
|
||||
|
@ -99,7 +112,7 @@ mod test {
|
|||
fn add_child_0() {
|
||||
let {p, children} = parent_with_3_children();
|
||||
let mut i = 0u;
|
||||
for each_child(p) {|c|
|
||||
for each_child(dtree, p) {|c|
|
||||
assert c.value == i;
|
||||
i += 1u;
|
||||
}
|
||||
|
@ -110,7 +123,7 @@ mod test {
|
|||
fn add_child_break() {
|
||||
let {p, _} = parent_with_3_children();
|
||||
let mut i = 0u;
|
||||
for each_child(p) {|_c|
|
||||
for each_child(dtree, p) {|_c|
|
||||
i += 1u;
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче