diff --git a/examples/hot_reload.rs b/examples/hot_reload.rs index 3e3df686f..e67204c09 100644 --- a/examples/hot_reload.rs +++ b/examples/hot_reload.rs @@ -34,6 +34,11 @@ fn app(cx: Scope) -> Element { Comp{ color: "green" } + { + (0..10).map(|i| { + cx.render(rsx!{p{"{i}"}}) + }) + } } }) } diff --git a/packages/core-macro/src/lib.rs b/packages/core-macro/src/lib.rs index e024be7f6..5bbb0d2e2 100644 --- a/packages/core-macro/src/lib.rs +++ b/packages/core-macro/src/lib.rs @@ -195,24 +195,26 @@ pub fn rsx(s: TokenStream) -> TokenStream { let line_num = get_line_num(); let rsx_text_index: RsxTextIndex = cx.consume_context().unwrap(); // only the insert the rsx text once - // todo: rsx could be conditionally rendered which would brake this - use_state(&cx, || { + if !rsx_text_index.read().contains_key(&line_num){ rsx_text_index.insert( line_num.clone(), #rsx_text.to_string(), ); - }); + } LazyNodes::new(move |__cx|{ - let read = rsx_text_index.read(); - if let Some(text) = read.get(&line_num){ + if let Some(text) = { + let read = rsx_text_index.read(); + // clone prevents deadlock on nested rsx calls + read.get(&line_num).cloned() + } { interpert_rsx( __cx, &text, #captured ) } - else{ - panic!("rsx: line number {:?} not found", line_num); + else { + panic!("rsx: line number {:?} not found in rsx index", line_num); } }) } diff --git a/packages/rsx_interperter/src/captuered_context.rs b/packages/rsx_interperter/src/captuered_context.rs index 0ba233396..a2a0930c3 100644 --- a/packages/rsx_interperter/src/captuered_context.rs +++ b/packages/rsx_interperter/src/captuered_context.rs @@ -9,7 +9,7 @@ pub struct CapturedContextBuilder { pub attributes: HashMap, pub text: Vec, pub components: Vec, - pub iterators: Vec, + pub iterators: Vec, pub captured_expressions: Vec, pub listeners: Vec, } @@ -70,7 +70,7 @@ impl CapturedContextBuilder { let formated: IfmtInput = syn::parse2(tokens).unwrap(); captured.text.push(formated); } - BodyNode::RawExpr(expr) => captured.iterators.push(expr), + BodyNode::RawExpr(_) => captured.iterators.push(node), BodyNode::Meta(_) => (), } captured @@ -93,9 +93,10 @@ impl ToTokens for CapturedContextBuilder { let compontents_str = components .iter() .map(|comp| comp.to_token_stream().to_string()); - let iterators_str = iterators - .iter() - .map(|expr| expr.to_token_stream().to_string()); + let iterators_str = iterators.iter().map(|node| match node { + BodyNode::RawExpr(expr) => expr.to_token_stream().to_string(), + _ => unreachable!(), + }); let captured: Vec<_> = attributes .iter() .map(|(_, fmt)| fmt.named_args.iter()) diff --git a/packages/rsx_interperter/src/interperter.rs b/packages/rsx_interperter/src/interperter.rs index 4f428eeff..a84ccb316 100644 --- a/packages/rsx_interperter/src/interperter.rs +++ b/packages/rsx_interperter/src/interperter.rs @@ -90,8 +90,8 @@ pub fn build<'a>( factory: &NodeFactory<'a>, ) -> VNode<'a> { let children_built = factory.bump().alloc(Vec::new()); - for (i, child) in rsx.roots.into_iter().enumerate() { - children_built.push(build_node(child, &mut ctx, factory, i.to_string().as_str())); + for child in rsx.roots { + children_built.push(build_node(child, &mut ctx, factory)); } factory.fragment_from_iter(children_built.iter()) } @@ -100,7 +100,6 @@ fn build_node<'a>( node: BodyNode, ctx: &mut CapturedContext<'a>, factory: &NodeFactory<'a>, - key: &str, ) -> Option> { let bump = factory.bump(); match node { @@ -173,8 +172,8 @@ fn build_node<'a>( }; } let children = bump.alloc(Vec::new()); - for (i, child) in el.children.into_iter().enumerate() { - let node = build_node(child, ctx, factory, i.to_string().as_str()); + for child in el.children { + let node = build_node(child, ctx, factory); if let Some(node) = node { children.push(node); } @@ -229,7 +228,22 @@ fn build_node<'a>( panic!("could not resolve component {:?}", comp.name); } } - BodyNode::RawExpr(_) => todo!(), + BodyNode::RawExpr(iterator) => { + if let Some(idx) = ctx + .iterators + .iter() + .position(|(code, _)| parse_str::(*code).unwrap() == iterator) + { + let (_, vnode) = ctx.iterators.remove(idx); + Some(vnode) + } else { + panic!( + "could not resolve iterator {} \n fron {:?}", + iterator.to_token_stream(), + ctx.iterators.iter().map(|(s, _)| s).collect::>() + ); + } + } BodyNode::Meta(_) => todo!(), } }