WIP: expose pipe for desktop
This commit is contained in:
1 parent
3b2ac82e8d
commit
0079f7d18b
7 files changed
+121
-93
No files matched your search
+1
-1
@@ -49,7 +49,7 @@ desktop = ["dioxus-desktop"]
|
|||||||
router = ["dioxus-router"]
|
router = ["dioxus-router"]
|
||||||
tui = ["dioxus-tui"]
|
tui = ["dioxus-tui"]
|
||||||
liveview = ["dioxus-liveview"]
|
liveview = ["dioxus-liveview"]
|
||||||
hot_reload = ["dioxus-core-macro/hot_reload", "dioxus-rsx-interpreter"]
|
hot_reload = ["dioxus-core-macro/hot_reload", "dioxus-rsx-interpreter", "dioxus-desktop?/hot_reload"]
|
||||||
native-core = ["dioxus-native-core", "dioxus-native-core-macro"]
|
native-core = ["dioxus-native-core", "dioxus-native-core-macro"]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-86
@@ -5,92 +5,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let rsx_code = use_state(&cx, || {
|
|
||||||
r##"div {
|
|
||||||
width: "100%",
|
|
||||||
height: "500px",
|
|
||||||
onclick: move |_| {
|
|
||||||
count.modify(|count| *count + 10);
|
|
||||||
},
|
|
||||||
|
|
||||||
p {
|
|
||||||
"High-Five counter: {count.to_string():?}",
|
|
||||||
}
|
|
||||||
|
|
||||||
div {
|
|
||||||
width: "{count}px",
|
|
||||||
height: "10px",
|
|
||||||
background_color: "red",
|
|
||||||
}
|
|
||||||
|
|
||||||
Comp {
|
|
||||||
color: "#083289"
|
|
||||||
}
|
|
||||||
|
|
||||||
Comp {
|
|
||||||
color: "green"
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
(0..10).map(|i| {
|
|
||||||
cx.render(rsx!{p {"{i}"}})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}"##
|
|
||||||
.to_string()
|
|
||||||
});
|
|
||||||
let submitted_rsx_code = use_state(&cx, || None);
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
display: "flex",
|
|
||||||
flex_direction: "row",
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
Editable{
|
|
||||||
current_code: submitted_rsx_code.get().clone(),
|
|
||||||
},
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
width: "50em",
|
|
||||||
height: "50em",
|
|
||||||
value: rsx_code,
|
|
||||||
oninput: move |evt| {
|
|
||||||
rsx_code.set(evt.value.clone());
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
height: "100%",
|
|
||||||
width: "10%",
|
|
||||||
onclick: move |_|{
|
|
||||||
submitted_rsx_code.set(Some(rsx_code.get().clone()));
|
|
||||||
},
|
|
||||||
"submit"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Props)]
|
|
||||||
struct EditableProps {
|
|
||||||
#[props(!optional)]
|
|
||||||
current_code: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn Editable(cx: Scope<EditableProps>) -> Element {
|
|
||||||
let count = use_state(&cx, || 170);
|
let count = use_state(&cx, || 170);
|
||||||
if let Some(code) = cx.props.current_code.as_ref() {
|
|
||||||
let rsx_index: RsxContext = cx.consume_context().unwrap();
|
|
||||||
rsx_index.insert(
|
|
||||||
CodeLocation {
|
|
||||||
file: r"examples\hot_reload.rs".to_string(),
|
|
||||||
line: 94,
|
|
||||||
column: 15,
|
|
||||||
},
|
|
||||||
code.clone(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@@ -98,7 +13,7 @@ fn Editable(cx: Scope<EditableProps>) -> Element {
|
|||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
count.modify(|count| *count + 10);
|
count.modify(|count| *count + 10);
|
||||||
},
|
},
|
||||||
|
p{"{__line_num:?}"}
|
||||||
p {
|
p {
|
||||||
"High-Five counter: {count.to_string():?}",
|
"High-Five counter: {count.to_string():?}",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ pub fn rsx(s: TokenStream) -> TokenStream {
|
|||||||
Ok(body) => {
|
Ok(body) => {
|
||||||
#[cfg(feature = "hot_reload")]
|
#[cfg(feature = "hot_reload")]
|
||||||
{
|
{
|
||||||
use dioxus_rsx_interperter::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) => {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
|
|||||||
dioxus-core = { path = "../core", version = "^0.2.1", features = ["serialize"] }
|
dioxus-core = { path = "../core", version = "^0.2.1", features = ["serialize"] }
|
||||||
dioxus-html = { path = "../html", features = ["serialize"], version = "^0.2.1" }
|
dioxus-html = { path = "../html", features = ["serialize"], version = "^0.2.1" }
|
||||||
dioxus-interpreter-js = { path = "../interpreter", version = "^0.2.1" }
|
dioxus-interpreter-js = { path = "../interpreter", version = "^0.2.1" }
|
||||||
|
dioxus-rsx-interpreter = { path = "../rsx_interpreter", optional = true }
|
||||||
|
|
||||||
serde = "1.0.136"
|
serde = "1.0.136"
|
||||||
serde_json = "1.0.79"
|
serde_json = "1.0.79"
|
||||||
@@ -32,6 +33,8 @@ webbrowser = "0.7.1"
|
|||||||
mime_guess = "2.0.3"
|
mime_guess = "2.0.3"
|
||||||
dunce = "1.0.2"
|
dunce = "1.0.2"
|
||||||
|
|
||||||
|
interprocess = { version = "1.1.1", optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
core-foundation = "0.9.3"
|
core-foundation = "0.9.3"
|
||||||
|
|
||||||
@@ -41,6 +44,7 @@ tokio_runtime = ["tokio"]
|
|||||||
fullscreen = ["wry/fullscreen"]
|
fullscreen = ["wry/fullscreen"]
|
||||||
transparent = ["wry/transparent"]
|
transparent = ["wry/transparent"]
|
||||||
tray = ["wry/tray"]
|
tray = ["wry/tray"]
|
||||||
|
hot_reload = ["dioxus-rsx-interpreter", "interprocess"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
dioxus-core-macro = { path = "../core-macro" }
|
dioxus-core-macro = { path = "../core-macro" }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::desktop_context::{DesktopContext, UserWindowEvent};
|
use crate::desktop_context::{DesktopContext, UserWindowEvent};
|
||||||
|
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
@@ -49,6 +50,96 @@ impl DesktopController {
|
|||||||
|
|
||||||
dom.base_scope().provide_context(window_context);
|
dom.base_scope().provide_context(window_context);
|
||||||
|
|
||||||
|
// allow other proccesses to send the new rsx text to the @dioxus ipc channel
|
||||||
|
#[cfg(feature = "hot_reload")]
|
||||||
|
{
|
||||||
|
use dioxus_rsx_interpreter::{
|
||||||
|
error::Error, ErrorHandler, RsxContext, RsxData, SetRsxMessage,
|
||||||
|
};
|
||||||
|
use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
|
||||||
|
use std::io::{BufRead, BufReader, Write};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
fn handle_error(
|
||||||
|
connection: std::io::Result<LocalSocketStream>,
|
||||||
|
) -> Option<LocalSocketStream> {
|
||||||
|
connection
|
||||||
|
.map_err(|error| eprintln!("Incoming connection failed: {}", error))
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
let latest_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
|
||||||
|
Arc::new(Mutex::new(None));
|
||||||
|
let latest_connection_handle = latest_connection.clone();
|
||||||
|
let latest_connection_handle2 = latest_connection.clone();
|
||||||
|
|
||||||
|
struct DesktopErrorHandler {
|
||||||
|
latest_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>>,
|
||||||
|
}
|
||||||
|
impl ErrorHandler for DesktopErrorHandler {
|
||||||
|
fn handle_error(&self, err: Error) {
|
||||||
|
println!("reporting err: {err:?}");
|
||||||
|
if let Some(conn) = &mut *self.latest_connection.lock().unwrap() {
|
||||||
|
if let Error::RecompileRequiredError(reason) = err {
|
||||||
|
conn.get_mut()
|
||||||
|
.write_all(
|
||||||
|
(serde_json::to_string(&reason).unwrap() + "\n")
|
||||||
|
.as_bytes(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
println!("sending error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let context = dom
|
||||||
|
.base_scope()
|
||||||
|
.provide_root_context(RsxContext::new(RsxData {
|
||||||
|
hm: HashMap::new(),
|
||||||
|
error_handler: Box::new(DesktopErrorHandler {
|
||||||
|
latest_connection: latest_connection_handle,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
if let Ok(listener) = LocalSocketListener::bind("@dioxus") {
|
||||||
|
for conn in listener.incoming().filter_map(handle_error) {
|
||||||
|
// conn.set_nonblocking(true);
|
||||||
|
println!("connected");
|
||||||
|
*latest_connection_handle2.lock().unwrap() =
|
||||||
|
Some(BufReader::new(conn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
loop {
|
||||||
|
if let Some(conn) = &mut *latest_connection.lock().unwrap() {
|
||||||
|
let mut buf = String::new();
|
||||||
|
println!("reading");
|
||||||
|
match conn.read_line(&mut buf) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("read");
|
||||||
|
let message: SetRsxMessage =
|
||||||
|
serde_json::from_str(&buf).unwrap();
|
||||||
|
println!("{:?}", message.location);
|
||||||
|
context.insert(message.location, message.new_text);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
if err.kind() != std::io::ErrorKind::WouldBlock {
|
||||||
|
println!("{err}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// give the error handler time to take the mutex
|
||||||
|
std::thread::sleep(Duration::from_millis(10));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let edits = dom.rebuild();
|
let edits = dom.rebuild();
|
||||||
|
|
||||||
edit_queue
|
edit_queue
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use dioxus_core::{Component, Element, LazyNodes, Scope, VNode};
|
use dioxus_core::{Component, Element, LazyNodes, Scope, VNode};
|
||||||
use dioxus_hooks::*;
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use interperter::build;
|
use interperter::build;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -11,7 +10,7 @@ use syn::parse_str;
|
|||||||
mod attributes;
|
mod attributes;
|
||||||
pub mod captuered_context;
|
pub mod captuered_context;
|
||||||
mod elements;
|
mod elements;
|
||||||
mod error;
|
pub mod error;
|
||||||
mod interperter;
|
mod interperter;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
@@ -50,7 +49,7 @@ pub struct RsxContext {
|
|||||||
|
|
||||||
pub struct RsxData {
|
pub struct RsxData {
|
||||||
pub hm: HashMap<CodeLocation, String>,
|
pub hm: HashMap<CodeLocation, String>,
|
||||||
error_handle: Box<dyn FnMut(Error)>,
|
pub error_handler: Box<dyn ErrorHandler + Send + Sync>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for RsxData {
|
impl std::fmt::Debug for RsxData {
|
||||||
@@ -60,6 +59,12 @@ impl std::fmt::Debug for RsxData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RsxContext {
|
impl RsxContext {
|
||||||
|
pub fn new(data: RsxData) -> Self {
|
||||||
|
Self {
|
||||||
|
data: Arc::new(RwLock::new(data)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert(&self, loc: CodeLocation, text: String) {
|
pub fn insert(&self, loc: CodeLocation, text: String) {
|
||||||
self.data.write().unwrap().hm.insert(loc, text);
|
self.data.write().unwrap().hm.insert(loc, text);
|
||||||
}
|
}
|
||||||
@@ -69,6 +74,16 @@ impl RsxContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn report_error(&self, error: Error) {
|
pub fn report_error(&self, error: Error) {
|
||||||
(self.data.write().unwrap().error_handle)(error)
|
self.data.write().unwrap().error_handler.handle_error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ErrorHandler {
|
||||||
|
fn handle_error(&self, err: Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct SetRsxMessage {
|
||||||
|
pub location: CodeLocation,
|
||||||
|
pub new_text: String,
|
||||||
|
}
|
||||||
+4
-1
@@ -46,6 +46,9 @@ pub mod events {
|
|||||||
|
|
||||||
pub use dioxus_rsx as rsx;
|
pub use dioxus_rsx as rsx;
|
||||||
|
|
||||||
|
#[cfg(feature = "hot_reload")]
|
||||||
|
pub use dioxus_rsx_interpreter as rsx_interpreter;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::hooks::*;
|
pub use crate::hooks::*;
|
||||||
pub use dioxus_core::prelude::*;
|
pub use dioxus_core::prelude::*;
|
||||||
@@ -60,7 +63,7 @@ pub mod prelude {
|
|||||||
pub use fermi::{use_atom_ref, use_init_atom_root, use_read, use_set, Atom, AtomRef};
|
pub use fermi::{use_atom_ref, use_init_atom_root, use_read, use_set, Atom, AtomRef};
|
||||||
|
|
||||||
#[cfg(feature = "hot_reload")]
|
#[cfg(feature = "hot_reload")]
|
||||||
pub use dioxus_rsx_interperter::{
|
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, CodeLocation, RsxContext,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user