diff options
Diffstat (limited to 'components/servo/lib.rs')
-rw-r--r-- | components/servo/lib.rs | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/components/servo/lib.rs b/components/servo/lib.rs new file mode 100644 index 00000000000..51297269a9b --- /dev/null +++ b/components/servo/lib.rs @@ -0,0 +1,172 @@ +/* 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/. */ + +#![comment = "The Servo Parallel Browser Project"] +#![license = "MPL"] + +#![feature(globs, macro_rules, phase, thread_local)] + +#![deny(unused_imports)] +#![deny(unused_variables)] + +#[phase(plugin, link)] +extern crate log; + +extern crate compositing; +extern crate devtools; +extern crate rustuv; +extern crate "net" as servo_net; +extern crate "msg" as servo_msg; +#[phase(plugin, link)] +extern crate "util" as servo_util; +extern crate script; +extern crate layout; +extern crate green; +extern crate gfx; +extern crate libc; +extern crate native; +extern crate rustrt; +extern crate url; + +use compositing::CompositorEventListener; +use compositing::windowing::{WindowEvent, WindowMethods}; + +#[cfg(not(test))] +use compositing::{CompositorProxy, CompositorTask, Constellation}; +#[cfg(not(test))] +use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg}; +#[cfg(not(test))] +use script::dom::bindings::codegen::RegisterBindings; + +#[cfg(not(test))] +use servo_net::image_cache_task::ImageCacheTask; +#[cfg(not(test))] +use servo_net::resource_task::new_resource_task; +#[cfg(not(test))] +use gfx::font_cache_task::FontCacheTask; +#[cfg(not(test))] +use servo_util::time::TimeProfiler; +#[cfg(not(test))] +use servo_util::memory::MemoryProfiler; +#[cfg(not(test))] +use servo_util::opts; +#[cfg(not(test))] +use servo_util::taskpool::TaskPool; + +#[cfg(not(test))] +use green::GreenTaskBuilder; +#[cfg(not(test))] +use std::os; +#[cfg(not(test))] +use std::rc::Rc; +#[cfg(not(test))] +use std::task::TaskBuilder; + +pub struct Browser<Window> { + pool: green::SchedPool, + compositor: Box<CompositorEventListener + 'static>, +} + +impl<Window> Browser<Window> where Window: WindowMethods + 'static { + #[cfg(not(test))] + pub fn new(window: Option<Rc<Window>>) -> Browser<Window> { + use rustuv::EventLoop; + fn event_loop() -> Box<green::EventLoop + Send> { + box EventLoop::new().unwrap() as Box<green::EventLoop + Send> + } + + ::servo_util::opts::set_experimental_enabled(opts::get().enable_experimental); + let opts = opts::get(); + RegisterBindings::RegisterProxyHandlers(); + + let mut pool_config = green::PoolConfig::new(); + pool_config.event_loop_factory = event_loop; + let mut pool = green::SchedPool::new(pool_config); + let shared_task_pool = TaskPool::new(8); + + let (compositor_proxy, compositor_receiver) = + WindowMethods::create_compositor_channel(&window); + let time_profiler_chan = TimeProfiler::create(opts.time_profiler_period); + let memory_profiler_chan = MemoryProfiler::create(opts.memory_profiler_period); + let devtools_chan = opts.devtools_port.map(|port| { + devtools::start_server(port) + }); + + let opts_clone = opts.clone(); + let time_profiler_chan_clone = time_profiler_chan.clone(); + + let (result_chan, result_port) = channel(); + let compositor_proxy_for_constellation = compositor_proxy.clone_compositor_proxy(); + TaskBuilder::new() + .green(&mut pool) + .spawn(proc() { + let opts = &opts_clone; + // Create a Servo instance. + let resource_task = new_resource_task(opts.user_agent.clone()); + // If we are emitting an output file, then we need to block on + // image load or we risk emitting an output file missing the + // image. + let image_cache_task = if opts.output_file.is_some() { + ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool) + } else { + ImageCacheTask::new(resource_task.clone(), shared_task_pool) + }; + let font_cache_task = FontCacheTask::new(resource_task.clone()); + let constellation_chan = Constellation::<layout::layout_task::LayoutTask, + script::script_task::ScriptTask>::start( + compositor_proxy_for_constellation, + resource_task, + image_cache_task, + font_cache_task, + time_profiler_chan_clone, + devtools_chan); + + // Send the URL command to the constellation. + let cwd = os::getcwd(); + for url in opts.urls.iter() { + let url = match url::Url::parse(url.as_slice()) { + Ok(url) => url, + Err(url::RelativeUrlWithoutBase) + => url::Url::from_file_path(&cwd.join(url.as_slice())).unwrap(), + Err(_) => panic!("URL parsing failed"), + }; + + let ConstellationChan(ref chan) = constellation_chan; + chan.send(InitLoadUrlMsg(url)); + } + + // Send the constallation Chan as the result + result_chan.send(constellation_chan); + }); + + let constellation_chan = result_port.recv(); + + debug!("preparing to enter main loop"); + let compositor = CompositorTask::create(window, + compositor_proxy, + compositor_receiver, + constellation_chan, + time_profiler_chan, + memory_profiler_chan); + + Browser { + pool: pool, + compositor: compositor, + } + } + + pub fn handle_event(&mut self, event: WindowEvent) -> bool { + self.compositor.handle_event(event) + } + + pub fn repaint_synchronously(&mut self) { + self.compositor.repaint_synchronously() + } + + pub fn shutdown(mut self) { + self.compositor.shutdown(); + self.pool.shutdown(); + } +} + |