Stub event handling

This commit is contained in:
Patrick Walton 2012-07-12 15:49:05 -07:00
parent 62396c1cb9
commit b9f103a879
8 changed files with 104 additions and 47 deletions

View file

@ -7,14 +7,16 @@ export Content;
export ControlMsg, ExecuteMsg, ParseMsg, ExitMsg; export ControlMsg, ExecuteMsg, ParseMsg, ExitMsg;
export PingMsg, PongMsg; export PingMsg, PongMsg;
import comm::{port, chan, listen}; import comm::{port, chan, listen, select2};
import task::{spawn, spawn_listener}; import task::{spawn, spawn_listener};
import io::{read_whole_file, println}; import io::{read_whole_file, println};
import result::{ok, err}; import result::{ok, err};
import dom::base::NodeScope; import dom::base::NodeScope;
import dom::event::ResizeEvent;
import dom::rcu::WriterMethods; import dom::rcu::WriterMethods;
import dom::style; import dom::style;
import gfx::renderer::Sink;
import parser::html_lexer::spawn_html_lexer_task; import parser::html_lexer::spawn_html_lexer_task;
import parser::css_builder::build_stylesheet; import parser::css_builder::build_stylesheet;
import parser::html_builder::build_dom; import parser::html_builder::build_dom;
@ -25,6 +27,7 @@ import jsrt = js::rust::rt;
import js::rust::methods; import js::rust::methods;
import js::global::{global_class, debug_fns}; import js::global::{global_class, debug_fns};
import either::{left, right};
import result::extensions; import result::extensions;
type Content = chan<ControlMsg>; type Content = chan<ControlMsg>;
@ -53,13 +56,16 @@ fn join_layout(scope: NodeScope, layout: Layout) {
} }
#[warn(no_non_implicitly_copyable_typarams)] #[warn(no_non_implicitly_copyable_typarams)]
fn Content(layout: Layout) -> Content { fn Content<S:Sink send copy>(layout: Layout, sink: S) -> Content {
spawn_listener::<ControlMsg>(|from_master| { spawn_listener::<ControlMsg>(|from_master| {
let event_port = port();
sink.add_event_listener(event_port.chan());
let scope = NodeScope(); let scope = NodeScope();
let rt = jsrt(); let rt = jsrt();
loop { loop {
alt from_master.recv() { alt select2(from_master, event_port) {
ParseMsg(filename) { left(ParseMsg(filename)) {
#debug["content: Received filename `%s` to parse", *filename]; #debug["content: Received filename `%s` to parse", *filename];
// Note: we can parse the next document in parallel // Note: we can parse the next document in parallel
@ -85,7 +91,7 @@ fn Content(layout: Layout) -> Content {
scope.reader_forked(); scope.reader_forked();
} }
ExecuteMsg(filename) { left(ExecuteMsg(filename)) {
#debug["content: Received filename `%s` to execute", *filename]; #debug["content: Received filename `%s` to execute", *filename];
alt read_whole_file(*filename) { alt read_whole_file(*filename) {
@ -104,10 +110,14 @@ fn Content(layout: Layout) -> Content {
} }
} }
ExitMsg { left(ExitMsg) {
layout.send(layout_task::ExitMsg); layout.send(layout_task::ExitMsg);
break; break;
} }
right(ResizeEvent(new_width, new_height)) {
#debug("content got resize event: %d, %d", new_width, new_height);
}
} }
} }
}) })

4
src/servo/dom/event.rs Normal file
View file

@ -0,0 +1,4 @@
enum Event {
ResizeEvent(int, int)
}

View file

@ -5,46 +5,61 @@ import layout::layout_task;
import layout_task::Layout; import layout_task::Layout;
import content::{Content, ExecuteMsg, ParseMsg, ExitMsg}; import content::{Content, ExecuteMsg, ParseMsg, ExitMsg};
type Engine = chan<Msg>; class Engine<S:Sink send copy> {
let sink: S;
let renderer: Renderer;
let layout: Layout;
let content: Content;
new(sink: S) {
self.sink = sink;
let renderer = Renderer(sink);
let layout = Layout(renderer);
let content = Content(layout, sink);
self.renderer = renderer;
self.layout = layout;
self.content = content;
}
fn start() -> chan<Msg> {
do spawn_listener::<Msg> |request| {
while self.handle_request(request.recv()) {
// Go on...
}
}
}
fn handle_request(request: Msg) -> bool {
alt request {
LoadURLMsg(url) {
let url = copy url;
if (*url).ends_with(".js") {
self.content.send(ExecuteMsg(url))
} else {
self.content.send(ParseMsg(url))
}
ret true;
}
ExitMsg(sender) {
self.content.send(content::ExitMsg);
self.layout.send(layout_task::ExitMsg);
do listen |response_channel| {
self.renderer.send(renderer::ExitMsg(response_channel));
response_channel.recv();
}
sender.send(());
ret false;
}
}
}
}
enum Msg { enum Msg {
LoadURLMsg(~str), LoadURLMsg(~str),
ExitMsg(chan<()>) ExitMsg(chan<()>)
} }
fn Engine<S: Sink send copy>(sink: S) -> Engine {
spawn_listener::<Msg>(|request| {
// The renderer
let renderer = Renderer(sink);
// The layout task
let layout = Layout(renderer);
// The content task
let content = Content(layout);
loop {
alt request.recv() {
LoadURLMsg(url) {
let url = copy url;
if (*url).ends_with(".js") {
content.send(ExecuteMsg(url))
} else {
content.send(ParseMsg(url))
}
}
ExitMsg(sender) {
content.send(content::ExitMsg);
layout.send(layout_task::ExitMsg);
listen(|response_channel| {
renderer.send(renderer::ExitMsg(response_channel));
response_channel.recv();
});
sender.send(());
break;
}
}
}
})
}

View file

@ -23,6 +23,7 @@ import comm::chan;
import unsafe::reinterpret_cast; import unsafe::reinterpret_cast;
import vec_from_buf = vec::unsafe::from_buf; import vec_from_buf = vec::unsafe::from_buf;
import ptr::addr_of; import ptr::addr_of;
import dom::event::Event;
type PngSink = chan<Msg>; type PngSink = chan<Msg>;
@ -39,6 +40,9 @@ impl PngSink of Sink for chan<Msg> {
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) { fn draw(next_dt: 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>) {
// No events in this sink.
}
} }
fn PngSink(output: chan<[u8]>) -> PngSink { fn PngSink(output: chan<[u8]>) -> PngSink {

View file

@ -7,6 +7,7 @@ import azure::*;
import azure::bindgen::*; import azure::bindgen::*;
import libc::size_t; import libc::size_t;
import text::text_run::TextRun; import text::text_run::TextRun;
import dom::event::{Event, ResizeEvent};
type Renderer = chan<Msg>; type Renderer = chan<Msg>;
@ -18,10 +19,13 @@ enum Msg {
#[doc = " #[doc = "
The interface used to by the renderer to aquire draw targets for The interface used to by the renderer to aquire draw targets for
each rendered frame and submit them to be drawn to the display each rendered frame and submit them to be drawn to the display
FIXME: Change this name to Compositor.
"] "]
iface Sink { iface Sink {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>); fn begin_drawing(next_dt: chan<AzDrawTargetRef>);
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef); fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef);
fn add_event_listener(listener: chan<Event>);
} }
fn Renderer<S: Sink send copy>(sink: S) -> chan<Msg> { fn Renderer<S: Sink send copy>(sink: S) -> chan<Msg> {

View file

@ -6,8 +6,10 @@ import azure::bindgen::*;
import azure::cairo; import azure::cairo;
import azure::cairo::bindgen::*; import azure::cairo::bindgen::*;
import comm::*; import comm::*;
import dvec::{dvec, extensions};
import azure::cairo::cairo_surface_t; import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink}; import gfx::renderer::{Sink};
import dom::event::{Event, ResizeEvent};
import layers::ImageLayer; import layers::ImageLayer;
import geom::size::Size2D; import geom::size::Size2D;
import std::cmp::fuzzy_eq; import std::cmp::fuzzy_eq;
@ -18,6 +20,7 @@ enum Msg {
BeginDrawing(chan<AzDrawTargetRef>), BeginDrawing(chan<AzDrawTargetRef>),
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef), Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
AddKeyHandler(chan<()>), AddKeyHandler(chan<()>),
AddEventListener(chan<Event>),
Exit Exit
} }
@ -32,6 +35,7 @@ fn OSMain() -> OSMain {
fn mainloop(po: port<Msg>) { fn mainloop(po: port<Msg>) {
let mut key_handlers: [chan<()>] = []; let mut key_handlers: [chan<()>] = [];
let event_listeners: @dvec<chan<Event>> = @dvec();
glut::init(); glut::init();
glut::init_display_mode(glut::DOUBLE); glut::init_display_mode(glut::DOUBLE);
@ -51,6 +55,13 @@ fn mainloop(po: port<Msg>) {
let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer), let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
Size2D(800.0f32, 600.0f32)); Size2D(800.0f32, 600.0f32));
do glut::reshape_func(window) |width, height| {
#debug("osmain: window resized to %d,%d", width as int, height as int);
for event_listeners.each |event_listener| {
event_listener.send(ResizeEvent(width as int, height as int));
}
}
loop { loop {
do glut::display_func() { do glut::display_func() {
#debug("osmain: drawing to screen"); #debug("osmain: drawing to screen");
@ -66,6 +77,9 @@ fn mainloop(po: port<Msg>) {
AddKeyHandler(key_ch) { AddKeyHandler(key_ch) {
key_handlers += [key_ch]; key_handlers += [key_ch];
} }
AddEventListener(event_listener) {
event_listeners.push(event_listener);
}
BeginDrawing(sender) { BeginDrawing(sender) {
lend_surface(surfaces, sender); lend_surface(surfaces, sender);
} }
@ -107,6 +121,9 @@ impl OSMain of Sink for OSMain {
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) { fn draw(next_dt: 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>) {
self.send(AddEventListener(listener));
}
} }
type surface_set = { type surface_set = {

View file

@ -20,6 +20,7 @@ use layers;
mod dom { mod dom {
mod base; mod base;
mod event;
mod rcu; mod rcu;
mod style; mod style;
} }

View file

@ -32,6 +32,7 @@ fn run_pipeline_screen(urls: [str]) {
// Create a serve instance // Create a serve instance
let engine = Engine(osmain); let engine = Engine(osmain);
let engine_chan = engine.start();
// Send each file to render then wait for keypress // Send each file to render then wait for keypress
listen(|keypress_from_osmain| { listen(|keypress_from_osmain| {
@ -39,7 +40,7 @@ fn run_pipeline_screen(urls: [str]) {
for urls.each |filename| { for urls.each |filename| {
#debug["master: Sending filename `%s`", filename]; #debug["master: Sending filename `%s`", filename];
engine.send(LoadURLMsg(~copy filename)); engine_chan.send(LoadURLMsg(~copy filename));
#debug["master: Waiting for keypress"]; #debug["master: Waiting for keypress"];
keypress_from_osmain.recv(); keypress_from_osmain.recv();
} }
@ -48,7 +49,7 @@ fn run_pipeline_screen(urls: [str]) {
// Shut everything down // Shut everything down
#debug["master: Shut down"]; #debug["master: Shut down"];
listen(|exit_response_from_engine| { listen(|exit_response_from_engine| {
engine.send(engine::ExitMsg(exit_response_from_engine)); engine_chan.send(engine::ExitMsg(exit_response_from_engine));
exit_response_from_engine.recv(); exit_response_from_engine.recv();
}); });
osmain.send(osmain::Exit); osmain.send(osmain::Exit);
@ -65,8 +66,9 @@ fn run_pipeline_png(-url: str, outfile: str) {
listen(|pngdata_from_sink| { listen(|pngdata_from_sink| {
let sink = PngSink(pngdata_from_sink); let sink = PngSink(pngdata_from_sink);
let engine = Engine(sink); let engine = Engine(sink);
let engine_chan = engine.start();
let url = copy url; let url = copy url;
engine.send(LoadURLMsg(~url)); engine_chan.send(LoadURLMsg(~url));
alt buffered_file_writer(outfile) { alt buffered_file_writer(outfile) {
ok(writer) { ok(writer) {
writer.write(pngdata_from_sink.recv()) writer.write(pngdata_from_sink.recv())
@ -74,7 +76,7 @@ fn run_pipeline_png(-url: str, outfile: str) {
err(e) { fail e } err(e) { fail e }
} }
listen(|exit_response_from_engine| { listen(|exit_response_from_engine| {
engine.send(engine::ExitMsg(exit_response_from_engine)); engine_chan.send(engine::ExitMsg(exit_response_from_engine));
exit_response_from_engine.recv(); exit_response_from_engine.recv();
}); });
sink.send(pngsink::Exit); sink.send(pngsink::Exit);