WIP macro progress
This commit is contained in:
1 parent
92f48169e9
commit
9e9fc09e6d
3 files changed
+165
-64
No files matched your search
@@ -36,6 +36,7 @@ fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||||||
};
|
};
|
||||||
let strct = Struct::parse(&fields);
|
let strct = Struct::parse(&fields);
|
||||||
let state_strct = StateStruct::parse(&fields, &strct);
|
let state_strct = StateStruct::parse(&fields, &strct);
|
||||||
|
|
||||||
let node_dep_state_fields = quote::__private::TokenStream::from_iter(
|
let node_dep_state_fields = quote::__private::TokenStream::from_iter(
|
||||||
state_strct
|
state_strct
|
||||||
.state_members
|
.state_members
|
||||||
@@ -86,67 +87,77 @@ fn impl_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||||||
.state_members
|
.state_members
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| f.dep_kind == DepKind::NodeDepState)
|
.filter(|f| f.dep_kind == DepKind::NodeDepState)
|
||||||
.map(|f| f.type_id());
|
.map(|f| &f.mem.ty);
|
||||||
let child_types = state_strct
|
let child_types = state_strct
|
||||||
.state_members
|
.state_members
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| f.dep_kind == DepKind::ChildDepState)
|
.filter(|f| f.dep_kind == DepKind::ChildDepState)
|
||||||
.map(|f| f.type_id());
|
.map(|f| &f.mem.ty);
|
||||||
let parent_types = state_strct
|
let parent_types = state_strct
|
||||||
.state_members
|
.state_members
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| f.dep_kind == DepKind::ParentDepState)
|
.filter(|f| f.dep_kind == DepKind::ParentDepState)
|
||||||
.map(|f| f.type_id());
|
.map(|f| &f.mem.ty);
|
||||||
|
|
||||||
let type_name_str = type_name.to_string();
|
let type_name_str = type_name.to_string();
|
||||||
|
|
||||||
let gen = quote! {
|
let gen = quote! {
|
||||||
impl State for #type_name{
|
impl State for #type_name{
|
||||||
fn update_node_dep_state(&mut self, ty: std::any::TypeId, node: dioxus_native_core::real_dom_new_api::NodeRef, ctx: &anymap::AnyMap){
|
fn update_node_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VElement<'a>, ctx: &anymap::AnyMap) -> bool{
|
||||||
use dioxus_native_core::real_dom_new_api::NodeDepState;
|
use dioxus_native_core::real_dom_new_api::NodeDepState;
|
||||||
if false {}
|
if false {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
#node_dep_state_fields
|
#node_dep_state_fields
|
||||||
else{
|
else{
|
||||||
panic!("{:?} not in {}", ty, #type_name_str);
|
panic!("{:?} not in {}", ty, #type_name_str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_parent_dep_state(&mut self, ty: std::any::TypeId, node: dioxus_native_core::real_dom_new_api::NodeRef, parent: &Self, ctx: &anymap::AnyMap){
|
fn update_parent_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VElement<'a>, parent: &Self, ctx: &anymap::AnyMap) -> bool{
|
||||||
use dioxus_native_core::real_dom_new_api::ParentDepState;
|
use dioxus_native_core::real_dom_new_api::ParentDepState;
|
||||||
if false {}
|
if false {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
#parent_dep_state_fields
|
#parent_dep_state_fields
|
||||||
else{
|
else{
|
||||||
panic!("{:?} not in {}", ty, #type_name_str);
|
panic!("{:?} not in {}", ty, #type_name_str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_child_dep_state(&mut self, ty: std::any::TypeId, node: dioxus_native_core::real_dom_new_api::NodeRef, children: Vec<&Self>, ctx: &anymap::AnyMap){
|
fn update_child_dep_state<'a>(&'a mut self, ty: std::any::TypeId, node: &'a dioxus_core::VElement<'a>, children: Vec<&Self>, ctx: &anymap::AnyMap) -> bool{
|
||||||
use dioxus_native_core::real_dom_new_api::ChildDepState;
|
use dioxus_native_core::real_dom_new_api::ChildDepState;
|
||||||
if false {}
|
if false {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
#child_dep_state_fields
|
#child_dep_state_fields
|
||||||
else{
|
else{
|
||||||
panic!("{:?} not in {}", ty, #type_name_str);
|
panic!("{:?} not in {}", ty, #type_name_str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child_dep_types(&self) -> Vec<std::any::TypeId>{
|
fn child_dep_types(&self, mask: &dioxus_native_core::real_dom_new_api::NodeMask) -> Vec<std::any::TypeId>{
|
||||||
// todo: order should depend on order of dependencies
|
let mut dep_types = Vec::new();
|
||||||
vec![
|
#(if #child_types::NODE_MASK.overlaps(mask) {
|
||||||
#(#child_types,)*
|
dep_types.push(std::any::TypeId::of::<#child_types>());
|
||||||
]
|
})*
|
||||||
|
dep_types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent_dep_types(&self) -> Vec<std::any::TypeId>{
|
fn parent_dep_types(&self, mask: &dioxus_native_core::real_dom_new_api::NodeMask) -> Vec<std::any::TypeId>{
|
||||||
// todo: order should depend on order of dependencies
|
let mut dep_types = Vec::new();
|
||||||
vec![
|
#(if #parent_types::NODE_MASK.overlaps(mask) {
|
||||||
#(#parent_types,)*
|
dep_types.push(std::any::TypeId::of::<#parent_types>());
|
||||||
]
|
})*
|
||||||
|
dep_types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_dep_types(&self) -> Vec<std::any::TypeId>{
|
fn node_dep_types(&self, mask: &dioxus_native_core::real_dom_new_api::NodeMask) -> Vec<std::any::TypeId>{
|
||||||
vec![
|
let mut dep_types = Vec::new();
|
||||||
#(#node_types,)*
|
#(if #node_types::NODE_MASK.overlaps(mask) {
|
||||||
]
|
dep_types.push(std::any::TypeId::of::<#node_types>());
|
||||||
|
})*
|
||||||
|
dep_types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -176,6 +187,9 @@ impl<'a> StateStruct<'a> {
|
|||||||
.zip(fields.iter())
|
.zip(fields.iter())
|
||||||
.filter_map(|(m, f)| StateMember::parse(f, m, &strct))
|
.filter_map(|(m, f)| StateMember::parse(f, m, &strct))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// todo: sort members
|
||||||
|
|
||||||
Self { state_members }
|
Self { state_members }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,28 +265,30 @@ impl<'a> StateMember<'a> {
|
|||||||
} else {
|
} else {
|
||||||
quote! {&()}
|
quote! {&()}
|
||||||
};
|
};
|
||||||
|
let ty = &self.mem.ty;
|
||||||
|
let node_view = quote!(NodeView::new(node, #ty::NODE_MASK));
|
||||||
if let Some(dep_ident) = &self.dep_mem.map(|m| &m.ident) {
|
if let Some(dep_ident) = &self.dep_mem.map(|m| &m.ident) {
|
||||||
match self.dep_kind {
|
match self.dep_kind {
|
||||||
DepKind::NodeDepState => {
|
DepKind::NodeDepState => {
|
||||||
quote!(self.#ident.reduce(node, #get_ctx);)
|
quote!(self.#ident.reduce(#node_view, #get_ctx))
|
||||||
}
|
}
|
||||||
DepKind::ChildDepState => {
|
DepKind::ChildDepState => {
|
||||||
quote!(self.#ident.reduce(node, children.iter().map(|s| &s.#dep_ident).collect(), #get_ctx);)
|
quote!(self.#ident.reduce(#node_view, children.iter().map(|s| &s.#dep_ident).collect(), #get_ctx))
|
||||||
}
|
}
|
||||||
DepKind::ParentDepState => {
|
DepKind::ParentDepState => {
|
||||||
quote!(self.#ident.reduce(node, &parent.#dep_ident, #get_ctx);)
|
quote!(self.#ident.reduce(#node_view, &parent.#dep_ident, #get_ctx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match self.dep_kind {
|
match self.dep_kind {
|
||||||
DepKind::NodeDepState => {
|
DepKind::NodeDepState => {
|
||||||
quote!(self.#ident.reduce(node, #get_ctx);)
|
quote!(self.#ident.reduce(#node_view, #get_ctx))
|
||||||
}
|
}
|
||||||
DepKind::ChildDepState => {
|
DepKind::ChildDepState => {
|
||||||
quote!(self.#ident.reduce(node, &(), #get_ctx);)
|
quote!(self.#ident.reduce(#node_view, &(), #get_ctx))
|
||||||
}
|
}
|
||||||
DepKind::ParentDepState => {
|
DepKind::ParentDepState => {
|
||||||
quote!(self.#ident.reduce(node, &(), #get_ctx);)
|
quote!(self.#ident.reduce(#node_view, &(), #get_ctx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,56 +3,141 @@ use std::any::TypeId;
|
|||||||
use anymap::AnyMap;
|
use anymap::AnyMap;
|
||||||
use dioxus_core::{Attribute, VElement};
|
use dioxus_core::{Attribute, VElement};
|
||||||
|
|
||||||
#[repr(transparent)]
|
pub struct NodeView<'a> {
|
||||||
pub struct NodeRef<'a>(&'a VElement<'a>);
|
inner: &'a VElement<'a>,
|
||||||
impl<'a> NodeRef<'a> {
|
view: NodeMask,
|
||||||
pub fn new(velement: &'a VElement<'a>) -> Self {
|
}
|
||||||
Self(velement)
|
impl<'a> NodeView<'a> {
|
||||||
|
pub fn new(velement: &'a VElement<'a>, view: NodeMask) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: velement,
|
||||||
|
view: view,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tag(&self) -> &'a str {
|
pub fn tag(&self) -> Option<&'a str> {
|
||||||
self.0.tag
|
if self.view.tag {
|
||||||
|
Some(self.inner.tag)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn namespace(&self) -> Option<&'a str> {
|
pub fn namespace(&self) -> Option<&'a str> {
|
||||||
self.0.namespace
|
if self.view.namespace {
|
||||||
|
self.inner.namespace
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributes(&self) -> &'a [Attribute<'a>] {
|
pub fn attributes(&self) -> impl Iterator<Item = &Attribute<'a>> {
|
||||||
self.0.attributes
|
self.inner
|
||||||
|
.attributes
|
||||||
|
.iter()
|
||||||
|
.filter(|a| self.view.attritutes.contains(&a.name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ChildDepState: PartialEq {
|
#[derive(Default)]
|
||||||
|
pub struct NodeMask {
|
||||||
|
// must be sorted
|
||||||
|
attritutes: &'static [&'static str],
|
||||||
|
tag: bool,
|
||||||
|
namespace: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NodeMask {
|
||||||
|
/// attritutes must be sorted!
|
||||||
|
pub const fn new(attritutes: &'static [&'static str], tag: bool, namespace: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
attritutes,
|
||||||
|
tag,
|
||||||
|
namespace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verify(&self) {
|
||||||
|
debug_assert!(
|
||||||
|
self.attritutes.windows(2).all(|w| w[0] < w[1]),
|
||||||
|
"attritutes must be increasing"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn overlaps(&self, other: &Self) -> bool {
|
||||||
|
(self.tag && other.tag)
|
||||||
|
|| (self.namespace && other.namespace)
|
||||||
|
|| self.attritutes_overlap(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attritutes_overlap(&self, other: &Self) -> bool {
|
||||||
|
let mut self_attrs = self.attritutes.iter();
|
||||||
|
let mut other_attrs = other.attritutes.iter();
|
||||||
|
if let Some(mut other_attr) = other_attrs.next() {
|
||||||
|
while let Some(self_attr) = self_attrs.next() {
|
||||||
|
while other_attr < self_attr {
|
||||||
|
if let Some(attr) = other_attrs.next() {
|
||||||
|
other_attr = attr;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if other_attr == self_attr {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ChildDepState {
|
||||||
type Ctx;
|
type Ctx;
|
||||||
type DepState: ChildDepState;
|
type DepState: ChildDepState;
|
||||||
fn reduce(&mut self, node: NodeRef, children: Vec<&Self::DepState>, ctx: &Self::Ctx);
|
const NODE_MASK: NodeMask = NodeMask::new(&[], false, false);
|
||||||
|
fn reduce(&mut self, node: NodeView, children: Vec<&Self::DepState>, ctx: &Self::Ctx) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ParentDepState: PartialEq {
|
pub trait ParentDepState {
|
||||||
type Ctx;
|
type Ctx;
|
||||||
type DepState: ParentDepState;
|
type DepState: ParentDepState;
|
||||||
fn reduce(&mut self, node: NodeRef, parent: &Self::DepState, ctx: &Self::Ctx);
|
const NODE_MASK: NodeMask = NodeMask::new(&[], false, false);
|
||||||
|
fn reduce(&mut self, node: NodeView, parent: &Self::DepState, ctx: &Self::Ctx) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NodeDepState: PartialEq {
|
pub trait NodeDepState {
|
||||||
type Ctx;
|
type Ctx;
|
||||||
fn reduce(&mut self, node: NodeRef, ctx: &Self::Ctx);
|
const NODE_MASK: NodeMask = NodeMask::new(&[], false, false);
|
||||||
|
fn reduce(&mut self, node: NodeView, ctx: &Self::Ctx) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait State {
|
pub trait State {
|
||||||
fn update_node_dep_state(&mut self, ty: TypeId, node: NodeRef, ctx: &AnyMap);
|
fn update_node_dep_state<'a>(
|
||||||
fn child_dep_types(&self) -> Vec<TypeId>;
|
&'a mut self,
|
||||||
|
|
||||||
fn update_parent_dep_state(&mut self, ty: TypeId, node: NodeRef, parent: &Self, ctx: &AnyMap);
|
|
||||||
fn parent_dep_types(&self) -> Vec<TypeId>;
|
|
||||||
|
|
||||||
fn update_child_dep_state(
|
|
||||||
&mut self,
|
|
||||||
ty: TypeId,
|
ty: TypeId,
|
||||||
node: NodeRef,
|
node: &'a VElement<'a>,
|
||||||
|
ctx: &AnyMap,
|
||||||
|
) -> bool;
|
||||||
|
/// This must be a valid resolution order. (no nodes updated before a state they rely on)
|
||||||
|
fn child_dep_types(&self, mask: &NodeMask) -> Vec<TypeId>;
|
||||||
|
|
||||||
|
fn update_parent_dep_state<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
ty: TypeId,
|
||||||
|
node: &'a VElement<'a>,
|
||||||
|
parent: &Self,
|
||||||
|
ctx: &AnyMap,
|
||||||
|
) -> bool;
|
||||||
|
/// This must be a valid resolution order. (no nodes updated before a state they rely on)
|
||||||
|
fn parent_dep_types(&self, mask: &NodeMask) -> Vec<TypeId>;
|
||||||
|
|
||||||
|
fn update_child_dep_state<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
ty: TypeId,
|
||||||
|
node: &'a VElement<'a>,
|
||||||
children: Vec<&Self>,
|
children: Vec<&Self>,
|
||||||
ctx: &AnyMap,
|
ctx: &AnyMap,
|
||||||
);
|
) -> bool;
|
||||||
fn node_dep_types(&self) -> Vec<TypeId>;
|
/// This must be a valid resolution order. (no nodes updated before a state they rely on)
|
||||||
|
fn node_dep_types(&self, mask: &NodeMask) -> Vec<TypeId>;
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ use dioxus_native_core::real_dom_new_api::NodeDepState;
|
|||||||
struct A;
|
struct A;
|
||||||
impl NodeDepState for A {
|
impl NodeDepState for A {
|
||||||
type Ctx = ();
|
type Ctx = ();
|
||||||
fn reduce(&mut self, _: NodeRef, _: &()) {
|
fn reduce(&mut self, _: NodeView, _: &()) -> bool {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,10 +38,10 @@ impl ChildDepState for B {
|
|||||||
type DepState = Self;
|
type DepState = Self;
|
||||||
fn reduce(
|
fn reduce(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: dioxus_native_core::real_dom_new_api::NodeRef,
|
_: dioxus_native_core::real_dom_new_api::NodeView,
|
||||||
_: Vec<&Self::DepState>,
|
_: Vec<&Self::DepState>,
|
||||||
_: &i32,
|
_: &i32,
|
||||||
) {
|
) -> bool {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,10 +53,10 @@ impl ParentDepState for C {
|
|||||||
type DepState = Self;
|
type DepState = Self;
|
||||||
fn reduce(
|
fn reduce(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: dioxus_native_core::real_dom_new_api::NodeRef,
|
_: dioxus_native_core::real_dom_new_api::NodeView,
|
||||||
_: &Self::DepState,
|
_: &Self::DepState,
|
||||||
_: &u8,
|
_: &u8,
|
||||||
) {
|
) -> bool {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user