Cleanup for new conventions

This commit is contained in:
Brian Anderson 2012-06-22 01:39:56 -07:00
parent b1b0434bc4
commit b754510d53
8 changed files with 167 additions and 131 deletions

View file

@ -3,21 +3,31 @@
tasks.
"]
export ControlMsg, PingMsg;
export content;
export Content, ControlMsg, PingMsg;
import comm::{port, chan, listen};
import task::{spawn, spawn_listener};
import io::{read_whole_file, println};
import result::{ok, err};
import dom::base::NodeScope;
import dom::rcu::WriterMethods;
import dom::style;
import style::print_sheet;
import parser::lexer::{spawn_css_lexer_task, spawn_html_parser_task};
import parser::css_builder::build_stylesheet;
import parser::html_builder::build_dom;
import layout::layout_task;
import layout_task::{Layout, BuildMsg};
import jsrt = js::rust::rt;
import js::rust::methods;
import js::global::{global_class, debug_fns};
import result::extensions;
type Content = chan<ControlMsg>;
enum ControlMsg {
ParseMsg(~str),
ExecuteMsg(~str),
@ -30,24 +40,23 @@ enum PingMsg {
#[doc="Sends a ping to layout and waits for the response."]
#[warn(no_non_implicitly_copyable_typarams)]
fn join_layout(scope: NodeScope, to_layout: chan<layout_task::Msg>) {
fn join_layout(scope: NodeScope, layout: Layout) {
if scope.is_reader_forked() {
comm::listen {
|from_layout|
to_layout.send(layout_task::PingMsg(from_layout));
from_layout.recv();
listen { |response_from_layout|
layout.send(layout_task::PingMsg(response_from_layout));
response_from_layout.recv();
}
scope.reader_joined();
}
}
#[warn(no_non_implicitly_copyable_typarams)]
fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> {
task::spawn_listener::<ControlMsg> {
fn Content(layout: Layout) -> Content {
spawn_listener::<ControlMsg> {
|from_master|
let scope = NodeScope();
let rt = js::rust::rt();
let rt = jsrt();
loop {
alt from_master.recv() {
ParseMsg(filename) {
@ -59,9 +68,9 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> {
let new_file = (*filename).substr(0u, (*filename).len() - 5u) + ".css";
// Send off a task to parse the stylesheet
let css_port = comm::port();
let css_chan = comm::chan(css_port);
task::spawn {||
let css_port = port();
let css_chan = chan(css_port);
spawn { ||
let new_file = copy new_file;
let css_stream = spawn_css_lexer_task(~new_file);
let css_rules = build_stylesheet(css_stream);
@ -74,19 +83,19 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> {
let root = build_dom(scope, stream);
// Collect the css stylesheet
let css_rules = comm::recv(css_port);
let css_rules = css_port.recv();
// Apply the css rules to the dom tree:
// TODO
#debug["%s",style::print_sheet(css_rules)];
#debug["%s", print_sheet(css_rules)];
// Now, join the layout so that they will see the latest
// changes we have made.
join_layout(scope, to_layout);
join_layout(scope, layout);
// Send new document to layout.
to_layout.send(layout_task::BuildMsg(root, css_rules));
layout.send(BuildMsg(root, css_rules));
// Indicate that reader was forked so any further
// changes will be isolated.
@ -96,17 +105,17 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> {
ExecuteMsg(filename) {
#debug["content: Received filename `%s` to execute", *filename];
alt io::read_whole_file(*filename) {
result::err(msg) {
io::println(#fmt["Error opening %s: %s", *filename, msg]);
alt read_whole_file(*filename) {
err(msg) {
println(#fmt["Error opening %s: %s", *filename, msg]);
}
result::ok(bytes) {
ok(bytes) {
let cx = rt.cx();
cx.set_default_options_and_version();
cx.set_logging_error_reporter();
cx.new_compartment(js::global::global_class).chain {
cx.new_compartment(global_class).chain {
|compartment|
compartment.define_functions(js::global::debug_fns);
compartment.define_functions(debug_fns);
cx.evaluate_script(compartment.global_obj, bytes, *filename, 1u)
};
}
@ -114,7 +123,7 @@ fn content(to_layout: chan<layout_task::Msg>) -> chan<ControlMsg> {
}
ExitMsg {
to_layout.send(layout_task::ExitMsg);
layout.send(layout_task::ExitMsg);
break;
}
}

View file

@ -1,36 +1,42 @@
import gfx::renderer::{Renderer, Sink};
import task::spawn_listener;
import comm::chan;
import gfx::renderer;
import layout::layout_task;
import layout_task::Layout;
import content::{Content, ExecuteMsg, ParseMsg};
type Engine = chan<Msg>;
enum Msg {
LoadURLMsg(~str),
ExitMsg(comm::chan<()>)
ExitMsg(chan<()>)
}
fn engine<S:renderer::sink send copy>(sink: S) -> chan<Msg> {
task::spawn_listener::<Msg> {|self_ch|
fn Engine<S: Sink send copy>(sink: S) -> Engine {
spawn_listener::<Msg> { |request|
// The renderer
let renderer = renderer::renderer(sink);
let renderer = Renderer(sink);
// The layout task
let layout = layout::layout_task::layout(renderer);
let layout = Layout(renderer);
// The content task
let content = content::content(layout);
let content = Content(layout);
loop {
alt self_ch.recv() {
alt request.recv() {
LoadURLMsg(url) {
let url = copy url;
if (*url).ends_with(".js") {
content.send(content::ExecuteMsg(url))
content.send(ExecuteMsg(url))
} else {
content.send(content::ParseMsg(url))
content.send(ParseMsg(url))
}
}
ExitMsg(sender) {
content.send(content::ExitMsg);
layout.send(layout::layout_task::ExitMsg);
layout.send(layout_task::ExitMsg);
listen {
|response_channel|
renderer.send(renderer::ExitMsg(response_channel));

View file

@ -5,64 +5,76 @@ Each time the renderer renders a frame the bufsink will output a
`[u8]` containing the frame in PNG format.
"];
export msg, pngsink;
export PngSink, Msg;
import azure::cairo;
import azure_bg = azure::bindgen;
import libc::{c_int, c_uint, c_void, c_uchar};
import azure::AzDrawTargetRef;
import azure_bg = azure::bindgen;
import azure_bg::{AzCreateDrawTargetForCairoSurface, AzReleaseDrawTarget};
import azure::cairo;
import cairo::{CAIRO_FORMAT_ARGB32, cairo_surface_t, cairo_status_t,
CAIRO_STATUS_SUCCESS};
import cairo_bg = cairo::bindgen;
import cairo_bg::{cairo_image_surface_create, cairo_surface_destroy,
cairo_surface_write_to_png_stream};
import renderer::{Renderer, Sink, RenderMsg};
import task::spawn_listener;
import comm::chan;
import unsafe::reinterpret_cast;
import vec_from_buf = vec::unsafe::from_buf;
import ptr::addr_of;
enum msg {
begin_drawing(chan<AzDrawTargetRef>),
draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
exit
type PngSink = chan<Msg>;
enum Msg {
BeginDrawing(chan<AzDrawTargetRef>),
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
Exit
}
impl pngsink of renderer::sink for chan<msg> {
impl PngSink of Sink for chan<Msg> {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
self.send(begin_drawing(next_dt))
self.send(BeginDrawing(next_dt))
}
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
self.send(draw(next_dt, draw_me))
self.send(Draw(next_dt, draw_me))
}
}
fn pngsink(output: chan<[u8]>) -> chan<msg> {
task::spawn_listener::<msg> { |po|
fn PngSink(output: chan<[u8]>) -> PngSink {
spawn_listener::<Msg> { |po|
let cairo_surf = cairo_bg::cairo_image_surface_create(
cairo::CAIRO_FORMAT_ARGB32, 800 as libc::c_int, 600 as libc::c_int
let cairo_surf = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, 800 as c_int, 600 as c_int
);
assert cairo_surf.is_not_null();
let draw_target = azure_bg::AzCreateDrawTargetForCairoSurface(cairo_surf);
let draw_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
assert draw_target.is_not_null();
loop {
alt po.recv() {
begin_drawing(sender) {
BeginDrawing(sender) {
#debug("pngsink: begin_drawing");
sender.send(draw_target);
}
draw(sender, dt) {
Draw(sender, dt) {
#debug("pngsink: draw");
do_draw(sender, dt, output, cairo_surf);
}
exit { break }
Exit { break }
}
}
azure_bg::AzReleaseDrawTarget(draw_target);
cairo_bg::cairo_surface_destroy(cairo_surf);
AzReleaseDrawTarget(draw_target);
cairo_surface_destroy(cairo_surf);
}
}
fn do_draw(sender: chan<AzDrawTargetRef>,
dt: AzDrawTargetRef,
output: comm::chan<[u8]>,
cairo_surf: *cairo::cairo_surface_t) {
import libc::*;
output: chan<[u8]>,
cairo_surf: *cairo_surface_t) {
listen {|data_ch|
@ -70,26 +82,26 @@ fn do_draw(sender: chan<AzDrawTargetRef>,
data: *c_uchar,
len: c_uint)
-> cairo::cairo_status_t unsafe {
-> cairo_status_t unsafe {
let p: *chan<[u8]> = unsafe::reinterpret_cast(closure);
let p: *chan<[u8]> = reinterpret_cast(closure);
let data_ch = *p;
// Convert from *c_uchar to *u8
let data = unsafe::reinterpret_cast(data);
let data = reinterpret_cast(data);
let len = len as uint;
// Copy to a vector
let data = vec::unsafe::from_buf(data, len);
let data = vec_from_buf(data, len);
data_ch.send(data);
ret cairo::CAIRO_STATUS_SUCCESS;
ret CAIRO_STATUS_SUCCESS;
}
let closure = ptr::addr_of(data_ch);
let closure = addr_of(data_ch);
unsafe {
cairo_bg::cairo_surface_write_to_png_stream(
cairo_surf, write_fn, unsafe::reinterpret_cast(closure));
cairo_surface_write_to_png_stream(
cairo_surf, write_fn, reinterpret_cast(closure));
}
// Collect the entire image into a single vector
@ -110,17 +122,17 @@ fn sanity_check() {
listen {
|self_channel|
let sink = pngsink(self_channel);
let renderer = renderer::renderer(sink);
let sink = PngSink(self_channel);
let renderer = Renderer(sink);
let dlist = [];
renderer.send(renderer::RenderMsg(dlist));
renderer.send(RenderMsg(dlist));
listen {
|from_renderer|
renderer.send(renderer::ExitMsg(from_renderer));
from_renderer.recv();
}
sink.send(exit)
sink.send(Exit)
}
}

View file

@ -8,6 +8,8 @@ import azure::bindgen::*;
import libc::size_t;
import text::text_run::TextRun;
type Renderer = chan<Msg>;
enum Msg {
RenderMsg(dl::display_list),
ExitMsg(comm::chan<()>)
@ -17,12 +19,12 @@ enum Msg {
The interface used to by the renderer to aquire draw targets for
each rendered frame and submit them to be drawn to the display
"]
iface sink {
iface Sink {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>);
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef);
}
fn renderer<S: sink send copy>(sink: S) -> chan<Msg> {
fn Renderer<S: Sink send copy>(sink: S) -> chan<Msg> {
task::spawn_listener::<Msg> {|po|
listen {
|draw_target_ch|

View file

@ -9,6 +9,7 @@ import display_list_builder::build_display_list;
import dom::base::{Node};
import dom::style::stylesheet;
import gfx::geometry::px_to_au;
import gfx::renderer::Renderer;
import base::{NodeMethods, layout_methods};
import layout::style::style::style_methods;
import box_builder::box_builder_methods;
@ -17,16 +18,18 @@ import layout::style::apply::ApplyStyleBoxMethods;
import task::*;
import comm::*;
type Layout = chan<Msg>;
enum Msg {
BuildMsg(Node, stylesheet),
PingMsg(chan<content::PingMsg>),
ExitMsg
}
fn layout(to_renderer: chan<renderer::Msg>) -> chan<Msg> {
spawn_listener::<Msg> { |po|
fn Layout(renderer: Renderer) -> Layout {
spawn_listener::<Msg> { |request|
loop {
alt po.recv() {
alt request.recv() {
PingMsg(ping_channel) {
ping_channel.send(content::PongMsg);
}
@ -47,7 +50,7 @@ fn layout(to_renderer: chan<renderer::Msg>) -> chan<Msg> {
this_box.reflow(px_to_au(800));
let dlist = build_display_list(this_box);
to_renderer.send(renderer::RenderMsg(dlist));
renderer.send(renderer::RenderMsg(dlist));
}
}
}

View file

@ -5,18 +5,18 @@ from command line arguments.
"];
type opts = {
type Opts = {
urls: [str],
render_mode: render_mode
render_mode: RenderMode
};
enum render_mode {
screen,
png(str)
enum RenderMode {
Screen,
Png(str)
}
#[warn(no_non_implicitly_copyable_typarams)]
fn from_cmdline_args(args: [str]) -> opts {
fn from_cmdline_args(args: [str]) -> Opts {
import std::getopts;
let args = args.tail();
@ -37,8 +37,8 @@ fn from_cmdline_args(args: [str]) -> opts {
};
let render_mode = alt getopts::opt_maybe_str(match, "o") {
some(output_file) { png(copy output_file) }
none { screen }
some(output_file) { Png(copy output_file) }
none { Screen }
};
{

View file

@ -1,4 +1,4 @@
export msg, osmain, gfxsink;
export OSMain, Msg;
import azure::*;
import azure::bindgen::*;
@ -6,17 +6,19 @@ import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import azure::cairo::cairo_surface_t;
import gfx::renderer;
import gfx::renderer::{Sink};
enum msg {
begin_drawing(chan<AzDrawTargetRef>),
draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
add_key_handler(chan<()>),
exit
type OSMain = chan<Msg>;
enum Msg {
BeginDrawing(chan<AzDrawTargetRef>),
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
AddKeyHandler(chan<()>),
Exit
}
fn osmain() -> chan<msg> {
on_osmain::<msg> {|po|
fn OSMain() -> OSMain {
on_osmain::<Msg> {|po|
platform::runmain {||
#debug("preparing to enter main loop");
mainloop(po);
@ -24,7 +26,7 @@ fn osmain() -> chan<msg> {
}
}
fn mainloop(po: port<msg>) {
fn mainloop(po: port<Msg>) {
let mut key_handlers: [chan<()>] = [];
@ -42,6 +44,7 @@ fn mainloop(po: port<msg>) {
loop {
sdl::event::poll_event {|event|
alt event {
sdl::event::keydown_event(_) {
key_handlers.iter {|key_ch|
@ -55,13 +58,13 @@ fn mainloop(po: port<msg>) {
// Handle messages
if po.peek() {
alt check po.recv() {
add_key_handler(key_ch) {
AddKeyHandler(key_ch) {
key_handlers += [key_ch];
}
begin_drawing(sender) {
BeginDrawing(sender) {
lend_surface(surfaces, sender);
}
draw(sender, dt) {
Draw(sender, dt) {
return_surface(surfaces, dt);
lend_surface(surfaces, sender);
@ -89,12 +92,12 @@ fn mainloop(po: port<msg>) {
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl gfxsink of renderer::sink for chan<msg> {
impl OSMain of Sink for OSMain {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
self.send(begin_drawing(next_dt))
self.send(BeginDrawing(next_dt))
}
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
self.send(draw(next_dt, draw_me))
self.send(Draw(next_dt, draw_me))
}
}

View file

@ -3,18 +3,21 @@ import parser::lexer;
import result::extensions;
import gfx::renderer;
import platform::osmain;
import osmain::{OSMain, AddKeyHandler};
import opts::{Opts, Screen, Png};
import engine::{Engine, LoadURLMsg};
fn main(args: [str]) {
run(opts::from_cmdline_args(args))
}
#[warn(no_non_implicitly_copyable_typarams)]
fn run(opts: opts::opts) {
fn run(opts: Opts) {
alt opts.render_mode {
opts::screen {
Screen {
run_pipeline_screen(opts.urls)
}
opts::png(outfile) {
Png(outfile) {
assert opts.urls.is_not_empty();
if opts.urls.len() > 1u {
fail "servo asks that you stick to a single URL in PNG output mode"
@ -26,58 +29,56 @@ fn run(opts: opts::opts) {
fn run_pipeline_screen(urls: [str]) {
// Use the platform thread as the renderer sink
import osmain::gfxsink;
// The platform event handler thread
let osmain = osmain::osmain();
let osmain = OSMain();
// Create a serve instance
let engine = engine::engine(osmain);
let engine = Engine(osmain);
// Send each file to render then wait for keypress
listen {|key_ch|
osmain.send(platform::osmain::add_key_handler(key_ch));
listen { |keypress_from_osmain|
osmain.send(AddKeyHandler(keypress_from_osmain));
for urls.each { |filename|
#debug["master: Sending filename `%s`", filename];
engine.send(engine::LoadURLMsg(~copy filename));
engine.send(LoadURLMsg(~copy filename));
#debug["master: Waiting for keypress"];
key_ch.recv();
keypress_from_osmain.recv();
}
}
// Shut everything down
#debug["master: Shut down"];
listen {|resp_ch|
engine.send(engine::ExitMsg(resp_ch));
resp_ch.recv();
listen { |exit_response_from_engine|
engine.send(engine::ExitMsg(exit_response_from_engine));
exit_response_from_engine.recv();
}
osmain.send(platform::osmain::exit);
osmain.send(osmain::Exit);
}
fn run_pipeline_png(-url: str, outfile: str) {
// Use a PNG encoder as the graphics sink
import gfx::pngsink;
import pngsink::pngsink;
import pngsink::PngSink;
import result::{ok, err};
import io::{writer, buffered_file_writer};
listen {|pngdata|
let sink = pngsink::pngsink(pngdata);
let engine = engine::engine(sink);
listen { |pngdata_from_sink|
let sink = PngSink(pngdata_from_sink);
let engine = Engine(sink);
let url = copy url;
engine.send(engine::LoadURLMsg(~url));
alt io::buffered_file_writer(outfile) {
result::ok(writer) {
import io::writer;
writer.write(pngdata.recv())
engine.send(LoadURLMsg(~url));
alt buffered_file_writer(outfile) {
ok(writer) {
writer.write(pngdata_from_sink.recv())
}
result::err(e) { fail e }
err(e) { fail e }
}
listen {|response_channel|
engine.send(engine::ExitMsg(response_channel));
response_channel.recv();
listen { |exit_response_from_engine|
engine.send(engine::ExitMsg(exit_response_from_engine));
exit_response_from_engine.recv();
}
sink.send(pngsink::exit);
sink.send(pngsink::Exit);
}
}