Remove last bit of unsafe

This commit is contained in:
Jonathan Kelley committed 2024-01-16 17:52:59 -08:00
1 parent 3008870818
commit 9d0d5d74f6
2 files changed
+34 -38

No files matched your search

+15 -14
View File
@@ -1,14 +1,13 @@
use std::cell::{Cell, Ref, RefCell};
use slab::Slab;
use crate::{ use crate::{
innerlude::{LocalTask, SchedulerMsg}, innerlude::{LocalTask, SchedulerMsg},
scope_context::ScopeContext, scope_context::ScopeContext,
scopes::ScopeId, scopes::ScopeId,
Task, Task,
}; };
use std::rc::Rc; use std::{
cell::{Cell, Ref, RefCell},
rc::Rc,
};
thread_local! { thread_local! {
static RUNTIMES: RefCell<Vec<Rc<Runtime>>> = RefCell::new(vec![]); static RUNTIMES: RefCell<Vec<Rc<Runtime>>> = RefCell::new(vec![]);
@@ -27,19 +26,19 @@ pub struct Runtime {
pub(crate) rendering: Cell<bool>, pub(crate) rendering: Cell<bool>,
/// Tasks created with cx.spawn /// Tasks created with cx.spawn
pub(crate) tasks: RefCell<Slab<LocalTask>>, pub(crate) tasks: RefCell<slab::Slab<LocalTask>>,
pub(crate) sender: futures_channel::mpsc::UnboundedSender<SchedulerMsg>, pub(crate) sender: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
} }
impl Runtime { impl Runtime {
pub(crate) fn new(tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>) -> Rc<Self> { pub(crate) fn new(sender: futures_channel::mpsc::UnboundedSender<SchedulerMsg>) -> Rc<Self> {
Rc::new(Self { Rc::new(Self {
sender,
rendering: Cell::new(true),
scope_contexts: Default::default(), scope_contexts: Default::default(),
scope_stack: Default::default(), scope_stack: Default::default(),
current_task: Default::default(), current_task: Default::default(),
rendering: Cell::new(true),
sender: tx,
tasks: Default::default(), tasks: Default::default(),
}) })
} }
@@ -59,7 +58,9 @@ impl Runtime {
} }
pub(crate) fn remove_context(&self, id: ScopeId) { pub(crate) fn remove_context(&self, id: ScopeId) {
self.scope_contexts.borrow_mut()[id.0] = None; if let Some(_scope) = self.scope_contexts.borrow_mut()[id.0].take() {
// todo: some cleanup work
}
} }
/// Get the current scope id /// Get the current scope id
@@ -88,12 +89,12 @@ impl Runtime {
} }
/// Pushes a new scope onto the stack /// Pushes a new scope onto the stack
pub(crate) fn push_runtime(runtime: Rc<Runtime>) { pub(crate) fn push(runtime: Rc<Runtime>) {
RUNTIMES.with(|stack| stack.borrow_mut().push(runtime)); RUNTIMES.with(|stack| stack.borrow_mut().push(runtime));
} }
/// Pops a scope off the stack /// Pops a scope off the stack
pub(crate) fn pop_runtime() { pub(crate) fn pop() {
RUNTIMES.with(|stack| stack.borrow_mut().pop()); RUNTIMES.with(|stack| stack.borrow_mut().pop());
} }
@@ -165,13 +166,13 @@ pub struct RuntimeGuard(());
impl RuntimeGuard { impl RuntimeGuard {
/// Create a new runtime guard that sets the current Dioxus runtime. The runtime will be reset when the guard is dropped /// Create a new runtime guard that sets the current Dioxus runtime. The runtime will be reset when the guard is dropped
pub fn new(runtime: Rc<Runtime>) -> Self { pub fn new(runtime: Rc<Runtime>) -> Self {
Runtime::push_runtime(runtime); Runtime::push(runtime);
Self(()) Self(())
} }
} }
impl Drop for RuntimeGuard { impl Drop for RuntimeGuard {
fn drop(&mut self) { fn drop(&mut self) {
Runtime::pop_runtime(); Runtime::pop();
} }
} }
+19 -24
View File
@@ -565,6 +565,21 @@ impl VirtualDom {
} }
} }
/// Rebuild the virtualdom without handling any of the mutations
///
/// This is useful for testing purposes and in cases where you render the output of the virtualdom without
/// handling any of its mutations.
pub fn rebuild_in_place(&mut self) {
self.rebuild(&mut NoOpMutations);
}
/// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes
pub fn rebuild_to_vec(&mut self) -> Mutations {
let mut mutations = Mutations::default();
self.rebuild(&mut mutations);
mutations
}
/// Performs a *full* rebuild of the virtual dom, returning every edit required to generate the actual dom from scratch. /// Performs a *full* rebuild of the virtual dom, returning every edit required to generate the actual dom from scratch.
/// ///
/// The mutations item expects the RealDom's stack to be the root of the application. /// The mutations item expects the RealDom's stack to be the root of the application.
@@ -596,21 +611,6 @@ impl VirtualDom {
to.append_children(ElementId(0), m); to.append_children(ElementId(0), m);
} }
/// Rebuild the virtualdom without handling any of the mutations
///
/// This is useful for testing purposes and in cases where you render the output of the virtualdom without
/// handling any of its mutations.
pub fn rebuild_in_place(&mut self) {
self.rebuild(&mut NoOpMutations);
}
/// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes
pub fn rebuild_to_vec(&mut self) -> Mutations {
let mut mutations = Mutations::default();
self.rebuild(&mut mutations);
mutations
}
/// Render whatever the VirtualDom has ready as fast as possible without requiring an executor to progress /// Render whatever the VirtualDom has ready as fast as possible without requiring an executor to progress
/// suspended subtrees. /// suspended subtrees.
pub fn render_immediate(&mut self, to: &mut impl WriteMutations) { pub fn render_immediate(&mut self, to: &mut impl WriteMutations) {
@@ -685,17 +685,12 @@ impl VirtualDom {
} }
} }
// Poll the suspense leaves in the meantime // Wait until the deadline is ready or we have work if there's no work ready
let mut work = self.wait_for_work(); let work = self.wait_for_work();
pin_mut!(work);
// safety: this is okay since we don't touch the original future
let pinned = unsafe { std::pin::Pin::new_unchecked(&mut work) };
// If the deadline is exceded (left) then we should return the mutations we have
use futures_util::future::{select, Either}; use futures_util::future::{select, Either};
if let Either::Left((_, _)) = select(&mut deadline, pinned).await { if let Either::Left((_, _)) = select(&mut deadline, &mut work).await {
// release the borrowed
drop(work);
return; return;
} }
} }