floem_reactive/
context.rs

1use std::any::{Any, TypeId};
2
3use crate::runtime::RUNTIME;
4
5/// Try to retrieve a stored Context value in the reactive system.
6/// You can store a Context value anywhere, and retrieve it from anywhere afterwards.
7///
8/// # Example
9/// In a parent component:
10/// ```rust
11/// # use floem_reactive::provide_context;
12/// provide_context(42);
13/// provide_context(String::from("Hello world"));
14/// ```
15///
16/// And so in a child component you can retrieve each context data by specifying the type:
17/// ```rust
18/// # use floem_reactive::use_context;
19/// let foo: Option<i32> = use_context();
20/// let bar: Option<String> = use_context();
21/// ```
22pub fn use_context<T>() -> Option<T>
23where
24    T: Clone + 'static,
25{
26    let ty = TypeId::of::<T>();
27    RUNTIME.with(|runtime| {
28        let contexts = runtime.contexts.borrow();
29        let context = contexts
30            .get(&ty)
31            .and_then(|val| val.downcast_ref::<T>())
32            .cloned();
33        context
34    })
35}
36
37/// Sets a context value to be stored in the reactive system.
38/// The stored context value can be retrieved from anywhere by using [use_context](use_context)
39///
40/// # Example
41/// In a parent component:
42/// ```rust
43/// # use floem_reactive::provide_context;
44/// provide_context(42);
45/// provide_context(String::from("Hello world"));
46/// ```
47///
48/// And so in a child component you can retrieve each context data by specifying the type:
49/// ```rust
50/// # use floem_reactive::use_context;
51/// let foo: Option<i32> = use_context();
52/// let bar: Option<String> = use_context();
53/// ```
54pub fn provide_context<T>(value: T)
55where
56    T: Clone + 'static,
57{
58    let id = value.type_id();
59
60    RUNTIME.with(|runtime| {
61        let mut contexts = runtime.contexts.borrow_mut();
62        contexts.insert(id, Box::new(value) as Box<dyn Any>);
63    });
64}