This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew_agent/worker/
lifecycle.rs

1use wasm_bindgen::prelude::*;
2
3use super::messages::ToWorker;
4use super::native_worker::{DedicatedWorker, WorkerSelf};
5use super::scope::{WorkerDestroyHandle, WorkerScope};
6use super::traits::Worker;
7use super::Shared;
8
9pub(crate) struct WorkerState<W>
10where
11    W: Worker,
12{
13    worker: Option<(W, WorkerScope<W>)>,
14    to_destroy: bool,
15}
16
17impl<W> WorkerState<W>
18where
19    W: Worker,
20{
21    pub fn new() -> Self {
22        WorkerState {
23            worker: None,
24            to_destroy: false,
25        }
26    }
27}
28
29/// Internal Worker lifecycle events
30pub(crate) enum WorkerLifecycleEvent<W: Worker> {
31    /// Request to create the scope
32    Create(WorkerScope<W>),
33
34    /// Internal Worker message
35    Message(W::Message),
36
37    /// External Messages from bridges
38    Remote(ToWorker<W>),
39
40    /// Destroy the Worker
41    Destroy,
42}
43
44pub(crate) struct WorkerRunnable<W: Worker> {
45    pub state: Shared<WorkerState<W>>,
46    pub event: WorkerLifecycleEvent<W>,
47}
48
49impl<W> WorkerRunnable<W>
50where
51    W: Worker + 'static,
52{
53    pub fn run(self) {
54        let mut state = self.state.borrow_mut();
55
56        // We should block all event other than message after a worker is destroyed.
57        match self.event {
58            WorkerLifecycleEvent::Create(scope) => {
59                if state.to_destroy {
60                    return;
61                }
62                state.worker = Some((W::create(&scope), scope));
63            }
64            WorkerLifecycleEvent::Message(msg) => {
65                if let Some((worker, scope)) = state.worker.as_mut() {
66                    worker.update(scope, msg);
67                }
68            }
69            WorkerLifecycleEvent::Remote(ToWorker::Connected(id)) => {
70                if state.to_destroy {
71                    return;
72                }
73
74                let (worker, scope) = state
75                    .worker
76                    .as_mut()
77                    .expect_throw("worker was not created to process connected messages");
78
79                worker.connected(scope, id);
80            }
81            WorkerLifecycleEvent::Remote(ToWorker::ProcessInput(id, inp)) => {
82                if state.to_destroy {
83                    return;
84                }
85
86                let (worker, scope) = state
87                    .worker
88                    .as_mut()
89                    .expect_throw("worker was not created to process inputs");
90
91                worker.received(scope, inp, id);
92            }
93            WorkerLifecycleEvent::Remote(ToWorker::Disconnected(id)) => {
94                if state.to_destroy {
95                    return;
96                }
97
98                let (worker, scope) = state
99                    .worker
100                    .as_mut()
101                    .expect_throw("worker was not created to process disconnected messages");
102
103                worker.disconnected(scope, id);
104            }
105            WorkerLifecycleEvent::Remote(ToWorker::Destroy) => {
106                if state.to_destroy {
107                    return;
108                }
109
110                state.to_destroy = true;
111
112                let (worker, scope) = state
113                    .worker
114                    .as_mut()
115                    .expect_throw("trying to destroy not existent worker");
116
117                let destruct = WorkerDestroyHandle::new(scope.clone());
118
119                worker.destroy(scope, destruct);
120            }
121
122            WorkerLifecycleEvent::Destroy => {
123                state
124                    .worker
125                    .take()
126                    .expect_throw("worker is not initialised or already destroyed");
127
128                DedicatedWorker::worker_self().close();
129            }
130        }
131    }
132}