use super::{waker::RcWake, SchedulerMsg}; use crate::ElementId; use crate::{innerlude::Mutations, Element, ScopeId}; use std::future::Future; use std::{ cell::{Cell, RefCell}, collections::HashSet, rc::Rc, }; /// An ID representing an ongoing suspended component #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub(crate) struct SuspenseId(pub usize); /// A boundary in the VirtualDom that captures all suspended components below it pub struct SuspenseContext { pub(crate) id: ScopeId, pub(crate) waiting_on: RefCell>, pub(crate) mutations: RefCell>, pub(crate) placeholder: Cell>, pub(crate) created_on_stack: Cell, } impl SuspenseContext { /// Create a new boundary for suspense pub fn new(id: ScopeId) -> Self { Self { id, waiting_on: Default::default(), mutations: RefCell::new(Mutations::default()), placeholder: Cell::new(None), created_on_stack: Cell::new(0), } } } pub(crate) struct SuspenseLeaf { pub(crate) id: SuspenseId, pub(crate) scope_id: ScopeId, pub(crate) tx: futures_channel::mpsc::UnboundedSender, pub(crate) notified: Cell, pub(crate) task: *mut dyn Future>, } impl RcWake for SuspenseLeaf { fn wake_by_ref(arc_self: &Rc) { arc_self.notified.set(true); _ = arc_self .tx .unbounded_send(SchedulerMsg::SuspenseNotified(arc_self.id)); } }