refactor interperting macro into function and don't rely on cx being in scope
This commit is contained in:
1 parent
0079f7d18b
commit
2bcaa2e43e
5 files changed
+64
-51
No files matched your search
@@ -189,44 +189,18 @@ pub fn rsx(s: TokenStream) -> TokenStream {
|
|||||||
use dioxus_rsx_interpreter::captuered_context::CapturedContextBuilder;
|
use dioxus_rsx_interpreter::captuered_context::CapturedContextBuilder;
|
||||||
|
|
||||||
match CapturedContextBuilder::from_call_body(body) {
|
match CapturedContextBuilder::from_call_body(body) {
|
||||||
Ok(captured) => {
|
Ok(captured) => quote::quote! {
|
||||||
quote::quote! {
|
{
|
||||||
{
|
LazyNodes::new(|__cx|{
|
||||||
let __line_num = get_line_num();
|
let captured = #captured;
|
||||||
let __rsx_text_index: RsxContext = cx.consume_context().expect("Hot reload is not avalable on this platform");
|
let line_num = get_line_num();
|
||||||
// only the insert the rsx text once
|
let text = #rsx_text;
|
||||||
if !__rsx_text_index.read().hm.contains_key(&__line_num){
|
|
||||||
__rsx_text_index.insert(
|
resolve_scope(line_num, text, captured, __cx)
|
||||||
__line_num.clone(),
|
})
|
||||||
#rsx_text.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
LazyNodes::new(move |__cx|{
|
|
||||||
if let Some(__text) = {
|
|
||||||
let read = __rsx_text_index.read();
|
|
||||||
// clone prevents deadlock on nested rsx calls
|
|
||||||
read.hm.get(&__line_num).cloned()
|
|
||||||
} {
|
|
||||||
match interpert_rsx(
|
|
||||||
__cx,
|
|
||||||
&__text,
|
|
||||||
#captured
|
|
||||||
){
|
|
||||||
Ok(vnode) => vnode,
|
|
||||||
Err(err) => {
|
|
||||||
__rsx_text_index.report_error(err);
|
|
||||||
__cx.text(format_args!(""))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
panic!("rsx: line number {:?} not found in rsx index", __line_num);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
.into(),
|
||||||
Err(err) => err.into_compile_error().into(),
|
Err(err) => err.into_compile_error().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ impl DesktopController {
|
|||||||
#[cfg(feature = "hot_reload")]
|
#[cfg(feature = "hot_reload")]
|
||||||
{
|
{
|
||||||
use dioxus_rsx_interpreter::{
|
use dioxus_rsx_interpreter::{
|
||||||
error::Error, ErrorHandler, RsxContext, RsxData, SetRsxMessage,
|
error::Error, ErrorHandler, RsxContext, RsxData, SetRsxMessage, RSX_CONTEXT,
|
||||||
};
|
};
|
||||||
use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
|
use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
|
||||||
use std::io::{BufRead, BufReader, Write};
|
use std::io::{BufRead, BufReader, Write};
|
||||||
@@ -93,14 +93,9 @@ impl DesktopController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = dom
|
RSX_CONTEXT.set_error_handler(DesktopErrorHandler {
|
||||||
.base_scope()
|
latest_connection: latest_connection_handle,
|
||||||
.provide_root_context(RsxContext::new(RsxData {
|
});
|
||||||
hm: HashMap::new(),
|
|
||||||
error_handler: Box::new(DesktopErrorHandler {
|
|
||||||
latest_connection: latest_connection_handle,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
if let Ok(listener) = LocalSocketListener::bind("@dioxus") {
|
if let Ok(listener) = LocalSocketListener::bind("@dioxus") {
|
||||||
@@ -124,7 +119,7 @@ impl DesktopController {
|
|||||||
let message: SetRsxMessage =
|
let message: SetRsxMessage =
|
||||||
serde_json::from_str(&buf).unwrap();
|
serde_json::from_str(&buf).unwrap();
|
||||||
println!("{:?}", message.location);
|
println!("{:?}", message.location);
|
||||||
context.insert(message.location, message.new_text);
|
RSX_CONTEXT.insert(message.location, message.new_text);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if err.kind() != std::io::ErrorKind::WouldBlock {
|
if err.kind() != std::io::ErrorKind::WouldBlock {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ syn = { version = "1.0", features = ["extra-traits"] }
|
|||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = { vesion = "1.0" }
|
serde_json = { vesion = "1.0" }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
dioxus-rsx = { path = "../rsx", default-features = false }
|
dioxus-rsx = { path = "../rsx", default-features = false }
|
||||||
dioxus-ssr = { path = "../ssr" }
|
dioxus-ssr = { path = "../ssr" }
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use dioxus_core::{Component, Element, LazyNodes, Scope, VNode};
|
use captuered_context::CapturedContext;
|
||||||
|
use dioxus_core::{Component, Element, LazyNodes, NodeFactory, Scope, ScopeState, VNode};
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use interperter::build;
|
use interperter::build;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::panic::Location;
|
use std::panic::Location;
|
||||||
@@ -13,6 +15,12 @@ mod elements;
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
mod interperter;
|
mod interperter;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// This a a global store of the current
|
||||||
|
// Global mutable data is genrally not great, but it allows users to not worry about passing down the text RsxContex every time they switch to hot reloading.
|
||||||
|
pub static ref RSX_CONTEXT: RsxContext = RsxContext::new(RsxData::default());
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct CodeLocation {
|
pub struct CodeLocation {
|
||||||
pub file: String,
|
pub file: String,
|
||||||
@@ -20,6 +28,34 @@ pub struct CodeLocation {
|
|||||||
pub column: u32,
|
pub column: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve_scope<'a>(
|
||||||
|
location: CodeLocation,
|
||||||
|
rsx: &'static str,
|
||||||
|
captured: CapturedContext<'a>,
|
||||||
|
factory: NodeFactory<'a>,
|
||||||
|
) -> VNode<'a> {
|
||||||
|
let rsx_text_index = &*RSX_CONTEXT;
|
||||||
|
// only the insert the rsx text once
|
||||||
|
if !rsx_text_index.read().hm.contains_key(&location) {
|
||||||
|
rsx_text_index.insert(location.clone(), rsx.to_string());
|
||||||
|
}
|
||||||
|
if let Some(text) = {
|
||||||
|
let read = rsx_text_index.read();
|
||||||
|
// clone prevents deadlock on nested rsx calls
|
||||||
|
read.hm.get(&location).cloned()
|
||||||
|
} {
|
||||||
|
match interpert_rsx(factory, &text, captured) {
|
||||||
|
Ok(vnode) => vnode,
|
||||||
|
Err(err) => {
|
||||||
|
rsx_text_index.report_error(err);
|
||||||
|
factory.text(format_args!(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("rsx: line number {:?} not found in rsx index", location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn interpert_rsx<'a, 'b>(
|
pub fn interpert_rsx<'a, 'b>(
|
||||||
factory: dioxus_core::NodeFactory<'a>,
|
factory: dioxus_core::NodeFactory<'a>,
|
||||||
text: &str,
|
text: &str,
|
||||||
@@ -47,9 +83,10 @@ pub struct RsxContext {
|
|||||||
data: Arc<RwLock<RsxData>>,
|
data: Arc<RwLock<RsxData>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct RsxData {
|
pub struct RsxData {
|
||||||
pub hm: HashMap<CodeLocation, String>,
|
pub hm: HashMap<CodeLocation, String>,
|
||||||
pub error_handler: Box<dyn ErrorHandler + Send + Sync>,
|
pub error_handler: Option<Box<dyn ErrorHandler>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for RsxData {
|
impl std::fmt::Debug for RsxData {
|
||||||
@@ -74,11 +111,17 @@ impl RsxContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn report_error(&self, error: Error) {
|
pub fn report_error(&self, error: Error) {
|
||||||
self.data.write().unwrap().error_handler.handle_error(error)
|
if let Some(handler) = &self.data.write().unwrap().error_handler {
|
||||||
|
handler.handle_error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_error_handler(&self, handler: impl ErrorHandler + 'static) {
|
||||||
|
self.data.write().unwrap().error_handler = Some(Box::new(handler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ErrorHandler {
|
pub trait ErrorHandler: Send + Sync {
|
||||||
fn handle_error(&self, err: Error);
|
fn handle_error(&self, err: Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -65,6 +65,6 @@ pub mod prelude {
|
|||||||
#[cfg(feature = "hot_reload")]
|
#[cfg(feature = "hot_reload")]
|
||||||
pub use dioxus_rsx_interpreter::{
|
pub use dioxus_rsx_interpreter::{
|
||||||
captuered_context::{CapturedContext, FormattedArg, IfmtArgs},
|
captuered_context::{CapturedContext, FormattedArg, IfmtArgs},
|
||||||
get_line_num, interpert_rsx, CodeLocation, RsxContext,
|
get_line_num, interpert_rsx, resolve_scope, CodeLocation, RsxContext,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user