mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Convert the content task's control messages and dom events to pipes
This commit is contained in:
parent
c2377c574c
commit
bee47744a3
7 changed files with 70 additions and 40 deletions
|
@ -42,6 +42,7 @@ use std::net::url::Url;
|
|||
use url_to_str = std::net::url::to_str;
|
||||
use util::url::make_url;
|
||||
use task::{task, SingleThreaded};
|
||||
use std::cell::Cell;
|
||||
|
||||
use js::glue::bindgen::RUST_JSVAL_TO_OBJECT;
|
||||
use js::JSVAL_NULL;
|
||||
|
@ -60,17 +61,30 @@ pub enum PingMsg {
|
|||
PongMsg
|
||||
}
|
||||
|
||||
pub type ContentTask = Chan<ControlMsg>;
|
||||
pub type ContentTask = pipes::SharedChan<ControlMsg>;
|
||||
|
||||
fn ContentTask<S: Compositor Send Copy>(layout_task: LayoutTask,
|
||||
compositor: S,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask) -> ContentTask {
|
||||
do task().sched_mode(SingleThreaded).spawn_listener::<ControlMsg> |from_master| {
|
||||
let content = Content(layout_task, from_master, resource_task, img_cache_task.clone());
|
||||
compositor.add_event_listener(content.event_port.chan());
|
||||
|
||||
let (control_chan, control_port) = pipes::stream();
|
||||
|
||||
let control_chan = pipes::SharedChan(control_chan);
|
||||
let control_chan_copy = control_chan.clone();
|
||||
let control_port = Cell(move control_port);
|
||||
|
||||
do task().sched_mode(SingleThreaded).spawn |move control_port| {
|
||||
let (event_chan, event_port) = pipes::stream();
|
||||
let event_chan = pipes::SharedChan(event_chan);
|
||||
let content = Content(layout_task, control_port.take(), control_chan_copy.clone(),
|
||||
resource_task,
|
||||
img_cache_task.clone(), move event_port, event_chan.clone());
|
||||
compositor.add_event_listener(move event_chan);
|
||||
content.start();
|
||||
}
|
||||
|
||||
return control_chan;
|
||||
}
|
||||
|
||||
struct Content {
|
||||
|
@ -78,8 +92,10 @@ struct Content {
|
|||
mut layout_join_port: Option<pipes::Port<()>>,
|
||||
|
||||
image_cache_task: ImageCacheTask,
|
||||
from_master: comm::Port<ControlMsg>,
|
||||
event_port: comm::Port<Event>,
|
||||
control_port: pipes::Port<ControlMsg>,
|
||||
control_chan: pipes::SharedChan<ControlMsg>,
|
||||
event_port: pipes::Port<Event>,
|
||||
event_chan: pipes::SharedChan<Event>,
|
||||
|
||||
scope: NodeScope,
|
||||
jsrt: jsrt,
|
||||
|
@ -96,13 +112,15 @@ struct Content {
|
|||
}
|
||||
|
||||
fn Content(layout_task: LayoutTask,
|
||||
from_master: Port<ControlMsg>,
|
||||
control_port: pipes::Port<ControlMsg>,
|
||||
control_chan: pipes::SharedChan<ControlMsg>,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask) -> @Content {
|
||||
img_cache_task: ImageCacheTask,
|
||||
event_port: pipes::Port<Event>,
|
||||
event_chan: pipes::SharedChan<Event>) -> @Content {
|
||||
|
||||
let jsrt = jsrt();
|
||||
let cx = jsrt.cx();
|
||||
let event_port = Port();
|
||||
|
||||
cx.set_default_options_and_version();
|
||||
cx.set_logging_error_reporter();
|
||||
|
@ -116,8 +134,10 @@ fn Content(layout_task: LayoutTask,
|
|||
layout_task : layout_task,
|
||||
layout_join_port : None,
|
||||
image_cache_task : img_cache_task,
|
||||
from_master : from_master,
|
||||
control_port : control_port,
|
||||
control_chan : control_chan,
|
||||
event_port : event_port,
|
||||
event_chan : event_chan,
|
||||
|
||||
scope : NodeScope(),
|
||||
jsrt : jsrt,
|
||||
|
@ -145,15 +165,15 @@ fn task_from_context(cx: *JSContext) -> *Content unsafe {
|
|||
impl Content {
|
||||
|
||||
fn start() {
|
||||
while self.handle_msg(select2(self.from_master, self.event_port)) {
|
||||
// Go on...
|
||||
while self.handle_msg() {
|
||||
// Go on ...
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_msg(msg: Either<ControlMsg,Event>) -> bool {
|
||||
match move msg {
|
||||
Left(move control_msg) => self.handle_control_msg(control_msg),
|
||||
Right(move event) => self.handle_event(event)
|
||||
fn handle_msg() -> bool {
|
||||
match pipes::select2i(&self.control_port, &self.event_port) {
|
||||
either::Left(*) => self.handle_control_msg(self.control_port.recv()),
|
||||
either::Right(*) => self.handle_event(self.event_port.recv())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +200,7 @@ impl Content {
|
|||
debug!("js_scripts: %?", js_scripts);
|
||||
|
||||
let document = Document(root, self.scope, css_rules);
|
||||
let window = Window(self.from_master);
|
||||
let window = Window(self.control_chan.clone());
|
||||
self.relayout(&document, &url);
|
||||
self.document = Some(@document);
|
||||
self.window = Some(@window);
|
||||
|
@ -283,7 +303,7 @@ impl Content {
|
|||
// Send new document and relevant styles to layout
|
||||
// FIXME: Put CSS rules in an arc or something.
|
||||
self.layout_task.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url,
|
||||
self.event_port.chan(), self.window_size, join_chan));
|
||||
self.event_chan.clone(), self.window_size, join_chan));
|
||||
|
||||
// Indicate that reader was forked so any further
|
||||
// changes will be isolated.
|
||||
|
|
|
@ -63,8 +63,7 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn Window(content_port: Port<ControlMsg>) -> Window {
|
||||
let content_chan = Chan(&content_port);
|
||||
fn Window(content_chan: pipes::SharedChan<ControlMsg>) -> Window {
|
||||
|
||||
Window {
|
||||
timer_chan: do task::spawn_listener |timer_port: Port<TimerControlMsg>| {
|
||||
|
|
|
@ -8,6 +8,6 @@ each rendered frame and submit them to be drawn to the display
|
|||
trait Compositor {
|
||||
fn begin_drawing(next_dt: pipes::Chan<LayerBuffer>);
|
||||
fn draw(next_dt: pipes::Chan<LayerBuffer>, +draw_me: LayerBuffer);
|
||||
fn add_event_listener(listener: comm::Chan<Event>);
|
||||
fn add_event_listener(listener: pipes::SharedChan<Event>);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ impl Chan<Msg> : Compositor {
|
|||
fn draw(next_dt: pipes::Chan<LayerBuffer>, draw_me: LayerBuffer) {
|
||||
self.send(Draw(next_dt, draw_me))
|
||||
}
|
||||
fn add_event_listener(_listener: Chan<Event>) {
|
||||
fn add_event_listener(_listener: pipes::SharedChan<Event>) {
|
||||
// No events in this compositor.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ enum LayoutQueryResponse_ {
|
|||
}
|
||||
|
||||
pub enum Msg {
|
||||
BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>, Size2D<uint>, pipes::Chan<()>),
|
||||
BuildMsg(Node, ARC<Stylesheet>, Url, pipes::SharedChan<Event>, Size2D<uint>, pipes::Chan<()>),
|
||||
QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
|
||||
ExitMsg
|
||||
}
|
||||
|
@ -96,14 +96,14 @@ impl Layout {
|
|||
|
||||
match self.from_content.recv() {
|
||||
BuildMsg(move node, move styles, move doc_url,
|
||||
move to_content, move window_size, move join_chan) => {
|
||||
move dom_event_chan, move window_size, move join_chan) => {
|
||||
|
||||
let styles = Cell(styles);
|
||||
let doc_url = Cell(doc_url);
|
||||
let join_chan = Cell(join_chan);
|
||||
|
||||
do time("layout: performing layout") {
|
||||
self.handle_build(node, styles.take(), doc_url.take(), to_content, window_size, join_chan.take());
|
||||
self.handle_build(node, styles.take(), doc_url.take(), dom_event_chan.clone(), window_size, join_chan.take());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -122,14 +122,14 @@ impl Layout {
|
|||
}
|
||||
|
||||
fn handle_build(node: Node, styles: ARC<Stylesheet>, doc_url: Url,
|
||||
to_content: comm::Chan<Event>, window_size: Size2D<uint>,
|
||||
join_chan: pipes::Chan<()>) {
|
||||
dom_event_chan: pipes::SharedChan<Event>, window_size: Size2D<uint>,
|
||||
content_join_chan: pipes::Chan<()>) {
|
||||
debug!("layout: received layout request for: %s", doc_url.to_str());
|
||||
debug!("layout: parsed Node tree");
|
||||
debug!("%?", node.dump());
|
||||
|
||||
// Reset the image cache
|
||||
self.local_image_cache.next_round(self.make_on_image_available_cb(to_content));
|
||||
self.local_image_cache.next_round(self.make_on_image_available_cb(move dom_event_chan));
|
||||
|
||||
let screen_size = Size2D(au::from_px(window_size.width as int),
|
||||
au::from_px(window_size.height as int));
|
||||
|
@ -187,7 +187,7 @@ impl Layout {
|
|||
} // time(layout: display list building)
|
||||
|
||||
// Tell content we're done
|
||||
join_chan.send(());
|
||||
content_join_chan.send(());
|
||||
|
||||
}
|
||||
|
||||
|
@ -225,10 +225,21 @@ impl Layout {
|
|||
}
|
||||
|
||||
// When images can't be loaded in time to display they trigger
|
||||
// this callback in some task somewhere. This w
|
||||
fn make_on_image_available_cb(to_content: comm::Chan<Event>) -> ~fn(ImageResponseMsg) {
|
||||
let f: ~fn(ImageResponseMsg) = |_msg| {
|
||||
to_content.send(ReflowEvent)
|
||||
// this callback in some task somewhere. This will send a message
|
||||
// to the content task, and ultimately cause the image to be
|
||||
// re-requested. We probably don't need to go all the way back to
|
||||
// the content task for this.
|
||||
fn make_on_image_available_cb(dom_event_chan: pipes::SharedChan<Event>) -> @fn() -> ~fn(ImageResponseMsg) {
|
||||
// This has a crazy signature because the image cache needs to
|
||||
// make multiple copies of the callback, and the dom event
|
||||
// channel is not a copyable type, so this is actually a
|
||||
// little factory to produce callbacks
|
||||
let f: @fn() -> ~fn(ImageResponseMsg) = |move dom_event_chan| {
|
||||
let dom_event_chan = dom_event_chan.clone();
|
||||
let f: ~fn(ImageResponseMsg) = |_msg, move dom_event_chan| {
|
||||
dom_event_chan.send(ReflowEvent)
|
||||
};
|
||||
f
|
||||
};
|
||||
return f;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ pub enum Msg {
|
|||
BeginDrawing(pipes::Chan<LayerBuffer>),
|
||||
Draw(pipes::Chan<LayerBuffer>, LayerBuffer),
|
||||
AddKeyHandler(pipes::Chan<()>),
|
||||
AddEventListener(comm::Chan<Event>),
|
||||
AddEventListener(pipes::SharedChan<Event>),
|
||||
Exit
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ fn OSMain() -> OSMain {
|
|||
|
||||
fn mainloop(mode: Mode, po: comm::Port<Msg>) {
|
||||
let key_handlers: @DVec<pipes::Chan<()>> = @DVec();
|
||||
let event_listeners: @DVec<comm::Chan<Event>> = @DVec();
|
||||
let event_listeners: @DVec<pipes::SharedChan<Event>> = @DVec();
|
||||
|
||||
let window;
|
||||
match mode {
|
||||
|
@ -98,7 +98,7 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>) {
|
|||
while po.peek() {
|
||||
match po.recv() {
|
||||
AddKeyHandler(move key_ch) => key_handlers.push(move key_ch),
|
||||
AddEventListener(event_listener) => event_listeners.push(event_listener),
|
||||
AddEventListener(move event_listener) => event_listeners.push(event_listener),
|
||||
BeginDrawing(move sender) => lend_surface(surfaces, sender),
|
||||
Draw(move sender, move dt) => {
|
||||
#debug("osmain: received new frame");
|
||||
|
@ -181,7 +181,7 @@ impl OSMain : Compositor {
|
|||
fn draw(next_dt: pipes::Chan<LayerBuffer>, draw_me: LayerBuffer) {
|
||||
self.send(Draw(next_dt, draw_me))
|
||||
}
|
||||
fn add_event_listener(listener: comm::Chan<Event>) {
|
||||
fn add_event_listener(listener: pipes::SharedChan<Event>) {
|
||||
self.send(AddEventListener(listener));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn LocalImageCache(
|
|||
pub struct LocalImageCache {
|
||||
priv image_cache_task: ImageCacheTask,
|
||||
priv mut round_number: uint,
|
||||
priv mut on_image_available: Option<~fn(ImageResponseMsg)>,
|
||||
priv mut on_image_available: Option<@fn() -> ~fn(ImageResponseMsg)>,
|
||||
priv state_map: UrlMap<@ImageState>
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ pub impl LocalImageCache {
|
|||
/// The local cache will only do a single remote request for a given
|
||||
/// URL in each 'round'. Layout should call this each time it begins
|
||||
// FIXME: 'pub' is an unexpected token?
|
||||
/* pub */ fn next_round(on_image_available: ~fn(ImageResponseMsg)) {
|
||||
/* pub */ fn next_round(on_image_available: @fn() -> ~fn(ImageResponseMsg)) {
|
||||
self.round_number += 1;
|
||||
self.on_image_available = Some(move on_image_available);
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ pub impl LocalImageCache {
|
|||
// on the image to load and triggering layout
|
||||
let image_cache_task = self.image_cache_task.clone();
|
||||
assert self.on_image_available.is_some();
|
||||
let on_image_available = {copy *self.on_image_available.get_ref()};
|
||||
let on_image_available = self.on_image_available.get()();
|
||||
let url = copy *url;
|
||||
do task::spawn |move url, move on_image_available| {
|
||||
let (response_chan, response_port) = pipes::stream();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue