wip: remove runner on hook and then update docs

This commit is contained in:
Jonathan Kelley committed 2022-01-02 02:15:04 -05:00
1 parent 7d41a16208
commit d1560450ba
95 files changed
+1339 -675

No files matched your search

+33 -40
View File
@@ -60,37 +60,33 @@ impl<T> ProvidedStateInner<T> {
///
///
pub fn use_context<'a, T: 'static>(cx: &'a ScopeState) -> Option<UseSharedState<'a, T>> {
cx.use_hook(
|_| {
let scope_id = cx.scope_id();
let root = cx.consume_context::<ProvidedState<T>>();
let state = cx.use_hook(|_| {
let scope_id = cx.scope_id();
let root = cx.consume_context::<ProvidedState<T>>();
if let Some(root) = root.as_ref() {
root.borrow_mut().consumers.insert(scope_id);
}
if let Some(root) = root.as_ref() {
root.borrow_mut().consumers.insert(scope_id);
}
let value = root.as_ref().map(|f| f.borrow().value.clone());
SharedStateInner {
root,
value,
scope_id,
needs_notification: Cell::new(false),
}
},
|f| {
//
f.needs_notification.set(false);
match (&f.value, &f.root) {
(Some(value), Some(root)) => Some(UseSharedState {
cx,
value,
root,
needs_notification: &f.needs_notification,
}),
_ => None,
}
},
)
let value = root.as_ref().map(|f| f.borrow().value.clone());
SharedStateInner {
root,
value,
scope_id,
needs_notification: Cell::new(false),
}
});
state.needs_notification.set(false);
match (&state.value, &state.root) {
(Some(value), Some(root)) => Some(UseSharedState {
cx,
value,
root,
needs_notification: &state.needs_notification,
}),
_ => None,
}
}
struct SharedStateInner<T: 'static> {
@@ -176,15 +172,12 @@ where
///
///
pub fn use_context_provider<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) {
cx.use_hook(
|_| {
let state: ProvidedState<T> = RefCell::new(ProvidedStateInner {
value: Rc::new(RefCell::new(f())),
notify_any: cx.schedule_update_any(),
consumers: HashSet::new(),
});
cx.provide_context(state)
},
|_inner| {},
)
cx.use_hook(|_| {
let state: ProvidedState<T> = RefCell::new(ProvidedStateInner {
value: Rc::new(RefCell::new(f())),
notify_any: cx.schedule_update_any(),
consumers: HashSet::new(),
});
cx.provide_context(state)
});
}
+40 -43
View File
@@ -1,6 +1,6 @@
use dioxus_core::{ScopeState, TaskId};
use std::future::Future;
use std::{cell::Cell, pin::Pin, rc::Rc};
use std::{cell::Cell, rc::Rc};
/*
@@ -22,61 +22,58 @@ pub fn use_coroutine<'a, F>(
where
F: Future<Output = ()> + 'static,
{
cx.use_hook(
move |_| {
let f = create_future();
let id = cx.push_future(f);
State {
let state = cx.use_hook(move |_| {
let f = create_future();
let id = cx.push_future(f);
State {
running: Default::default(),
id
_id: id
// pending_fut: Default::default(),
// running_fut: Default::default(),
}
},
|state| {
// state.pending_fut.set(Some(Box::pin(f)));
});
// if let Some(fut) = state.running_fut.as_mut() {
// cx.push_future(fut);
// }
// state.pending_fut.set(Some(Box::pin(f)));
// if let Some(fut) = state.running_fut.take() {
// state.running.set(true);
// fut.resume();
// }
// if let Some(fut) = state.running_fut.as_mut() {
// cx.push_future(fut);
// }
// let submit: Box<dyn FnOnce() + 'a> = Box::new(move || {
// let g = async move {
// running.set(true);
// create_future().await;
// running.set(false);
// };
// let p: Pin<Box<dyn Future<Output = ()>>> = Box::pin(g);
// fut_slot
// .borrow_mut()
// .replace(unsafe { std::mem::transmute(p) });
// });
// if let Some(fut) = state.running_fut.take() {
// state.running.set(true);
// fut.resume();
// }
// let submit = unsafe { std::mem::transmute(submit) };
// state.submit.get_mut().replace(submit);
// let submit: Box<dyn FnOnce() + 'a> = Box::new(move || {
// let g = async move {
// running.set(true);
// create_future().await;
// running.set(false);
// };
// let p: Pin<Box<dyn Future<Output = ()>>> = Box::pin(g);
// fut_slot
// .borrow_mut()
// .replace(unsafe { std::mem::transmute(p) });
// });
// 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() {
// drop(fut);
// }
// }
CoroutineHandle { cx, inner: state }
},
)
// 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() {
// drop(fut);
// }
// }
CoroutineHandle { cx, inner: state }
}
struct State {
running: Rc<Cell<bool>>,
id: TaskId,
_id: TaskId,
// the way this is structure, you can toggle the coroutine without re-rendering the comppnent
// this means every render *generates* the future, which is a bit of a waste
// todo: allocate pending futures in the bump allocator and then have a true promotion
+30 -32
View File
@@ -5,40 +5,38 @@ pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
cx: &'a ScopeState,
f: impl FnOnce() -> F,
) -> (Option<&T>, FutureHandle<'a, T>) {
cx.use_hook(
|_| {
//
let fut = f();
let slot = Rc::new(Cell::new(None));
let updater = cx.schedule_update();
let state = cx.use_hook(|_| {
//
let fut = f();
let slot = Rc::new(Cell::new(None));
let updater = cx.schedule_update();
let _slot = slot.clone();
let new_fut = async move {
let res = fut.await;
_slot.set(Some(res));
updater();
};
let task = cx.push_future(new_fut);
let _slot = slot.clone();
let new_fut = async move {
let res = fut.await;
_slot.set(Some(res));
updater();
};
let task = cx.push_future(new_fut);
UseFutureInner {
needs_regen: true,
slot,
value: None,
task: Some(task),
}
},
|state| {
if let Some(value) = state.slot.take() {
state.value = Some(value);
state.task = None;
}
(
state.value.as_ref(),
FutureHandle {
cx,
value: Cell::new(None),
},
)
UseFutureInner {
needs_regen: true,
slot,
value: None,
task: Some(task),
}
});
if let Some(value) = state.slot.take() {
state.value = Some(value);
state.task = None;
}
(
state.value.as_ref(),
FutureHandle {
cx,
value: Cell::new(None),
},
)
}
+13 -27
View File
@@ -14,18 +14,15 @@ use std::{
};
pub fn use_model<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) -> UseModel<'a, T> {
cx.use_hook(
|_| UseModelInner {
update_scheduled: Cell::new(false),
update_callback: cx.schedule_update(),
value: RefCell::new(f()),
// tasks: RefCell::new(Vec::new()),
},
|inner| {
inner.update_scheduled.set(false);
UseModel { inner }
},
)
let inner = cx.use_hook(|_| UseModelInner {
update_scheduled: Cell::new(false),
update_callback: cx.schedule_update(),
value: RefCell::new(f()),
// tasks: RefCell::new(Vec::new()),
});
inner.update_scheduled.set(false);
UseModel { inner }
}
pub struct UseModel<'a, T> {
@@ -81,21 +78,10 @@ pub fn use_model_coroutine<'a, T, F: Future<Output = ()> + 'static>(
_model: UseModel<T>,
_f: impl FnOnce(AppModels) -> F,
) -> UseModelCoroutine {
cx.use_hook(
|_| {
//
UseModelTaskInner {
task: Default::default(),
}
},
|inner| {
// if let Some(task) = inner.task.get_mut() {
// cx.push_task(|| task);
// }
//
todo!()
},
)
cx.use_hook(|_| UseModelTaskInner {
task: Default::default(),
});
todo!()
}
impl<T> Copy for UseModel<'_, T> {}
+8 -11
View File
@@ -6,17 +6,14 @@ use std::{
use dioxus_core::ScopeState;
pub fn use_ref<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) -> UseRef<'a, T> {
cx.use_hook(
|_| UseRefInner {
update_scheduled: Cell::new(false),
update_callback: cx.schedule_update(),
value: RefCell::new(f()),
},
|inner| {
inner.update_scheduled.set(false);
UseRef { inner }
},
)
let inner = cx.use_hook(|_| UseRefInner {
update_scheduled: Cell::new(false),
update_callback: cx.schedule_update(),
value: RefCell::new(f()),
});
inner.update_scheduled.set(false);
UseRef { inner }
}
pub struct UseRef<'a, T> {
+20 -24
View File
@@ -51,32 +51,28 @@ pub fn use_state<'a, T: 'static>(
cx: &'a ScopeState,
initial_state_fn: impl FnOnce() -> T,
) -> UseState<'a, T> {
cx.use_hook(
move |_| {
let first_val = initial_state_fn();
UseStateInner {
current_val: Rc::new(first_val),
update_callback: cx.schedule_update(),
wip: Rc::new(RefCell::new(None)),
update_scheuled: Cell::new(false),
}
},
move |hook| {
hook.update_scheuled.set(false);
let hook = cx.use_hook(move |_| {
let first_val = initial_state_fn();
UseStateInner {
current_val: Rc::new(first_val),
update_callback: cx.schedule_update(),
wip: Rc::new(RefCell::new(None)),
update_scheuled: Cell::new(false),
}
});
let mut new_val = hook.wip.borrow_mut();
if new_val.is_some() {
// if there's only one reference (weak or otherwise), we can just swap the values
if let Some(val) = Rc::get_mut(&mut hook.current_val) {
*val = new_val.take().unwrap();
} else {
hook.current_val = Rc::new(new_val.take().unwrap());
}
}
hook.update_scheuled.set(false);
let mut new_val = hook.wip.borrow_mut();
if new_val.is_some() {
// if there's only one reference (weak or otherwise), we can just swap the values
if let Some(val) = Rc::get_mut(&mut hook.current_val) {
*val = new_val.take().unwrap();
} else {
hook.current_val = Rc::new(new_val.take().unwrap());
}
}
UseState { inner: &*hook }
},
)
UseState { inner: &*hook }
}
struct UseStateInner<T: 'static> {
current_val: Rc<T>,
+22 -25
View File
@@ -7,34 +7,31 @@ pub fn use_suspense<R: 'static, F: Future<Output = R> + 'static>(
create_future: impl FnOnce() -> F,
render: impl FnOnce(&R) -> Element,
) -> Element {
cx.use_hook(
|_| {
let fut = create_future();
let sus = cx.use_hook(|_| {
let fut = create_future();
let wip_value: Rc<Cell<Option<R>>> = Default::default();
let wip_value: Rc<Cell<Option<R>>> = Default::default();
let wip = wip_value.clone();
let new_fut = async move {
let val = fut.await;
wip.set(Some(val));
};
let wip = wip_value.clone();
let new_fut = async move {
let val = fut.await;
wip.set(Some(val));
};
let task = cx.push_future(new_fut);
SuspenseInner {
task,
value: None,
wip_value,
}
},
|sus| {
if let Some(value) = sus.value.as_ref() {
render(&value)
} else {
// generate a placeholder node if the future isnt ready
None
}
},
)
let task = cx.push_future(new_fut);
SuspenseInner {
task,
value: None,
wip_value,
}
});
if let Some(value) = sus.value.as_ref() {
render(&value)
} else {
// generate a placeholder node if the future isnt ready
None
}
}
struct SuspenseInner<R> {