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

Move yew-agent to gloo #2326

Merged
merged 4 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion examples/agents/src/bin/worker.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use agents::native_worker::Worker;
use yew_agent::PublicAgent;
use yew_agent::PublicWorker;

fn main() {
wasm_logger::init(wasm_logger::Config::default());
Expand Down
7 changes: 4 additions & 3 deletions examples/agents/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod native_worker;

use std::rc::Rc;
use yew::{html, Component, Context, Html};
use yew_agent::{Bridge, Bridged};

Expand All @@ -17,9 +18,9 @@ impl Component for Model {
type Properties = ();

fn create(ctx: &Context<Self>) -> Self {
let link = ctx.link();
let callback = link.callback(|_| Msg::DataReceived);
let worker = native_worker::Worker::bridge(callback);
let link = ctx.link().clone();
let callback = move |_| link.send_message(Msg::DataReceived);
let worker = native_worker::Worker::bridge(Rc::new(callback));

Self { worker }
}
Expand Down
8 changes: 4 additions & 4 deletions examples/agents/src/native_worker.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gloo_timers::callback::Interval;
use serde::{Deserialize, Serialize};
use yew_agent::{Agent, AgentLink, HandlerId, Public};
use yew_agent::{WorkerLink, HandlerId, Public};

#[derive(Serialize, Deserialize, Debug)]
pub enum Request {
Expand All @@ -17,17 +17,17 @@ pub enum Msg {
}

pub struct Worker {
link: AgentLink<Worker>,
link: WorkerLink<Worker>,
_interval: Interval,
}

impl Agent for Worker {
impl yew_agent::Worker for Worker {
type Reach = Public<Self>;
type Message = Msg;
type Input = Request;
type Output = Response;

fn create(link: AgentLink<Self>) -> Self {
fn create(link: WorkerLink<Self>) -> Self {
let duration = 3;

let interval = {
Expand Down
8 changes: 4 additions & 4 deletions examples/web_worker_fib/src/agent.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use yew_agent::{Agent, AgentLink, HandlerId, Public};
use yew_agent::{HandlerId, Public, WorkerLink};

pub struct Worker {
link: AgentLink<Self>,
link: WorkerLink<Self>,
}

#[derive(Serialize, Deserialize)]
Expand All @@ -15,13 +15,13 @@ pub struct WorkerOutput {
pub value: u32,
}

impl Agent for Worker {
impl yew_agent::Worker for Worker {
type Reach = Public<Self>;
type Message = ();
type Input = WorkerInput;
type Output = WorkerOutput;

fn create(link: AgentLink<Self>) -> Self {
fn create(link: WorkerLink<Self>) -> Self {
Self { link }
}

Expand Down
7 changes: 6 additions & 1 deletion examples/web_worker_fib/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::agent::{Worker, WorkerInput, WorkerOutput};
use std::rc::Rc;

use web_sys::HtmlInputElement;
use yew::prelude::*;
Expand All @@ -22,7 +23,11 @@ impl Component for Model {
type Properties = ();

fn create(ctx: &Context<Self>) -> Self {
let worker = Worker::bridge(ctx.link().callback(Self::Message::WorkerMsg));
let cb = {
let link = ctx.link().clone();
move |e| link.send_message(Self::Message::WorkerMsg(e))
};
let worker = Worker::bridge(Rc::new(cb));

Self {
clicker_value: 0,
Expand Down
2 changes: 1 addition & 1 deletion examples/web_worker_fib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod agent;
pub mod app;
use app::Model;
use wasm_bindgen::prelude::*;
use yew_agent::PublicAgent;
use yew_agent::PublicWorker;

#[wasm_bindgen(start)]
pub fn start() {
Expand Down
24 changes: 1 addition & 23 deletions packages/yew-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,6 @@ readme = "../../README.md"
description = "Agents for Yew"
license = "MIT OR Apache-2.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anymap2 = "0.13"
bincode = "1"
gloo-console = "0.2"
gloo-utils = "0.1"
js-sys = "0.3"
serde = { version = "1", features = ["derive"] }
slab = "0.4"
wasm-bindgen = "0.2"
yew = { version = "0.19.3", path = "../yew" }
wasm-bindgen-futures = "0.4"

[dependencies.web-sys]
version = "0.3"
features = [
"Blob",
"BlobPropertyBag",
"DedicatedWorkerGlobalScope",
"MessageEvent",
"Url",
"Worker",
"WorkerOptions",
]
gloo-worker = { git = "https://github.com/hamza1311/gloo", branch = "gloo-worker" }
ranile marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 10 additions & 8 deletions packages/yew-agent/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ impl<T> UseBridgeHandle<T>
where
T: Bridged,
{
/// Send a message to an agent.
/// Send a message to an worker.
pub fn send(&self, msg: T::Input) {
let mut bridge = self.inner.borrow_mut();
bridge.send(msg);
}
}

/// A hook to bridge to an Agent.
/// A hook to bridge to an [`Worker`].
///
/// This hooks will only bridge the agent once over the entire component lifecycle.
/// This hooks will only bridge the worker 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.
Expand All @@ -46,16 +46,18 @@ where
}

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

UseBridgeHandle { inner: bridge }
}

impl<T: Agent> Clone for UseBridgeHandle<T> {
impl<T: Worker> Clone for UseBridgeHandle<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
Expand Down
116 changes: 2 additions & 114 deletions packages/yew-agent/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,119 +1,7 @@
//! This module contains Yew's web worker implementation.

mod hooks;
mod link;
mod pool;
mod worker;

#[doc(inline)]
pub use gloo_worker::*;
pub use hooks::{use_bridge, UseBridgeHandle};
pub use link::AgentLink;
pub(crate) use link::*;
pub(crate) use pool::*;
pub use pool::{Dispatched, Dispatcher};
pub use worker::{Private, PrivateAgent, Public, PublicAgent};

use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::{Deref, DerefMut};
use yew::callback::Callback;

/// Declares the behavior of the agent.
pub trait Agent: Sized + 'static {
/// Reach capability of the agent.
type Reach: Discoverer<Agent = Self>;
/// Type of an input message.
type Message;
/// Incoming message type.
type Input;
/// Outgoing message type.
type Output;

/// Creates an instance of an agent.
fn create(link: AgentLink<Self>) -> Self;

/// This method called on every update message.
fn update(&mut self, msg: Self::Message);

/// This method called on when a new bridge created.
fn connected(&mut self, _id: HandlerId) {}

/// This method called on every incoming message.
fn handle_input(&mut self, msg: Self::Input, id: HandlerId);

/// This method called on when a new bridge destroyed.
fn disconnected(&mut self, _id: HandlerId) {}

/// This method called when the agent is destroyed.
fn destroy(&mut self) {}

/// Represents the name of loading resorce for remote workers which
/// have to live in a separate files.
fn name_of_resource() -> &'static str {
"main.js"
}

/// Indicates whether the name of the resource is relative.
///
/// The default implementation returns `false`, which will cause the result
/// returned by [`Self::name_of_resource`] to be interpreted as an absolute
/// URL. If `true` is returned, it will be interpreted as a relative URL.
fn resource_path_is_relative() -> bool {
false
}

/// Signifies if resource is a module.
/// This has pending browser support.
fn is_module() -> bool {
false
}
}

/// Id of responses handler.
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Hash, Clone, Copy)]
pub struct HandlerId(usize, bool);

impl HandlerId {
fn new(id: usize, respondable: bool) -> Self {
HandlerId(id, respondable)
}
fn raw_id(self) -> usize {
self.0
}
/// Indicates if a handler id corresponds to callback in the Agent runtime.
pub fn is_respondable(self) -> bool {
self.1
}
}

/// Determine a visibility of an agent.
#[doc(hidden)]
pub trait Discoverer {
type Agent: Agent;

/// Spawns an agent and returns `Bridge` implementation.
fn spawn_or_join(
_callback: Option<Callback<<Self::Agent as Agent>::Output>>,
) -> Box<dyn Bridge<Self::Agent>>;
}

/// Bridge to a specific kind of worker.
pub trait Bridge<AGN: Agent> {
/// Send a message to an agent.
fn send(&mut self, msg: AGN::Input);
}

/// This trait allows registering or getting the address of a worker.
pub trait Bridged: Agent + Sized + 'static {
/// Creates a messaging bridge between a worker and the component.
fn bridge(callback: Callback<Self::Output>) -> Box<dyn Bridge<Self>>;
}

impl<T> Bridged for T
where
T: Agent,
<T as Agent>::Reach: Discoverer<Agent = T>,
{
fn bridge(callback: Callback<Self::Output>) -> Box<dyn Bridge<Self>> {
Self::Reach::spawn_or_join(Some(callback))
}
}
Loading