feat: diffing works on desktop!

This commit is contained in:
Jonathan Kelley committed 2022-11-17 22:31:14 -08:00
1 parent 30ef225812
commit 20f9957fbe
10 files changed
+176 -166

No files matched your search

+22 -14
View File
@@ -1,8 +1,9 @@
use super::{waker::RcWake, Scheduler, SchedulerMsg};
use crate::ScopeId;
use std::cell::RefCell;
use std::future::Future;
use std::task::Context;
use std::{cell::UnsafeCell, pin::Pin, rc::Rc, task::Poll};
use std::{pin::Pin, rc::Rc, task::Poll};
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -10,23 +11,19 @@ pub struct TaskId(pub usize);
/// the task itself is the waker
pub(crate) struct LocalTask {
pub id: TaskId,
pub scope: ScopeId,
pub tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
// todo: use rc and weak, or the bump slab instead of unsafecell
pub task: UnsafeCell<Pin<Box<dyn Future<Output = ()> + 'static>>>,
id: TaskId,
tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
task: RefCell<Pin<Box<dyn Future<Output = ()> + 'static>>>,
}
impl LocalTask {
pub fn progress(self: &Rc<Self>) -> bool {
/// Poll this task and return whether or not it is complete
pub(super) fn progress(self: &Rc<Self>) -> bool {
let waker = self.waker();
let mut cx = Context::from_waker(&waker);
// safety: the waker owns its task and everythig is single threaded
let fut = unsafe { &mut *self.task.get() };
match Pin::new(fut).poll(&mut cx) {
match self.task.borrow_mut().as_mut().poll(&mut cx) {
Poll::Ready(_) => true,
_ => false,
}
@@ -34,6 +31,15 @@ impl LocalTask {
}
impl Scheduler {
/// Start a new future on the same thread as the rest of the VirtualDom.
///
/// This future will not contribute to suspense resolving, so you should primarily use this for reacting to changes
/// and long running tasks.
///
/// Whenever the component that owns this future is dropped, the future will be dropped as well.
///
/// Spawning a future onto the root scope will cause it to be dropped when the root component is dropped - which
/// will only occur when the VirtuaalDom itself has been dropped.
pub fn spawn(&self, scope: ScopeId, task: impl Future<Output = ()> + 'static) -> TaskId {
let mut tasks = self.tasks.borrow_mut();
let entry = tasks.vacant_entry();
@@ -42,7 +48,7 @@ impl Scheduler {
entry.insert(Rc::new(LocalTask {
id: task_id,
tx: self.sender.clone(),
task: UnsafeCell::new(Box::pin(task)),
task: RefCell::new(Box::pin(task)),
scope,
}));
@@ -53,9 +59,11 @@ impl Scheduler {
task_id
}
// drops the future
/// Drop the future with the given TaskId
///
/// This does nto abort the task, so you'll want to wrap it in an aborthandle if that's important to you
pub fn remove(&self, id: TaskId) {
//
self.tasks.borrow_mut().remove(id.0);
}
}