mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Reduce the number of channels that talk to the script task to one
This commit is contained in:
parent
6365becb6b
commit
b17d9dc220
8 changed files with 160 additions and 173 deletions
|
@ -3,8 +3,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use compositing::resize_rate_limiter::ResizeRateLimiter;
|
||||
use dom::event::Event;
|
||||
use platform::{Application, Window};
|
||||
use scripting::script_task::{LoadMsg, ScriptMsg};
|
||||
use windowing::{ApplicationMethods, WindowMethods};
|
||||
|
||||
use azure::azure_hl::{BackendType, B8G8R8A8, DataSourceSurface, DrawTarget, SourceSurfaceMethods};
|
||||
|
@ -30,11 +30,11 @@ pub struct CompositorImpl {
|
|||
|
||||
impl CompositorImpl {
|
||||
/// Creates a new compositor instance.
|
||||
pub fn new(dom_event_chan: SharedChan<Event>, opts: Opts) -> CompositorImpl {
|
||||
let dom_event_chan = Cell(dom_event_chan);
|
||||
pub fn new(script_chan: SharedChan<ScriptMsg>, opts: Opts) -> CompositorImpl {
|
||||
let script_chan = Cell(script_chan);
|
||||
let chan: Chan<Msg> = do on_osmain |port| {
|
||||
debug!("preparing to enter main loop");
|
||||
mainloop(port, dom_event_chan.take(), &opts);
|
||||
mainloop(port, script_chan.take(), &opts);
|
||||
};
|
||||
|
||||
CompositorImpl {
|
||||
|
@ -76,7 +76,7 @@ impl layers::layers::ImageData for AzureDrawTargetImageData {
|
|||
}
|
||||
}
|
||||
|
||||
fn mainloop(po: Port<Msg>, dom_event_chan: SharedChan<Event>, opts: &Opts) {
|
||||
fn mainloop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) {
|
||||
let key_handlers: @mut ~[Chan<()>] = @mut ~[];
|
||||
|
||||
let app: Application = ApplicationMethods::new();
|
||||
|
@ -110,7 +110,7 @@ fn mainloop(po: Port<Msg>, dom_event_chan: SharedChan<Event>, opts: &Opts) {
|
|||
identity());
|
||||
|
||||
let done = @mut false;
|
||||
let resize_rate_limiter = @mut ResizeRateLimiter(dom_event_chan);
|
||||
let resize_rate_limiter = @mut ResizeRateLimiter(script_chan.clone());
|
||||
let check_for_messages: @fn() = || {
|
||||
// Periodically check if the script task responded to our last resize event
|
||||
resize_rate_limiter.check_resize_response();
|
||||
|
@ -197,6 +197,12 @@ fn mainloop(po: Port<Msg>, dom_event_chan: SharedChan<Event>, opts: &Opts) {
|
|||
resize_rate_limiter.window_resized(width, height);
|
||||
}
|
||||
|
||||
// When the user enters a new URL, load it.
|
||||
do window.set_load_url_callback |url_string| {
|
||||
debug!("osmain: loading URL `%s`", url_string);
|
||||
script_chan.send(LoadMsg(url::make_url(url_string.to_str(), None)))
|
||||
}
|
||||
|
||||
// Enter the main event loop.
|
||||
while !*done {
|
||||
// Check for new messages coming from the rendering task.
|
||||
|
|
|
@ -2,27 +2,28 @@
|
|||
* 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/. */
|
||||
|
||||
/*!
|
||||
A little class that rate limits the number of resize events sent to the script task
|
||||
based on how fast script dispatches those events. It waits until each event is handled
|
||||
before sending the next. If the window is resized multiple times before an event is handled
|
||||
then some events will never be sent.
|
||||
*/
|
||||
//! A little class that rate limits the number of resize events sent to the script task
|
||||
/// based on how fast script dispatches those events. It waits until each event is handled
|
||||
/// before sending the next. If the window is resized multiple times before an event is handled
|
||||
/// then some events will never be sent.
|
||||
|
||||
use dom::event::{Event, ResizeEvent};
|
||||
use dom::event::ResizeEvent;
|
||||
use scripting::script_task::{ScriptMsg, SendEventMsg};
|
||||
|
||||
use core::comm::{Port, SharedChan};
|
||||
|
||||
pub struct ResizeRateLimiter {
|
||||
/// The channel we send resize events on
|
||||
/* priv */ dom_event_chan: comm::SharedChan<Event>,
|
||||
priv script_chan: SharedChan<ScriptMsg>,
|
||||
/// The port we are waiting on for a response to the last resize event
|
||||
/* priv */ last_response_port: Option<comm::Port<()>>,
|
||||
priv last_response_port: Option<Port<()>>,
|
||||
/// The next window resize event we should fire
|
||||
/* priv */ next_resize_event: Option<(uint, uint)>
|
||||
priv next_resize_event: Option<(uint, uint)>
|
||||
}
|
||||
|
||||
pub fn ResizeRateLimiter(dom_event_chan: comm::SharedChan<Event>) -> ResizeRateLimiter {
|
||||
pub fn ResizeRateLimiter(script_chan: SharedChan<ScriptMsg>) -> ResizeRateLimiter {
|
||||
ResizeRateLimiter {
|
||||
dom_event_chan: dom_event_chan,
|
||||
script_chan: script_chan,
|
||||
last_response_port: None,
|
||||
next_resize_event: None
|
||||
}
|
||||
|
@ -64,7 +65,7 @@ pub impl ResizeRateLimiter {
|
|||
|
||||
priv fn send_event(&mut self, width: uint, height: uint) {
|
||||
let (port, chan) = comm::stream();
|
||||
self.dom_event_chan.send(ResizeEvent(width, height, chan));
|
||||
self.script_chan.send(SendEventMsg(ResizeEvent(width, height, chan)));
|
||||
self.last_response_port = Some(port);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use dom::event::ReflowEvent;
|
|||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::node::AbstractNode;
|
||||
use dom::window::Window;
|
||||
use scripting::script_task::global_script_context;
|
||||
use scripting::script_task::{SendEventMsg, global_script_context};
|
||||
|
||||
use js::jsapi::bindgen::{JS_AddObjectRoot, JS_RemoveObjectRoot};
|
||||
use servo_util::tree::{TreeNodeRef, TreeUtils};
|
||||
|
@ -64,9 +64,9 @@ pub impl Document {
|
|||
}
|
||||
|
||||
fn content_changed(&self) {
|
||||
do self.window.map |window| {
|
||||
let chan = &mut window.dom_event_chan;
|
||||
chan.send(ReflowEvent)
|
||||
};
|
||||
for self.window.each |window| {
|
||||
window.script_chan.send(SendEventMsg(ReflowEvent))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
use dom::bindings::utils::WrapperCache;
|
||||
use dom::bindings::window;
|
||||
use dom::event::Event;
|
||||
use scripting::script_task::{ControlMsg, ExitMsg, FireTimerMsg, ScriptContext};
|
||||
use scripting::script_task::{ExitMsg, FireTimerMsg, ScriptMsg, ScriptContext};
|
||||
use scripting::script_task::{global_script_context};
|
||||
use util::task::spawn_listener;
|
||||
|
||||
|
@ -24,7 +23,7 @@ pub enum TimerControlMsg {
|
|||
// only used for querying layout from arbitrary script.
|
||||
pub struct Window {
|
||||
timer_chan: Chan<TimerControlMsg>,
|
||||
dom_event_chan: SharedChan<Event>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
script_context: *mut ScriptContext,
|
||||
wrapper: WrapperCache
|
||||
}
|
||||
|
@ -82,22 +81,20 @@ pub impl Window {
|
|||
&self.timer_chan,
|
||||
TimerMessage_Fire(~TimerData(argc, argv)));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Window(script_chan: comm::SharedChan<ControlMsg>,
|
||||
dom_event_chan: comm::SharedChan<Event>,
|
||||
script_context: *mut ScriptContext)
|
||||
pub fn new(script_chan: SharedChan<ScriptMsg>, script_context: *mut ScriptContext)
|
||||
-> @mut Window {
|
||||
let script_chan_copy = script_chan.clone();
|
||||
let win = @mut Window {
|
||||
wrapper: WrapperCache::new(),
|
||||
dom_event_chan: dom_event_chan,
|
||||
script_chan: script_chan,
|
||||
timer_chan: {
|
||||
do spawn_listener |timer_port: Port<TimerControlMsg>| {
|
||||
loop {
|
||||
match timer_port.recv() {
|
||||
TimerMessage_Close => break,
|
||||
TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(td)),
|
||||
TimerMessage_TriggerExit => script_chan.send(ExitMsg),
|
||||
TimerMessage_Fire(td) => script_chan_copy.send(FireTimerMsg(td)),
|
||||
TimerMessage_TriggerExit => script_chan_copy.send(ExitMsg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,4 +105,6 @@ pub fn Window(script_chan: comm::SharedChan<ControlMsg>,
|
|||
let compartment = global_script_context().js_compartment;
|
||||
window::create(compartment, win);
|
||||
win
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use compositing::CompositorImpl;
|
||||
use dom::event::Event;
|
||||
use layout::layout_task::LayoutTask;
|
||||
use layout::layout_task;
|
||||
use scripting::script_task::{ExecuteMsg, LoadMsg, ScriptTask};
|
||||
use scripting::script_task::{ExecuteMsg, LoadMsg, ScriptMsg, ScriptTask};
|
||||
use scripting::script_task;
|
||||
use util::task::spawn_listener;
|
||||
|
||||
|
@ -40,24 +39,23 @@ pub struct Engine {
|
|||
impl Engine {
|
||||
pub fn start(compositor: CompositorImpl,
|
||||
opts: &Opts,
|
||||
dom_event_port: Port<Event>,
|
||||
dom_event_chan: SharedChan<Event>,
|
||||
script_port: Port<ScriptMsg>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask)
|
||||
-> EngineTask {
|
||||
let dom_event_port = Cell(dom_event_port);
|
||||
let dom_event_chan = Cell(dom_event_chan);
|
||||
|
||||
let (script_port, script_chan) = (Cell(script_port), Cell(script_chan));
|
||||
let opts = Cell(copy *opts);
|
||||
|
||||
do spawn_listener::<Msg> |request| {
|
||||
let render_task = RenderTask(compositor.clone(), opts.with_ref(|o| copy *o));
|
||||
|
||||
let opts = opts.take();
|
||||
let layout_task = LayoutTask(render_task.clone(), image_cache_task.clone(), opts);
|
||||
|
||||
let script_task = ScriptTask::new(layout_task.clone(),
|
||||
dom_event_port.take(),
|
||||
dom_event_chan.take(),
|
||||
let script_task = ScriptTask::new(script_port.take(),
|
||||
script_chan.take(),
|
||||
layout_task.clone(),
|
||||
resource_task.clone(),
|
||||
image_cache_task.clone());
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
use css::matching::MatchMethods;
|
||||
use css::select::new_css_select_ctx;
|
||||
use dom::event::{Event, ReflowEvent};
|
||||
use dom::event::ReflowEvent;
|
||||
use dom::node::{AbstractNode, LayoutData};
|
||||
use layout::aux::LayoutAuxMethods;
|
||||
use layout::box_builder::LayoutTreeBuilder;
|
||||
|
@ -15,6 +15,7 @@ use layout::context::LayoutContext;
|
|||
use layout::debug::{BoxedMutDebugMethods, DebugMethods};
|
||||
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
||||
use layout::flow::FlowContext;
|
||||
use scripting::script_task::{ScriptMsg, SendEventMsg};
|
||||
use util::task::spawn_listener;
|
||||
use util::time::time;
|
||||
|
||||
|
@ -79,19 +80,19 @@ impl Damage {
|
|||
pub struct BuildData {
|
||||
node: AbstractNode,
|
||||
url: Url,
|
||||
dom_event_chan: comm::SharedChan<Event>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
window_size: Size2D<uint>,
|
||||
script_join_chan: comm::Chan<()>,
|
||||
script_join_chan: Chan<()>,
|
||||
damage: Damage,
|
||||
}
|
||||
|
||||
pub fn LayoutTask(render_task: RenderTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
opts: Opts) -> LayoutTask {
|
||||
SharedChan::new(spawn_listener::<Msg>(|from_script| {
|
||||
SharedChan::new(do spawn_listener::<Msg> |from_script| {
|
||||
let mut layout = Layout(render_task.clone(), img_cache_task.clone(), from_script, &opts);
|
||||
layout.start();
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
struct Layout {
|
||||
|
@ -170,8 +171,7 @@ impl Layout {
|
|||
let node = &data.node;
|
||||
// FIXME: Bad copy!
|
||||
let doc_url = copy data.url;
|
||||
// FIXME: Bad clone!
|
||||
let dom_event_chan = data.dom_event_chan.clone();
|
||||
let script_chan = data.script_chan.clone();
|
||||
|
||||
debug!("layout: received layout request for: %s", doc_url.to_str());
|
||||
debug!("layout: damage is %?", data.damage);
|
||||
|
@ -179,7 +179,7 @@ impl Layout {
|
|||
debug!("%?", node.dump());
|
||||
|
||||
// Reset the image cache.
|
||||
self.local_image_cache.next_round(self.make_on_image_available_cb(dom_event_chan));
|
||||
self.local_image_cache.next_round(self.make_on_image_available_cb(script_chan));
|
||||
|
||||
let screen_size = Size2D(Au::from_px(data.window_size.width as int),
|
||||
Au::from_px(data.window_size.height as int));
|
||||
|
@ -315,15 +315,16 @@ impl Layout {
|
|||
// to the script task, and ultimately cause the image to be
|
||||
// re-requested. We probably don't need to go all the way back to
|
||||
// the script task for this.
|
||||
fn make_on_image_available_cb(&self, dom_event_chan: comm::SharedChan<Event>) -> @fn() -> ~fn(ImageResponseMsg) {
|
||||
fn make_on_image_available_cb(&self, script_chan: SharedChan<ScriptMsg>)
|
||||
-> @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) = || {
|
||||
let dom_event_chan = dom_event_chan.clone();
|
||||
let script_chan = script_chan.clone();
|
||||
let f: ~fn(ImageResponseMsg) = |_| {
|
||||
dom_event_chan.send(ReflowEvent)
|
||||
script_chan.send(SendEventMsg(ReflowEvent))
|
||||
};
|
||||
f
|
||||
};
|
||||
|
|
|
@ -20,7 +20,6 @@ use core::cell::Cell;
|
|||
use core::comm::{Port, SharedChan};
|
||||
use core::io::read_whole_file;
|
||||
use core::local_data;
|
||||
use core::pipes::select2i;
|
||||
use core::ptr::null;
|
||||
use core::task::{SingleThreaded, task};
|
||||
use core::util::replace;
|
||||
|
@ -40,12 +39,14 @@ use servo_util::tree::TreeNodeRef;
|
|||
use std::net::url::Url;
|
||||
use std::net::url;
|
||||
|
||||
/// Messages used to control the script task at a high level.
|
||||
pub enum ControlMsg {
|
||||
/// Messages used to control the script task.
|
||||
pub enum ScriptMsg {
|
||||
/// Loads a new URL.
|
||||
LoadMsg(Url),
|
||||
/// Executes a standalone script.
|
||||
ExecuteMsg(Url),
|
||||
/// Sends a DOM event.
|
||||
SendEventMsg(Event),
|
||||
/// Fires a JavaScript timeout.
|
||||
FireTimerMsg(~TimerData),
|
||||
/// Exits the engine.
|
||||
|
@ -54,42 +55,34 @@ pub enum ControlMsg {
|
|||
|
||||
/// Encapsulates external communication with the script task.
|
||||
pub struct ScriptTask {
|
||||
/// The channel used to send control messages to the script task.
|
||||
chan: SharedChan<ControlMsg>,
|
||||
/// The channel used to send messages to the script task.
|
||||
chan: SharedChan<ScriptMsg>,
|
||||
}
|
||||
|
||||
impl ScriptTask {
|
||||
/// Creates a new script task.
|
||||
pub fn new(layout_task: LayoutTask,
|
||||
dom_event_port: Port<Event>,
|
||||
dom_event_chan: SharedChan<Event>,
|
||||
pub fn new(script_port: Port<ScriptMsg>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
layout_task: LayoutTask,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask)
|
||||
-> ScriptTask {
|
||||
let (control_port, control_chan) = comm::stream();
|
||||
|
||||
let control_chan = SharedChan::new(control_chan);
|
||||
let control_chan_copy = control_chan.clone();
|
||||
let control_port = Cell(control_port);
|
||||
let dom_event_port = Cell(dom_event_port);
|
||||
let dom_event_chan = Cell(dom_event_chan);
|
||||
let (script_chan_copy, script_port) = (script_chan.clone(), Cell(script_port));
|
||||
|
||||
// FIXME: rust#6399
|
||||
let mut the_task = task();
|
||||
the_task.sched_mode(SingleThreaded);
|
||||
do the_task.spawn {
|
||||
let script_context = ScriptContext::new(layout_task.clone(),
|
||||
control_port.take(),
|
||||
control_chan_copy.clone(),
|
||||
script_port.take(),
|
||||
script_chan_copy.clone(),
|
||||
resource_task.clone(),
|
||||
image_cache_task.clone(),
|
||||
dom_event_port.take(),
|
||||
dom_event_chan.take());
|
||||
image_cache_task.clone());
|
||||
script_context.start();
|
||||
}
|
||||
|
||||
ScriptTask {
|
||||
chan: control_chan
|
||||
chan: script_chan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,16 +109,11 @@ pub struct ScriptContext {
|
|||
/// The port that we will use to join layout. If this is `None`, then layout is not currently
|
||||
/// running.
|
||||
layout_join_port: Option<Port<()>>,
|
||||
/// The port on which we receive control messages (load URL, exit, etc.)
|
||||
control_port: Port<ControlMsg>,
|
||||
/// A channel for us to hand out when we want some other task to be able to send us control
|
||||
/// The port on which we receive messages (load URL, exit, etc.)
|
||||
script_port: Port<ScriptMsg>,
|
||||
/// A channel for us to hand out when we want some other task to be able to send us script
|
||||
/// messages.
|
||||
control_chan: SharedChan<ControlMsg>,
|
||||
/// The port on which we receive DOM events.
|
||||
event_port: Port<Event>,
|
||||
/// A channel for us to hand out when we want some other task to be able to send us DOM
|
||||
/// events.
|
||||
event_chan: SharedChan<Event>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
|
||||
/// The JavaScript runtime.
|
||||
js_runtime: js::rust::rt,
|
||||
|
@ -173,12 +161,10 @@ impl Drop for ScriptContext {
|
|||
impl ScriptContext {
|
||||
/// Creates a new script context.
|
||||
pub fn new(layout_task: LayoutTask,
|
||||
control_port: Port<ControlMsg>,
|
||||
control_chan: SharedChan<ControlMsg>,
|
||||
script_port: Port<ScriptMsg>,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
event_port: Port<Event>,
|
||||
event_chan: SharedChan<Event>)
|
||||
img_cache_task: ImageCacheTask)
|
||||
-> @mut ScriptContext {
|
||||
let js_runtime = js::rust::rt();
|
||||
let js_context = js_runtime.cx();
|
||||
|
@ -197,10 +183,8 @@ impl ScriptContext {
|
|||
resource_task: resource_task,
|
||||
|
||||
layout_join_port: None,
|
||||
control_port: control_port,
|
||||
control_chan: control_chan,
|
||||
event_port: event_port,
|
||||
event_chan: event_chan,
|
||||
script_port: script_port,
|
||||
script_chan: script_chan,
|
||||
|
||||
js_runtime: js_runtime,
|
||||
js_context: js_context,
|
||||
|
@ -233,55 +217,37 @@ impl ScriptContext {
|
|||
|
||||
/// Handles an incoming control message.
|
||||
fn handle_msg(&mut self) -> bool {
|
||||
match select2i(&mut self.control_port, &mut self.event_port) {
|
||||
Left(*) => {
|
||||
let msg = self.control_port.recv();
|
||||
self.handle_control_msg(msg)
|
||||
}
|
||||
Right(*) => {
|
||||
let ev = self.event_port.recv();
|
||||
self.handle_event(ev);
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles a control message from the compositor/front-end. Returns true if the task is to
|
||||
/// continue and false otherwise.
|
||||
fn handle_control_msg(&mut self, control_msg: ControlMsg) -> bool {
|
||||
match control_msg {
|
||||
match self.script_port.recv() {
|
||||
LoadMsg(url) => {
|
||||
debug!("script: Received url `%s` to load", url::to_str(&url));
|
||||
self.load(url);
|
||||
true
|
||||
}
|
||||
|
||||
FireTimerMsg(timer_data) => {
|
||||
let this_value = if timer_data.args.len() > 0 {
|
||||
RUST_JSVAL_TO_OBJECT(timer_data.args[0])
|
||||
} else {
|
||||
self.js_compartment.global_obj.ptr
|
||||
};
|
||||
|
||||
let rval = JSVAL_NULL;
|
||||
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
|
||||
JS_CallFunctionValue(self.js_context.ptr,
|
||||
this_value,
|
||||
timer_data.funval,
|
||||
0,
|
||||
null(),
|
||||
&rval);
|
||||
|
||||
self.relayout();
|
||||
ExecuteMsg(url) => {
|
||||
self.handle_execute_msg(url);
|
||||
true
|
||||
}
|
||||
SendEventMsg(event) => {
|
||||
self.handle_event(event);
|
||||
true
|
||||
}
|
||||
FireTimerMsg(timer_data) => {
|
||||
self.handle_fire_timer_msg(timer_data);
|
||||
true
|
||||
}
|
||||
ExitMsg => {
|
||||
self.handle_exit_msg();
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ExecuteMsg(url) => {
|
||||
/// Handles a request to execute a script.
|
||||
fn handle_execute_msg(&self, url: Url) {
|
||||
debug!("script: Received url `%s` to execute", url::to_str(&url));
|
||||
|
||||
match read_whole_file(&Path(url.path)) {
|
||||
Err(msg) => println(fmt!("Error opening %s: %s", url::to_str(&url), msg)),
|
||||
|
||||
Ok(bytes) => {
|
||||
self.js_compartment.define_functions(debug_fns);
|
||||
let _ = self.js_context.evaluate_script(self.js_compartment.global_obj,
|
||||
|
@ -290,15 +256,31 @@ impl ScriptContext {
|
|||
1);
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
ExitMsg => {
|
||||
self.layout_task.send(layout_task::ExitMsg);
|
||||
false
|
||||
}
|
||||
/// Handles a timer that fired.
|
||||
fn handle_fire_timer_msg(&mut self, timer_data: ~TimerData) {
|
||||
let this_value = if timer_data.args.len() > 0 {
|
||||
RUST_JSVAL_TO_OBJECT(timer_data.args[0])
|
||||
} else {
|
||||
self.js_compartment.global_obj.ptr
|
||||
};
|
||||
|
||||
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
|
||||
let rval = JSVAL_NULL;
|
||||
JS_CallFunctionValue(self.js_context.ptr,
|
||||
this_value,
|
||||
timer_data.funval,
|
||||
0,
|
||||
null(),
|
||||
&rval);
|
||||
|
||||
self.relayout()
|
||||
}
|
||||
|
||||
/// Handles a request to exit the script task and shut down layout.
|
||||
fn handle_exit_msg(&mut self) {
|
||||
self.layout_task.send(layout_task::ExitMsg)
|
||||
}
|
||||
|
||||
/// The entry point to document loading. Defines bindings, sets up the window and document
|
||||
|
@ -332,7 +314,7 @@ impl ScriptContext {
|
|||
debug!("js_scripts: %?", js_scripts);
|
||||
|
||||
// Create the window and document objects.
|
||||
let window = Window(self.control_chan.clone(), self.event_chan.clone(), &mut *self);
|
||||
let window = Window::new(self.script_chan.clone(), &mut *self);
|
||||
let document = Document(root_node, Some(window));
|
||||
|
||||
// Tie the root into the document.
|
||||
|
@ -405,7 +387,7 @@ impl ScriptContext {
|
|||
let data = ~BuildData {
|
||||
node: root_frame.document.root,
|
||||
url: copy root_frame.url,
|
||||
dom_event_chan: self.event_chan.clone(),
|
||||
script_chan: self.script_chan.clone(),
|
||||
window_size: self.window_size,
|
||||
script_join_chan: join_chan,
|
||||
damage: replace(&mut self.damage, NoDamage),
|
||||
|
|
|
@ -133,11 +133,11 @@ fn main() {
|
|||
}
|
||||
|
||||
fn run(opts: &Opts) {
|
||||
let (dom_event_port, dom_event_chan) = comm::stream();
|
||||
let dom_event_chan = SharedChan::new(dom_event_chan);
|
||||
let (script_port, script_chan) = comm::stream();
|
||||
let script_chan = SharedChan::new(script_chan);
|
||||
|
||||
// The platform event handler thread
|
||||
let compositor = CompositorImpl::new(dom_event_chan.clone(), copy *opts);
|
||||
let compositor = CompositorImpl::new(script_chan.clone(), copy *opts);
|
||||
|
||||
// Send each file to render then wait for keypress
|
||||
let (keypress_from_compositor, keypress_to_engine) = comm::stream();
|
||||
|
@ -148,8 +148,8 @@ fn run(opts: &Opts) {
|
|||
let image_cache_task = ImageCacheTask(resource_task.clone());
|
||||
let engine_task = Engine::start(compositor.clone(),
|
||||
opts,
|
||||
dom_event_port,
|
||||
dom_event_chan,
|
||||
script_port,
|
||||
script_chan,
|
||||
resource_task,
|
||||
image_cache_task);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue