fix: really big bug around hooks

This commit is contained in:
Jonathan Kelley committed 2021-11-29 11:10:40 -05:00
1 parent 36d89beb34
commit 52c7154897
22 files changed
+413 -342

No files matched your search

+3
View File
@@ -6,3 +6,6 @@ pub use useref::*;
mod use_shared_state;
pub use use_shared_state::*;
mod usecoroutine;
pub use usecoroutine::*;
+76
View File
@@ -0,0 +1,76 @@
use dioxus_core::Context;
use futures::Future;
use std::{
borrow::Borrow,
cell::{Cell, RefCell},
pin::Pin,
rc::Rc,
};
pub fn use_coroutine<'a, F: Future<Output = ()> + 'a>(
cx: Context<'a>,
f: impl FnOnce() -> F + 'a,
) -> CoroutineHandle {
//
cx.use_hook(
move |_| State {
running: Default::default(),
fut: Default::default(),
submit: Default::default(),
},
|state| {
let fut_slot = state.fut.clone();
let running = state.running.clone();
let submit: Box<dyn FnOnce() + 'a> = Box::new(move || {
let g = async move {
running.set(true);
f().await;
running.set(false);
};
let p: Pin<Box<dyn Future<Output = ()>>> = Box::pin(g);
fut_slot
.borrow_mut()
.replace(unsafe { std::mem::transmute(p) });
});
let submit = unsafe { std::mem::transmute(submit) };
state.submit.get_mut().replace(submit);
if state.running.get() {
let mut fut = state.fut.borrow_mut();
cx.push_task(|| fut.as_mut().unwrap().as_mut());
} else {
// make sure to drop the old future
if let Some(fut) = state.fut.borrow_mut().take() {
//
}
}
CoroutineHandle { cx, inner: state }
},
)
}
struct State {
running: Rc<Cell<bool>>,
submit: RefCell<Option<Box<dyn FnOnce()>>>,
fut: Rc<RefCell<Option<Pin<Box<dyn Future<Output = ()>>>>>>,
}
pub struct CoroutineHandle<'a> {
cx: Context<'a>,
inner: &'a State,
}
impl<'a> CoroutineHandle<'a> {
pub fn start(&self) {
if self.inner.running.get() {
return;
}
if let Some(submit) = self.inner.submit.borrow_mut().take() {
submit();
let mut fut = self.inner.fut.borrow_mut();
self.cx.push_task(|| fut.as_mut().unwrap().as_mut());
}
}
pub fn resume(&self) {}
}
+14 -7
View File
@@ -1,7 +1,7 @@
use dioxus_core::prelude::Context;
use std::{
cell::{Cell, Ref, RefCell, RefMut},
fmt::Display,
fmt::{Debug, Display},
ops::Not,
rc::Rc,
};
@@ -54,11 +54,14 @@ pub fn use_state<'a, T: 'static>(
initial_state_fn: impl FnOnce() -> T,
) -> UseState<'a, T> {
cx.use_hook(
move |_| UseStateInner {
current_val: initial_state_fn(),
update_callback: cx.schedule_update(),
wip: Rc::new(RefCell::new(None)),
update_scheuled: Cell::new(false),
move |_| {
//
UseStateInner {
current_val: initial_state_fn(),
update_callback: cx.schedule_update(),
wip: Rc::new(RefCell::new(None)),
update_scheuled: Cell::new(false),
}
},
move |hook| {
hook.update_scheuled.set(false);
@@ -91,7 +94,11 @@ where
UseState { inner: self.inner }
}
}
impl<T: Debug> Debug for UseState<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.inner.current_val)
}
}
impl<'a, T: 'static> UseState<'a, T> {
/// Tell the Dioxus Scheduler that we need to be processed
pub fn needs_update(&self) {