rsiot/components/cmp_leptos/create_signal_from_msg/
create.rs

1use leptos::prelude::*;
2use tracing::trace;
3
4use crate::message::MsgDataBound;
5
6use super::{super::GlobalState, Config};
7
8/// Функция создания сигнала на основе сообщений
9pub 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}