mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-11 15:07:08 +00:00
fix rendering
This commit is contained in:
parent
628638b9af
commit
3b06059834
11 changed files with 509 additions and 65 deletions
|
@ -10,50 +10,64 @@ fn tui_update(c: &mut Criterion) {
|
|||
let mut group = c.benchmark_group("Update boxes");
|
||||
|
||||
// We can also use loops to define multiple benchmarks, even over multiple dimensions.
|
||||
for size in 1..=6 {
|
||||
let parameter_string = format!("{}", 5 * size);
|
||||
for size in 1..=8u32 {
|
||||
let parameter_string = format!("{}", (3 * size).pow(2));
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("size", parameter_string),
|
||||
&size,
|
||||
|b, size| {
|
||||
b.iter(|| match size {
|
||||
1 => dioxus::tui::launch_cfg(
|
||||
app5,
|
||||
app3,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
2 => dioxus::tui::launch_cfg(
|
||||
app10,
|
||||
app6,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
3 => dioxus::tui::launch_cfg(
|
||||
app15,
|
||||
app9,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
4 => dioxus::tui::launch_cfg(
|
||||
app20,
|
||||
app12,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
5 => dioxus::tui::launch_cfg(
|
||||
app25,
|
||||
app15,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
6 => dioxus::tui::launch_cfg(
|
||||
app30,
|
||||
app18,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
7 => dioxus::tui::launch_cfg(
|
||||
app21,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
8 => dioxus::tui::launch_cfg(
|
||||
app24,
|
||||
Config {
|
||||
headless: true,
|
||||
..Default::default()
|
||||
|
@ -157,25 +171,49 @@ fn Grid(cx: Scope<GridProps>) -> Element {
|
|||
})
|
||||
}
|
||||
|
||||
fn app5(cx: Scope) -> Element {
|
||||
fn app3(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 5,
|
||||
size: 3,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn app10(cx: Scope) -> Element {
|
||||
fn app6(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 10,
|
||||
size: 6,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn app9(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 9,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn app12(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 12,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -193,37 +231,37 @@ fn app15(cx: Scope) -> Element {
|
|||
})
|
||||
}
|
||||
|
||||
fn app20(cx: Scope) -> Element {
|
||||
fn app18(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 20,
|
||||
size: 18,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn app25(cx: Scope) -> Element {
|
||||
fn app21(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 25,
|
||||
size: 21,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn app30(cx: Scope) -> Element {
|
||||
fn app24(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
Grid{
|
||||
size: 30,
|
||||
size: 24,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -4,12 +4,35 @@ use proc_macro::TokenStream;
|
|||
use quote::{quote, ToTokens};
|
||||
use syn::{
|
||||
self,
|
||||
parse::{Parse, ParseStream},
|
||||
parse::{Parse, ParseStream, Result},
|
||||
punctuated::Punctuated,
|
||||
token::Paren,
|
||||
Field, Ident, Token, Type, TypeTuple,
|
||||
Field, Ident, LitStr, Token, Type, TypeTuple,
|
||||
};
|
||||
|
||||
// struct StrSlice {
|
||||
// init: LitStr,
|
||||
// }
|
||||
|
||||
// impl Parse for StrSlice {
|
||||
// fn parse(input: ParseStream) -> Result<Self> {
|
||||
// input.parse::<Token![[]>()?;
|
||||
// let str: LitStr = input.parse()?;
|
||||
// let name: Ident = input.parse()?;
|
||||
// input.parse::<Token![,]>()?;
|
||||
// input.parse::<Token![]]>()?;
|
||||
// Ok(LazyStatic {
|
||||
// visibility,
|
||||
// name,
|
||||
// ty,
|
||||
// init,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[proc_macro]
|
||||
// pub fn sorted_str_slice(input: TokenStream) -> TokenStream {}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum DepKind {
|
||||
NodeDepState,
|
||||
|
@ -105,7 +128,7 @@ fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||
|
||||
let gen = quote! {
|
||||
impl State for #type_name{
|
||||
fn update_node_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, ctx: &anymap::AnyMap) -> bool{
|
||||
fn update_node_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, vdom: &'a dioxus_core::VirtualDom, ctx: &anymap::AnyMap) -> bool{
|
||||
use dioxus_native_core::state::NodeDepState as _;
|
||||
// println!("called update_node_dep_state with ty: {:?}", ty);
|
||||
if false {
|
||||
|
@ -117,7 +140,7 @@ fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_parent_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, parent: Option<&Self>, ctx: &anymap::AnyMap) -> bool{
|
||||
fn update_parent_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, vdom: &'a dioxus_core::VirtualDom, parent: Option<&Self>, ctx: &anymap::AnyMap) -> bool{
|
||||
use dioxus_native_core::state::ParentDepState as _;
|
||||
// println!("called update_parent_dep_state with ty: {:?}", ty);
|
||||
if false {
|
||||
|
@ -129,7 +152,7 @@ fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_child_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, children: &[&Self], ctx: &anymap::AnyMap) -> bool{
|
||||
fn update_child_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, vdom: &'a dioxus_core::VirtualDom, children: &[&Self], ctx: &anymap::AnyMap) -> bool{
|
||||
use dioxus_native_core::state::ChildDepState as _;
|
||||
// println!("called update_child_dep_state with ty: {:?}", ty);
|
||||
if false {
|
||||
|
@ -205,7 +228,7 @@ struct DepTypes {
|
|||
}
|
||||
|
||||
impl Parse for DepTypes {
|
||||
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let dep_ty = input.parse().ok();
|
||||
let comma: Option<Token![,]> = input.parse().ok();
|
||||
let ctx_ty = input.parse().ok();
|
||||
|
@ -221,7 +244,7 @@ struct NodeDepTypes {
|
|||
}
|
||||
|
||||
impl Parse for NodeDepTypes {
|
||||
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let ctx_ty = input.parse().ok();
|
||||
Ok(Self { ctx_ty })
|
||||
}
|
||||
|
@ -307,7 +330,7 @@ impl<'a> StateMember<'a> {
|
|||
quote! {&()}
|
||||
};
|
||||
let ty = &self.mem.ty;
|
||||
let node_view = quote!(NodeView::new(node, #ty::NODE_MASK));
|
||||
let node_view = quote!(NodeView::new(node, #ty::NODE_MASK, vdom));
|
||||
if let Some(dep_ident) = &self.dep_mem.map(|m| &m.ident) {
|
||||
match self.dep_kind {
|
||||
DepKind::NodeDepState => {
|
||||
|
|
368
packages/native-core-macro/src/lib.rs~Stashed changes
Normal file
368
packages/native-core-macro/src/lib.rs~Stashed changes
Normal file
|
@ -0,0 +1,368 @@
|
|||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{
|
||||
self,
|
||||
parse::{Parse, ParseStream, Result},
|
||||
punctuated::Punctuated,
|
||||
token::Paren,
|
||||
Field, Ident, LitStr, Token, Type, TypeTuple,
|
||||
};
|
||||
|
||||
// struct StrSlice {
|
||||
// init: LitStr,
|
||||
// }
|
||||
|
||||
// impl Parse for StrSlice {
|
||||
// fn parse(input: ParseStream) -> Result<Self> {
|
||||
// input.parse::<Token![[]>()?;
|
||||
// let str: LitStr = input.parse()?;
|
||||
// let name: Ident = input.parse()?;
|
||||
// input.parse::<Token![,]>()?;
|
||||
// input.parse::<Token![]]>()?;
|
||||
// Ok(LazyStatic {
|
||||
// visibility,
|
||||
// name,
|
||||
// ty,
|
||||
// init,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[proc_macro]
|
||||
// pub fn sorted_str_slice(input: TokenStream) -> TokenStream {}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum DepKind {
|
||||
NodeDepState,
|
||||
ChildDepState,
|
||||
ParentDepState,
|
||||
}
|
||||
|
||||
// macro that streams data from the State for any attributes that end with _
|
||||
#[proc_macro_derive(State, attributes(node_dep_state, child_dep_state, parent_dep_state))]
|
||||
pub fn state_macro_derive(input: TokenStream) -> TokenStream {
|
||||
let ast = syn::parse(input).unwrap();
|
||||
impl_derive_macro(&ast)
|
||||
}
|
||||
|
||||
fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let type_name = &ast.ident;
|
||||
let fields: Vec<_> = match &ast.data {
|
||||
syn::Data::Struct(data) => match &data.fields {
|
||||
syn::Fields::Named(e) => &e.named,
|
||||
syn::Fields::Unnamed(_) => todo!("unnamed fields"),
|
||||
syn::Fields::Unit => todo!("unit fields"),
|
||||
}
|
||||
.iter()
|
||||
.collect(),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
let strct = Struct::parse(&fields);
|
||||
let state_strct = StateStruct::parse(&fields, &strct);
|
||||
|
||||
let node_dep_state_fields = quote::__private::TokenStream::from_iter(
|
||||
state_strct
|
||||
.state_members
|
||||
.iter()
|
||||
.filter(|f| f.dep_kind == DepKind::NodeDepState)
|
||||
.map(|f| {
|
||||
let ty_id = &f.type_id();
|
||||
let reduce = &f.reduce_self();
|
||||
quote! {
|
||||
else if ty == #ty_id {
|
||||
#reduce
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
let child_dep_state_fields = quote::__private::TokenStream::from_iter(
|
||||
state_strct
|
||||
.state_members
|
||||
.iter()
|
||||
.filter(|f| f.dep_kind == DepKind::ChildDepState)
|
||||
.map(|f| {
|
||||
let ty_id = &f.type_id();
|
||||
let reduce = &f.reduce_self();
|
||||
quote! {
|
||||
else if ty == #ty_id {
|
||||
#reduce
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
let parent_dep_state_fields = quote::__private::TokenStream::from_iter(
|
||||
state_strct
|
||||
.state_members
|
||||
.iter()
|
||||
.filter(|f| f.dep_kind == DepKind::ParentDepState)
|
||||
.map(|f| {
|
||||
let ty_id = &f.type_id();
|
||||
let reduce = &f.reduce_self();
|
||||
quote! {
|
||||
else if ty == #ty_id {
|
||||
#reduce
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
let node_types = state_strct
|
||||
.state_members
|
||||
.iter()
|
||||
.filter(|f| f.dep_kind == DepKind::NodeDepState)
|
||||
.map(|f| &f.mem.ty);
|
||||
let child_types = state_strct
|
||||
.state_members
|
||||
.iter()
|
||||
.filter(|f| f.dep_kind == DepKind::ChildDepState)
|
||||
.map(|f| &f.mem.ty);
|
||||
let parent_types = state_strct
|
||||
.state_members
|
||||
.iter()
|
||||
.filter(|f| f.dep_kind == DepKind::ParentDepState)
|
||||
.map(|f| &f.mem.ty);
|
||||
|
||||
let type_name_str = type_name.to_string();
|
||||
|
||||
let gen = quote! {
|
||||
impl State for #type_name{
|
||||
fn update_node_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, vdom: &'a dioxus_core::VirtualDom, ctx: &anymap::AnyMap) -> bool{
|
||||
use dioxus_native_core::state::NodeDepState as _;
|
||||
// println!("called update_node_dep_state with ty: {:?}", ty);
|
||||
if false {
|
||||
unreachable!();
|
||||
}
|
||||
#node_dep_state_fields
|
||||
else{
|
||||
panic!("{:?} not in {}", ty, #type_name_str)
|
||||
}
|
||||
}
|
||||
|
||||
fn update_parent_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, vdom: &'a dioxus_core::VirtualDom, parent: Option<&Self>, ctx: &anymap::AnyMap) -> bool{
|
||||
use dioxus_native_core::state::ParentDepState as _;
|
||||
// println!("called update_parent_dep_state with ty: {:?}", ty);
|
||||
if false {
|
||||
unreachable!();
|
||||
}
|
||||
#parent_dep_state_fields
|
||||
else{
|
||||
panic!("{:?} not in {}", ty, #type_name_str)
|
||||
}
|
||||
}
|
||||
|
||||
fn update_child_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VNode<'a>, vdom: &'a dioxus_core::VirtualDom, children: &[&Self], ctx: &anymap::AnyMap) -> bool{
|
||||
use dioxus_native_core::state::ChildDepState as _;
|
||||
// println!("called update_child_dep_state with ty: {:?}", ty);
|
||||
if false {
|
||||
unreachable!()
|
||||
}
|
||||
#child_dep_state_fields
|
||||
else{
|
||||
panic!("{:?} not in {}", ty, #type_name_str)
|
||||
}
|
||||
}
|
||||
|
||||
fn child_dep_types(&self, mask: &dioxus_native_core::state::NodeMask) -> Vec<std::any::TypeId>{
|
||||
let mut dep_types = Vec::new();
|
||||
#(if #child_types::NODE_MASK.overlaps(mask) {
|
||||
dep_types.push(std::any::TypeId::of::<#child_types>());
|
||||
})*
|
||||
dep_types
|
||||
}
|
||||
|
||||
fn parent_dep_types(&self, mask: &dioxus_native_core::state::NodeMask) -> Vec<std::any::TypeId>{
|
||||
let mut dep_types = Vec::new();
|
||||
#(if #parent_types::NODE_MASK.overlaps(mask) {
|
||||
dep_types.push(std::any::TypeId::of::<#parent_types>());
|
||||
})*
|
||||
dep_types
|
||||
}
|
||||
|
||||
fn node_dep_types(&self, mask: &dioxus_native_core::state::NodeMask) -> Vec<std::any::TypeId>{
|
||||
let mut dep_types = Vec::new();
|
||||
#(if #node_types::NODE_MASK.overlaps(mask) {
|
||||
dep_types.push(std::any::TypeId::of::<#node_types>());
|
||||
})*
|
||||
dep_types
|
||||
}
|
||||
}
|
||||
};
|
||||
gen.into()
|
||||
}
|
||||
|
||||
struct Struct {
|
||||
members: Vec<Member>,
|
||||
}
|
||||
|
||||
impl Struct {
|
||||
fn parse(fields: &[&Field]) -> Self {
|
||||
let members = fields.iter().filter_map(|f| Member::parse(f)).collect();
|
||||
Self { members }
|
||||
}
|
||||
}
|
||||
|
||||
struct StateStruct<'a> {
|
||||
state_members: Vec<StateMember<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> StateStruct<'a> {
|
||||
fn parse(fields: &[&'a Field], strct: &'a Struct) -> Self {
|
||||
let state_members = strct
|
||||
.members
|
||||
.iter()
|
||||
.zip(fields.iter())
|
||||
.filter_map(|(m, f)| StateMember::parse(f, m, &strct))
|
||||
.collect();
|
||||
|
||||
// todo: sort members
|
||||
|
||||
Self { state_members }
|
||||
}
|
||||
}
|
||||
|
||||
struct DepTypes {
|
||||
ctx_ty: Option<Type>,
|
||||
dep_ty: Option<Type>,
|
||||
}
|
||||
|
||||
impl Parse for DepTypes {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let dep_ty = input.parse().ok();
|
||||
let comma: Option<Token![,]> = input.parse().ok();
|
||||
let ctx_ty = input.parse().ok();
|
||||
Ok(Self {
|
||||
ctx_ty: comma.and(ctx_ty),
|
||||
dep_ty,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct NodeDepTypes {
|
||||
ctx_ty: Option<Type>,
|
||||
}
|
||||
|
||||
impl Parse for NodeDepTypes {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let ctx_ty = input.parse().ok();
|
||||
Ok(Self { ctx_ty })
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeDepTypes> for DepTypes {
|
||||
fn from(node_dep_types: NodeDepTypes) -> Self {
|
||||
Self {
|
||||
ctx_ty: node_dep_types.ctx_ty,
|
||||
dep_ty: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Member {
|
||||
ty: Type,
|
||||
ident: Ident,
|
||||
}
|
||||
|
||||
impl Member {
|
||||
fn parse(field: &Field) -> Option<Self> {
|
||||
Some(Self {
|
||||
ty: field.ty.clone(),
|
||||
ident: field.ident.as_ref()?.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct StateMember<'a> {
|
||||
mem: &'a Member,
|
||||
dep_kind: DepKind,
|
||||
dep_mem: Option<&'a Member>,
|
||||
ctx_ty: Option<Type>,
|
||||
}
|
||||
|
||||
impl<'a> StateMember<'a> {
|
||||
fn parse(field: &Field, mem: &'a Member, parent: &'a Struct) -> Option<StateMember<'a>> {
|
||||
field.attrs.iter().find_map(|a| {
|
||||
let dep_kind = a
|
||||
.path
|
||||
.get_ident()
|
||||
.map(|i| match i.to_string().as_str() {
|
||||
"node_dep_state" => Some(DepKind::NodeDepState),
|
||||
"child_dep_state" => Some(DepKind::ChildDepState),
|
||||
"parent_dep_state" => Some(DepKind::ParentDepState),
|
||||
_ => None,
|
||||
})
|
||||
.flatten()?;
|
||||
let deps: DepTypes = match dep_kind {
|
||||
DepKind::NodeDepState => a.parse_args::<NodeDepTypes>().ok()?.into(),
|
||||
_ => a.parse_args().ok()?,
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
mem,
|
||||
dep_kind,
|
||||
dep_mem: deps
|
||||
.dep_ty
|
||||
.map(|ty| parent.members.iter().find(|m| m.ty == ty))
|
||||
.flatten(),
|
||||
ctx_ty: deps.ctx_ty,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_self(&self) -> quote::__private::TokenStream {
|
||||
let ident = &self.mem.ident;
|
||||
let get_ctx = if let Some(ctx_ty) = &self.ctx_ty {
|
||||
if ctx_ty
|
||||
== &Type::Tuple(TypeTuple {
|
||||
paren_token: Paren {
|
||||
span: quote::__private::Span::call_site(),
|
||||
},
|
||||
elems: Punctuated::new(),
|
||||
})
|
||||
{
|
||||
quote! {&()}
|
||||
} else {
|
||||
let msg = ctx_ty.to_token_stream().to_string() + " not found in context";
|
||||
quote! {ctx.get().expect(#msg)}
|
||||
}
|
||||
} else {
|
||||
quote! {&()}
|
||||
};
|
||||
let ty = &self.mem.ty;
|
||||
let node_view = quote!(NodeView::new(node, #ty::NODE_MASK, vdom));
|
||||
if let Some(dep_ident) = &self.dep_mem.map(|m| &m.ident) {
|
||||
match self.dep_kind {
|
||||
DepKind::NodeDepState => {
|
||||
quote!(self.#ident.reduce(#node_view, #get_ctx))
|
||||
}
|
||||
DepKind::ChildDepState => {
|
||||
quote!(self.#ident.reduce(#node_view, children.iter().map(|s| &s.#dep_ident), #get_ctx))
|
||||
}
|
||||
DepKind::ParentDepState => {
|
||||
quote!(self.#ident.reduce(#node_view, parent.as_ref().map(|p| &p.#dep_ident), #get_ctx))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match self.dep_kind {
|
||||
DepKind::NodeDepState => {
|
||||
quote!(self.#ident.reduce(#node_view, #get_ctx))
|
||||
}
|
||||
DepKind::ChildDepState => {
|
||||
quote!(self.#ident.reduce(#node_view, &(), #get_ctx))
|
||||
}
|
||||
DepKind::ParentDepState => {
|
||||
quote!(self.#ident.reduce(#node_view, Some(&()), #get_ctx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn type_id(&self) -> quote::__private::TokenStream {
|
||||
let ty = &self.mem.ty;
|
||||
quote!({
|
||||
let type_id = std::any::TypeId::of::<#ty>();
|
||||
type_id
|
||||
})
|
||||
}
|
||||
}
|
|
@ -29,6 +29,8 @@
|
|||
- [ ] pub aspect_ratio: Number,
|
||||
*/
|
||||
|
||||
// align-content,align-items,align-self,animation,animation-delay,animation-direction,animation-duration,animation-fill-mode,animation-iteration-count,animation-name,animation-play-state,animation-timing-function,backface-visibility,border,border-bottom,border-bottom-color,border-bottom-left-radius,border-bottom-right-radius,border-bottom-style,border-bottom-width,border-collapse,border-color,border-image,border-image-outset,border-image-repeat,border-image-slice,border-image-source,border-image-width,border-left,border-left-color,border-left-style,border-left-width,border-radius,border-right,border-right-color,border-right-style,border-right-width,border-spacing,border-style,border-top,border-top-color,border-top-left-radius,border-top-right-radius,border-top-style,border-top-width,border-width,bottom,box-shadow,box-sizing,caption-side,clear,clip,column-count,column-fill,column-gap,column-rule,column-rule-color,column-rule-style,column-rule-width,column-span,column-width,columns,content,counter-increment,counter-reset,cursor,direction,ltr,rtl,display,empty-cells,flex,flex-basis,flex-direction,flex-flow,flex-grow,flex-shrink,flex-wrap,float,height,justify-content,flex-start,flex-end,center,space-between,space-around,space-evenly,left,letter-spacing,line-height,list-style,list-style-image,list-style-position,list-style-type,margin,margin-bottom,margin-left,margin-right,margin-top,max-height,max-width,min-height,min-width,opacity,order,outline,outline-color,outline-offset,outline-style,outline-width,overflow,overflow-x,overflow-y,padding,padding-bottom,padding-left,padding-right,padding-top,page-break-after,page-break-before,page-break-inside,perspective,perspective-origin,position,static,relative,fixed,absolute,sticky,pointer-events,quotes,resize,right,tab-size,table-layout,top,transform,transform-origin,transform-style,transition,transition-delay,transition-duration,transition-property,transition-timing-function,vertical-align,visibility,white-space,width,word-break,word-spacing,word-wrap,z-index
|
||||
|
||||
use stretch2::{prelude::*, style::PositionType};
|
||||
|
||||
/// applies the entire html namespace defined in dioxus-html
|
||||
|
|
|
@ -301,7 +301,7 @@ impl<S: State> RealDom<S> {
|
|||
for ty in ids {
|
||||
let node = &mut self[node_ref.id];
|
||||
let vnode = node.element(vdom);
|
||||
changed |= node.state.update_node_dep_state(ty, vnode, &ctx);
|
||||
changed |= node.state.update_node_dep_state(ty, vnode, vdom, &ctx);
|
||||
}
|
||||
if changed {
|
||||
to_rerender.insert(node_ref.id);
|
||||
|
@ -328,7 +328,7 @@ impl<S: State> RealDom<S> {
|
|||
let vnode = node.element(vdom);
|
||||
if node
|
||||
.state
|
||||
.update_child_dep_state(ty, vnode, &children_state, &ctx)
|
||||
.update_child_dep_state(ty, vnode, vdom, &children_state, &ctx)
|
||||
{
|
||||
changed.push(ty);
|
||||
}
|
||||
|
@ -387,6 +387,7 @@ impl<S: State> RealDom<S> {
|
|||
if state.update_parent_dep_state(
|
||||
ty,
|
||||
vnode,
|
||||
vdom,
|
||||
parent.filter(|n| n.id.0 != 0).map(|n| &n.state),
|
||||
&ctx,
|
||||
) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{any::TypeId, fmt::Debug};
|
||||
|
||||
use anymap::AnyMap;
|
||||
use dioxus_core::{Attribute, ElementId, VElement, VNode, VText};
|
||||
use dioxus_core::{Attribute, ElementId, VElement, VNode, VText, VirtualDom};
|
||||
|
||||
pub(crate) fn union_ordered_iter<T: Ord + Debug>(
|
||||
s_iter: impl Iterator<Item = T>,
|
||||
|
@ -40,7 +40,11 @@ pub struct NodeView<'a> {
|
|||
mask: NodeMask,
|
||||
}
|
||||
impl<'a> NodeView<'a> {
|
||||
pub fn new(vnode: &'a VNode<'a>, view: NodeMask) -> Self {
|
||||
pub fn new(mut vnode: &'a VNode<'a>, view: NodeMask, vdom: &'a VirtualDom) -> Self {
|
||||
if let VNode::Component(sc) = vnode {
|
||||
let scope = vdom.get_scope(sc.scope.get().unwrap()).unwrap();
|
||||
vnode = scope.root_node();
|
||||
}
|
||||
Self {
|
||||
inner: vnode,
|
||||
mask: view,
|
||||
|
@ -284,6 +288,7 @@ pub trait State: Default + Clone {
|
|||
&'a mut self,
|
||||
ty: TypeId,
|
||||
node: &'a VNode<'a>,
|
||||
vdom: &'a dioxus_core::VirtualDom,
|
||||
ctx: &AnyMap,
|
||||
) -> bool;
|
||||
/// This must be a valid resolution order. (no nodes updated before a state they rely on)
|
||||
|
@ -293,6 +298,7 @@ pub trait State: Default + Clone {
|
|||
&'a mut self,
|
||||
ty: TypeId,
|
||||
node: &'a VNode<'a>,
|
||||
vdom: &'a dioxus_core::VirtualDom,
|
||||
parent: Option<&Self>,
|
||||
ctx: &AnyMap,
|
||||
) -> bool;
|
||||
|
@ -303,6 +309,7 @@ pub trait State: Default + Clone {
|
|||
&'a mut self,
|
||||
ty: TypeId,
|
||||
node: &'a VNode<'a>,
|
||||
vdom: &'a dioxus_core::VirtualDom,
|
||||
children: &[&Self],
|
||||
ctx: &AnyMap,
|
||||
) -> bool;
|
||||
|
|
|
@ -14,12 +14,6 @@ struct Z {
|
|||
z: C,
|
||||
}
|
||||
|
||||
// struct Z {
|
||||
// x: A,
|
||||
// y: B,
|
||||
// z: C,
|
||||
// }
|
||||
|
||||
use dioxus_native_core::state::NodeDepState;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
|
|
|
@ -28,11 +28,13 @@ impl ChildDepState for StretchLayout {
|
|||
where
|
||||
Self::DepState: 'a,
|
||||
{
|
||||
let mut changed = false;
|
||||
let mut stretch = ctx.borrow_mut();
|
||||
let mut style = Style::default();
|
||||
if let Some(text) = node.text() {
|
||||
let char_len = text.chars().count();
|
||||
|
||||
let style = Style {
|
||||
style = Style {
|
||||
size: Size {
|
||||
// characters are 1 point tall
|
||||
height: Dimension::Points(1.0),
|
||||
|
@ -42,7 +44,6 @@ impl ChildDepState for StretchLayout {
|
|||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(n) = self.node {
|
||||
if self.style != style {
|
||||
stretch.set_style(n, style).unwrap();
|
||||
|
@ -50,12 +51,8 @@ impl ChildDepState for StretchLayout {
|
|||
} else {
|
||||
self.node = Some(stretch.new_node(style, &[]).unwrap());
|
||||
}
|
||||
|
||||
self.style = style;
|
||||
} else {
|
||||
// gather up all the styles from the attribute list
|
||||
let mut style = Style::default();
|
||||
|
||||
for &Attribute { name, value, .. } in node.attributes() {
|
||||
apply_layout_attributes(name, value, &mut style);
|
||||
}
|
||||
|
@ -73,18 +70,27 @@ impl ChildDepState for StretchLayout {
|
|||
}
|
||||
|
||||
if let Some(n) = self.node {
|
||||
if stretch.children(n).unwrap() != child_layout {
|
||||
stretch.set_children(n, &child_layout).unwrap();
|
||||
}
|
||||
if self.style != style {
|
||||
stretch.set_style(n, style).unwrap();
|
||||
}
|
||||
} else {
|
||||
self.node = Some(stretch.new_node(style, &child_layout).unwrap());
|
||||
self.node = Some(stretch.new_node(style, &[]).unwrap());
|
||||
}
|
||||
|
||||
if let Some(n) = self.node {
|
||||
if self.style != style {
|
||||
stretch.set_style(n, style).unwrap();
|
||||
}
|
||||
if stretch.children(n).unwrap() != child_layout {
|
||||
stretch.set_children(n, &child_layout).unwrap();
|
||||
}
|
||||
} else {
|
||||
self.node = Some(stretch.new_node(style, &[]).unwrap());
|
||||
}
|
||||
}
|
||||
if self.style != style {
|
||||
changed = true;
|
||||
self.style = style;
|
||||
}
|
||||
true
|
||||
changed
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,8 +148,7 @@ fn render_vdom(
|
|||
fn resize(dims: Rect, stretch: &mut Stretch, rdom: &Dom) {
|
||||
let width = dims.width;
|
||||
let height = dims.height;
|
||||
let root_id = rdom.root_id();
|
||||
let root_node = rdom[root_id].state.layout.node.unwrap();
|
||||
let root_node = rdom[0].state.layout.node.unwrap();
|
||||
|
||||
stretch
|
||||
.compute_layout(
|
||||
|
@ -165,7 +164,7 @@ fn render_vdom(
|
|||
terminal.draw(|frame| {
|
||||
// size is guaranteed to not change when rendering
|
||||
resize(frame.size(), &mut stretch.borrow_mut(), &rdom);
|
||||
let root = &rdom[rdom.root_id()];
|
||||
let root = &rdom[0];
|
||||
render::render_vnode(frame, &stretch.borrow(), &rdom, &root, cfg);
|
||||
})?;
|
||||
} else {
|
||||
|
|
|
@ -30,6 +30,7 @@ pub(crate) fn render_vnode(
|
|||
}
|
||||
|
||||
let Layout { location, size, .. } = layout.layout(node.state.layout.node.unwrap()).unwrap();
|
||||
// println!("rendering {node:?} {location:?} {size:?}");
|
||||
|
||||
let Point { x, y } = location;
|
||||
let Size { width, height } = size;
|
||||
|
|
|
@ -50,22 +50,22 @@ impl ParentDepState for StyleModifier {
|
|||
const NODE_MASK: NodeMask = NodeMask::new(AttributeMask::All, true, true, false);
|
||||
|
||||
fn reduce(&mut self, node: NodeView, parent: Option<&Self::DepState>, _: &Self::Ctx) -> bool {
|
||||
*self = StyleModifier::default();
|
||||
let mut new = StyleModifier::default();
|
||||
if parent.is_some() {
|
||||
self.style.fg = None;
|
||||
new.style.fg = None;
|
||||
}
|
||||
|
||||
// handle text modifier elements
|
||||
if node.namespace().is_none() {
|
||||
if let Some(tag) = node.tag() {
|
||||
match tag {
|
||||
"b" => apply_style_attributes("font-weight", "bold", self),
|
||||
"strong" => apply_style_attributes("font-weight", "bold", self),
|
||||
"u" => apply_style_attributes("text-decoration", "underline", self),
|
||||
"ins" => apply_style_attributes("text-decoration", "underline", self),
|
||||
"del" => apply_style_attributes("text-decoration", "line-through", self),
|
||||
"i" => apply_style_attributes("font-style", "italic", self),
|
||||
"em" => apply_style_attributes("font-style", "italic", self),
|
||||
"b" => apply_style_attributes("font-weight", "bold", &mut new),
|
||||
"strong" => apply_style_attributes("font-weight", "bold", &mut new),
|
||||
"u" => apply_style_attributes("text-decoration", "underline", &mut new),
|
||||
"ins" => apply_style_attributes("text-decoration", "underline", &mut new),
|
||||
"del" => apply_style_attributes("text-decoration", "line-through", &mut new),
|
||||
"i" => apply_style_attributes("font-style", "italic", &mut new),
|
||||
"em" => apply_style_attributes("font-style", "italic", &mut new),
|
||||
"mark" => {
|
||||
apply_style_attributes("background-color", "rgba(241, 231, 64, 50%)", self)
|
||||
}
|
||||
|
@ -76,16 +76,21 @@ impl ParentDepState for StyleModifier {
|
|||
|
||||
// gather up all the styles from the attribute list
|
||||
for &Attribute { name, value, .. } in node.attributes() {
|
||||
apply_style_attributes(name, value, self);
|
||||
apply_style_attributes(name, value, &mut new);
|
||||
}
|
||||
|
||||
// keep the text styling from the parent element
|
||||
if let Some(parent) = parent {
|
||||
let mut new_style = self.style.merge(parent.style);
|
||||
new_style.bg = self.style.bg;
|
||||
self.style = new_style;
|
||||
let mut new_style = new.style.merge(parent.style);
|
||||
new_style.bg = new.style.bg;
|
||||
new.style = new_style;
|
||||
}
|
||||
if &mut new != self {
|
||||
*self = new;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue