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