wip: remove runner on hook and then update docs
This commit is contained in:
1 parent
7d41a16208
commit
d1560450ba
95 files changed
+1339
-675
No files matched your search
@@ -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)
|
||||
});
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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> {}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in new issue
Block a user