1
0

lib.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. use std::{
  2. cell::{Ref, RefMut},
  3. fmt::Display,
  4. marker::PhantomData,
  5. ops::{Add, Div, Mul, Sub},
  6. };
  7. mod rt;
  8. use dioxus_core::ScopeState;
  9. pub use rt::*;
  10. pub fn use_init_signal_rt(cx: &ScopeState) {
  11. cx.use_hook(|| {
  12. let rt = crate::rt::claim_rt(cx.schedule_update_any());
  13. cx.provide_context(rt);
  14. });
  15. }
  16. pub fn use_signal<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal<T> {
  17. cx.use_hook(|| {
  18. let rt: &'static SignalRt = cx.consume_context().unwrap();
  19. let id = rt.init(f());
  20. rt.subscribe(id, cx.scope_id());
  21. struct SignalHook<T> {
  22. signal: Signal<T>,
  23. }
  24. impl<T> Drop for SignalHook<T> {
  25. fn drop(&mut self) {
  26. self.signal.rt.remove(self.signal.id);
  27. }
  28. }
  29. SignalHook {
  30. signal: Signal {
  31. id,
  32. rt,
  33. t: PhantomData,
  34. },
  35. }
  36. })
  37. .signal
  38. }
  39. pub struct Signal<T> {
  40. id: usize,
  41. rt: &'static SignalRt,
  42. t: PhantomData<T>,
  43. }
  44. impl<T: 'static> Signal<T> {
  45. pub fn read(&self) -> Ref<T> {
  46. self.rt.read(self.id)
  47. }
  48. pub fn write(&self) -> RefMut<T> {
  49. self.rt.write(self.id)
  50. }
  51. pub fn set(&mut self, value: T) {
  52. self.rt.set(self.id, value);
  53. }
  54. pub fn update<O>(&self, _f: impl FnOnce(&mut T) -> O) -> O {
  55. let mut write = self.write();
  56. _f(&mut *write)
  57. }
  58. }
  59. impl<T: Clone + 'static> Signal<T> {
  60. pub fn get(&self) -> T {
  61. self.rt.get(self.id)
  62. }
  63. }
  64. // impl<T> std::ops::Deref for Signal<T> {
  65. // type Target = dyn Fn() -> T;
  66. // fn deref(&self) -> &Self::Target {
  67. // todo!()
  68. // }
  69. // }
  70. impl<T> std::clone::Clone for Signal<T> {
  71. fn clone(&self) -> Self {
  72. Self {
  73. t: PhantomData,
  74. id: self.id,
  75. rt: self.rt,
  76. }
  77. }
  78. }
  79. impl<T> Copy for Signal<T> {}
  80. impl<T: Display + 'static> Display for Signal<T> {
  81. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  82. self.rt.with::<T, _>(self.id, |v| T::fmt(v, f))
  83. }
  84. }
  85. impl<T: Add<Output = T> + Copy + 'static> std::ops::AddAssign<T> for Signal<T> {
  86. fn add_assign(&mut self, rhs: T) {
  87. self.set(self.get() + rhs);
  88. }
  89. }
  90. impl<T: Sub<Output = T> + Copy + 'static> std::ops::SubAssign<T> for Signal<T> {
  91. fn sub_assign(&mut self, rhs: T) {
  92. self.set(self.get() - rhs);
  93. }
  94. }
  95. impl<T: Mul<Output = T> + Copy + 'static> std::ops::MulAssign<T> for Signal<T> {
  96. fn mul_assign(&mut self, rhs: T) {
  97. self.set(self.get() * rhs);
  98. }
  99. }
  100. impl<T: Div<Output = T> + Copy + 'static> std::ops::DivAssign<T> for Signal<T> {
  101. fn div_assign(&mut self, rhs: T) {
  102. self.set(self.get() / rhs);
  103. }
  104. }
  105. // impl<T: Add<Output = T> + Copy> std::ops::AddAssign<T> for Signal<T> {
  106. // fn add_assign(&mut self, rhs: T) {
  107. // self.set((*self.current()) + rhs);
  108. // }
  109. // }
  110. // impl<T: Sub<Output = T> + Copy> std::ops::SubAssign<T> for Signal<T> {
  111. // fn sub_assign(&mut self, rhs: T) {
  112. // self.set((*self.current()) - rhs);
  113. // }
  114. // }
  115. // impl<T: Mul<Output = T> + Copy> std::ops::MulAssign<T> for Signal<T> {
  116. // fn mul_assign(&mut self, rhs: T) {
  117. // self.set((*self.current()) * rhs);
  118. // }
  119. // }
  120. // impl<T: Div<Output = T> + Copy> std::ops::DivAssign<T> for Signal<T> {
  121. // fn div_assign(&mut self, rhs: T) {
  122. // self.set((*self.current()) / rhs);
  123. // }
  124. // }