From 3565288c996ea93f2f3429c480f70c6ac91df56b Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Sat, 7 Dec 2019 18:18:33 -0500 Subject: [PATCH] Rename methods and loosen mutability for component link and agent (#780) * Rename methods and loosen mutability for component link and agent * Update send_back to callback * mut link -> link --- README.md | 6 ++--- examples/dashboard/src/lib.rs | 8 +++---- examples/file_upload/src/lib.rs | 4 ++-- examples/futures/src/lib.rs | 2 +- examples/game_of_life/src/lib.rs | 4 ++-- examples/js_callback/src/lib.rs | 2 +- examples/multi_thread/src/context.rs | 2 +- examples/multi_thread/src/job.rs | 2 +- examples/multi_thread/src/lib.rs | 10 ++++---- examples/multi_thread/src/native_worker.rs | 2 +- examples/npm_and_rest/src/lib.rs | 4 ++-- examples/routing/src/b_component.rs | 4 ++-- examples/routing/src/lib.rs | 4 ++-- examples/routing/src/router.rs | 2 +- examples/timer/src/lib.rs | 6 ++--- src/agent.rs | 9 ++++---- src/html/mod.rs | 27 ++++++++++------------ src/html/scope.rs | 6 ++--- src/services/fetch.rs | 12 +++++----- 19 files changed, 56 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index b04a6edc76c..47c0797666c 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ impl Agent for Worker { Worker { link } } - // Handle inner messages (of services of `send_back` callbacks) + // Handle inner messages (from callbacks) fn update(&mut self, msg: Self::Message) { /* ... */ } // Handle incoming messages from components of other agents. @@ -195,7 +195,7 @@ impl Component for Model { type Properties = (); fn create(_: Self::Properties, link: ComponentLink) -> Self { - let callback = link.send_back(|_| Msg::ContextMsg); + let callback = link.callback(|_| Msg::ContextMsg); // `Worker::bridge` spawns an instance if no one is available let context = context::Worker::bridge(callback); // Connected! :tada: Model { context } @@ -362,7 +362,7 @@ impl Component for Model { fn update(&mut self, msg: Self::Message) -> ShouldRender { match msg { Msg::Fire => { - let send_msg = self.link.send_back(|_| Msg::Timeout); + let send_msg = self.link.callback(|_| Msg::Timeout); self.timeout.spawn(Duration::from_secs(5), send_msg); } Msg::Timeout => { diff --git a/examples/dashboard/src/lib.rs b/examples/dashboard/src/lib.rs index db834c0ff5b..78880a2811f 100644 --- a/examples/dashboard/src/lib.rs +++ b/examples/dashboard/src/lib.rs @@ -87,7 +87,7 @@ impl Component for Model { self.fetching = true; let task = match format { Format::Json => { - let callback = self.link.send_back( + let callback = self.link.callback( move |response: Response>>| { let (meta, Json(data)) = response.into_parts(); println!("META: {:?}, {:?}", meta, data); @@ -106,7 +106,7 @@ impl Component for Model { } } Format::Toml => { - let callback = self.link.send_back( + let callback = self.link.callback( move |response: Response>>| { let (meta, Toml(data)) = response.into_parts(); println!("META: {:?}, {:?}", meta, data); @@ -129,8 +129,8 @@ impl Component for Model { } Msg::WsAction(action) => match action { WsAction::Connect => { - let callback = self.link.send_back(|Json(data)| Msg::WsReady(data)); - let notification = self.link.send_back(|status| match status { + let callback = self.link.callback(|Json(data)| Msg::WsReady(data)); + let notification = self.link.callback(|status| match status { WebSocketStatus::Opened => Msg::Ignore, WebSocketStatus::Closed | WebSocketStatus::Error => WsAction::Lost.into(), }); diff --git a/examples/file_upload/src/lib.rs b/examples/file_upload/src/lib.rs index 8b236ae125e..dea88e7ae6f 100644 --- a/examples/file_upload/src/lib.rs +++ b/examples/file_upload/src/lib.rs @@ -48,10 +48,10 @@ impl Component for Model { for file in files.into_iter() { let task = { if chunks { - let callback = self.link.send_back(Msg::Chunk); + let callback = self.link.callback(Msg::Chunk); self.reader.read_file_by_chunks(file, callback, 10) } else { - let callback = self.link.send_back(Msg::Loaded); + let callback = self.link.callback(Msg::Loaded); self.reader.read_file(file, callback) } }; diff --git a/examples/futures/src/lib.rs b/examples/futures/src/lib.rs index 5f5e22b832f..b59fd2136d3 100644 --- a/examples/futures/src/lib.rs +++ b/examples/futures/src/lib.rs @@ -94,7 +94,7 @@ impl Component for Model { }; self.link.send_future(future); self.link - .send_self(SetMarkdownFetchState(FetchState::Fetching)); + .send_message(SetMarkdownFetchState(FetchState::Fetching)); false } } diff --git a/examples/game_of_life/src/lib.rs b/examples/game_of_life/src/lib.rs index b004fa9c66e..76bb46fb59d 100644 --- a/examples/game_of_life/src/lib.rs +++ b/examples/game_of_life/src/lib.rs @@ -155,8 +155,8 @@ impl Component for Model { type Message = Msg; type Properties = (); - fn create(_: Self::Properties, mut link: ComponentLink) -> Self { - let callback = link.send_back(|_| Msg::Tick); + fn create(_: Self::Properties, link: ComponentLink) -> Self { + let callback = link.callback(|_| Msg::Tick); let mut interval = IntervalService::new(); let handle = interval.spawn(Duration::from_millis(200), callback); Model { diff --git a/examples/js_callback/src/lib.rs b/examples/js_callback/src/lib.rs index b12bfb9a641..da256dca7e0 100644 --- a/examples/js_callback/src/lib.rs +++ b/examples/js_callback/src/lib.rs @@ -43,7 +43,7 @@ impl Component for Model { } } AsyncPayload => { - get_payload_later(self.link.send_back(Msg::Payload)); + get_payload_later(self.link.callback(Msg::Payload)); false } } diff --git a/examples/multi_thread/src/context.rs b/examples/multi_thread/src/context.rs index e917e770255..d5bec7bfe69 100644 --- a/examples/multi_thread/src/context.rs +++ b/examples/multi_thread/src/context.rs @@ -37,7 +37,7 @@ impl Agent for Worker { fn create(link: AgentLink) -> Self { let mut interval = IntervalService::new(); let duration = Duration::from_secs(3); - let callback = link.send_back(|_| Msg::Updating); + let callback = link.callback(|_| Msg::Updating); let task = interval.spawn(duration, callback); Worker { link, diff --git a/examples/multi_thread/src/job.rs b/examples/multi_thread/src/job.rs index dc392cf54d4..f8fda50ec5e 100644 --- a/examples/multi_thread/src/job.rs +++ b/examples/multi_thread/src/job.rs @@ -37,7 +37,7 @@ impl Agent for Worker { fn create(link: AgentLink) -> Self { let mut interval = IntervalService::new(); let duration = Duration::from_secs(3); - let callback = link.send_back(|_| Msg::Updating); + let callback = link.callback(|_| Msg::Updating); let task = interval.spawn(duration, callback); Worker { link, diff --git a/examples/multi_thread/src/lib.rs b/examples/multi_thread/src/lib.rs index 8c0e49516c1..5b8f02e0b66 100644 --- a/examples/multi_thread/src/lib.rs +++ b/examples/multi_thread/src/lib.rs @@ -26,17 +26,17 @@ impl Component for Model { type Message = Msg; type Properties = (); - fn create(_: Self::Properties, mut link: ComponentLink) -> Self { - let callback = link.send_back(|_| Msg::DataReceived); + fn create(_: Self::Properties, link: ComponentLink) -> Self { + let callback = link.callback(|_| Msg::DataReceived); let worker = native_worker::Worker::bridge(callback); - let callback = link.send_back(|_| Msg::DataReceived); + let callback = link.callback(|_| Msg::DataReceived); let job = job::Worker::bridge(callback); - let callback = link.send_back(|_| Msg::DataReceived); + let callback = link.callback(|_| Msg::DataReceived); let context = context::Worker::bridge(callback); - let callback = link.send_back(|_| Msg::DataReceived); + let callback = link.callback(|_| Msg::DataReceived); let context_2 = context::Worker::bridge(callback); Model { diff --git a/examples/multi_thread/src/native_worker.rs b/examples/multi_thread/src/native_worker.rs index 7e5ce0d80aa..83f6a809e98 100644 --- a/examples/multi_thread/src/native_worker.rs +++ b/examples/multi_thread/src/native_worker.rs @@ -37,7 +37,7 @@ impl Agent for Worker { fn create(link: AgentLink) -> Self { let mut interval = IntervalService::new(); let duration = Duration::from_secs(3); - let callback = link.send_back(|_| Msg::Updating); + let callback = link.callback(|_| Msg::Updating); let task = interval.spawn(duration, callback); Worker { link, diff --git a/examples/npm_and_rest/src/lib.rs b/examples/npm_and_rest/src/lib.rs index a2916d75064..3065907da2c 100644 --- a/examples/npm_and_rest/src/lib.rs +++ b/examples/npm_and_rest/src/lib.rs @@ -33,11 +33,11 @@ impl Component for Model { type Message = Msg; type Properties = (); - fn create(_: Self::Properties, mut link: ComponentLink) -> Self { + fn create(_: Self::Properties, link: ComponentLink) -> Self { Model { gravatar: GravatarService::new(), ccxt: CcxtService::new(), - callback: link.send_back(Msg::GravatarReady), + callback: link.callback(Msg::GravatarReady), profile: None, exchanges: Vec::new(), task: None, diff --git a/examples/routing/src/b_component.rs b/examples/routing/src/b_component.rs index 90f04dec374..d110f5fa88e 100644 --- a/examples/routing/src/b_component.rs +++ b/examples/routing/src/b_component.rs @@ -21,8 +21,8 @@ impl Component for BModel { type Message = Msg; type Properties = (); - fn create(_: Self::Properties, mut link: ComponentLink) -> Self { - let callback = link.send_back(|route: Route<()>| Msg::HandleRoute(route)); + fn create(_: Self::Properties, link: ComponentLink) -> Self { + let callback = link.callback(|route: Route<()>| Msg::HandleRoute(route)); let mut router = Router::bridge(callback); router.send(Request::GetCurrentRoute); diff --git a/examples/routing/src/lib.rs b/examples/routing/src/lib.rs index f5fad039fe2..50570479147 100644 --- a/examples/routing/src/lib.rs +++ b/examples/routing/src/lib.rs @@ -32,8 +32,8 @@ impl Component for Model { type Message = Msg; type Properties = (); - fn create(_: Self::Properties, mut link: ComponentLink) -> Self { - let callback = link.send_back(|route: Route<()>| Msg::HandleRoute(route)); + fn create(_: Self::Properties, link: ComponentLink) -> Self { + let callback = link.callback(|route: Route<()>| Msg::HandleRoute(route)); let router = router::Router::bridge(callback); Model { child: Child::Loading, // This should be quickly overwritten by the actual route. diff --git a/examples/routing/src/router.rs b/examples/routing/src/router.rs index 3c7302501cd..fe991575045 100644 --- a/examples/routing/src/router.rs +++ b/examples/routing/src/router.rs @@ -117,7 +117,7 @@ where type Output = Route; fn create(link: AgentLink) -> Self { - let callback = link.send_back(|route_changed: (String, T)| { + let callback = link.callback(|route_changed: (String, T)| { Msg::BrowserNavigationRouteChanged(route_changed) }); let mut route_service = RouteService::new(); diff --git a/examples/timer/src/lib.rs b/examples/timer/src/lib.rs index 87d63dcb82e..c705ad19f0a 100644 --- a/examples/timer/src/lib.rs +++ b/examples/timer/src/lib.rs @@ -27,7 +27,7 @@ impl Component for Model { type Message = Msg; type Properties = (); - fn create(_: Self::Properties, mut link: ComponentLink) -> Self { + fn create(_: Self::Properties, link: ComponentLink) -> Self { // This callback doesn't send any message to a scope let callback = |_| { println!("Example of a standalone callback."); @@ -39,8 +39,8 @@ impl Component for Model { timeout: TimeoutService::new(), interval, console: ConsoleService::new(), - callback_tick: link.send_back(|_| Msg::Tick), - callback_done: link.send_back(|_| Msg::Done), + callback_tick: link.callback(|_| Msg::Tick), + callback_done: link.callback(|_| Msg::Done), job: None, messages: Vec::new(), _standalone: Box::new(handle), diff --git a/src/agent.rs b/src/agent.rs index 92a1975a16a..5560c1dcaf5 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -786,21 +786,20 @@ impl AgentLink { } } - /// Send response to an actor. + /// Send response to an agent. pub fn response(&self, id: HandlerId, output: AGN::Output) { self.responder.response(id, output); } - /// This method sends messages back to the component's loop. - pub fn send_back(&self, function: F) -> Callback + /// Create a callback which will send a message to the agent when invoked. + pub fn callback(&self, function: F) -> Callback where F: Fn(IN) -> AGN::Message + 'static, { let scope = self.scope.clone(); let closure = move |input| { let output = function(input); - let msg = AgentUpdate::Message(output); - scope.clone().send(msg); + scope.send(AgentUpdate::Message(output)); }; closure.into() } diff --git a/src/html/mod.rs b/src/html/mod.rs index 507cfa4af63..a2d5bc39127 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -385,9 +385,9 @@ where } } - /// This method sends batch of messages back to the component's loop when the - /// returned callback is called. - pub fn send_back_batch(&mut self, function: F) -> Callback + /// This method creates a `Callback` which will send a batch of messages back to the linked + /// component's update method when called. + pub fn batch_callback(&self, function: F) -> Callback where F: Fn(IN) -> Vec + 'static, { @@ -399,15 +399,16 @@ where closure.into() } - /// This method sends messages back to the component's loop when the returned callback is called. - pub fn send_back(&mut self, function: F) -> Callback + /// This method creates a `Callback` which will send a message to the linked component's + /// update method when invoked. + pub fn callback(&self, function: F) -> Callback where F: Fn(IN) -> COMP::Message + 'static, { let scope = self.scope.clone(); let closure = move |input| { let output = function(input); - scope.clone().send_message(output); + scope.send_message(output); }; closure.into() } @@ -425,13 +426,9 @@ where use wasm_bindgen::JsValue; use wasm_bindgen_futures::future_to_promise; - let mut scope = self.scope.clone(); - - let js_future = async { - let message: COMP::Message = future.await; - // Force movement of the cloned scope into the async block. - let scope_send = move || scope.send_message(message); - scope_send(); + let scope = self.scope.clone(); + let js_future = async move { + scope.send_message(future.await); Ok(JsValue::NULL) }; future_to_promise(js_future); @@ -439,7 +436,7 @@ where /// This method sends a message to this component to be processed immediately after the /// component has been updated and/or rendered. - pub fn send_self(&mut self, msg: COMP::Message) { + pub fn send_message(&mut self, msg: COMP::Message) { self.scope.send_message(msg); } @@ -448,7 +445,7 @@ where /// /// All messages will first be processed by `update`, and if _any_ of them return `true`, /// then re-render will occur. - pub fn send_self_batch(&mut self, msgs: Vec) { + pub fn send_message_batch(&mut self, msgs: Vec) { self.scope.send_message_batch(msgs) } } diff --git a/src/html/scope.rs b/src/html/scope.rs index f59adb87e44..74aaceb861b 100644 --- a/src/html/scope.rs +++ b/src/html/scope.rs @@ -90,7 +90,7 @@ impl Scope { } /// Schedules a task to send a message or new props to a component - pub(crate) fn update(&mut self, update: ComponentUpdate) { + pub(crate) fn update(&self, update: ComponentUpdate) { let update = UpdateComponent { shared_state: self.shared_state.clone(), update, @@ -106,12 +106,12 @@ impl Scope { } /// Send a message to the component - pub fn send_message(&mut self, msg: COMP::Message) { + pub fn send_message(&self, msg: COMP::Message) { self.update(ComponentUpdate::Message(msg)); } /// Send a batch of messages to the component - pub fn send_message_batch(&mut self, messages: Vec) { + pub fn send_message_batch(&self, messages: Vec) { self.update(ComponentUpdate::MessageBatch(messages)); } } diff --git a/src/services/fetch.rs b/src/services/fetch.rs index 908380acae4..219760dae9b 100644 --- a/src/services/fetch.rs +++ b/src/services/fetch.rs @@ -155,12 +155,12 @@ impl FetchService { ///# Error ///# } ///# fn dont_execute() { - ///# let mut link: ComponentLink = unimplemented!(); + ///# let link: ComponentLink = unimplemented!(); ///# let mut fetch_service: FetchService = FetchService::new(); ///# let post_request: Request> = unimplemented!(); /// let task = fetch_service.fetch( /// post_request, - /// link.send_back(|response: Response>| { + /// link.callback(|response: Response>| { /// if response.status().is_success() { /// Msg::Noop /// } else { @@ -199,9 +199,9 @@ impl FetchService { /// } /// ///# fn dont_execute() { - ///# let mut link: ComponentLink = unimplemented!(); + ///# let link: ComponentLink = unimplemented!(); /// let get_request = Request::get("/thing").body(Nothing).unwrap(); - /// let callback = link.send_back(|response: Response>>| { + /// let callback = link.callback(|response: Response>>| { /// if let (meta, Json(Ok(body))) = response.into_parts() { /// if meta.status.is_success() { /// return Msg::FetchResourceComplete(body); @@ -244,8 +244,8 @@ impl FetchService { ///# } ///# pub enum Msg {} ///# fn dont_execute() { - ///# let mut link: ComponentLink = unimplemented!(); - ///# let callback = link.send_back(|response: Response>| unimplemented!()); + ///# let link: ComponentLink = unimplemented!(); + ///# let callback = link.callback(|response: Response>| unimplemented!()); /// let request = fetch::Request::get("/path/") /// .body(Nothing) /// .unwrap();