maycoon_core/app/
context.rs

1use crate::app::update::{Update, UpdateManager};
2use crate::signal::eval::EvalSignal;
3use crate::signal::fixed::FixedSignal;
4use crate::signal::memoized::MemoizedSignal;
5use crate::signal::state::StateSignal;
6use crate::signal::Signal;
7use std::sync::Arc;
8
9/// The application context for managing the application lifecycle.
10#[derive(Clone, Debug)]
11pub struct AppContext {
12    update: UpdateManager,
13}
14
15impl AppContext {
16    /// Create a new application context using the given [UpdateManager].
17    pub fn new(update: UpdateManager) -> Self {
18        Self { update }
19    }
20
21    /// Get the [UpdateManager] of this application context.
22    pub fn update(&self) -> UpdateManager {
23        self.update.clone()
24    }
25
26    /// Hook the given [Signal] to the [UpdateManager] of this application.
27    ///
28    /// This makes the signal reactive, so it will notify the renderer when the inner value changes.
29    pub fn hook_signal<T: 'static, S: Signal<T>>(&self, signal: &mut S) {
30        let update = self.update();
31
32        signal.listen(Box::new(move |_| {
33            update.insert(Update::EVAL);
34        }));
35    }
36
37    /// Hook the given [Signal] to the [UpdateManager] of this application and return it inside an [Arc].
38    ///
39    /// See [AppContext::hook_signal] for more.
40    pub fn use_signal<T: 'static, S: Signal<T>>(&self, mut signal: S) -> Arc<S> {
41        self.hook_signal(&mut signal);
42
43        Arc::new(signal)
44    }
45
46    /// Shortcut for creating and hooking a [StateSignal] into the application lifecycle.
47    pub fn use_state<T: 'static>(&self, value: T) -> Arc<StateSignal<T>> {
48        self.use_signal(StateSignal::new(value))
49    }
50
51    /// Shortcut for creating and hooking a [MemoizedSignal] into the application lifecycle.
52    pub fn use_memoized<T: 'static>(
53        &self,
54        value: impl Fn() -> T + 'static,
55    ) -> Arc<MemoizedSignal<T>> {
56        self.use_signal(MemoizedSignal::new(value))
57    }
58
59    /// Shortcut for creating and hooking a [FixedSignal] into the application lifecycle.
60    pub fn use_fixed<T: 'static>(&self, value: T) -> Arc<FixedSignal<T>> {
61        self.use_signal(FixedSignal::new(value))
62    }
63
64    /// Shortcut for creating and hooking an [EvalSignal] into the application lifecycle.
65    pub fn use_eval<T: 'static>(&self, eval: impl Fn() -> T + 'static) -> Arc<EvalSignal<T>> {
66        self.use_signal(EvalSignal::new(eval))
67    }
68}