freya_core/lifecycle/
effect.rs1use std::{
2 cell::RefCell,
3 rc::Rc,
4};
5
6use crate::{
7 prelude::{
8 State,
9 spawn,
10 use_hook,
11 use_reactive,
12 },
13 reactive_context::ReactiveContext,
14};
15
16pub struct Effect;
17
18impl Effect {
19 pub fn create(mut callback: impl FnMut() + 'static) {
20 let (rx, rc) = ReactiveContext::new_for_task();
21 spawn(async move {
22 loop {
23 ReactiveContext::run(rc.clone(), &mut callback);
24 rx.notified().await;
25 }
26 });
27 }
28
29 pub fn create_sync_with_gen(mut callback: impl FnMut(usize) + 'static) {
31 let (rx, rc) = ReactiveContext::new_for_task();
32 ReactiveContext::run(rc.clone(), || callback(0));
33 spawn(async move {
34 let mut current_gen = 1;
35 loop {
36 rx.notified().await;
37 ReactiveContext::run(rc.clone(), || callback(current_gen));
38 current_gen += 1;
39 }
40 });
41 }
42
43 pub fn create_sync(mut callback: impl FnMut() + 'static) {
44 let (rx, rc) = ReactiveContext::new_for_task();
45 ReactiveContext::run(rc.clone(), &mut callback);
46 spawn(async move {
47 loop {
48 rx.notified().await;
49 ReactiveContext::run(rc.clone(), &mut callback);
50 }
51 });
52 }
53
54 pub fn create_after(callback: impl FnMut() + 'static) {
55 let (rx, rc) = ReactiveContext::new_for_task();
56 let callback = Rc::new(RefCell::new(callback));
57 spawn(async move {
58 loop {
59 let callback = callback.clone();
60 let rc = rc.clone();
61 spawn(async move {
62 ReactiveContext::run(rc, &mut *callback.borrow_mut());
63 });
64 rx.notified().await;
65 }
66 });
67 }
68
69 pub fn create_value<T: 'static>(mut callback: impl FnMut() -> T + 'static) -> State<T> {
70 let (rx, rc) = ReactiveContext::new_for_task();
71 let mut state = State::create(ReactiveContext::run(rc.clone(), &mut callback));
72 spawn(async move {
73 let mut current_gen = 0;
74 loop {
75 if current_gen > 0 {
76 state.set(ReactiveContext::run(rc.clone(), &mut callback));
77 }
78 rx.notified().await;
79 current_gen += 1;
80 }
81 });
82 state
83 }
84}
85
86pub fn use_side_effect(callback: impl FnMut() + 'static) {
88 use_hook(|| Effect::create(callback));
89}
90
91pub fn use_after_side_effect(callback: impl FnMut() + 'static) {
92 use_hook(|| Effect::create_after(callback));
93}
94
95pub fn use_side_effect_value<T: 'static>(callback: impl FnMut() -> T + 'static) -> State<T> {
96 use_hook(|| Effect::create_value(callback))
97}
98
99pub fn use_side_effect_with_deps<D: 'static + Clone + PartialEq>(
100 deps: &D,
101 mut callback: impl FnMut(&D) + 'static,
102) {
103 let deps = use_reactive(deps);
104 use_hook(move || {
105 Effect::create(move || {
106 let deps = deps.read();
107 callback(&deps)
108 })
109 });
110}