dioxus/packages/core/src/any_props.rs

82 lines
2.3 KiB
Rust
Raw Normal View History

2022-11-02 01:42:29 +00:00
use futures_util::Future;
use crate::{
2022-11-02 01:42:29 +00:00
component::{Component, ComponentFn, Dummy, IntoComponent},
scopes::{Scope, ScopeState},
2022-11-03 08:38:18 +00:00
Element,
};
2022-11-03 09:11:04 +00:00
pub trait AnyProps<'a> {
fn as_ptr(&self) -> *const ();
2022-11-03 09:11:04 +00:00
fn render(&'a self, bump: &'a ScopeState) -> Element<'a>;
unsafe fn memoize(&self, other: &dyn AnyProps) -> bool;
}
2022-11-03 09:11:04 +00:00
pub(crate) struct VComponentProps<'a, P, F: Future<Output = Element<'a>> = Dummy<'a>> {
pub render_fn: ComponentFn<'a, P, F>,
pub memo: unsafe fn(&P, &P) -> bool,
2022-11-02 01:42:29 +00:00
pub props: *const P,
}
2022-11-03 09:37:41 +00:00
impl<'a> VComponentProps<'a, ()> {
pub fn new_empty(render_fn: Component<'a, ()>) -> Self {
Self {
2022-11-02 01:42:29 +00:00
render_fn: render_fn.into_component(),
memo: <() as PartialEq>::eq,
2022-11-02 01:42:29 +00:00
props: std::ptr::null_mut(),
}
}
}
2022-11-03 09:37:41 +00:00
impl<'a, P, F: Future<Output = Element<'a>>> VComponentProps<'a, P, F> {
pub(crate) fn new(
2022-11-03 09:37:41 +00:00
render_fn: ComponentFn<'a, P, F>,
memo: unsafe fn(&P, &P) -> bool,
2022-11-02 01:42:29 +00:00
props: *const P,
) -> Self {
Self {
2022-11-03 09:37:41 +00:00
render_fn,
memo,
props,
}
}
}
2022-11-03 09:37:41 +00:00
impl<'a, P, F: Future<Output = Element<'a>>> AnyProps<'a> for VComponentProps<'a, P, F> {
fn as_ptr(&self) -> *const () {
&self.props as *const _ as *const ()
}
// Safety:
// this will downcast the other ptr as our swallowed type!
// you *must* make this check *before* calling this method
// if your functions are not the same, then you will downcast a pointer into a different type (UB)
unsafe fn memoize(&self, other: &dyn AnyProps) -> bool {
let real_other: &P = &*(other.as_ptr() as *const _ as *const P);
let real_us: &P = &*(self.as_ptr() as *const _ as *const P);
(self.memo)(real_us, real_other)
}
2022-11-03 09:11:04 +00:00
fn render<'b>(&'b self, scope: &'b ScopeState) -> Element<'b> {
// Make sure the scope ptr is not null
2022-11-02 01:42:29 +00:00
// self.props.state.set(scope);
let scope = Scope {
props: unsafe { &*self.props },
scope,
};
// Call the render function directly
// todo: implement async
2022-11-03 09:11:04 +00:00
// let res = match self.render_fn {
// ComponentFn::Sync(f) => {
// let f = unsafe { std::mem::transmute(f) };
// f(scope)
// }
// ComponentFn::Async(_) => todo!(),
// };
todo!()
}
}