servo: Merge #29 - Pipes (from eholk:pipes)

Source-Repo: https://github.com/servo/servo
Source-Revision: 0f1e778653fc59f511da111e840512d5bfebb819
This commit is contained in:
Eric Holk 2012-07-26 16:21:56 -07:00
Родитель 9a97f05066
Коммит 9818212faf
11 изменённых файлов: 115 добавлений и 94 удалений

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

@ -73,8 +73,8 @@ class Document {
class Content<S:Sink send copy> { class Content<S:Sink send copy> {
let sink: S; let sink: S;
let layout: Layout; let layout: Layout;
let from_master: port<ControlMsg>; let from_master: comm::port<ControlMsg>;
let event_port: port<Event>; let event_port: comm::port<Event>;
let scope: NodeScope; let scope: NodeScope;
let jsrt: jsrt; let jsrt: jsrt;

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

@ -5,14 +5,16 @@ import layout::layout_task;
import layout_task::Layout; import layout_task::Layout;
import content::{Content, ExecuteMsg, ParseMsg, ExitMsg, create_content}; import content::{Content, ExecuteMsg, ParseMsg, ExitMsg, create_content};
import pipes::{port, chan};
class Engine<S:Sink send copy> { class Engine<S:Sink send copy> {
let sink: S; let sink: S;
let renderer: Renderer; let renderer: Renderer;
let layout: Layout; let layout: Layout;
let content: chan<content::ControlMsg>; let content: comm::chan<content::ControlMsg>;
new(sink: S) { new(+sink: S) {
self.sink = sink; self.sink = sink;
let renderer = Renderer(sink); let renderer = Renderer(sink);
@ -24,7 +26,7 @@ class Engine<S:Sink send copy> {
self.content = content; self.content = content;
} }
fn start() -> chan<Msg> { fn start() -> comm::chan<Msg> {
do spawn_listener::<Msg> |request| { do spawn_listener::<Msg> |request| {
while self.handle_request(request.recv()) { while self.handle_request(request.recv()) {
// Go on... // Go on...
@ -47,10 +49,12 @@ class Engine<S:Sink send copy> {
ExitMsg(sender) { ExitMsg(sender) {
self.content.send(content::ExitMsg); self.content.send(content::ExitMsg);
self.layout.send(layout_task::ExitMsg); self.layout.send(layout_task::ExitMsg);
do listen |response_channel| {
self.renderer.send(renderer::ExitMsg(response_channel)); let (response_chan, response_port) = pipes::stream();
response_channel.recv();
} self.renderer.send(renderer::ExitMsg(response_chan));
response_port.recv();
sender.send(()); sender.send(());
ret false; ret false;
} }

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

@ -30,16 +30,16 @@ import layout::display_list::display_list;
type PngSink = chan<Msg>; type PngSink = chan<Msg>;
enum Msg { enum Msg {
BeginDrawing(chan<AzDrawTargetRef>), BeginDrawing(pipes::chan<AzDrawTargetRef>),
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef), Draw(pipes::chan<AzDrawTargetRef>, AzDrawTargetRef),
Exit Exit
} }
impl PngSink of Sink for chan<Msg> { impl PngSink of Sink for chan<Msg> {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>) { fn begin_drawing(+next_dt: pipes::chan<AzDrawTargetRef>) {
self.send(BeginDrawing(next_dt)) self.send(BeginDrawing(next_dt))
} }
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) { fn draw(+next_dt: pipes::chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
self.send(Draw(next_dt, draw_me)) self.send(Draw(next_dt, draw_me))
} }
fn add_event_listener(_listener: chan<Event>) { fn add_event_listener(_listener: chan<Event>) {
@ -76,7 +76,7 @@ fn PngSink(output: chan<~[u8]>) -> PngSink {
}) })
} }
fn do_draw(sender: chan<AzDrawTargetRef>, fn do_draw(sender: pipes::chan<AzDrawTargetRef>,
dt: AzDrawTargetRef, dt: AzDrawTargetRef,
output: chan<~[u8]>, output: chan<~[u8]>,
cairo_surf: *cairo_surface_t) { cairo_surf: *cairo_surface_t) {
@ -131,10 +131,9 @@ fn sanity_check() {
let dlist : display_list = dvec(); let dlist : display_list = dvec();
renderer.send(RenderMsg(dlist)); renderer.send(RenderMsg(dlist));
listen(|from_renderer| { let (exit_chan, exit_response_from_engine) = pipes::stream();
renderer.send(renderer::ExitMsg(from_renderer)); renderer.send(renderer::ExitMsg(exit_chan));
from_renderer.recv(); exit_response_from_engine.recv();
});
sink.send(Exit) sink.send(Exit)
}) })

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

@ -15,11 +15,13 @@ import azure_hl::AsAzureRect;
import ptr::addr_of; import ptr::addr_of;
import arc::arc; import arc::arc;
type Renderer = chan<Msg>; import pipes::{port, chan};
type Renderer = comm::chan<Msg>;
enum Msg { enum Msg {
RenderMsg(dl::display_list), RenderMsg(dl::display_list),
ExitMsg(comm::chan<()>) ExitMsg(pipes::chan<()>)
} }
#[doc = " #[doc = "
@ -29,38 +31,45 @@ each rendered frame and submit them to be drawn to the display
FIXME: Change this name to Compositor. FIXME: Change this name to Compositor.
"] "]
iface Sink { iface Sink {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>); fn begin_drawing(+next_dt: pipes::chan<AzDrawTargetRef>);
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef); fn draw(+next_dt: pipes::chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef);
fn add_event_listener(listener: chan<Event>); fn add_event_listener(listener: comm::chan<Event>);
} }
fn Renderer<S: Sink send copy>(sink: S) -> chan<Msg> { fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
task::spawn_listener::<Msg>(|po| { task::spawn_listener::<Msg>(|po| {
listen(|draw_target_ch| { let (draw_target_ch, draw_target_po) = pipes::stream();
#debug("renderer: beginning rendering loop"); let mut draw_target_ch = draw_target_ch;
sink.begin_drawing(draw_target_ch); let mut draw_target_po = draw_target_po;
loop { #debug("renderer: beginning rendering loop");
alt po.recv() { sink.begin_drawing(draw_target_ch);
RenderMsg(display_list) {
#debug("renderer: got render request");
let draw_target = draw_target_ch.recv();
#debug("renderer: rendering");
do util::time::time(~"rendering") { loop {
clear(draw_target); alt po.recv() {
draw_display_list(draw_target, display_list); RenderMsg(display_list) {
#debug("renderer: returning surface"); #debug("renderer: got render request");
sink.draw(draw_target_ch, draw_target); let draw_target = draw_target_po.recv();
} let (ch, po) = pipes::stream();
} let mut draw_target_ch_ = some(ch);
ExitMsg(response_ch) { draw_target_po = po;
response_ch.send(()); #debug("renderer: rendering");
break; do util::time::time(~"rendering") {
} let mut draw_target_ch = none;
draw_target_ch_ <-> draw_target_ch;
let draw_target_ch = option::unwrap(draw_target_ch);
clear(draw_target);
draw_display_list(draw_target, display_list);
#debug("renderer: returning surface");
sink.draw(draw_target_ch, draw_target);
} }
}
ExitMsg(response_ch) {
response_ch.send(());
break;
}
} }
}) }
}) })
} }

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

@ -34,7 +34,8 @@ fn Layout(renderer: Renderer) -> Layout {
ping_channel.send(content::PongMsg); ping_channel.send(content::PongMsg);
} }
ExitMsg { ExitMsg {
break; #debug("layout: ExitMsg received");
break;
} }
BuildMsg(node, styles) { BuildMsg(node, styles) {
#debug("layout: received layout request for:"); #debug("layout: received layout request for:");

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

@ -17,7 +17,7 @@ import parser::parser_util::{parse_display_type, parse_font_size, parse_size};
import util::color::parsing::parse_color; import util::color::parsing::parse_color;
import vec::push; import vec::push;
type TokenReader = {stream : port<Token>, mut lookahead : option<Token>}; type TokenReader = {stream : pipes::port<Token>, mut lookahead : option<Token>};
trait util_methods { trait util_methods {
fn get() -> Token; fn get() -> Token;
@ -28,7 +28,7 @@ impl util_methods of util_methods for TokenReader {
fn get() -> Token { fn get() -> Token {
alt copy self.lookahead { alt copy self.lookahead {
some(tok) { self.lookahead = none; copy tok } some(tok) { self.lookahead = none; copy tok }
none { recv(self.stream) } none { self.stream.recv() }
} }
} }
@ -195,7 +195,7 @@ impl parser_methods of parser_methods for TokenReader {
} }
} }
fn build_stylesheet(stream : port<Token>) -> ~[~style::Rule] { fn build_stylesheet(+stream : pipes::port<Token>) -> ~[~style::Rule] {
let mut rule_list = ~[]; let mut rule_list = ~[];
let reader = {stream : stream, mut lookahead : none}; let reader = {stream : stream, mut lookahead : none};

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

@ -1,11 +1,12 @@
#[doc = "Code to lex and tokenize css files."] #[doc = "Code to lex and tokenize css files."]
import comm::{port, chan};
import dom::style; import dom::style;
import option::is_none; import option::is_none;
import str::from_bytes; import str::from_bytes;
import vec::push; import vec::push;
import pipes::{port, chan};
import lexer_util::*; import lexer_util::*;
enum ParserState { enum ParserState {
@ -243,8 +244,7 @@ fn lex_css_from_bytes(-content : ~[u8], result_chan : chan<Token>) {
} }
fn spawn_css_lexer_from_string(-content : ~str) -> port<Token> { fn spawn_css_lexer_from_string(-content : ~str) -> port<Token> {
let result_port = port(); let (result_chan, result_port) = pipes::stream();
let result_chan = chan(result_port);
task::spawn(|| lex_css_from_bytes(str::bytes(content), result_chan)); task::spawn(|| lex_css_from_bytes(str::bytes(content), result_chan));
@ -252,22 +252,21 @@ fn spawn_css_lexer_from_string(-content : ~str) -> port<Token> {
} }
#[warn(no_non_implicitly_copyable_typarams)] #[warn(no_non_implicitly_copyable_typarams)]
fn spawn_css_lexer_from_file(-filename: ~str) -> port<Token> { fn spawn_css_lexer_task(-filename: ~str) -> pipes::port<Token> {
let result_port = port(); let (result_chan, result_port) = pipes::stream();
let result_chan = chan(result_port);
task::spawn(|| { task::spawn(|| {
assert (copy filename).ends_with(~".css"); assert filename.ends_with(".css");
let file_try = io::read_whole_file(filename); let file_try = io::read_whole_file(filename);
// Check if the given css file existed, if it does, parse it, // Check if the given css file existed, if it does, parse it,
// otherwise just send an eof. // otherwise just send an eof.
if file_try.is_ok() { if file_try.is_ok() {
#debug["Lexing css sheet %?", copy filename]; #debug["Lexing css sheet %?", filename];
let file_data = file_try.get(); let file_data = file_try.get();
lex_css_from_bytes(file_data, result_chan); lex_css_from_bytes(file_data, result_chan);
} else { } else {
#debug["Failed to open css sheet %?", copy filename]; #debug["Failed to open css sheet %?", filename];
result_chan.send(Eof); result_chan.send(Eof);
} }
}); });

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

@ -94,7 +94,7 @@ spawned, collates them, and sends them to the given result channel.
* `from_parent` - A port on which to receive new links. * `from_parent` - A port on which to receive new links.
"] "]
fn css_link_listener(to_parent : chan<Stylesheet>, from_parent : port<CSSMessage>) { fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::port<CSSMessage>) {
let mut result_vec = ~[]; let mut result_vec = ~[];
loop { loop {
@ -106,7 +106,7 @@ fn css_link_listener(to_parent : chan<Stylesheet>, from_parent : port<CSSMessage
task::spawn(|| { task::spawn(|| {
//TODO: deal with extraneous copies //TODO: deal with extraneous copies
let filename <- copy filename; let filename <- copy filename;
let css_stream = css_lexer::spawn_css_lexer_from_file(filename); let css_stream = css_lexer::spawn_css_lexer_task(filename);
let mut css_rules = css_builder::build_stylesheet(css_stream); let mut css_rules = css_builder::build_stylesheet(css_stream);
result_chan.send(css_rules); result_chan.send(css_rules);
}); });
@ -124,7 +124,7 @@ fn css_link_listener(to_parent : chan<Stylesheet>, from_parent : port<CSSMessage
to_parent.send(css_rules); to_parent.send(css_rules);
} }
fn js_script_listener(to_parent : chan<~[~[u8]]>, from_parent : port<js_message>) { fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port<js_message>) {
let mut result_vec = ~[]; let mut result_vec = ~[];
loop { loop {
@ -155,7 +155,7 @@ fn js_script_listener(to_parent : chan<~[~[u8]]>, from_parent : port<js_message>
} }
#[warn(no_non_implicitly_copyable_typarams)] #[warn(no_non_implicitly_copyable_typarams)]
fn build_dom(scope: NodeScope, stream: port<Token>) -> (Node, port<Stylesheet>, port<~[~[u8]]>) { fn build_dom(scope: NodeScope, stream: comm::port<Token>) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
// The current reference node. // The current reference node.
let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement))); let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
// We will spawn a separate task to parse any css that is // We will spawn a separate task to parse any css that is

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

@ -16,13 +16,15 @@ import std::cmp::fuzzy_eq;
import task::task_builder; import task::task_builder;
import vec::push; import vec::push;
type OSMain = chan<Msg>; import pipes::chan;
type OSMain = comm::chan<Msg>;
enum Msg { enum Msg {
BeginDrawing(chan<AzDrawTargetRef>), BeginDrawing(pipes::chan<AzDrawTargetRef>),
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef), Draw(pipes::chan<AzDrawTargetRef>, AzDrawTargetRef),
AddKeyHandler(chan<()>), AddKeyHandler(pipes::chan<()>),
AddEventListener(chan<Event>), AddEventListener(comm::chan<Event>),
Exit Exit
} }
@ -36,12 +38,17 @@ fn OSMain() -> OSMain {
} }
fn mainloop(po: port<Msg>) { fn mainloop(po: port<Msg>) {
let key_handlers: @dvec<chan<()>> = @dvec(); let key_handlers: @dvec<pipes::chan<()>> = @dvec();
let event_listeners: @dvec<chan<Event>> = @dvec(); let event_listeners: @dvec<comm::chan<Event>> = @dvec();
glut::init(); glut::init();
glut::init_display_mode(glut::DOUBLE); glut::init_display_mode(glut::DOUBLE);
#macro[
[#move[x],
unsafe { let y <- *ptr::addr_of(x); y }]
];
let surfaces = @surface_set(); let surfaces = @surface_set();
let window = glut::create_window(~"Servo"); let window = glut::create_window(~"Servo");
@ -65,7 +72,7 @@ fn mainloop(po: port<Msg>) {
while po.peek() { while po.peek() {
alt po.recv() { alt po.recv() {
AddKeyHandler(key_ch) { AddKeyHandler(key_ch) {
key_handlers.push(key_ch); key_handlers.push(#move(key_ch));
} }
AddEventListener(event_listener) { AddEventListener(event_listener) {
event_listeners.push(event_listener); event_listeners.push(event_listener);
@ -131,13 +138,13 @@ Implementation to allow the osmain channel to be used as a graphics
sink for the renderer sink for the renderer
"] "]
impl OSMain of Sink for OSMain { impl OSMain of Sink for OSMain {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>) { fn begin_drawing(+next_dt: pipes::chan<AzDrawTargetRef>) {
self.send(BeginDrawing(next_dt)) self.send(BeginDrawing(next_dt))
} }
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) { fn draw(+next_dt: pipes::chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
self.send(Draw(next_dt, draw_me)) self.send(Draw(next_dt, draw_me))
} }
fn add_event_listener(listener: chan<Event>) { fn add_event_listener(listener: comm::chan<Event>) {
self.send(AddEventListener(listener)); self.send(AddEventListener(listener));
} }
} }
@ -153,7 +160,7 @@ type surface_set = {
} }
}; };
fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) { fn lend_surface(surfaces: surface_set, recvr: pipes::chan<AzDrawTargetRef>) {
// We are in a position to lend out the surface? // We are in a position to lend out the surface?
assert surfaces.s1.have; assert surfaces.s1.have;
// Ok then take it // Ok then take it

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

@ -114,4 +114,3 @@ mod opts;
mod engine; mod engine;
import servo_text = text; import servo_text = text;

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

@ -5,6 +5,8 @@ import osmain::{OSMain, AddKeyHandler};
import opts::{Opts, Screen, Png}; import opts::{Opts, Screen, Png};
import engine::{Engine, LoadURLMsg}; import engine::{Engine, LoadURLMsg};
import pipes::{port, chan};
fn main(args: ~[~str]) { fn main(args: ~[~str]) {
run(opts::from_cmdline_args(args)) run(opts::from_cmdline_args(args))
} }
@ -30,28 +32,30 @@ fn run_pipeline_screen(urls: ~[~str]) {
// The platform event handler thread // The platform event handler thread
let osmain = OSMain(); let osmain = OSMain();
// Send each file to render then wait for keypress
let (keypress_to_engine, keypress_from_osmain) = pipes::stream();
osmain.send(AddKeyHandler(keypress_to_engine));
// Create a serve instance // Create a serve instance
let engine = Engine(osmain); let engine = Engine(osmain);
let engine_chan = engine.start(); let engine_chan = engine.start();
// Send each file to render then wait for keypress for urls.each |filename| {
listen(|keypress_from_osmain| { #debug["master: Sending filename `%s`", filename];
osmain.send(AddKeyHandler(keypress_from_osmain)); engine_chan.send(LoadURLMsg(copy filename));
#debug["master: Waiting for keypress"];
for urls.each |filename| { alt keypress_from_osmain.try_recv() {
#debug["master: Sending filename `%s`", filename]; some(*) { }
engine_chan.send(LoadURLMsg(copy filename)); none { #error("keypress stream closed unexpectedly") }
#debug["master: Waiting for keypress"]; };
keypress_from_osmain.recv(); }
}
});
// Shut everything down // Shut everything down
#debug["master: Shut down"]; #debug["master: Shut down"];
listen(|exit_response_from_engine| { let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_chan.send(engine::ExitMsg(exit_response_from_engine)); engine_chan.send(engine::ExitMsg(exit_chan));
exit_response_from_engine.recv(); exit_response_from_engine.recv();
});
osmain.send(osmain::Exit); osmain.send(osmain::Exit);
} }
@ -75,10 +79,9 @@ fn run_pipeline_png(-url: ~str, outfile: ~str) {
} }
err(e) { fail e } err(e) { fail e }
} }
listen(|exit_response_from_engine| { let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_chan.send(engine::ExitMsg(exit_response_from_engine)); engine_chan.send(engine::ExitMsg(exit_chan));
exit_response_from_engine.recv(); exit_response_from_engine.recv();
});
sink.send(pngsink::Exit); sink.send(pngsink::Exit);
}) })
} }