rate_ui/widget/
live.rs

1use super::{DropHook, Msg, OnWireEvent, Widget, WidgetContext};
2use crate::agents::live::registry::REGISTRY;
3use crate::agents::live::wire::{WireEnvelope, WireTask};
4use crate::agents::live::{LiveAgent, LiveRequest, LiveResponse};
5use crate::widget::wired_bridge::{AgentHook, TagRegistry};
6use rill_protocol::io::client::ClientReqId;
7use yew::Bridge;
8
9pub struct Live<'a, T: Widget> {
10    link: &'a mut dyn Bridge<LiveAgent>,
11    registry: &'a mut TagRegistry<T::Tag, ClientReqId>,
12}
13
14impl<'a, T: Widget> Live<'a, T> {
15    pub fn wire(&mut self, tag: T::Tag, task: impl WireTask) {
16        let action = Box::new(task);
17        let req_id = REGISTRY.acquire();
18        self.registry.insert(tag, req_id);
19        let request = LiveRequest::Wire(action);
20        let envelope = WireEnvelope::new(req_id, request);
21        self.link.send(envelope);
22    }
23
24    pub fn unwire(&mut self, tag: &T::Tag) {
25        if let Some(req_id) = self.registry.get(tag) {
26            let request = LiveRequest::TerminateWire;
27            let envelope = WireEnvelope::new(*req_id, request);
28            self.link.send(envelope);
29        } else {
30        }
31    }
32}
33
34impl<T: Widget> WidgetContext<T> {
35    pub fn live<H>(&mut self) -> Live<'_, T>
36    where
37        H: AgentHook<Agent = LiveAgent>,
38        T: OnWireEvent<H>,
39    {
40        if !self.live.is_linked() {
41            // TODO: Add DropHook
42            let hook: DropHook<T> = Box::new(|_widget, this| {
43                let (link, registry) = this.live.get_mut_linked(&this.link);
44                if !registry.is_empty() {
45                    let all_tags = registry.all_tags();
46                    let mut live: Live<'_, T> = Live { link, registry };
47                    for tag in all_tags {
48                        live.unwire(tag.as_ref());
49                    }
50                }
51            });
52            self.drop_hooks.push(hook);
53        }
54        let (link, registry) = self.live.get_mut_linked(&self.link);
55        Live { link, registry }
56    }
57}
58
59impl<T: Widget> From<WireEnvelope<ClientReqId, LiveResponse>> for Msg<T> {
60    fn from(response: WireEnvelope<ClientReqId, LiveResponse>) -> Self {
61        Self::LiveIncomingWired(response)
62    }
63}