diff --git a/src/servo/engine.rs b/src/servo/engine.rs index 01836ec8c97..7e3f9eab655 100644 --- a/src/servo/engine.rs +++ b/src/servo/engine.rs @@ -42,59 +42,45 @@ struct Engine { fn start() -> EngineProto::client::Running { do spawn_service(EngineProto::init) |request| { - // this could probably be an @vector - let mut request = ~[move request]; + import EngineProto::*; + let mut request = 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 + select! { + request => { + LoadURL(url) -> next { + // TODO: change copy to move once we have match move + let url = move_ref!(url); + if url.path.ends_with(".js") { + self.content.send(ExecuteMsg(url)) + } else { + self.content.send(ParseMsg(url)) + } + request = next; + }, + + Exit -> channel { + self.content.send(content::ExitMsg); + self.layout.send(layout_task::ExitMsg); + + let (response_chan, response_port) = + pipes::stream(); + + self.renderer.send( + renderer::ExitMsg(response_chan)); + response_port.recv(); + + self.image_cache_task.exit(); + self.resource_task.send(resource_task::Exit); + + server::Exited(channel); + break + } } - } - - _ => fail ~"select returned something unexpected." } } } } - - 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 = move_ref!(url); - if url.path.ends_with(".js") { - self.content.send(ExecuteMsg(url)) - } else { - self.content.send(ParseMsg(url)) - } - return some(move_ref!(next)); - } - - Exit(ref channel) => { - self.content.send(content::ExitMsg); - self.layout.send(layout_task::ExitMsg); - - let (response_chan, response_port) = pipes::stream(); - - self.renderer.send(renderer::ExitMsg(response_chan)); - response_port.recv(); - - self.image_cache_task.exit(); - self.resource_task.send(resource_task::Exit); - - server::Exited(move_ref!(channel)); - return none; - } - } - } } proto! EngineProto { diff --git a/src/servo/macros.rs b/src/servo/macros.rs index 0c9f5793751..7538bc7698e 100644 --- a/src/servo/macros.rs +++ b/src/servo/macros.rs @@ -6,4 +6,63 @@ macro_rules! move_val { { $x:expr } => { unsafe { let y <- *ptr::addr_of(*$x); y } } } + + // select! + macro_rules! select_if { + + { + $index:expr, + $count:expr + } => { + fail + }; + + { + $index:expr, + $count:expr, + $port:path => [ + $(type_this $message:path$(($(x $x: ident),+))dont_type_this* + -> $next:ident => { $e:expr }),+ + ] + $(, $ports:path => [ + $(type_this $messages:path$(($(x $xs: ident),+))dont_type_this* + -> $nexts:ident => { $es:expr }),+ + ] )* + } => { + if $index == $count { + match move pipes::try_recv($port) { + $(some($message($($(ref $x,)+)* ref next)) => { + // FIXME (#2329) we really want move out of enum here. + let $next = move_ref!(next); + $e + })+ + _ => fail + } + } else { + select_if!{ + $index, + $count + 1 + $(, $ports => [ + $(type_this $messages$(($(x $xs),+))dont_type_this* + -> $nexts => { $es }),+ + ])* + } + } + }; + } + + macro_rules! select { + { + $( $port:path => { + $($message:path$(($($x: ident),+))dont_type_this* + -> $next:ident $e:expr),+ + } )+ + } => { + let index = pipes::selecti([$(($port).header()),+]/_); + select_if!{index, 0 $(, $port => [ + $(type_this $message$(($(x $x),+))dont_type_this* -> $next => { $e }),+ + ])+} + } + } + }