Skip to content

Commit

Permalink
reorganize code, add tests for tree, add 'make test'
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Mar 27, 2012
1 parent 668f28d commit da19925
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*~
14 changes: 11 additions & 3 deletions Makefile.in
Expand Up @@ -5,13 +5,21 @@ RUSTFLAGS?=

RUST_SRC=$(shell find $(VPATH)/src -type f -name '*.rs')

.PHONY: all
all: servo

servo: src/servo.rc $(RUST_SRC)
servo: \
src/servo.rc $(RUST_SRC)
$(RUSTC) $(RUSTFLAGS) -o $@ $<

.PHONY: clean
servo-test: \
src/servo.rc $(RUST_SRC)
$(RUSTC) $(RUSTFLAGS) --test -o $@ $<

.PHONY: clean
clean:
rm -f servo
rm -f servo servo-test

.PHONY: test
test: servo-test
./servo-test
11 changes: 10 additions & 1 deletion src/dom/rcu.rs
@@ -1,6 +1,15 @@
enum handle<T> = @T;
enum handle<T> {
_handle(@T)
}

impl methods<T> for handle<T> {
fn get() -> @T { *self }

fn with(f: fn(T)) {
f(**self)
}
}

fn handle<T:copy>(t: T) -> handle<T> {
_handle(@t)
}
110 changes: 66 additions & 44 deletions src/layout/base.rs
@@ -1,29 +1,16 @@
import dom::rcu;
import dom::rcu::methods;

// FIXME--mut should be inherited
type point<A> = { mut x: A, mut y: A };
type size<A> = { mut width: A, mut height: A };
type rect<A> = { mut origin: point<A>, mut size: size<A> };

enum au = int;

type tree_fields<T> = {
parent: option<T>,
first_child: option<T>,
last_child: option<T>,
prev_sibling: option<T>,
next_sibling: option<T>
};
import util::{tree, geom};
import geom::{size, rect, point, au};

enum box = @{
tree: tree_fields<box>,
tree: tree::fields<box>,
node: node,
mut bounds: rect<au>
mut bounds: geom::rect<au>
};

