smudge_core/reactive.rs
1//! The reactive runtime: signals, memos, effects and owners driven by the frame.
2//!
3//! The core is a small signal engine written for Smudge. It is single-threaded
4//! and stores everything in one arena per thread. A signal write marks the
5//! effects it reaches and queues them; the effects run when the frame calls
6//! [`flush`], in the order they were woken, and writes made by an effect are
7//! picked up by the same flush. Nothing runs between flushes.
8//!
9//! Every thread owns its own runtime, so effects on two threads never share
10//! state. There is no executor to install and nothing to poll: call [`init`]
11//! if you want the runtime to exist before the first signal, but creating a
12//! signal does it too.
13//!
14//! A wake is reported to the callback set by [`set_wake_callback`], which is
15//! how the platform learns that the next frame has work to do. The callback
16//! belongs to the owner tree it was set under, so two apps on one thread each
17//! get their own redraw requests. It runs on the first wake of its tree after
18//! a flush and not again until the next flush ends. A write inside a flush
19//! that wakes a tree the flush already serves asks for nothing, and one that
20//! wakes another tree asks that tree for a redraw. While an app runs the
21//! part of its frame that flushes until no effect is left, its tree asks for
22//! nothing either, because the frame runs what the write woke. A wake is reported on the
23//! thread that writes the signal, so write signals only on the thread that
24//! runs their effects.
25//!
26//! ## Semantics
27//!
28//! - An effect runs once synchronously when it is created, and again from a
29//! flush after a source it read changed.
30//! - An effect re-tracks its sources on every run, so conditional reads work.
31//! - A memo recomputes when read after a source changed, and stops
32//! propagation when its new value compares equal. Memos are therefore
33//! glitch-free: a reader never sees a memo that disagrees with its sources.
34//! - Effects are not glitch-free across effect-to-effect writes: an effect
35//! that reads what another effect writes sees whichever value the wake
36//! order gives it. Put a memo in between when that matters.
37//! - An effect that runs more than a fixed number of times in one flush is a
38//! cycle. Debug builds panic; release builds stop running it for that
39//! flush, so the frame finishes.
40//! - An effect whose body panics stays subscribed and runs again on the next
41//! write to a source it reached.
42//! - Cleaning up an owner stops its effects and disposes its signals, children
43//! first. Dropping the last handle to an owner cleans it up too, so mount
44//! and unmount cycles return all of their memory.
45//!
46//! The reactive API is defined here, so a widget imports it from one place.
47//! Types are at the module root and the traits that give them their methods
48//! are in [`prelude`].
49//!
50//! ```
51//! use smudge_core::reactive::{self, Owner, RenderEffect, prelude::*};
52//! use std::cell::Cell;
53//! use std::rc::Rc;
54//!
55//! reactive::init();
56//! let owner = Owner::new();
57//! owner.set();
58//!
59//! let (count, set_count) = reactive::signal_local(0u32);
60//! let seen = Rc::new(Cell::new(0u32));
61//! let recorder = Rc::clone(&seen);
62//! let _effect = RenderEffect::new(move || recorder.set(count.get()));
63//!
64//! set_count.set(1);
65//! assert_eq!(seen.get(), 0, "the write waits for the frame");
66//!
67//! reactive::flush();
68//! assert_eq!(seen.get(), 1);
69//! ```
70
71use std::any::TypeId;
72use std::cell::{Cell, RefCell};
73use std::rc::{Rc, Weak};
74
75pub(crate) mod runtime;
76
77use runtime::{CurrentOwnerGuard, EffectCell, MemoData, NodeId, OwnerData, OwnerState, SignalData};
78
79/// Installs the runtime on the calling thread.
80///
81/// Creating a signal, memo, effect or owner does this implicitly, so calling
82/// `init` is never required. It exists so a thread can state that it runs the
83/// reactive runtime, and so older call sites keep working. Calling it again
84/// does nothing.
85///
86/// # Examples
87///
88/// ```
89/// use smudge_core::reactive;
90///
91/// reactive::init();
92/// assert!(!reactive::flush(), "nothing was woken");
93/// ```
94pub fn init() {
95 runtime::with_runtime(|_| {});
96}
97
98/// Runs every effect woken since the last call, in the order they were woken,
99/// and returns whether any effect ran.
100///
101/// Call this once per frame, before reading the updates that effects
102/// produced. A write made while the flush runs has its effect run in the same
103/// call, so the return value covers everything that write set off.
104///
105/// Does nothing and returns `false` when called from inside a running flush,
106/// because that flush already drains the queue.
107///
108/// # Examples
109///
110/// ```
111/// use smudge_core::reactive::{self, Owner, RenderEffect, prelude::*};
112///
113/// let owner = Owner::new();
114/// owner.set();
115/// let (count, set_count) = reactive::signal_local(0u32);
116/// let _effect = RenderEffect::new(move || count.get());
117///
118/// assert!(!reactive::flush(), "the creation run is not a flush");
119/// set_count.set(1);
120/// assert!(reactive::flush(), "the write woke the effect");
121/// assert!(!reactive::flush(), "nothing was woken since");
122/// ```
123pub fn flush() -> bool {
124 runtime::flush()
125}
126
127/// Sets the callback that a wake between flushes runs to request a redraw.
128///
129/// The callback is stored on the root scope of the current owner tree, which
130/// is the app whose owner is current. When no owner is current it is stored on
131/// the thread's default scope. Replaces any previous callback of that scope.
132///
133/// The callback runs on the first wake of its tree after a flush and not
134/// again until the next flush ends, so a frame that writes many signals
135/// requests one redraw. A wake that arrives during a flush asks for nothing
136/// when the tree already has an effect in that flush, because the flush
137/// applies the write itself.
138///
139/// A wake is reported on the thread that writes the signal, so write signals
140/// only on the thread that runs their effects.
141///
142/// # Examples
143///
144/// ```
145/// use smudge_core::reactive::{self, Owner, RenderEffect, prelude::*};
146/// use std::cell::Cell;
147/// use std::rc::Rc;
148///
149/// let owner = Owner::new();
150/// owner.set();
151/// let redraws = Rc::new(Cell::new(0u32));
152/// let counter = Rc::clone(&redraws);
153/// reactive::set_wake_callback(move || counter.set(counter.get() + 1));
154///
155/// let (count, set_count) = reactive::signal_local(0u32);
156/// let _effect = RenderEffect::new(move || count.get());
157/// reactive::flush();
158///
159/// set_count.set(1);
160/// assert_eq!(redraws.get(), 1);
161/// ```
162pub fn set_wake_callback(callback: impl Fn() + 'static) {
163 // The previous callback drops after the runtime is released, so its drop
164 // may enter the runtime.
165 let scope = runtime::with_runtime(|runtime| runtime.current_scope());
166 scope.wake.replace(Some(Rc::new(callback)));
167}
168
169/// The traits and constructors that signals, memos and owners need.
170///
171/// Import this module with a glob to call `.get()`, `.set()` and `.update()`
172/// on reactive values, to read them with or without tracking, and to create
173/// signals and provide context.
174pub mod prelude {
175 pub use super::{Get, Read, Set, Update, With, provide_context, signal_local, use_context};
176}
177
178/// Applies a closure to a reactive value, tracking it as a source.
179pub trait With<T: ?Sized + 'static> {
180 /// Applies `fun` to the current value and returns its result.
181 ///
182 /// When an effect or a memo is running, the value becomes one of its
183 /// sources and a later change wakes it.
184 fn with<U>(&self, fun: impl FnOnce(&T) -> U) -> U;
185}
186
187/// Applies a closure to a reactive value without tracking it.
188pub trait Read<T: ?Sized + 'static> {
189 /// Applies `fun` to the current value and returns its result.
190 ///
191 /// No source is recorded, so a later change wakes nothing through this
192 /// read.
193 fn read<U>(&self, fun: impl FnOnce(&T) -> U) -> U;
194}
195
196/// Clones the value of a reactive value, tracking it as a source.
197pub trait Get<T: Clone + 'static>: With<T> {
198 /// Returns a clone of the current value.
199 fn get(&self) -> T {
200 self.with(T::clone)
201 }
202}
203
204impl<S, T> Get<T> for S
205where
206 S: With<T> + ?Sized,
207 T: Clone + 'static,
208{
209}
210
211/// Updates the value of a reactive value in place and notifies subscribers.
212pub trait Update<T: 'static> {
213 /// Applies `fun` to the value and notifies subscribers that it changed,
214 /// whether or not `fun` changed anything.
215 ///
216 /// # Panics
217 ///
218 /// Panics when the value is already mutably borrowed, which happens when
219 /// `fun` reads the same value.
220 fn update<U>(&self, fun: impl FnOnce(&mut T) -> U) -> U;
221}
222
223/// Replaces the value of a reactive value and notifies subscribers.
224pub trait Set<T: 'static>: Update<T> {
225 /// Replaces the value and notifies subscribers, whether or not the new
226 /// value compares equal to the old one.
227 fn set(&self, value: T) {
228 self.update(|slot| *slot = value);
229 }
230}
231
232impl<S, T> Set<T> for S
233where
234 S: Update<T> + ?Sized,
235 T: 'static,
236{
237}
238
239/// A signal that can be read and written.
240///
241/// Created with [`RwSignal::new`], or split into a [`ReadSignal`] and a
242/// [`WriteSignal`] by [`signal_local`]. Cloning the handle is cheap, and
243/// every clone names the same signal.
244pub struct RwSignal<T> {
245 /// The value and the node that carries the subscribers.
246 data: Rc<SignalData<T>>,
247}
248
249impl<T: 'static> RwSignal<T> {
250 /// Creates a signal holding `value`, under the current owner.
251 ///
252 /// The signal is disposed when that owner is cleaned up. Handles that
253 /// outlive it keep the value readable but notify nothing. With no current
254 /// owner nothing disposes it, and its entry in the runtime stays until the
255 /// thread ends.
256 pub fn new(value: T) -> RwSignal<T> {
257 let node = runtime::with_runtime(runtime::Runtime::new_signal);
258 RwSignal {
259 data: Rc::new(SignalData {
260 value: RefCell::new(value),
261 node: Cell::new(node),
262 }),
263 }
264 }
265}
266
267impl<T: 'static> Clone for RwSignal<T> {
268 fn clone(&self) -> RwSignal<T> {
269 RwSignal {
270 data: Rc::clone(&self.data),
271 }
272 }
273}
274
275impl<T: 'static> Clone for ReadSignal<T> {
276 fn clone(&self) -> ReadSignal<T> {
277 ReadSignal {
278 data: Rc::clone(&self.data),
279 }
280 }
281}
282
283impl<T: 'static> Clone for WriteSignal<T> {
284 fn clone(&self) -> WriteSignal<T> {
285 WriteSignal {
286 data: Rc::clone(&self.data),
287 }
288 }
289}
290
291impl<T: 'static> Clone for Memo<T> {
292 fn clone(&self) -> Memo<T> {
293 Memo {
294 data: Rc::clone(&self.data),
295 }
296 }
297}
298
299impl<T: 'static> With<T> for RwSignal<T> {
300 fn with<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
301 runtime::track_read(self.data.node.get());
302 fun(&self.data.value.borrow())
303 }
304}
305
306impl<T: 'static> Read<T> for RwSignal<T> {
307 fn read<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
308 fun(&self.data.value.borrow())
309 }
310}
311
312impl<T: 'static> Update<T> for RwSignal<T> {
313 fn update<U>(&self, fun: impl FnOnce(&mut T) -> U) -> U {
314 let result = fun(&mut self.data.value.borrow_mut());
315 let wake = runtime::with_runtime(|runtime| runtime.notify(self.data.node.get()));
316 runtime::fire_wakes(wake);
317 result
318 }
319}
320
321/// The read half of a signal. Cloning the handle is cheap, and every clone
322/// names the same value.
323pub struct ReadSignal<T> {
324 /// The value and the node that carries the subscribers.
325 data: Rc<SignalData<T>>,
326}
327
328impl<T: 'static> With<T> for ReadSignal<T> {
329 fn with<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
330 runtime::track_read(self.data.node.get());
331 fun(&self.data.value.borrow())
332 }
333}
334
335impl<T: 'static> Read<T> for ReadSignal<T> {
336 fn read<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
337 fun(&self.data.value.borrow())
338 }
339}
340
341/// The write half of a signal. Cloning the handle is cheap, and every clone
342/// writes the same value.
343pub struct WriteSignal<T> {
344 /// The value and the node that carries the subscribers.
345 data: Rc<SignalData<T>>,
346}
347
348impl<T: 'static> Update<T> for WriteSignal<T> {
349 fn update<U>(&self, fun: impl FnOnce(&mut T) -> U) -> U {
350 let result = fun(&mut self.data.value.borrow_mut());
351 let wake = runtime::with_runtime(|runtime| runtime.notify(self.data.node.get()));
352 runtime::fire_wakes(wake);
353 result
354 }
355}
356
357/// Creates a signal and returns its read and write halves.
358///
359/// The signal is disposed when the current owner is cleaned up. Handles that
360/// outlive it keep the value readable but notify nothing. With no current
361/// owner nothing disposes it, and its entry in the runtime stays until the
362/// thread ends.
363///
364/// ```
365/// use smudge_core::reactive::{self, Owner, RenderEffect, prelude::*};
366/// use std::cell::Cell;
367/// use std::rc::Rc;
368///
369/// let owner = Owner::new();
370/// owner.set();
371/// let (count, set_count) = signal_local(3u32);
372/// let seen = Rc::new(Cell::new(0u32));
373/// let recorder = Rc::clone(&seen);
374/// let _effect = RenderEffect::new(move || recorder.set(count.get()));
375/// reactive::flush();
376///
377/// set_count.update(|value| *value += 1);
378/// reactive::flush();
379/// assert_eq!(seen.get(), 4);
380/// ```
381pub fn signal_local<T: 'static>(value: T) -> (ReadSignal<T>, WriteSignal<T>) {
382 let node = runtime::with_runtime(runtime::Runtime::new_signal);
383 let data = Rc::new(SignalData {
384 value: RefCell::new(value),
385 node: Cell::new(node),
386 });
387 (
388 ReadSignal {
389 data: Rc::clone(&data),
390 },
391 WriteSignal { data },
392 )
393}
394
395/// A value computed from signals, recomputed when a read needs it.
396///
397/// A memo recomputes when it is read after one of its sources changed, and it
398/// stops propagation when the new value compares equal to the old one, so
399/// effects that read it do not rerun. Because a memo is always brought up to
400/// date on read, a reader never sees a memo that disagrees with its sources.
401///
402/// The memo is disposed when the current owner is cleaned up. Handles that
403/// outlive it keep the last value readable. With no current owner nothing
404/// disposes it, so its computation stays in the runtime until the thread
405/// ends. Cloning the handle is cheap, and every clone names the same memo.
406pub struct Memo<T> {
407 /// The value and the node that carries the subscribers.
408 data: Rc<MemoData<T>>,
409}
410
411impl<T: 'static> Memo<T> {
412 /// Creates a memo that computes its value with `compute`.
413 ///
414 /// The first computation runs at once, tracking the signals it reads into
415 /// the effect or memo that is running, if any.
416 ///
417 /// The value type needs [`PartialEq`] so the memo can recognize an
418 /// unchanged value and stop propagation.
419 pub fn new(compute: impl Fn() -> T + 'static) -> Memo<T>
420 where
421 T: PartialEq,
422 {
423 let data = Rc::new(MemoData {
424 value: RefCell::new(None),
425 node: Cell::new(NodeId::default()),
426 });
427 let stored = Rc::clone(&data);
428 let run: Rc<dyn Fn()> = Rc::new(move || {
429 let value = compute();
430 let changed = stored
431 .value
432 .borrow()
433 .as_ref()
434 .is_none_or(|old| *old != value);
435 if changed {
436 *stored.value.borrow_mut() = Some(value);
437 let wake = runtime::with_runtime(|runtime| runtime.notify(stored.node.get()));
438 runtime::fire_wakes(wake);
439 }
440 });
441 let node = runtime::with_runtime(|runtime| runtime.new_memo(run));
442 data.node.set(node);
443 runtime::compute_new_memo(node);
444 Memo { data }
445 }
446}
447
448impl<T: 'static> With<T> for Memo<T> {
449 fn with<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
450 runtime::update_memo(self.data.node.get());
451 runtime::track_read(self.data.node.get());
452 let value = self.data.value.borrow();
453 fun(value.as_ref().expect(
454 "a memo holds a value once its first computation finished, so a \
455 read sees one unless the memo reads itself",
456 ))
457 }
458}
459
460impl<T: 'static> Read<T> for Memo<T> {
461 fn read<U>(&self, fun: impl FnOnce(&T) -> U) -> U {
462 runtime::update_memo(self.data.node.get());
463 let value = self.data.value.borrow();
464 fun(value.as_ref().expect(
465 "a memo holds a value once its first computation finished, so a \
466 read sees one unless the memo reads itself",
467 ))
468 }
469}
470
471/// A function that reruns when a signal or memo it read changes.
472///
473/// The first run happens when the effect is created, with tracking, so the
474/// sources it reaches are the ones that wake it later. Every run re-tracks
475/// from scratch, which makes conditional reads work.
476///
477/// The effect is owned by the current owner: cleaning that owner up, or
478/// dropping its last handle, stops the effect and frees its closure. Created
479/// with no current owner, the effect lives until the returned handle drops.
480/// Dropping the handle of an owned effect does nothing.
481///
482/// A write inside an effect body queues the effect again, and a body that
483/// keeps waking itself is stopped at a fixed number of runs per flush:
484/// debug builds panic, release builds skip the effect for the rest of that
485/// flush.
486pub struct RenderEffect {
487 /// The node that carries the sources, the queue state and the body.
488 node: NodeId,
489 /// Whether an owner took responsibility for disposing the node.
490 owned: bool,
491}
492
493impl RenderEffect {
494 /// Creates an effect and runs its body once, with tracking.
495 ///
496 /// The effect is owned by the current owner, when there is one. See the
497 /// type's documentation for the lifetime rules. The body's return value
498 /// is ignored.
499 pub fn new<T>(mut run: impl FnMut() -> T + 'static) -> RenderEffect {
500 let owned = runtime::with_runtime(|runtime| runtime.current_owner().is_some());
501 let scope = runtime::with_runtime(|runtime| runtime.current_scope());
502 let cell = Rc::new(EffectCell {
503 run: RefCell::new(Some(Box::new(move || {
504 run();
505 }))),
506 });
507 let node = runtime::with_runtime(|runtime| runtime.new_effect(Rc::clone(&cell), scope));
508 let mut guard = runtime::DisposeOnUnwind {
509 node,
510 armed: !owned,
511 };
512 runtime::run_body(&cell, node);
513 guard.armed = false;
514 RenderEffect { node, owned }
515 }
516}
517
518impl Drop for RenderEffect {
519 fn drop(&mut self) {
520 if !self.owned {
521 runtime::dispose(self.node);
522 }
523 }
524}
525
526/// The owner of the reactive values and effects created while it is current.
527///
528/// Owners form a tree. [`Owner::new`] attaches to the current owner when there
529/// is one, [`Owner::child`] attaches to an owner directly, and [`Owner::set`]
530/// and [`Owner::with`] make one current, which is where new values and effects
531/// are registered. [`Owner::cleanup`] stops the owner's effects and disposes
532/// its values, children first; dropping the last handle to an owner does the
533/// same, so nothing has to be cleaned up by hand.
534///
535/// Context values are provided on an owner with [`provide_context`] and read
536/// by the owner and its descendants with [`use_context`].
537#[derive(Clone)]
538pub struct Owner {
539 /// The parent, scope and contents of the owner.
540 inner: Rc<OwnerData>,
541}
542
543impl Default for Owner {
544 fn default() -> Owner {
545 Owner::new()
546 }
547}
548
549impl Owner {
550 /// Creates an owner under the current owner, when there is one.
551 ///
552 /// With no current owner the new owner starts a new root scope, which
553 /// carries its own wake callback.
554 pub fn new() -> Owner {
555 let parent = runtime::with_runtime(|runtime| runtime.current_owner());
556 let scope = runtime::with_runtime(|runtime| runtime.owner_scope(parent.as_deref()));
557 let inner = Rc::new(OwnerData {
558 parent: parent.as_ref().map(Rc::downgrade),
559 scope,
560 cleaned: Cell::new(false),
561 state: RefCell::new(OwnerState::default()),
562 timer_book: RefCell::new(None),
563 clipboard: RefCell::new(None),
564 channel_book: RefCell::new(None),
565 window_book: RefCell::new(None),
566 });
567 if let Some(parent) = parent {
568 parent.adopt(&inner);
569 }
570 Owner { inner }
571 }
572
573 /// Creates an owner under this one.
574 ///
575 /// The child inherits this owner's root scope, so its effects wake the
576 /// same redraw requests.
577 pub fn child(&self) -> Owner {
578 self.inner.child()
579 }
580
581 /// Makes this owner current until another one is set or a `with` block
582 /// restores the previous one.
583 pub fn set(&self) {
584 runtime::with_runtime(|runtime| runtime.set_current(&self.inner));
585 }
586
587 /// Runs `fun` with this owner current, restoring the previous one after.
588 pub fn with<T>(&self, fun: impl FnOnce() -> T) -> T {
589 let _guard = CurrentOwnerGuard::enter(&self.inner);
590 fun()
591 }
592
593 /// Stops the owner's effects and disposes the values created under it,
594 /// children first, then runs the cleanup functions that
595 /// [`Owner::on_cleanup`] registered.
596 ///
597 /// Running it twice does nothing. Dropping the last handle to the owner
598 /// runs it too.
599 pub fn cleanup(&self) {
600 self.inner.cleanup();
601 }
602
603 /// Sets the callback that a wake in this owner's tree runs to request a
604 /// redraw.
605 ///
606 /// Every effect created under this owner reports its wake here, so two
607 /// owners on one thread each get their own redraw requests. See
608 /// [`set_wake_callback`] for when the callback runs.
609 pub fn set_wake_callback(&self, callback: impl Fn() + 'static) {
610 self.inner.scope.wake.replace(Some(Rc::new(callback)));
611 }
612
613 /// Registers `fun` to run when the current owner is cleaned up.
614 ///
615 /// With no current owner, `fun` is dropped.
616 pub fn on_cleanup(fun: impl FnOnce() + 'static) {
617 let Some(owner) = Owner::current() else {
618 return;
619 };
620 owner.state.borrow_mut().cleanups.push(Box::new(fun));
621 }
622
623 /// Returns the current owner, when one is set and still alive.
624 fn current() -> Option<Rc<OwnerData>> {
625 runtime::with_runtime(|runtime| runtime.current_owner())
626 }
627
628 /// Runs the wake callback of this owner's tree, when one is set.
629 ///
630 /// The callback runs outside the runtime, so it may write signals.
631 pub(crate) fn wake(&self) {
632 let callback = self.inner.scope.wake.borrow().clone();
633 if let Some(callback) = callback {
634 callback();
635 }
636 }
637
638 /// Returns the owner's data, for the crate's own wiring such as the
639 /// timer book an app installs on its root owner.
640 pub(crate) fn data(&self) -> &Rc<OwnerData> {
641 &self.inner
642 }
643}
644
645impl Drop for Owner {
646 fn drop(&mut self) {
647 if Rc::strong_count(&self.inner) == 1 {
648 self.inner.cleanup();
649 }
650 }
651}
652
653/// Stores `value` on the current owner for [`use_context`] to read.
654///
655/// The value is visible to the owner it was provided on and to everything
656/// created under it, and invisible to its siblings and ancestors. A second
657/// value of the same type replaces the first.
658///
659/// With no current owner, `value` is dropped.
660pub fn provide_context<T: 'static>(value: T) {
661 let Some(owner) = Owner::current() else {
662 return;
663 };
664 let key = TypeId::of::<T>();
665 let value: Rc<dyn std::any::Any> = Rc::new(value);
666 let mut state = owner.state.borrow_mut();
667 match state
668 .contexts
669 .iter_mut()
670 .find(|(existing, _)| *existing == key)
671 {
672 Some((_, slot)) => *slot = value,
673 None => state.contexts.push((key, value)),
674 }
675}
676
677/// Returns a clone of the context value of type `T`, provided on the current
678/// owner or the closest ancestor that provided one.
679///
680/// Returns `None` when neither has one.
681pub fn use_context<T: Clone + 'static>() -> Option<T> {
682 let key = TypeId::of::<T>();
683 let mut current = Owner::current();
684 while let Some(owner) = current {
685 let found = owner
686 .state
687 .borrow()
688 .contexts
689 .iter()
690 .find(|(existing, _)| *existing == key)
691 .map(|(_, value)| Rc::clone(value));
692 if let Some(value) = found
693 && let Ok(value) = value.downcast::<T>()
694 {
695 return Some(T::clone(&value));
696 }
697 current = owner.parent.as_ref().and_then(Weak::upgrade);
698 }
699 None
700}