maycoon_core/app/
context.rs1use crate::app::diagnostics::Diagnostics;
2use crate::app::update::{Update, UpdateManager};
3use crate::signal::Signal;
4use crate::signal::eval::EvalSignal;
5use crate::signal::fixed::FixedSignal;
6use crate::signal::listener::Listener;
7use crate::signal::memoized::MemoizedSignal;
8use crate::signal::state::StateSignal;
9
10#[derive(Clone)]
12pub struct AppContext {
13 update: UpdateManager,
14 diagnostics: Diagnostics,
15}
16
17impl AppContext {
18 #[tracing::instrument(level = "trace", skip_all)]
20 pub fn new(update: UpdateManager, diagnostics: Diagnostics) -> Self {
21 Self {
22 update,
23 diagnostics,
24 }
25 }
26
27 pub fn diagnostics(&self) -> Diagnostics {
29 self.diagnostics
30 }
31
32 pub fn update(&self) -> UpdateManager {
34 self.update.clone()
35 }
36
37 pub fn exit(&self) {
39 self.update.insert(Update::EXIT);
40 }
41
42 #[tracing::instrument(level = "trace", skip_all, fields(signal = std::any::type_name::<T>()))]
46 pub fn hook_signal<T: 'static, S: Signal<T>>(&self, signal: &mut S) {
47 let update = self.update();
48 signal.listen(Listener::new(move |_| update.insert(Update::EVAL)));
49 }
50
51 pub fn use_signal<T: 'static, S: Signal<T>>(&self, mut signal: S) -> S {
55 self.hook_signal(&mut signal);
56
57 signal
58 }
59
60 pub fn use_state<T: 'static>(&self, value: T) -> StateSignal<T> {
62 self.use_signal(StateSignal::new(value))
63 }
64
65 pub fn use_memoized<T: 'static>(&self, value: impl Fn() -> T + 'static) -> MemoizedSignal<T> {
67 self.use_signal(MemoizedSignal::new(value))
68 }
69
70 pub fn use_fixed<T: 'static>(&self, value: T) -> FixedSignal<T> {
72 self.use_signal(FixedSignal::new(value))
73 }
74
75 pub fn use_eval<T: 'static>(&self, eval: impl Fn() -> T + 'static) -> EvalSignal<T> {
77 self.use_signal(EvalSignal::new(eval))
78 }
79}