rsiot/components/cmp_leptos/create_signal_from_msg/
create.rs1use leptos::prelude::*;
2use tracing::trace;
3
4use crate::message::MsgDataBound;
5
6use super::{super::GlobalState, Config};
7
8pub fn create<TMsg, TValue>(
10 config: Config<TMsg, TValue>,
11) -> (ReadSignal<TValue>, WriteSignal<TValue>)
12where
13 TValue: Clone + std::fmt::Debug + Default + 'static + Send + Sync,
14 TMsg: MsgDataBound + 'static,
15{
16 let gs = use_context::<GlobalState<TMsg>>().expect("No global state in create_signal_from_msg");
17
18 let default_content = (config.fn_input)(&config.default).unwrap();
19 let (input, input_set) = signal(default_content.clone());
20 let (output, output_set) = signal(TValue::default());
21
22 let cache = gs.cache.clone();
23 {
24 let lock = cache.blocking_read();
25 let key = config.default.key;
26 let msg = lock.get(&key);
27 if let Some(msg) = msg {
28 let content = (config.fn_input)(msg).unwrap();
29 input_set.set(content)
30 }
31 }
32
33 let gs_clone = gs.clone();
34 Effect::new(move |_| {
35 let msg = match gs_clone.input.get() {
36 Some(msg) => msg,
37 None => return,
38 };
39 trace!("create_signal_from_msg: {}", msg.key);
40 let msg = (config.fn_input)(&msg);
41 if let Some(msg) = msg {
42 input_set.set(msg)
43 }
44 });
45
46 let gs_clone = gs.clone();
47 Effect::new(move |prev_value: Option<()>| {
48 let output = output.get();
49 if prev_value.is_none() {
50 return;
51 }
52 let msg = (config.fn_output)(output);
53 let msg = match msg {
54 Some(msg) => msg,
55 None => return,
56 };
57 gs_clone.output.set(Some(msg));
58 });
59
60 (input, output_set)
61}