yew_agent/worker/
native_worker.rs1use serde::{Deserialize, Serialize};
2use wasm_bindgen::closure::Closure;
3use wasm_bindgen::prelude::*;
4use wasm_bindgen::{JsCast, JsValue};
5pub(crate) use web_sys::Worker as DedicatedWorker;
6use web_sys::{DedicatedWorkerGlobalScope, MessageEvent};
7
8use crate::codec::Codec;
9
10pub(crate) trait WorkerSelf {
11 type GlobalScope;
12
13 fn worker_self() -> Self::GlobalScope;
14}
15
16impl WorkerSelf for DedicatedWorker {
17 type GlobalScope = DedicatedWorkerGlobalScope;
18
19 fn worker_self() -> Self::GlobalScope {
20 JsValue::from(js_sys::global()).into()
21 }
22}
23
24pub(crate) trait NativeWorkerExt {
25 fn set_on_packed_message<T, CODEC, F>(&self, handler: F)
26 where
27 T: Serialize + for<'de> Deserialize<'de>,
28 CODEC: Codec,
29 F: 'static + Fn(T);
30
31 fn post_packed_message<T, CODEC>(&self, data: T)
32 where
33 T: Serialize + for<'de> Deserialize<'de>,
34 CODEC: Codec;
35}
36
37macro_rules! worker_ext_impl {
38 ($($type:path),+) => {$(
39 impl NativeWorkerExt for $type {
40 fn set_on_packed_message<T, CODEC, F>(&self, handler: F)
41 where
42 T: Serialize + for<'de> Deserialize<'de>,
43 CODEC: Codec,
44 F: 'static + Fn(T)
45 {
46 let handler = move |message: MessageEvent| {
47 let msg = CODEC::decode(message.data());
48 handler(msg);
49 };
50 let closure = Closure::wrap(Box::new(handler) as Box<dyn Fn(MessageEvent)>).into_js_value();
51 self.set_onmessage(Some(closure.as_ref().unchecked_ref()));
52 }
53
54 fn post_packed_message<T, CODEC>(&self, data: T)
55 where
56 T: Serialize + for<'de> Deserialize<'de>,
57 CODEC: Codec
58 {
59 self.post_message(&CODEC::encode(data))
60 .expect_throw("failed to post message");
61 }
62 }
63 )+};
64}
65
66worker_ext_impl! {
67 DedicatedWorker, DedicatedWorkerGlobalScope
68}