effect.rs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. use crate::innerlude::ScopeOrder;
  2. use crate::Runtime;
  3. use std::borrow::Borrow;
  4. use std::cell::RefCell;
  5. use std::collections::VecDeque;
  6. /// Effects will always run after all changes to the DOM have been applied.
  7. ///
  8. /// Effects are the lowest priority task in the scheduler.
  9. /// They are run after all other dirty scopes and futures have been resolved. Other dirty scopes and futures may cause the component this effect is attached to to rerun, which would update the DOM.
  10. pub(crate) struct Effect {
  11. // The scope that the effect is attached to
  12. pub(crate) order: ScopeOrder,
  13. // The callbacks that will be run when effects are rerun
  14. effect: RefCell<VecDeque<Box<dyn FnOnce() + 'static>>>,
  15. }
  16. impl Effect {
  17. pub(crate) fn new(order: ScopeOrder, f: impl FnOnce() + 'static) -> Self {
  18. let mut effect = VecDeque::new();
  19. effect.push_back(Box::new(f) as Box<dyn FnOnce() + 'static>);
  20. Self {
  21. order,
  22. effect: RefCell::new(effect),
  23. }
  24. }
  25. pub(crate) fn push_back(&self, f: impl FnOnce() + 'static) {
  26. self.effect.borrow_mut().push_back(Box::new(f));
  27. }
  28. pub(crate) fn run(&self, runtime: &Runtime) {
  29. runtime.rendering.set(false);
  30. let mut effect = self.effect.borrow_mut();
  31. while let Some(f) = effect.pop_front() {
  32. f();
  33. }
  34. runtime.rendering.set(true);
  35. }
  36. }
  37. impl PartialOrd for Effect {
  38. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  39. Some(self.order.cmp(&other.order))
  40. }
  41. }
  42. impl Ord for Effect {
  43. fn cmp(&self, other: &Self) -> std::cmp::Ordering {
  44. self.order.cmp(&other.order)
  45. }
  46. }
  47. impl PartialEq for Effect {
  48. fn eq(&self, other: &Self) -> bool {
  49. self.order == other.order
  50. }
  51. }
  52. impl Eq for Effect {}
  53. impl Borrow<ScopeOrder> for Effect {
  54. fn borrow(&self) -> &ScopeOrder {
  55. &self.order
  56. }
  57. }