diff --git a/src/servo/engine.rs b/src/servo/engine.rs index 91ce3e5cfade..01836ec8c976 100644 --- a/src/servo/engine.rs +++ b/src/servo/engine.rs @@ -1,6 +1,5 @@ import gfx::renderer::{Renderer, Sink}; -import task::spawn_listener; -import comm::chan; +import pipes::{spawn_service, select}; import layout::layout_task; import layout_task::Layout; import content::{Content, ExecuteMsg, ParseMsg, ExitMsg, create_content}; @@ -12,6 +11,10 @@ import image_cache_task::{ImageCacheTask, image_cache_task, ImageCacheTaskClient import pipes::{port, chan}; +fn macros() { + include!("macros.rs"); +} + struct Engine { let sink: S; @@ -37,28 +40,45 @@ struct Engine { self.content = content; } - fn start() -> comm::Chan { - do spawn_listener:: |request| { - while self.handle_request(request.recv()) { - // Go on... + fn start() -> EngineProto::client::Running { + do spawn_service(EngineProto::init) |request| { + // this could probably be an @vector + let mut request = ~[move request]; + + loop { + match move select(move request) { + (_, some(ref message), ref requests) => { + match move self.handle_request(move_ref!(message)) { + some(ref req) => + request = vec::append_one(move_ref!(requests), + move_ref!(req)), + none => break + } + } + + _ => fail ~"select returned something unexpected." + } } } } - fn handle_request(request: Msg) -> bool { - match request { - LoadURLMsg(url) => { + fn handle_request(+request: EngineProto::Running) + -> option + { + import EngineProto::*; + match move request { + LoadURL(ref url, ref next) => { // TODO: change copy to move once we have match move - let url = copy url; + let url = move_ref!(url); if url.path.ends_with(".js") { self.content.send(ExecuteMsg(url)) } else { self.content.send(ParseMsg(url)) } - return true; + return some(move_ref!(next)); } - ExitMsg(sender) => { + Exit(ref channel) => { self.content.send(content::ExitMsg); self.layout.send(layout_task::ExitMsg); @@ -70,15 +90,20 @@ struct Engine { self.image_cache_task.exit(); self.resource_task.send(resource_task::Exit); - sender.send(()); - return false; + server::Exited(move_ref!(channel)); + return none; } } } } -enum Msg { - LoadURLMsg(url), - ExitMsg(chan<()>) -} +proto! EngineProto { + Running:send { + LoadURL(url) -> Running, + Exit -> Exiting + } + Exiting:recv { + Exited -> ! + } +} diff --git a/src/servo/macros.rs b/src/servo/macros.rs new file mode 100644 index 000000000000..0c9f5793751c --- /dev/null +++ b/src/servo/macros.rs @@ -0,0 +1,9 @@ +{ + macro_rules! move_ref { + { $x:expr } => { unsafe { let y <- *ptr::addr_of(*$x); y } } + } + + macro_rules! move_val { + { $x:expr } => { unsafe { let y <- *ptr::addr_of(*$x); y } } + } +} diff --git a/src/servo/servo.rs b/src/servo/servo.rs index 521456b6e9d9..de4a59bff1b2 100644 --- a/src/servo/servo.rs +++ b/src/servo/servo.rs @@ -1,9 +1,11 @@ import comm::*; +import option::swap_unwrap; import gfx::renderer; import platform::osmain; import osmain::{OSMain, AddKeyHandler}; import opts::{Opts, Screen, Png}; -import engine::{Engine, LoadURLMsg}; +import engine::Engine; +import engine::EngineProto; import url_to_str = std::net::url::to_str; import util::url::make_url; @@ -39,12 +41,14 @@ fn run_pipeline_screen(urls: ~[~str]) { // Create a serve instance let engine = Engine(osmain); - let engine_chan = engine.start(); + let mut engine_chan = some(engine.start()); for urls.each |filename| { let url = make_url(filename, none); #debug["master: Sending url `%s`", url_to_str(url)]; - engine_chan.send(LoadURLMsg(url)); + engine_chan = + some(EngineProto::client::LoadURL(swap_unwrap(&mut engine_chan), + url)); #debug["master: Waiting for keypress"]; match keypress_from_osmain.try_recv() { @@ -55,9 +59,8 @@ fn run_pipeline_screen(urls: ~[~str]) { // Shut everything down #debug["master: Shut down"]; - let (exit_chan, exit_response_from_engine) = pipes::stream(); - engine_chan.send(engine::ExitMsg(exit_chan)); - exit_response_from_engine.recv(); + let engine_chan = EngineProto::client::Exit(option::unwrap(engine_chan)); + pipes::recv(engine_chan); osmain.send(osmain::Exit); } @@ -74,16 +77,16 @@ fn run_pipeline_png(-url: ~str, outfile: ~str) { let sink = PngSink(pngdata_from_sink); let engine = Engine(sink); let engine_chan = engine.start(); - engine_chan.send(LoadURLMsg(make_url(url, none))); + let engine_chan = + EngineProto::client::LoadURL(engine_chan, make_url(url, none)); match buffered_file_writer(outfile) { ok(writer) => writer.write(pngdata_from_sink.recv()), err(e) => fail e } - let (exit_chan, exit_response_from_engine) = pipes::stream(); - engine_chan.send(engine::ExitMsg(exit_chan)); - exit_response_from_engine.recv(); + let engine_chan = EngineProto::client::Exit(engine_chan); + pipes::recv(engine_chan); sink.send(pngsink::Exit); }) }