wip: allow async into component

This commit is contained in:
Jonathan Kelley committed 2022-11-03 02:11:04 -07:00
1 parent 5d91f51e17
commit 591674f701
7 files changed
+53 -35

No files matched your search

+17 -12
View File
@@ -6,19 +6,19 @@ use crate::{
Element, Element,
}; };
pub trait AnyProps { pub trait AnyProps<'a> {
fn as_ptr(&self) -> *const (); fn as_ptr(&self) -> *const ();
fn render<'a>(&'a self, bump: &'a ScopeState) -> Element<'a>; fn render(&'a self, bump: &'a ScopeState) -> Element<'a>;
unsafe fn memoize(&self, other: &dyn AnyProps) -> bool; unsafe fn memoize(&self, other: &dyn AnyProps) -> bool;
} }
pub(crate) struct VComponentProps<P, F: Future<Output = ()> = Dummy> { pub(crate) struct VComponentProps<'a, P, F: Future<Output = Element<'a>> = Dummy<'a>> {
pub render_fn: ComponentFn<P, F>, pub render_fn: ComponentFn<'a, P, F>,
pub memo: unsafe fn(&P, &P) -> bool, pub memo: unsafe fn(&P, &P) -> bool,
pub props: *const P, pub props: *const P,
} }
impl VComponentProps<()> { impl VComponentProps<'_, ()> {
pub fn new_empty(render_fn: Component<()>) -> Self { pub fn new_empty(render_fn: Component<()>) -> Self {
Self { Self {
render_fn: render_fn.into_component(), render_fn: render_fn.into_component(),
@@ -28,7 +28,7 @@ impl VComponentProps<()> {
} }
} }
impl<P> VComponentProps<P> { impl<P> VComponentProps<'_, P> {
pub(crate) fn new( pub(crate) fn new(
render_fn: Component<P>, render_fn: Component<P>,
memo: unsafe fn(&P, &P) -> bool, memo: unsafe fn(&P, &P) -> bool,
@@ -42,7 +42,7 @@ impl<P> VComponentProps<P> {
} }
} }
impl<P> AnyProps for VComponentProps<P> { impl<'a, P> AnyProps<'a> for VComponentProps<'a, P> {
fn as_ptr(&self) -> *const () { fn as_ptr(&self) -> *const () {
&self.props as *const _ as *const () &self.props as *const _ as *const ()
} }
@@ -57,7 +57,7 @@ impl<P> AnyProps for VComponentProps<P> {
(self.memo)(real_us, real_other) (self.memo)(real_us, real_other)
} }
fn render<'a>(&'a self, scope: &'a ScopeState) -> Element<'a> { fn render<'b>(&'b self, scope: &'b ScopeState) -> Element<'b> {
// Make sure the scope ptr is not null // Make sure the scope ptr is not null
// self.props.state.set(scope); // self.props.state.set(scope);
@@ -68,9 +68,14 @@ impl<P> AnyProps for VComponentProps<P> {
// Call the render function directly // Call the render function directly
// todo: implement async // todo: implement async
match self.render_fn { // let res = match self.render_fn {
ComponentFn::Sync(f) => f(scope), // ComponentFn::Sync(f) => {
ComponentFn::Async(_) => todo!(), // let f = unsafe { std::mem::transmute(f) };
} // f(scope)
// }
// ComponentFn::Async(_) => todo!(),
// };
todo!()
} }
} }
+16 -14
View File
@@ -2,39 +2,41 @@
// fn into_component_type(self) -> ComponentType; // fn into_component_type(self) -> ComponentType;
// } // }
use std::marker::PhantomData;
use futures_util::Future; use futures_util::Future;
use crate::{scopes::Scope, Element}; use crate::{scopes::Scope, Element};
pub type Component<T = ()> = fn(Scope<T>) -> Element; pub type Component<T = ()> = fn(Scope<T>) -> Element;
pub enum ComponentFn<T, F: Future<Output = ()> = Dummy> { pub enum ComponentFn<'a, T, F: Future<Output = Element<'a>> = Dummy<'a>> {
Sync(fn(Scope<T>) -> Element), Sync(fn(Scope<'a, T>) -> Element),
Async(fn(Scope<T>) -> F), Async(fn(Scope<'a, T>) -> F),
} }
pub trait IntoComponent<T, A = ()> { pub trait IntoComponent<'a, T, F: Future<Output = Element<'a>> = Dummy<'a>, A = ()> {
fn into_component(self) -> ComponentFn<T>; fn into_component(self) -> ComponentFn<'a, T, F>;
} }
impl<T> IntoComponent<T> for fn(Scope<T>) -> Element { impl<'a, T> IntoComponent<'a, T, Dummy<'a>> for fn(Scope<T>) -> Element {
fn into_component(self) -> ComponentFn<T> { fn into_component(self) -> ComponentFn<'a, T> {
ComponentFn::Sync(self) ComponentFn::Sync(self)
} }
} }
pub struct AsyncMarker; pub struct AsyncMarker;
impl<'a, T, F: Future<Output = Element<'a>>> IntoComponent<T, AsyncMarker> impl<'a, T, F: Future<Output = Element<'a>>> IntoComponent<'a, T, F, AsyncMarker>
for fn(&'a Scope<T>) -> F for fn(Scope<'a, T>) -> F
{ {
fn into_component(self) -> ComponentFn<T> { fn into_component(self) -> ComponentFn<'a, T, F> {
todo!() ComponentFn::Async(self)
} }
} }
pub struct Dummy; pub struct Dummy<'a>(PhantomData<&'a ()>);
impl Future for Dummy { impl<'a> Future for Dummy<'a> {
type Output = (); type Output = Element<'a>;
fn poll( fn poll(
self: std::pin::Pin<&mut Self>, self: std::pin::Pin<&mut Self>,
+1 -1
View File
@@ -170,7 +170,7 @@ impl VirtualDom {
} }
DynamicNode::Component { props, .. } => { DynamicNode::Component { props, .. } => {
let id = self.new_scope(*props); let id = self.new_scope(unsafe { std::mem::transmute(*props) });
let template = self.run_scope(id); let template = self.run_scope(id);
+8
View File
@@ -24,4 +24,12 @@ impl VirtualDom {
fn diff_scope<'a>(&'a mut self, mutations: &mut Vec<Mutation<'a>>, scope: ScopeId) { fn diff_scope<'a>(&'a mut self, mutations: &mut Vec<Mutation<'a>>, scope: ScopeId) {
let scope_state = &mut self.scopes[scope.0]; let scope_state = &mut self.scopes[scope.0];
} }
fn diff_template<'a>(
&'a mut self,
mutations: &mut Vec<Mutation<'a>>,
left: &VNode,
right: &VNode,
) {
}
} }
+1 -1
View File
@@ -78,7 +78,7 @@ pub enum DynamicNode<'a> {
Component { Component {
name: &'static str, name: &'static str,
can_memoize: bool, can_memoize: bool,
props: *mut dyn AnyProps, props: *mut dyn AnyProps<'a>,
}, },
// Comes in with string interpolation or from format_args, include_str, etc // Comes in with string interpolation or from format_args, include_str, etc
+9 -6
View File
@@ -8,7 +8,7 @@ use crate::{
}; };
impl VirtualDom { impl VirtualDom {
pub fn new_scope(&mut self, props: *mut dyn AnyProps) -> ScopeId { pub fn new_scope(&mut self, props: *mut dyn AnyProps<'static>) -> ScopeId {
let parent = self.acquire_current_scope_raw(); let parent = self.acquire_current_scope_raw();
let container = self.acquire_current_container(); let container = self.acquire_current_container();
let entry = self.scopes.vacant_entry(); let entry = self.scopes.vacant_entry();
@@ -48,14 +48,17 @@ impl VirtualDom {
.and_then(|id| self.scopes.get_mut(id.0).map(|f| f as *mut ScopeState)) .and_then(|id| self.scopes.get_mut(id.0).map(|f| f as *mut ScopeState))
} }
pub fn run_scope<'a>(&'a mut self, id: ScopeId) -> &'a VNode<'a> { pub fn run_scope(&mut self, id: ScopeId) -> &VNode {
let scope = &mut self.scopes[id.0]; let scope = &mut self.scopes[id.0];
scope.hook_idx.set(0); scope.hook_idx.set(0);
let props = unsafe { &mut *scope.props }; let res = {
let props = unsafe { &mut *scope.props };
let res = props.render(scope).unwrap(); let props: &mut dyn AnyProps = unsafe { std::mem::transmute(props) };
let res: VNode<'static> = unsafe { std::mem::transmute(res) }; let res: VNode = props.render(scope).unwrap();
let res: VNode<'static> = unsafe { std::mem::transmute(res) };
res
};
let frame = match scope.render_cnt % 2 { let frame = match scope.render_cnt % 2 {
0 => &mut scope.node_arena_1, 0 => &mut scope.node_arena_1,
+1 -1
View File
@@ -66,7 +66,7 @@ pub struct ScopeState {
pub tasks: FutureQueue, pub tasks: FutureQueue,
pub props: *mut dyn AnyProps, pub props: *mut dyn AnyProps<'static>,
} }
impl ScopeState { impl ScopeState {