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 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}