|
@@ -11,7 +11,7 @@ use crate::{
|
|
};
|
|
};
|
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
|
use bumpslab::{BumpSlab, Slot};
|
|
use bumpslab::{BumpSlab, Slot};
|
|
-use rustc_hash::{FxHashMap, FxHashSet};
|
|
|
|
|
|
+use rustc_hash::FxHashSet;
|
|
use slab::{Slab, VacantEntry};
|
|
use slab::{Slab, VacantEntry};
|
|
use std::{
|
|
use std::{
|
|
any::{Any, TypeId},
|
|
any::{Any, TypeId},
|
|
@@ -173,7 +173,7 @@ pub struct ScopeState {
|
|
pub(crate) hooks: RefCell<Vec<Box<UnsafeCell<dyn Any>>>>,
|
|
pub(crate) hooks: RefCell<Vec<Box<UnsafeCell<dyn Any>>>>,
|
|
pub(crate) hook_idx: Cell<usize>,
|
|
pub(crate) hook_idx: Cell<usize>,
|
|
|
|
|
|
- pub(crate) shared_contexts: RefCell<FxHashMap<TypeId, Box<dyn Any>>>,
|
|
|
|
|
|
+ pub(crate) shared_contexts: RefCell<Vec<(TypeId, Box<dyn Any>)>>,
|
|
|
|
|
|
pub(crate) tasks: Rc<Scheduler>,
|
|
pub(crate) tasks: Rc<Scheduler>,
|
|
pub(crate) spawned_tasks: RefCell<FxHashSet<TaskId>>,
|
|
pub(crate) spawned_tasks: RefCell<FxHashSet<TaskId>>,
|
|
@@ -347,7 +347,9 @@ impl<'src> ScopeState {
|
|
pub fn has_context<T: 'static + Clone>(&self) -> Option<T> {
|
|
pub fn has_context<T: 'static + Clone>(&self) -> Option<T> {
|
|
self.shared_contexts
|
|
self.shared_contexts
|
|
.borrow()
|
|
.borrow()
|
|
- .get(&TypeId::of::<T>())?
|
|
|
|
|
|
+ .iter()
|
|
|
|
+ .find(|(k, _)| *k == TypeId::of::<T>())
|
|
|
|
+ .map(|(_, v)| v)?
|
|
.downcast_ref::<T>()
|
|
.downcast_ref::<T>()
|
|
.cloned()
|
|
.cloned()
|
|
}
|
|
}
|
|
@@ -364,8 +366,13 @@ impl<'src> ScopeState {
|
|
while let Some(parent_ptr) = search_parent {
|
|
while let Some(parent_ptr) = search_parent {
|
|
// safety: all parent pointers are valid thanks to the bump arena
|
|
// safety: all parent pointers are valid thanks to the bump arena
|
|
let parent = unsafe { &*parent_ptr };
|
|
let parent = unsafe { &*parent_ptr };
|
|
- if let Some(shared) = parent.shared_contexts.borrow().get(&TypeId::of::<T>()) {
|
|
|
|
- return shared.downcast_ref::<T>().cloned();
|
|
|
|
|
|
+ if let Some(shared) = parent
|
|
|
|
+ .shared_contexts
|
|
|
|
+ .borrow()
|
|
|
|
+ .iter()
|
|
|
|
+ .find(|(k, _)| *k == TypeId::of::<T>())
|
|
|
|
+ {
|
|
|
|
+ return shared.1.downcast_ref::<T>().cloned();
|
|
}
|
|
}
|
|
search_parent = parent.parent;
|
|
search_parent = parent.parent;
|
|
}
|
|
}
|
|
@@ -394,13 +401,21 @@ impl<'src> ScopeState {
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
/// ```
|
|
pub fn provide_context<T: 'static + Clone>(&self, value: T) -> T {
|
|
pub fn provide_context<T: 'static + Clone>(&self, value: T) -> T {
|
|
- let value2 = value.clone();
|
|
|
|
|
|
+ let mut contexts = self.shared_contexts.borrow_mut();
|
|
|
|
+
|
|
|
|
+ // If the context exists, swap it out for the new value
|
|
|
|
+ for ctx in contexts.iter_mut() {
|
|
|
|
+ // Swap the ptr directly
|
|
|
|
+ if let Some(ctx) = ctx.1.downcast_mut::<T>() {
|
|
|
|
+ std::mem::swap(ctx, &mut value.clone());
|
|
|
|
+ return value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- self.shared_contexts
|
|
|
|
- .borrow_mut()
|
|
|
|
- .insert(TypeId::of::<T>(), Box::new(value));
|
|
|
|
|
|
+ // Else, just push it
|
|
|
|
+ contexts.push((TypeId::of::<T>(), Box::new(value.clone())));
|
|
|
|
|
|
- value2
|
|
|
|
|
|
+ value
|
|
}
|
|
}
|
|
|
|
|
|
/// Pushes the future onto the poll queue to be polled after the component renders.
|
|
/// Pushes the future onto the poll queue to be polled after the component renders.
|