From acac40ea418d5059051f26e51b04ed980293bd89 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 12 Jul 2012 16:32:27 -0700 Subject: [PATCH] servo: Make content a class Source-Repo: https://github.com/servo/servo Source-Revision: 9b599e4e5ab4829d12d21e799b62f8a0962b8bf7 --- servo/src/servo/content.rs | 164 +++++++++++++++++++++++-------------- servo/src/servo/engine.rs | 6 +- 2 files changed, 107 insertions(+), 63 deletions(-) diff --git a/servo/src/servo/content.rs b/servo/src/servo/content.rs index 9a0a03641930..63b065971249 100644 --- a/servo/src/servo/content.rs +++ b/servo/src/servo/content.rs @@ -6,6 +6,7 @@ export Content; export ControlMsg, ExecuteMsg, ParseMsg, ExitMsg; export PingMsg, PongMsg; +export create_content; import comm::{port, chan, listen, select2}; import task::{spawn, spawn_listener}; @@ -13,7 +14,7 @@ import io::{read_whole_file, println}; import result::{ok, err}; import dom::base::NodeScope; -import dom::event::ResizeEvent; +import dom::event::{Event, ResizeEvent}; import dom::rcu::WriterMethods; import dom::style; import gfx::renderer::Sink; @@ -27,7 +28,7 @@ import jsrt = js::rust::rt; import js::rust::methods; import js::global::{global_class, debug_fns}; -import either::{left, right}; +import either::{either, left, right}; import result::extensions; type Content = chan; @@ -55,70 +56,113 @@ fn join_layout(scope: NodeScope, layout: Layout) { } } -#[warn(no_non_implicitly_copyable_typarams)] -fn Content(layout: Layout, sink: S) -> Content { - spawn_listener::(|from_master| { - let event_port = port(); - sink.add_event_listener(event_port.chan()); +class Content { + let sink: S; + let layout: Layout; + let from_master: port; + let event_port: port; - let scope = NodeScope(); - let rt = jsrt(); - loop { - alt select2(from_master, event_port) { - left(ParseMsg(filename)) { - #debug["content: Received filename `%s` to parse", *filename]; + let scope: NodeScope; + let jsrt: jsrt; - // Note: we can parse the next document in parallel - // with any previous documents. - let stream = spawn_html_lexer_task(copy filename); - let (root, style_port) = build_dom(scope, stream); - - // Collect the css stylesheet - let css_rules = style_port.recv(); - - // Apply the css rules to the dom tree: - #debug["%?", css_rules]; + new(layout: Layout, sink: S, from_master: port) { + self.layout = layout; + self.sink = sink; + self.from_master = from_master; + self.event_port = port(); - // Now, join the layout so that they will see the latest - // changes we have made. - join_layout(scope, layout); + self.scope = NodeScope(); + self.jsrt = jsrt(); - // Send new document and relevant styles to layout - layout.send(BuildMsg(root, css_rules)); + self.sink.add_event_listener(self.event_port.chan()); + } - // Indicate that reader was forked so any further - // changes will be isolated. - scope.reader_forked(); - } + fn start() { + while self.handle_msg(select2(self.from_master, self.event_port)) { + // Go on... + } + } - left(ExecuteMsg(filename)) { - #debug["content: Received filename `%s` to execute", *filename]; - - alt read_whole_file(*filename) { - err(msg) { - println(#fmt["Error opening %s: %s", *filename, msg]); - } - ok(bytes) { - let cx = rt.cx(); - cx.set_default_options_and_version(); - cx.set_logging_error_reporter(); - cx.new_compartment(global_class).chain(|compartment| { - compartment.define_functions(debug_fns); - cx.evaluate_script(compartment.global_obj, bytes, *filename, 1u) - }); - } - } - } - - left(ExitMsg) { - layout.send(layout_task::ExitMsg); - break; - } - - right(ResizeEvent(new_width, new_height)) { - #debug("content got resize event: %d, %d", new_width, new_height); - } + fn handle_msg(msg: either) -> bool { + alt msg { + left(control_msg) { + ret self.handle_control_msg(control_msg); + } + right(event) { + ret self.handle_event(event); } } - }) + } + + fn handle_control_msg(control_msg: ControlMsg) -> bool { + alt control_msg { + ParseMsg(filename) { + #debug["content: Received filename `%s` to parse", *filename]; + + // Note: we can parse the next document in parallel + // with any previous documents. + let stream = spawn_html_lexer_task(copy filename); + let (root, style_port) = build_dom(self.scope, stream); + + // Collect the css stylesheet + let css_rules = style_port.recv(); + + // Apply the css rules to the dom tree: + #debug["%?", css_rules]; + + // Now, join the layout so that they will see the latest + // changes we have made. + join_layout(self.scope, self.layout); + + // Send new document and relevant styles to layout + self.layout.send(BuildMsg(root, css_rules)); + + // Indicate that reader was forked so any further + // changes will be isolated. + self.scope.reader_forked(); + ret true; + } + + ExecuteMsg(filename) { + #debug["content: Received filename `%s` to execute", *filename]; + + alt read_whole_file(*filename) { + err(msg) { + println(#fmt["Error opening %s: %s", *filename, msg]); + } + ok(bytes) { + let cx = self.jsrt.cx(); + cx.set_default_options_and_version(); + cx.set_logging_error_reporter(); + cx.new_compartment(global_class).chain(|compartment| { + compartment.define_functions(debug_fns); + cx.evaluate_script(compartment.global_obj, bytes, *filename, 1u) + }); + } + } + ret true; + } + + ExitMsg { + self.layout.send(layout_task::ExitMsg); + ret false; + } + } + } + + fn handle_event(event: Event) -> bool { + alt event { + ResizeEvent(new_width, new_height) { + #debug("content got resize event: %d, %d", new_width, new_height); + ret true; + } + } + } } + +fn create_content(layout: Layout, sink: S) -> chan { + do spawn_listener:: |from_master| { + Content(layout, sink, from_master).start(); + } +} + diff --git a/servo/src/servo/engine.rs b/servo/src/servo/engine.rs index ca5f9b2a5f36..bd51839116c7 100644 --- a/servo/src/servo/engine.rs +++ b/servo/src/servo/engine.rs @@ -3,21 +3,21 @@ import task::spawn_listener; import comm::chan; import layout::layout_task; import layout_task::Layout; -import content::{Content, ExecuteMsg, ParseMsg, ExitMsg}; +import content::{Content, ExecuteMsg, ParseMsg, ExitMsg, create_content}; class Engine { let sink: S; let renderer: Renderer; let layout: Layout; - let content: Content; + let content: chan; new(sink: S) { self.sink = sink; let renderer = Renderer(sink); let layout = Layout(renderer); - let content = Content(layout, sink); + let content = create_content(layout, sink); self.renderer = renderer; self.layout = layout;