egui_reactor/context.rs
1//! `provide_context` / `use_context`: values passed down a subtree by type.
2
3use std::any::TypeId;
4
5use crate::cx::Cx;
6use crate::state::Handle;
7
8/// Make `value` visible to `use_context::<T>` inside `children`.
9///
10/// The binding lasts exactly as long as `children` runs. What is stored is the
11/// slot id, not the handle, so the store needs no lifetime parameter and no
12/// `unsafe`.
13pub fn provide_context<'s, T: 'static>(
14 cx: &mut Cx<'s, '_>,
15 value: Handle<'s, T>,
16 children: impl FnOnce(&mut Cx<'s, '_>),
17) {
18 let store = cx.store;
19 store.push_context(TypeId::of::<T>(), value.slot_id());
20 children(cx);
21 store.pop_context();
22}
23
24/// Read the innermost [`Handle`] provided for `T`, if any.
25///
26/// A [`Handle`] rather than a guard: the provider usually still holds its own
27/// state, and two guards on one slot would double-borrow.
28pub fn use_context<'s, T: 'static>(cx: &Cx<'s, '_>) -> Option<Handle<'s, T>> {
29 let store = cx.store;
30 let id = store.lookup_context(TypeId::of::<T>())?;
31 let slot = store.slot_by_id(id)?;
32 Some(Handle::new(store, slot))
33}