mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Stub event handling
This commit is contained in:
parent
62396c1cb9
commit
b9f103a879
8 changed files with 104 additions and 47 deletions
|
@ -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
4
src/servo/dom/event.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
enum Event {
|
||||||
|
ResizeEvent(int, int)
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use layers;
|
||||||
|
|
||||||
mod dom {
|
mod dom {
|
||||||
mod base;
|
mod base;
|
||||||
|
mod event;
|
||||||
mod rcu;
|
mod rcu;
|
||||||
mod style;
|
mod style;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue