1use std::rc::Rc;
6
7use base::generic_channel::GenericCallback;
8use serde::Serialize;
9use serde::de::DeserializeOwned;
10
11use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
12use crate::dom::bindings::reflector::DomObject;
13use crate::dom::promise::Promise;
14use crate::script_runtime::CanGc;
15use crate::task_source::TaskSource;
16
17pub(crate) trait RoutedPromiseListener<R: Serialize + DeserializeOwned + Send> {
18 fn handle_response(&self, response: R, promise: &Rc<Promise>, can_gc: CanGc);
19}
20
21pub(crate) struct RoutedPromiseContext<
22 R: Serialize + DeserializeOwned + Send,
23 T: RoutedPromiseListener<R> + DomObject,
24> {
25 trusted: TrustedPromise,
26 receiver: Trusted<T>,
27 _phantom: std::marker::PhantomData<R>,
28}
29
30impl<R: Serialize + DeserializeOwned + Send, T: RoutedPromiseListener<R> + DomObject>
31 RoutedPromiseContext<R, T>
32{
33 fn response(self, response: R, can_gc: CanGc) {
34 let promise = self.trusted.root();
35 self.receiver
36 .root()
37 .handle_response(response, &promise, can_gc);
38 }
39}
40
41pub(crate) fn callback_promise<
42 R: Serialize + DeserializeOwned + Send + 'static,
43 T: RoutedPromiseListener<R> + DomObject + 'static,
44>(
45 promise: &Rc<Promise>,
46 receiver: &T,
47 task_source: TaskSource,
48) -> GenericCallback<R> {
49 let task_source = task_source.to_sendable();
50 let mut trusted: Option<TrustedPromise> = Some(TrustedPromise::new(promise.clone()));
51 let trusted_receiver = Trusted::new(receiver);
52 GenericCallback::new(move |message| {
53 let trusted = if let Some(trusted) = trusted.take() {
54 trusted
55 } else {
56 error!("RoutedPromiseListener callback called twice!");
57 return;
58 };
59
60 let context = RoutedPromiseContext {
61 trusted,
62 receiver: trusted_receiver.clone(),
63 _phantom: Default::default(),
64 };
65 task_source.queue(task!(routed_promise_task: move|| {
66 context.response(message.unwrap(), CanGc::note());
67 }));
68 })
69 .expect("Could not create callback in script.")
70}