type node_data = {
tree: tree_fields<node>,
enum node_data = {
tree: tree::fields<node>,
kind: node_kind,

// Points to the primary box. Note that there may be multiple
Expand All @@ -36,44 +23,37 @@ enum node_kind {
nk_img(size<au>)
}

enum node = rcu::handle<node_data>;
type node = rcu::handle<node_data>;

iface tree {
fn tree_fields() -> tree_fields<self>;
}

impl of tree for box {
fn tree_fields() -> tree_fields<box> {
impl of tree::tree for box {
fn tree_fields() -> tree::fields<box> {
ret self.tree;
}
}

impl of tree for node {
fn tree_fields() -> tree_fields<node> {
ret (*self).get().tree;
impl of tree::tree for node {
fn tree_fields() -> tree::fields<node> {
ret self.get().tree;
}
}

fn each_child<T:copy tree>(
node: T, f: fn(T) -> bool) {

let mut p = node.tree_fields().first_child;
loop {
alt p {
none { ret; }
some(c) {
if !f(c) { ret; }
p = c.tree_fields().next_sibling;
}
}
}
fn new_node(+k: node_kind) -> node {
rcu::handle(node_data({tree: tree::empty(),
kind: k,
mut linfo: none}))
}

fn new_box(n: node) -> box {
box(@{tree: tree::empty(),
node: n,
mut bounds: geom::zero_rect_au()})
}

fn reflow_block(root: box, available_width: au) {
// Root here is the root of the reflow, not necessarily the doc as
// a whole.

alt (*root.node).get().kind {
alt root.node.get().kind {
nk_img(size) {
root.bounds.size = size;
ret;
Expand All @@ -83,7 +63,7 @@ fn reflow_block(root: box, available_width: au) {
}

let mut current_height = 0;
for each_child(root) {|c|
for tree::each_child(root) {|c|
let mut blk_available_width = available_width;
// FIXME subtract borders, margins, etc
c.bounds.origin = {x: au(0), y: au(current_height)};
Expand All @@ -94,3 +74,45 @@ fn reflow_block(root: box, available_width: au) {
root.bounds.size = {width: available_width, // FIXME
height: au(current_height)};
}

/*
#[cfg(test)]
mod test {
use sdl;
import sdl::video;
fn with_screen(f: fn(*sdl::surface)) {
let screen = video::set_video_mode(
320, 200, 32,
[video::hwsurface], [video::doublebuf]);
assert screen != ptr::null();
f(screen);
video::free_surface(screen);
}
}
#[test]
fn do_layout() {
test::with_screen {|s|
let n0 = node(nk_img(size(au(22),au(44))));
let n1 = node(nk_img(size(au(22),au(44))));
let n2 = node(nk_img(size(au(22),au(44))));
let n3 = node(nk_div);
tree::add_child(n3, n0);
tree::add_child(n3, n1);
tree::add_child(n3, n2);
let b0 = box(n0);
let b1 = box(n1);
let b2 = box(n2);
let b3 = box(n3);
tree::add_child(b3, b0);
tree::add_child(b3, b1);
tree::add_child(b3, b2);
}
}
*/
6 changes: 6 additions & 0 deletions src/servo.rc
Expand Up @@ -6,6 +6,8 @@
#[comment = "The Servo Parallel Browser Project"];
#[license = "MPL"];

use std;

mod dom {
mod base;
mod rcu;
Expand All @@ -19,3 +21,7 @@ mod widget {
mod base;
}

mod util {
mod tree;
mod geom;
}
25 changes: 25 additions & 0 deletions src/util/geom.rs
@@ -0,0 +1,25 @@
// FIXME--mut should be inherited
type point<A> = { mut x: A, mut y: A };
type size<A> = { mut width: A, mut height: A };
type rect<A> = { mut origin: point<A>, mut size: size<A> };

enum au = int;

fn point<A:copy>(x: A, y: A) -> point<A> {
{mut x: x, mut y: y}
}

fn size<A:copy>(w: A, h: A) -> size<A> {
{mut width: w, mut height: h}
}

fn box<A:copy>(x: A, y: A, w: A, h: A) -> rect<A> {
{mut origin: point(x, y),
mut size: size(w, h)}
}

fn zero_rect_au() -> rect<au> {
let z = au(0);
{mut origin: point(z, z), mut size: size(z, z)}
}

98 changes: 98 additions & 0 deletions src/util/tree.rs
@@ -0,0 +1,98 @@
type fields<T> = @{
mut parent: option<T>,
mut first_child: option<T>,
mut last_child: option<T>,
mut prev_sibling: option<T>,
mut next_sibling: option<T>
};

iface tree {
fn tree_fields() -> fields<self>;
}

fn each_child<T:copy tree>(
node: T, f: fn(T) -> bool) {

let mut p = node.tree_fields().first_child;
loop {
alt p {
none { ret; }
some(c) {
if !f(c) { ret; }
p = c.tree_fields().next_sibling;
}
}
}
}

fn empty<T>() -> fields<T> {
@{mut parent: none,
mut first_child: none,
mut last_child: none,
mut prev_sibling: none,
mut next_sibling: none}
}

fn add_child<T:copy tree>(
node: T, child: T) {

let child_tf = child.tree_fields();
alt child_tf.parent {
some(_) { fail "Already has a parent"; }
none { child_tf.parent = some(node); }
}

assert child_tf.prev_sibling == none;
assert child_tf.next_sibling == none;

let node_tf = node.tree_fields();
alt node_tf.last_child {
none {
node_tf.first_child = some(child);
}

some(lc) {
let lc_tf = lc.tree_fields();
assert lc_tf.next_sibling == none;
lc_tf.next_sibling = some(child);
child_tf.prev_sibling = some(lc);
}
}

node_tf.last_child = some(child);
}

#[cfg(test)]
mod test {
enum dummy = @{
fields: fields<dummy>,
value: uint
};

impl of tree for dummy {
fn tree_fields() -> fields<dummy> { self.fields }
}

fn new_dummy(v: uint) -> dummy {
dummy(@{fields: empty(), value: v})
}

#[test]
fn add_child_0() {
let children = [new_dummy(0u),
new_dummy(1u),
new_dummy(2u)];
let p = new_dummy(3u);

for vec::each(children) {|c|
add_child(p, c);
}

let mut i = 0u;
for each_child(p) {|c|
assert c.value == i;
i += 1u;
}
assert i == children.len();
}
}

0 comments on commit da19925

Please sign in to comment.