зеркало из https://github.com/mozilla/gecko-dev.git
servo: Stub event handling
Source-Repo: https://github.com/servo/servo Source-Revision: b9f103a879d2f6b59de9a29a2cf2d0a366133a9b
This commit is contained in:
Родитель
0575af237c
Коммит
173ae430f3
|
@ -7,14 +7,16 @@ export Content;
|
|||
export ControlMsg, ExecuteMsg, ParseMsg, ExitMsg;
|
||||
export PingMsg, PongMsg;
|
||||
|
||||
import comm::{port, chan, listen};
|
||||
import comm::{port, chan, listen, select2};
|
||||
import task::{spawn, spawn_listener};
|
||||
import io::{read_whole_file, println};
|
||||
import result::{ok, err};
|
||||
|
||||
import dom::base::NodeScope;
|
||||
import dom::event::ResizeEvent;
|
||||
import dom::rcu::WriterMethods;
|
||||
import dom::style;
|
||||
import gfx::renderer::Sink;
|
||||
import parser::html_lexer::spawn_html_lexer_task;
|
||||
import parser::css_builder::build_stylesheet;
|
||||
import parser::html_builder::build_dom;
|
||||
|
@ -25,6 +27,7 @@ import jsrt = js::rust::rt;
|
|||
import js::rust::methods;
|
||||
import js::global::{global_class, debug_fns};
|
||||
|
||||
import either::{left, right};
|
||||
import result::extensions;
|
||||
|
||||
type Content = chan<ControlMsg>;
|
||||
|
@ -53,13 +56,16 @@ fn join_layout(scope: NodeScope, layout: Layout) {
|
|||
}
|
||||
|
||||
#[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| {
|
||||
let event_port = port();
|
||||
sink.add_event_listener(event_port.chan());
|
||||
|
||||
let scope = NodeScope();
|
||||
let rt = jsrt();
|
||||
loop {
|
||||
alt from_master.recv() {
|
||||
ParseMsg(filename) {
|
||||
alt select2(from_master, event_port) {
|
||||
left(ParseMsg(filename)) {
|
||||
#debug["content: Received filename `%s` to parse", *filename];
|
||||
|
||||
// Note: we can parse the next document in parallel
|
||||
|
@ -85,7 +91,7 @@ fn Content(layout: Layout) -> Content {
|
|||
scope.reader_forked();
|
||||
}
|
||||
|
||||
ExecuteMsg(filename) {
|
||||
left(ExecuteMsg(filename)) {
|
||||
#debug["content: Received filename `%s` to execute", *filename];
|
||||
|
||||
alt read_whole_file(*filename) {
|
||||
|
@ -104,10 +110,14 @@ fn Content(layout: Layout) -> Content {
|
|||
}
|
||||
}
|
||||
|
||||
ExitMsg {
|
||||
left(ExitMsg) {
|
||||
layout.send(layout_task::ExitMsg);
|
||||
break;
|
||||
}
|
||||
|
||||
right(ResizeEvent(new_width, new_height)) {
|
||||
#debug("content got resize event: %d, %d", new_width, new_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
enum Event {
|
||||
ResizeEvent(int, int)
|
||||
}
|
||||
|
|
@ -5,46 +5,61 @@ import layout::layout_task;
|
|||
import layout_task::Layout;
|
||||
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 {
|
||||
LoadURLMsg(~str),
|
||||
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 vec_from_buf = vec::unsafe::from_buf;
|
||||
import ptr::addr_of;
|
||||
import dom::event::Event;
|
||||
|
||||
type PngSink = chan<Msg>;
|
||||
|
||||
|
@ -39,6 +40,9 @@ impl PngSink of Sink for chan<Msg> {
|
|||
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
|
||||
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 {
|
||||
|
|
|
@ -7,6 +7,7 @@ import azure::*;
|
|||
import azure::bindgen::*;
|
||||
import libc::size_t;
|
||||
import text::text_run::TextRun;
|
||||
import dom::event::{Event, ResizeEvent};
|
||||
|
||||
type Renderer = chan<Msg>;
|
||||
|
||||
|
@ -18,10 +19,13 @@ enum Msg {
|
|||
#[doc = "
|
||||
The interface used to by the renderer to aquire draw targets for
|
||||
each rendered frame and submit them to be drawn to the display
|
||||
|
||||
FIXME: Change this name to Compositor.
|
||||
"]
|
||||
iface Sink {
|
||||
fn begin_drawing(next_dt: chan<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> {
|
||||
|
|
|
@ -6,8 +6,10 @@ import azure::bindgen::*;
|
|||
import azure::cairo;
|
||||
import azure::cairo::bindgen::*;
|
||||
import comm::*;
|
||||
import dvec::{dvec, extensions};
|
||||
import azure::cairo::cairo_surface_t;
|
||||
import gfx::renderer::{Sink};
|
||||
import dom::event::{Event, ResizeEvent};
|
||||
import layers::ImageLayer;
|
||||
import geom::size::Size2D;
|
||||
import std::cmp::fuzzy_eq;
|
||||
|
@ -18,6 +20,7 @@ enum Msg {
|
|||
BeginDrawing(chan<AzDrawTargetRef>),
|
||||
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
|
||||
AddKeyHandler(chan<()>),
|
||||
AddEventListener(chan<Event>),
|
||||
Exit
|
||||
}
|
||||
|
||||
|
@ -32,6 +35,7 @@ fn OSMain() -> OSMain {
|
|||
|
||||
fn mainloop(po: port<Msg>) {
|
||||
let mut key_handlers: [chan<()>] = [];
|
||||
let event_listeners: @dvec<chan<Event>> = @dvec();
|
||||
|
||||
glut::init();
|
||||
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),
|
||||
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 {
|
||||
do glut::display_func() {
|
||||
#debug("osmain: drawing to screen");
|
||||
|
@ -66,6 +77,9 @@ fn mainloop(po: port<Msg>) {
|
|||
AddKeyHandler(key_ch) {
|
||||
key_handlers += [key_ch];
|
||||
}
|
||||
AddEventListener(event_listener) {
|
||||
event_listeners.push(event_listener);
|
||||
}
|
||||
BeginDrawing(sender) {
|
||||
lend_surface(surfaces, sender);
|
||||
}
|
||||
|
@ -107,6 +121,9 @@ impl OSMain of Sink for OSMain {
|
|||
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
|
||||
self.send(Draw(next_dt, draw_me))
|
||||
}
|
||||
fn add_event_listener(listener: chan<Event>) {
|
||||
self.send(AddEventListener(listener));
|
||||
}
|
||||
}
|
||||
|
||||
type surface_set = {
|
||||
|
|
|
@ -20,6 +20,7 @@ use layers;
|
|||
|
||||
mod dom {
|
||||
mod base;
|
||||
mod event;
|
||||
mod rcu;
|
||||
mod style;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ fn run_pipeline_screen(urls: [str]) {
|
|||
|
||||
// Create a serve instance
|
||||
let engine = Engine(osmain);
|
||||
let engine_chan = engine.start();
|
||||
|
||||
// Send each file to render then wait for keypress
|
||||
listen(|keypress_from_osmain| {
|
||||
|
@ -39,7 +40,7 @@ fn run_pipeline_screen(urls: [str]) {
|
|||
|
||||
for urls.each |filename| {
|
||||
#debug["master: Sending filename `%s`", filename];
|
||||
engine.send(LoadURLMsg(~copy filename));
|
||||
engine_chan.send(LoadURLMsg(~copy filename));
|
||||
#debug["master: Waiting for keypress"];
|
||||
keypress_from_osmain.recv();
|
||||
}
|
||||
|
@ -48,7 +49,7 @@ fn run_pipeline_screen(urls: [str]) {
|
|||
// Shut everything down
|
||||
#debug["master: Shut down"];
|
||||
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();
|
||||
});
|
||||
osmain.send(osmain::Exit);
|
||||
|
@ -65,8 +66,9 @@ fn run_pipeline_png(-url: str, outfile: str) {
|
|||
listen(|pngdata_from_sink| {
|
||||
let sink = PngSink(pngdata_from_sink);
|
||||
let engine = Engine(sink);
|
||||
let engine_chan = engine.start();
|
||||
let url = copy url;
|
||||
engine.send(LoadURLMsg(~url));
|
||||
engine_chan.send(LoadURLMsg(~url));
|
||||
alt buffered_file_writer(outfile) {
|
||||
ok(writer) {
|
||||
writer.write(pngdata_from_sink.recv())
|
||||
|
@ -74,7 +76,7 @@ fn run_pipeline_png(-url: str, outfile: str) {
|
|||
err(e) { fail e }
|
||||
}
|
||||
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();
|
||||
});
|
||||
sink.send(pngsink::Exit);
|
||||
|
|
Загрузка…
Ссылка в новой задаче