Provide an interface to the engine for the script task

This commit is contained in:
Tim Kuehn 2013-06-06 15:16:05 -07:00 committed by Patrick Walton
parent abe6a06cbf
commit bf4df24521
7 changed files with 74 additions and 50 deletions

View file

@ -4,13 +4,13 @@
use compositing::CompositorTask; use compositing::CompositorTask;
use layout::layout_task; use layout::layout_task;
use util::task::spawn_listener;
use core::cell::Cell; use core::cell::Cell;
use core::comm::{Chan, Port, SharedChan}; use core::comm::{Port, SharedChan};
use gfx::opts::Opts; use gfx::opts::Opts;
use gfx::render_task::RenderTask; use gfx::render_task::RenderTask;
use gfx::render_task; use gfx::render_task;
use script::engine_interface::{EngineTask, ExitMsg, LoadUrlMsg, Msg};
use script::layout_interface::LayoutTask; use script::layout_interface::LayoutTask;
use script::layout_interface; use script::layout_interface;
use script::script_task::{ExecuteMsg, LoadMsg, ScriptMsg, ScriptTask}; use script::script_task::{ExecuteMsg, LoadMsg, ScriptMsg, ScriptTask};
@ -18,15 +18,7 @@ use script::script_task;
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient}; use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
use servo_net::resource_task::ResourceTask; use servo_net::resource_task::ResourceTask;
use servo_net::resource_task; use servo_net::resource_task;
use servo_util::time::{profiler_force_print, ProfilerChan, ProfilerPort, ProfilerTask}; use servo_util::time::{ProfilerChan, ProfilerPort, ProfilerTask, ForcePrintMsg};
use std::net::url::Url;
pub type EngineTask = Chan<Msg>;
pub enum Msg {
LoadUrlMsg(Url),
ExitMsg(Chan<()>),
}
pub struct Engine { pub struct Engine {
request_port: Port<Msg>, request_port: Port<Msg>,
@ -41,7 +33,7 @@ pub struct Engine {
impl Drop for Engine { impl Drop for Engine {
fn finalize(&self) { fn finalize(&self) {
profiler_force_print(self.profiler_task.chan.clone()); self.profiler_task.chan.send(ForcePrintMsg);
} }
} }
@ -56,10 +48,13 @@ impl Engine {
profiler_chan: ProfilerChan) profiler_chan: ProfilerChan)
-> EngineTask { -> EngineTask {
let (script_port, script_chan) = (Cell(script_port), Cell(script_chan)); let (script_port, script_chan) = (Cell(script_port), Cell(script_chan));
let (request_port, request_chan) = comm::stream();
let (request_port, request_chan) = (Cell(request_port), SharedChan::new(request_chan));
let request_chan_clone = request_chan.clone();
let profiler_port = Cell(profiler_port); let profiler_port = Cell(profiler_port);
let opts = Cell(copy *opts); let opts = Cell(copy *opts);
do spawn_listener::<Msg> |request| { do task::spawn {
let render_task = RenderTask::new(compositor.clone(), let render_task = RenderTask::new(compositor.clone(),
opts.with_ref(|o| copy *o), opts.with_ref(|o| copy *o),
profiler_chan.clone()); profiler_chan.clone());
@ -77,13 +72,14 @@ impl Engine {
let script_task = ScriptTask::new(script_port.take(), let script_task = ScriptTask::new(script_port.take(),
script_chan.take(), script_chan.take(),
request_chan_clone.clone(),
layout_task.clone(), layout_task.clone(),
resource_task.clone(), resource_task.clone(),
image_cache_task.clone()); image_cache_task.clone());
Engine { Engine {
request_port: request, request_port: request_port.take(),
compositor: compositor.clone(), compositor: compositor.clone(),
render_task: render_task, render_task: render_task,
resource_task: resource_task.clone(), resource_task: resource_task.clone(),
@ -91,8 +87,9 @@ impl Engine {
layout_task: layout_task, layout_task: layout_task,
script_task: script_task, script_task: script_task,
profiler_task: profiler_task, profiler_task: profiler_task,
}.run() }.run();
} }
request_chan.clone()
} }
fn run(&self) { fn run(&self) {

View file

@ -34,7 +34,8 @@ extern mod core_graphics;
extern mod core_text; extern mod core_text;
use compositing::CompositorTask; use compositing::CompositorTask;
use engine::{Engine, LoadUrlMsg}; use engine::Engine;
use script::engine_interface::{ExitMsg, LoadUrlMsg};
use core::comm::SharedChan; use core::comm::SharedChan;
use gfx::opts; use gfx::opts;
@ -121,7 +122,7 @@ fn run(opts: &Opts) {
// Shut the engine down. // Shut the engine down.
debug!("master: Shut down"); debug!("master: Shut down");
let (exit_response_from_engine, exit_chan) = comm::stream(); let (exit_response_from_engine, exit_chan) = comm::stream();
engine_task.send(engine::ExitMsg(exit_chan)); engine_task.send(ExitMsg(exit_chan));
exit_response_from_engine.recv(); exit_response_from_engine.recv();
} }

View file

@ -5,11 +5,11 @@
use core::comm::{Chan, Port}; use core::comm::{Chan, Port};
pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> { pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = comm::stream(); let (setup_port, setup_chan) = comm::stream();
do task::spawn { do task::spawn {
let (po, ch) = comm::stream(); let (port, chan) = comm::stream();
setup_ch.send(ch); setup_chan.send(chan);
f(po); f(port);
} }
setup_po.recv() setup_port.recv()
} }

View file

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! The high-level interface from script to engine. Using this abstract interface helps reduce
/// coupling between these two components
use core::comm::{Chan, SharedChan};
use std::net::url::Url;
pub type EngineTask = SharedChan<Msg>;
pub enum Msg {
LoadUrlMsg(Url),
ExitMsg(Chan<()>),
}

View file

@ -65,5 +65,6 @@ pub mod html {
} }
pub mod layout_interface; pub mod layout_interface;
pub mod engine_interface;
pub mod script_task; pub mod script_task;

View file

@ -16,6 +16,7 @@ use layout_interface::{HitTestResponse, LayoutQuery, LayoutResponse, LayoutTask}
use layout_interface::{MatchSelectorsDocumentDamage, QueryMsg, Reflow, ReflowDocumentDamage}; use layout_interface::{MatchSelectorsDocumentDamage, QueryMsg, Reflow, ReflowDocumentDamage};
use layout_interface::{ReflowForDisplay, ReflowForScriptQuery, ReflowGoal, ReflowMsg}; use layout_interface::{ReflowForDisplay, ReflowForScriptQuery, ReflowGoal, ReflowMsg};
use layout_interface; use layout_interface;
use engine_interface::{EngineTask, LoadUrlMsg};
use core::cast::transmute; use core::cast::transmute;
use core::cell::Cell; use core::cell::Cell;
@ -65,6 +66,7 @@ impl ScriptTask {
/// Creates a new script task. /// Creates a new script task.
pub fn new(script_port: Port<ScriptMsg>, pub fn new(script_port: Port<ScriptMsg>,
script_chan: SharedChan<ScriptMsg>, script_chan: SharedChan<ScriptMsg>,
engine_task: EngineTask,
layout_task: LayoutTask, layout_task: LayoutTask,
resource_task: ResourceTask, resource_task: ResourceTask,
image_cache_task: ImageCacheTask) image_cache_task: ImageCacheTask)
@ -78,6 +80,7 @@ impl ScriptTask {
let script_context = ScriptContext::new(layout_task.clone(), let script_context = ScriptContext::new(layout_task.clone(),
script_port.take(), script_port.take(),
script_chan_copy.clone(), script_chan_copy.clone(),
engine_task.clone(),
resource_task.clone(), resource_task.clone(),
image_cache_task.clone()); image_cache_task.clone());
script_context.start(); script_context.start();
@ -117,6 +120,9 @@ pub struct ScriptContext {
/// messages. /// messages.
script_chan: SharedChan<ScriptMsg>, script_chan: SharedChan<ScriptMsg>,
/// For communicating load url messages to the engine
engine_task: EngineTask,
/// The JavaScript runtime. /// The JavaScript runtime.
js_runtime: js::rust::rt, js_runtime: js::rust::rt,
/// The JavaScript context. /// The JavaScript context.
@ -168,6 +174,7 @@ impl ScriptContext {
pub fn new(layout_task: LayoutTask, pub fn new(layout_task: LayoutTask,
script_port: Port<ScriptMsg>, script_port: Port<ScriptMsg>,
script_chan: SharedChan<ScriptMsg>, script_chan: SharedChan<ScriptMsg>,
engine_task: EngineTask,
resource_task: ResourceTask, resource_task: ResourceTask,
img_cache_task: ImageCacheTask) img_cache_task: ImageCacheTask)
-> @mut ScriptContext { -> @mut ScriptContext {
@ -191,6 +198,8 @@ impl ScriptContext {
script_port: script_port, script_port: script_port,
script_chan: script_chan, script_chan: script_chan,
engine_task: engine_task,
js_runtime: js_runtime, js_runtime: js_runtime,
js_context: js_context, js_context: js_context,
js_compartment: compartment, js_compartment: compartment,
@ -552,7 +561,7 @@ impl ScriptContext {
debug!("clicked on link to %?", attr.value); debug!("clicked on link to %?", attr.value);
let url = from_str(attr.value); let url = from_str(attr.value);
match url { match url {
Ok(url) => self.script_chan.send(LoadMsg(url)), Ok(url) => self.engine_task.send(LoadUrlMsg(url)),
Err(msg) => debug!(msg) Err(msg) => debug!(msg)
}; };
break; break;

View file

@ -8,6 +8,9 @@ use core::cell::Cell;
use core::comm::{Port, SharedChan}; use core::comm::{Port, SharedChan};
use std::sort::tim_sort; use std::sort::tim_sort;
pub type ProfilerChan = SharedChan<ProfilerMsg>;
pub type ProfilerPort = Port<ProfilerMsg>;
#[deriving(Eq)] #[deriving(Eq)]
pub enum ProfilerCategory { pub enum ProfilerCategory {
CompositingCategory, CompositingCategory,
@ -26,6 +29,29 @@ pub enum ProfilerCategory {
// hackish but helps prevent errors when adding new categories // hackish but helps prevent errors when adding new categories
NUM_BUCKETS, NUM_BUCKETS,
} }
// FIXME(#5873) this should be initialized by a NUM_BUCKETS cast,
static BUCKETS: uint = 13;
pub enum ProfilerMsg {
// Normal message used for reporting time
TimeMsg(ProfilerCategory, f64),
// Message used to force print the profiling metrics
ForcePrintMsg,
}
// front-end representation of the profiler used to communicate with the profiler context
pub struct ProfilerTask {
chan: ProfilerChan,
}
// back end of the profiler that handles data aggregation and performance metrics
pub struct ProfilerContext {
port: ProfilerPort,
buckets: ~[(ProfilerCategory, ~[f64])],
verbose: bool,
period: f64,
last_print: f64,
}
impl ProfilerCategory { impl ProfilerCategory {
@ -76,20 +102,6 @@ impl ProfilerCategory {
fmt!("%s%?", padding, self) fmt!("%s%?", padding, self)
} }
} }
// FIXME(#5873) this should be initialized by a NUM_BUCKETS cast,
static BUCKETS: uint = 13;
pub enum ProfilerMsg {
// Normal message used for reporting time
TimeMsg(ProfilerCategory, f64),
// Message used to force print the profiling metrics
ForcePrintMsg,
}
pub type ProfilerChan = SharedChan<ProfilerMsg>;
pub type ProfilerPort = Port<ProfilerMsg>;
pub struct ProfilerTask {
chan: ProfilerChan,
}
impl ProfilerTask { impl ProfilerTask {
pub fn new(profiler_port: ProfilerPort, pub fn new(profiler_port: ProfilerPort,
@ -109,14 +121,6 @@ impl ProfilerTask {
} }
} }
pub struct ProfilerContext {
port: ProfilerPort,
buckets: ~[(ProfilerCategory, ~[f64])],
verbose: bool,
period: f64,
mut last_print: f64,
}
impl ProfilerContext { impl ProfilerContext {
pub fn new(port: ProfilerPort, period: Option<f64>) -> ProfilerContext { pub fn new(port: ProfilerPort, period: Option<f64>) -> ProfilerContext {
let (verbose, period) = match period { let (verbose, period) = match period {
@ -197,11 +201,6 @@ pub fn profile<T>(category: ProfilerCategory,
return val; return val;
} }
pub fn profiler_force_print(profiler_chan: ProfilerChan) {
profiler_chan.send(ForcePrintMsg);
}
pub fn time<T>(msg: &str, callback: &fn() -> T) -> T{ pub fn time<T>(msg: &str, callback: &fn() -> T) -> T{
let start_time = precise_time_ns(); let start_time = precise_time_ns();
let val = callback(); let val = callback();