aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/script_task.rs
diff options
context:
space:
mode:
authorTim Kuehn <tkuehn@cmu.edu>2013-06-26 22:42:01 -0700
committerTim Kuehn <tkuehn@cmu.edu>2013-07-01 11:03:31 -0700
commitfba7ec423c99a63bdcbe16029740e7ab4e38c088 (patch)
tree0e8a15014ee5bbf912153e8072c0a5505d3b4ecc /src/components/script/script_task.rs
parentfdb0d820a49fac9ae2df623751912adcbe7a119d (diff)
downloadservo-fba7ec423c99a63bdcbe16029740e7ab4e38c088.tar.gz
servo-fba7ec423c99a63bdcbe16029740e7ab4e38c088.zip
add pipeline.rs, modularized pipelines communicating with constellation
Diffstat (limited to 'src/components/script/script_task.rs')
-rw-r--r--src/components/script/script_task.rs134
1 files changed, 68 insertions, 66 deletions
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index 7ef0b0035e1..ce89ef5efd7 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -5,19 +5,21 @@
/// The script task is the task that owns the DOM in memory, runs JavaScript, and spawns parsing
/// and layout tasks.
-use servo_msg::compositor::{ReadyState, Loading, PerformingLayout, FinishedLoading};
+use servo_msg::compositor::{ScriptListener, Loading, PerformingLayout};
+use servo_msg::compositor::FinishedLoading;
use dom::bindings::utils::GlobalStaticData;
use dom::document::Document;
use dom::element::Element;
use dom::event::{Event, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseUpEvent};
use dom::node::{AbstractNode, ScriptView, define_bindings};
use dom::window::Window;
-use layout_interface::{AddStylesheetMsg, DocumentDamage, DocumentDamageLevel, HitTestQuery};
-use layout_interface::{HitTestResponse, LayoutQuery, LayoutResponse, LayoutChan};
-use layout_interface::{MatchSelectorsDocumentDamage, QueryMsg, Reflow, ReflowDocumentDamage};
-use layout_interface::{ReflowForDisplay, ReflowForScriptQuery, ReflowGoal, ReflowMsg};
+use layout_interface::{AddStylesheetMsg, DocumentDamage};
+use layout_interface::{DocumentDamageLevel, HitTestQuery, HitTestResponse, LayoutQuery};
+use layout_interface::{LayoutChan, MatchSelectorsDocumentDamage, QueryMsg, Reflow};
+use layout_interface::{ReflowDocumentDamage, ReflowForDisplay, ReflowForScriptQuery, ReflowGoal};
+use layout_interface::ReflowMsg;
use layout_interface;
-use servo_msg::engine::{EngineChan, LoadUrlMsg};
+use servo_msg::engine::{EngineChan, LoadUrlMsg, RendererReadyMsg};
use std::cast::transmute;
use std::cell::Cell;
@@ -91,7 +93,9 @@ pub struct Frame {
/// frames.
///
/// FIXME: Rename to `Page`, following WebKit?
-pub struct ScriptContext {
+pub struct ScriptTask {
+ /// A unique identifier to the script's pipeline
+ id: uint,
/// A handle to the layout task.
layout_chan: LayoutChan,
/// A handle to the image cache task.
@@ -110,8 +114,8 @@ pub struct ScriptContext {
/// For communicating load url messages to the engine
engine_chan: EngineChan,
- /// For communicating loading messages to the compositor
- compositor_task: ~fn(ReadyState),
+ /// For permission to communicate ready state messages to the compositor
+ compositor: @ScriptListener,
/// The JavaScript runtime.
js_runtime: js::rust::rt,
@@ -134,26 +138,26 @@ pub struct ScriptContext {
damage: Option<DocumentDamage>,
}
-fn global_script_context_key(_: @ScriptContext) {}
+fn global_script_context_key(_: @ScriptTask) {}
/// Returns this task's script context singleton.
-pub fn global_script_context() -> @ScriptContext {
+pub fn global_script_context() -> @ScriptTask {
unsafe {
local_data::local_data_get(global_script_context_key).get()
}
}
-/// Returns the script context from the JS Context.
+/// Returns the script task from the JS Context.
///
/// FIXME: Rename to `script_context_from_js_context`.
-pub fn task_from_context(js_context: *JSContext) -> *mut ScriptContext {
+pub fn task_from_context(js_context: *JSContext) -> *mut ScriptTask {
unsafe {
- JS_GetContextPrivate(js_context) as *mut ScriptContext
+ JS_GetContextPrivate(js_context) as *mut ScriptTask
}
}
#[unsafe_destructor]
-impl Drop for ScriptContext {
+impl Drop for ScriptTask {
fn finalize(&self) {
unsafe {
let _ = local_data::local_data_pop(global_script_context_key);
@@ -161,16 +165,17 @@ impl Drop for ScriptContext {
}
}
-impl ScriptContext {
- /// Creates a new script context.
- pub fn new(layout_chan: LayoutChan,
+impl ScriptTask {
+ /// Creates a new script task.
+ pub fn new(id: uint,
+ compositor: @ScriptListener,
+ layout_chan: LayoutChan,
script_port: Port<ScriptMsg>,
script_chan: ScriptChan,
engine_chan: EngineChan,
- compositor_task: ~fn(ReadyState),
resource_task: ResourceTask,
img_cache_task: ImageCacheTask)
- -> @mut ScriptContext {
+ -> @mut ScriptTask {
let js_runtime = js::rust::rt();
let js_context = js_runtime.cx();
@@ -182,7 +187,10 @@ impl ScriptContext {
Err(()) => fail!("Failed to create a compartment"),
};
- let script_context = @mut ScriptContext {
+ let script_task = @mut ScriptTask {
+ id: id,
+ compositor: compositor,
+
layout_chan: layout_chan,
image_cache_task: img_cache_task,
resource_task: resource_task,
@@ -192,7 +200,6 @@ impl ScriptContext {
script_chan: script_chan,
engine_chan: engine_chan,
- compositor_task: compositor_task,
js_runtime: js_runtime,
js_context: js_context,
@@ -207,17 +214,17 @@ impl ScriptContext {
damage: None,
};
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
- let script_context_ptr = {
- let borrowed_ctx= &mut *script_context;
- borrowed_ctx as *mut ScriptContext
+ let script_task_ptr = {
+ let borrowed_ctx= &mut *script_task;
+ borrowed_ctx as *mut ScriptTask
};
unsafe {
- js_context.set_cx_private(script_context_ptr as *());
- local_data::local_data_set(global_script_context_key, transmute(script_context))
+ js_context.set_cx_private(script_task_ptr as *());
+ local_data::local_data_set(global_script_context_key, transmute(script_task))
}
- script_context
+ script_task
}
/// Starts the script task. After calling this method, the script task will loop receiving
@@ -228,27 +235,29 @@ impl ScriptContext {
}
}
- pub fn create_script_context(layout_chan: LayoutChan,
- script_port: Port<ScriptMsg>,
- script_chan: ScriptChan,
- engine_chan: EngineChan,
- compositor_task: ~fn(ReadyState),
- resource_task: ResourceTask,
- image_cache_task: ImageCacheTask) {
+ pub fn create<C: ScriptListener + Owned>(id: uint,
+ compositor: C,
+ layout_chan: LayoutChan,
+ script_port: Port<ScriptMsg>,
+ script_chan: ScriptChan,
+ engine_chan: EngineChan,
+ resource_task: ResourceTask,
+ image_cache_task: ImageCacheTask) {
+ let compositor = Cell::new(compositor);
let script_port = Cell::new(script_port);
- let compositor_task = Cell::new(compositor_task);
// FIXME: rust#6399
let mut the_task = task();
the_task.sched_mode(SingleThreaded);
- do the_task.spawn {
- let script_context = ScriptContext::new(layout_chan.clone(),
- script_port.take(),
- script_chan.clone(),
- engine_chan.clone(),
- compositor_task.take(),
- resource_task.clone(),
- image_cache_task.clone());
- script_context.start();
+ do spawn {
+ let script_task = ScriptTask::new(id,
+ @compositor.take() as @ScriptListener,
+ layout_chan.clone(),
+ script_port.take(),
+ script_chan.clone(),
+ engine_chan.clone(),
+ resource_task.clone(),
+ image_cache_task.clone());
+ script_task.start();
}
}
@@ -324,7 +333,8 @@ impl ScriptContext {
/// Handles a notification that reflow completed.
fn handle_reflow_complete_msg(&mut self) {
self.layout_join_port = None;
- self.set_ready_state(FinishedLoading)
+ self.engine_chan.send(RendererReadyMsg(self.id));
+ self.compositor.set_ready_state(FinishedLoading);
}
/// Handles a request to exit the script task and shut down layout.
@@ -337,12 +347,6 @@ impl ScriptContext {
self.layout_chan.send(layout_interface::ExitMsg)
}
- // tells the compositor when loading starts and finishes
- // FIXME ~compositor_interface doesn't work right now, which is why this is necessary
- fn set_ready_state(&self, msg: ReadyState) {
- (self.compositor_task)(msg);
- }
-
/// The entry point to document loading. Defines bindings, sets up the window and document
/// objects, parses HTML and CSS, and kicks off initial layout.
fn load(&mut self, url: Url) {
@@ -354,7 +358,7 @@ impl ScriptContext {
self.bindings_initialized = true
}
- self.set_ready_state(Loading);
+ self.compositor.set_ready_state(Loading);
// Parse HTML.
//
// Note: We can parse the next document in parallel with any previous documents.
@@ -446,7 +450,7 @@ impl ScriptContext {
self.join_layout();
// Tell the user that we're performing layout.
- self.set_ready_state(PerformingLayout);
+ self.compositor.set_ready_state(PerformingLayout);
// Layout will let us know when it's done.
let (join_port, join_chan) = comm::stream();
@@ -478,7 +482,7 @@ impl ScriptContext {
/// FIXME: This should basically never be used.
pub fn reflow_all(&mut self, goal: ReflowGoal) {
for self.root_frame.iter().advance |root_frame| {
- ScriptContext::damage(&mut self.damage,
+ ScriptTask::damage(&mut self.damage,
root_frame.document.root,
MatchSelectorsDocumentDamage)
}
@@ -487,12 +491,10 @@ impl ScriptContext {
}
/// Sends the given query to layout.
- pub fn query_layout(&mut self, query: LayoutQuery) -> Result<LayoutResponse,()> {
- self.join_layout();
-
- let (response_port, response_chan) = comm::stream();
- self.layout_chan.send(QueryMsg(query, response_chan));
- response_port.recv()
+ pub fn query_layout<T: Owned>(&mut self, query: LayoutQuery, response_port: Port<Result<T, ()>>) -> Result<T,()> {
+ self.join_layout();
+ self.layout_chan.send(QueryMsg(query));
+ response_port.recv()
}
/// Adds the given damage.
@@ -526,7 +528,7 @@ impl ScriptContext {
self.window_size = Size2D(new_width, new_height);
for self.root_frame.iter().advance |root_frame| {
- ScriptContext::damage(&mut self.damage,
+ ScriptTask::damage(&mut self.damage,
root_frame.document.root,
ReflowDocumentDamage);
}
@@ -541,7 +543,7 @@ impl ScriptContext {
debug!("script got reflow event");
for self.root_frame.iter().advance |root_frame| {
- ScriptContext::damage(&mut self.damage,
+ ScriptTask::damage(&mut self.damage,
root_frame.document.root,
MatchSelectorsDocumentDamage);
}
@@ -557,7 +559,8 @@ impl ScriptContext {
Some(ref frame) => frame.document.root,
None => fail!("root frame is None")
};
- match self.query_layout(HitTestQuery(root, point)) {
+ let (port, chan) = comm::stream();
+ match self.query_layout(HitTestQuery(root, point, chan), port) {
Ok(node) => match node {
HitTestResponse(node) => {
debug!("clicked on %?", node.debug_str());
@@ -580,7 +583,6 @@ impl ScriptContext {
}
}
}
- _ => fail!(~"unexpected layout reply")
},
Err(()) => {
debug!(fmt!("layout query error"));
@@ -594,7 +596,7 @@ impl ScriptContext {
priv fn load_url_from_element(&self, element: &Element) {
// if the node's element is "a," load url from href attr
- for element.attrs.each |attr| {
+ for element.attrs.iter().advance |attr| {
if attr.name == ~"href" {
debug!("clicked on link to %?", attr.value);
let current_url = match self.root_frame {