dioxus_core/
generational_box.rs1use generational_box::{AnyStorage, Owner, SyncStorage, UnsyncStorage};
6use std::{
7 any::{Any, TypeId},
8 cell::RefCell,
9};
10
11pub fn with_owner<S: AnyStorage, F: FnOnce() -> R, R>(owner: Owner<S>, f: F) -> R {
15 let old_owner = set_owner(Some(owner));
16 let result = f();
17 set_owner(old_owner);
18 result
19}
20
21fn set_owner<S: AnyStorage>(owner: Option<Owner<S>>) -> Option<Owner<S>> {
23 let id = TypeId::of::<S>();
24 if id == TypeId::of::<SyncStorage>() {
25 SYNC_OWNER.with(|cell| {
26 std::mem::replace(
27 &mut *cell.borrow_mut(),
28 owner.map(|owner| {
29 *(Box::new(owner) as Box<dyn Any>)
30 .downcast::<Owner<SyncStorage>>()
31 .unwrap()
32 }),
33 )
34 .map(|owner| *(Box::new(owner) as Box<dyn Any>).downcast().unwrap())
35 })
36 } else {
37 UNSYNC_OWNER.with(|cell| {
38 std::mem::replace(
39 &mut *cell.borrow_mut(),
40 owner.map(|owner| {
41 *(Box::new(owner) as Box<dyn Any>)
42 .downcast::<Owner<UnsyncStorage>>()
43 .unwrap()
44 }),
45 )
46 .map(|owner| *(Box::new(owner) as Box<dyn Any>).downcast().unwrap())
47 })
48 }
49}
50
51thread_local! {
52 static SYNC_OWNER: RefCell<Option<Owner<SyncStorage>>> = const { RefCell::new(None) };
53 static UNSYNC_OWNER: RefCell<Option<Owner<UnsyncStorage>>> = const { RefCell::new(None) };
54}
55
56pub fn current_owner<S: AnyStorage>() -> Owner<S> {
60 let id = TypeId::of::<S>();
61 let override_owner = if id == TypeId::of::<SyncStorage>() {
62 SYNC_OWNER.with(|cell| {
63 let owner = cell.borrow();
64
65 owner.clone().map(|owner| {
66 *(Box::new(owner) as Box<dyn Any>)
67 .downcast::<Owner<S>>()
68 .unwrap()
69 })
70 })
71 } else {
72 UNSYNC_OWNER.with(|cell| {
73 cell.borrow().clone().map(|owner| {
74 *(Box::new(owner) as Box<dyn Any>)
75 .downcast::<Owner<S>>()
76 .unwrap()
77 })
78 })
79 };
80 if let Some(owner) = override_owner {
81 return owner;
82 }
83
84 crate::Runtime::current().current_owner()
85}