Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use_bridge hook for agents #2125

Merged
merged 10 commits into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions packages/yew-agent/src/hooks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::cell::RefCell;
use std::rc::Rc;

use crate::*;
use yew::prelude::*;

/// State handle for [`use_bridge`] hook
pub struct UseBridgeHandle<T>
where
T: Bridged,
{
inner: Rc<RefCell<Box<dyn Bridge<T>>>>,
}

impl<T> UseBridgeHandle<T>
where
T: Bridged,
{
/// Send a message to an agent.
pub fn send(&self, msg: T::Input) {
let mut bridge = self.inner.borrow_mut();
bridge.send(msg);
}
}

/// A hook to bridge to an Agent.
///
/// This hooks will only bridge the agent once over the entire component lifecycle.
///
/// Takes a callback as the only argument. The callback will be updated on every render to make
/// sure captured values (if any) are up to date.
pub fn use_bridge<T, F>(on_output: F) -> UseBridgeHandle<T>
where
T: Bridged,
F: Fn(T::Output) + 'static,
{
let on_output = Rc::new(on_output);

let on_output_clone = on_output.clone();
let on_output_ref = use_ref(move || on_output_clone);

// Refresh the callback on every render.
{
let mut on_output_ref = on_output_ref.borrow_mut();
*on_output_ref = on_output;
}

let bridge = use_ref(move || {
T::bridge(Callback::from(move |output| {
let on_output = on_output_ref.borrow().clone();
on_output(output);
}))
});

UseBridgeHandle { inner: bridge }
}
2 changes: 2 additions & 0 deletions packages/yew-agent/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! This module contains types to support multi-threading and state management.

mod hooks;
mod link;
mod local;
mod pool;
pub mod utils;
mod worker;

pub use hooks::{use_bridge, UseBridgeHandle};
pub use link::AgentLink;
pub(crate) use link::*;
pub use local::{Context, Job};
Expand Down
2 changes: 2 additions & 0 deletions website/docs/concepts/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ In order for agents to run concurrently, Yew uses [web-workers](https://develope

A bridge allows bi-directional communication between an agent and a component. Bridges also allow agents to communicate with one another.

A `use_bridge` hook is also provided to create bridges in a function component.

### Dispatchers

A dispatcher allows uni-directional communication between a component and an agent. A dispatcher allows a component to send messages to an agent.
Expand Down