suspense.rs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. use super::{waker::RcWake, SchedulerMsg};
  2. use crate::ElementId;
  3. use crate::{innerlude::Mutations, Element, ScopeId};
  4. use std::future::Future;
  5. use std::{
  6. cell::{Cell, RefCell},
  7. collections::HashSet,
  8. rc::Rc,
  9. };
  10. /// An ID representing an ongoing suspended component
  11. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
  12. pub(crate) struct SuspenseId(pub usize);
  13. /// A boundary in the VirtualDom that captures all suspended components below it
  14. pub struct SuspenseContext {
  15. pub(crate) id: ScopeId,
  16. pub(crate) waiting_on: RefCell<HashSet<SuspenseId>>,
  17. pub(crate) mutations: RefCell<Mutations<'static>>,
  18. pub(crate) placeholder: Cell<Option<ElementId>>,
  19. pub(crate) created_on_stack: Cell<usize>,
  20. }
  21. impl SuspenseContext {
  22. /// Create a new boundary for suspense
  23. pub fn new(id: ScopeId) -> Self {
  24. Self {
  25. id,
  26. waiting_on: Default::default(),
  27. mutations: RefCell::new(Mutations::default()),
  28. placeholder: Cell::new(None),
  29. created_on_stack: Cell::new(0),
  30. }
  31. }
  32. }
  33. pub(crate) struct SuspenseLeaf {
  34. pub(crate) id: SuspenseId,
  35. pub(crate) scope_id: ScopeId,
  36. pub(crate) tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
  37. pub(crate) notified: Cell<bool>,
  38. pub(crate) task: *mut dyn Future<Output = Element<'static>>,
  39. }
  40. impl RcWake for SuspenseLeaf {
  41. fn wake_by_ref(arc_self: &Rc<Self>) {
  42. arc_self.notified.set(true);
  43. _ = arc_self
  44. .tx
  45. .unbounded_send(SchedulerMsg::SuspenseNotified(arc_self.id));
  46. }
  47. }