px_wsdom_core/interaction/
await.rs1use core::{
2 fmt::Write,
3 future::{Future, IntoFuture},
4 task::Poll,
5};
6
7use alloc::{borrow::ToOwned, string::String};
8
9use crate::{
10 js_types::JsValue,
11 link::RetrievalState,
12 protocol::{DEL, ERR, GET, REP, SET},
13 Browser,
14};
15
16pub struct Await {
17 browser: Browser,
18 ret_id: u64,
19 cell_id: u64,
20}
21
22impl Future for Await {
23 type Output = JsValue;
24
25 fn poll(
26 self: core::pin::Pin<&mut Self>,
27 cx: &mut core::task::Context<'_>,
28 ) -> core::task::Poll<Self::Output> {
29 let this = self.get_mut();
30 let mut link = this.browser.0.lock();
31 let ret_id = this.ret_id;
32 match link.retrievals.entry(ret_id) {
33 hashbrown::hash_map::Entry::Occupied(mut occ) => {
34 let state = occ.get_mut();
35
36 let new_waker = cx.waker();
37 if !state.waker.will_wake(new_waker) {
38 state.waker = new_waker.to_owned();
39 }
40
41 if state.times != 0 {
42 let val_id = link.get_new_id();
43 let cell_id = this.cell_id;
44 writeln!(
45 link.raw_commands_buf(),
46 "{{var v = {GET}({cell_id}).$);(v.r?{ERR}:{SET})({val_id}, v.e), {DEL}({cell_id})}}}};"
47 )
48 .unwrap();
49 link.wake_outgoing_lazy();
50 Poll::Ready(JsValue {
51 browser: this.browser.clone(),
52 id: val_id,
53 })
54 } else {
55 Poll::Pending
56 }
57 }
58 hashbrown::hash_map::Entry::Vacant(vac) => {
59 vac.insert(RetrievalState {
60 waker: cx.waker().to_owned(),
61 last_value: String::new(),
62 times: 0,
63 });
64 Poll::Pending
65 }
66 }
67 }
68}
69impl IntoFuture for JsValue {
70 type Output = JsValue;
71
72 type IntoFuture = Await;
73
74 fn into_future(self) -> Self::IntoFuture {
75 let mut link = self.browser.0.lock();
76 let ret_id = link.get_new_id();
77 let cell_id = link.get_new_id();
78 let id = self.id;
79 writeln!(
80 link.raw_commands_buf(),
81 "{SET}({cell_id},{{}}); try{{Promise.prototype.then.call({GET}({id}),function(e) {{{GET}({cell_id}).$ = {{e,r:0}}; {REP}({ret_id}, 0) }},function(e) {{{GET}({cell_id}).$ = {{e,r:1}}; {REP}({ret_id}, 0) }}))}}catch($){{{GET}({cell_id}).$ = {{e:e,r:1}}; {REP}({ret_id}, 0)}};"
82 )
83 .unwrap();
84 link.wake_outgoing_lazy();
85 return Await {
86 browser: self.browser.clone(),
87 ret_id,
88 cell_id,
89 };
90 }
91}