Merge branch 'upstream' into simplify-native-core
This commit is contained in:
commit
a2236df773
13 files changed
+69
-26
No files matched your search
@@ -4,6 +4,7 @@ version = "0.0.1"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Dioxus guide, including testable examples"
|
description = "Dioxus guide, including testable examples"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
|
publish = false
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
dioxus = { path = "../../packages/dioxus" }
|
dioxus = { path = "../../packages/dioxus" }
|
||||||
@@ -20,4 +21,4 @@ fermi = { path = "../../packages/fermi" }
|
|||||||
serde = { version = "1.0.138", features=["derive"] }
|
serde = { version = "1.0.138", features=["derive"] }
|
||||||
reqwest = { version = "0.11.11", features = ["json"] }
|
reqwest = { version = "0.11.11", features = ["json"] }
|
||||||
tokio = { version = "1.19.2" , features=[]}
|
tokio = { version = "1.19.2" , features=[]}
|
||||||
axum = { version = "0.6.1", features = ["ws"] }
|
axum = { version = "0.6.1", features = ["ws"] }
|
||||||
@@ -12,7 +12,7 @@ TUI support is currently quite experimental. But, if you're willing to venture i
|
|||||||
|
|
||||||
- It uses flexbox for the layout
|
- It uses flexbox for the layout
|
||||||
- It only supports a subset of the attributes and elements
|
- It only supports a subset of the attributes and elements
|
||||||
- Regular widgets will not work in the tui render, but the tui renderer has its own widget components that start with a capital letter. See the [widgets example](https://github.com/DioxusLabs/dioxus/blob/master/packages/tui/examples/tui_widgets.rs)
|
- Regular widgets will not work in the tui render, but the tui renderer has its own widget components that start with a capital letter. See the [widgets example](https://github.com/DioxusLabs/dioxus/blob/master/packages/tui/examples/widgets.rs)
|
||||||
- 1px is one character line height. Your regular CSS px does not translate
|
- 1px is one character line height. Your regular CSS px does not translate
|
||||||
- If your app panics, your terminal is wrecked. This will be fixed eventually
|
- If your app panics, your terminal is wrecked. This will be fixed eventually
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -6,6 +6,13 @@ fn main() {
|
|||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
button { "hello, desktop!" }
|
button {
|
||||||
|
onclick: |_| async move {
|
||||||
|
println!("hello, desktop!");
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
|
println!("goodbye, desktop!");
|
||||||
|
},
|
||||||
|
"hello, desktop!"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ use std::iter::Peekable;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use TemplateNode::*;
|
use TemplateNode::*;
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
fn sort_bfs(paths: &[&'static [u8]]) -> Vec<(usize, &'static [u8])> {
|
fn sort_bfs(paths: &[&'static [u8]]) -> Vec<(usize, &'static [u8])> {
|
||||||
let mut with_indecies = paths.iter().copied().enumerate().collect::<Vec<_>>();
|
let mut with_indecies = paths.iter().copied().enumerate().collect::<Vec<_>>();
|
||||||
with_indecies.sort_unstable_by(|(_, a), (_, b)| {
|
with_indecies.sort_unstable_by(|(_, a), (_, b)| {
|
||||||
@@ -386,6 +387,8 @@ impl<'b> VirtualDom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a new template into the VirtualDom's template registry
|
/// Insert a new template into the VirtualDom's template registry
|
||||||
|
// used in conditional compilation
|
||||||
|
#[allow(unused_mut)]
|
||||||
pub(crate) fn register_template(&mut self, mut template: Template<'static>) {
|
pub(crate) fn register_template(&mut self, mut template: Template<'static>) {
|
||||||
let (path, byte_index) = template.name.rsplit_once(':').unwrap();
|
let (path, byte_index) = template.name.rsplit_once(':').unwrap();
|
||||||
let byte_index = byte_index.parse::<usize>().unwrap();
|
let byte_index = byte_index.parse::<usize>().unwrap();
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ use std::{
|
|||||||
rc::Rc,
|
rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use futures_util::Future;
|
||||||
|
|
||||||
|
use crate::ScopeState;
|
||||||
|
|
||||||
/// A wrapper around some generic data that handles the event's state
|
/// A wrapper around some generic data that handles the event's state
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -106,6 +110,23 @@ impl<T: std::fmt::Debug> std::fmt::Debug for Event<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub trait EventReturn<P>: Sized {
|
||||||
|
fn spawn(self, _cx: &ScopeState) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventReturn<()> for () {}
|
||||||
|
|
||||||
|
pub struct AsyncMarker;
|
||||||
|
impl<T> EventReturn<AsyncMarker> for T
|
||||||
|
where
|
||||||
|
T: Future<Output = ()> + 'static,
|
||||||
|
{
|
||||||
|
fn spawn(self, cx: &ScopeState) {
|
||||||
|
cx.spawn(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The callback type generated by the `rsx!` macro when an `on` field is specified for components.
|
/// The callback type generated by the `rsx!` macro when an `on` field is specified for components.
|
||||||
///
|
///
|
||||||
/// This makes it possible to pass `move |evt| {}` style closures into components as property fields.
|
/// This makes it possible to pass `move |evt| {}` style closures into components as property fields.
|
||||||
|
|||||||
@@ -71,10 +71,10 @@ pub(crate) mod innerlude {
|
|||||||
|
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue, CapturedError,
|
fc_to_builder, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue, CapturedError,
|
||||||
Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode, LazyNodes, Mutation,
|
Component, DynamicNode, Element, ElementId, Event, EventReturn, Fragment, IntoDynNode,
|
||||||
Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, SuspenseContext,
|
LazyNodes, Mutation, Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped,
|
||||||
TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText,
|
SuspenseContext, TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode,
|
||||||
VirtualDom,
|
VPlaceholder, VText, VirtualDom,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The purpose of this module is to alleviate imports of many common types
|
/// The purpose of this module is to alleviate imports of many common types
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::{
|
|||||||
innerlude::{ErrorBoundary, Scheduler, SchedulerMsg},
|
innerlude::{ErrorBoundary, Scheduler, SchedulerMsg},
|
||||||
lazynodes::LazyNodes,
|
lazynodes::LazyNodes,
|
||||||
nodes::{ComponentReturn, IntoAttributeValue, IntoDynNode, RenderReturn},
|
nodes::{ComponentReturn, IntoAttributeValue, IntoDynNode, RenderReturn},
|
||||||
AnyValue, Attribute, AttributeValue, Element, Event, Properties, TaskId,
|
AnyValue, Attribute, AttributeValue, Element, Event, EventReturn, Properties, TaskId,
|
||||||
};
|
};
|
||||||
use bumpalo::{boxed::Box as BumpBox, Bump};
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
||||||
use bumpslab::{BumpSlab, Slot};
|
use bumpslab::{BumpSlab, Slot};
|
||||||
@@ -581,9 +581,9 @@ impl<'src> ScopeState {
|
|||||||
/// Create a new [`AttributeValue`] with the listener variant from a callback
|
/// Create a new [`AttributeValue`] with the listener variant from a callback
|
||||||
///
|
///
|
||||||
/// The callback must be confined to the lifetime of the ScopeState
|
/// The callback must be confined to the lifetime of the ScopeState
|
||||||
pub fn listener<T: 'static>(
|
pub fn listener<T: 'static, P, E: EventReturn<P>>(
|
||||||
&'src self,
|
&'src self,
|
||||||
mut callback: impl FnMut(Event<T>) + 'src,
|
mut callback: impl FnMut(Event<T>) -> E + 'src,
|
||||||
) -> AttributeValue<'src> {
|
) -> AttributeValue<'src> {
|
||||||
// safety: there's no other way to create a dynamicly-dispatched bump box other than alloc + from-raw
|
// safety: there's no other way to create a dynamicly-dispatched bump box other than alloc + from-raw
|
||||||
// This is the suggested way to build a bumpbox
|
// This is the suggested way to build a bumpbox
|
||||||
@@ -596,6 +596,7 @@ impl<'src> ScopeState {
|
|||||||
propagates: event.propagates,
|
propagates: event.propagates,
|
||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
|
.spawn(self);
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::Config;
|
|||||||
use crate::WebviewHandler;
|
use crate::WebviewHandler;
|
||||||
use dioxus_core::ScopeState;
|
use dioxus_core::ScopeState;
|
||||||
use dioxus_core::VirtualDom;
|
use dioxus_core::VirtualDom;
|
||||||
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
use dioxus_hot_reload::HotReloadMsg;
|
use dioxus_hot_reload::HotReloadMsg;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
@@ -285,6 +286,7 @@ pub enum EventData {
|
|||||||
|
|
||||||
Ipc(IpcMessage),
|
Ipc(IpcMessage),
|
||||||
|
|
||||||
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
HotReloadEvent(HotReloadMsg),
|
HotReloadEvent(HotReloadMsg),
|
||||||
|
|
||||||
NewWindow,
|
NewWindow,
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Event::UserEvent(event) => match event.0 {
|
Event::UserEvent(event) => match event.0 {
|
||||||
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
EventData::HotReloadEvent(msg) => match msg {
|
EventData::HotReloadEvent(msg) => match msg {
|
||||||
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
|
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
|
||||||
for webview in webviews.values_mut() {
|
for webview in webviews.values_mut() {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ macro_rules! impl_event {
|
|||||||
) => {
|
) => {
|
||||||
$(
|
$(
|
||||||
$( #[$attr] )*
|
$( #[$attr] )*
|
||||||
pub fn $name<'a>(_cx: &'a ::dioxus_core::ScopeState, _f: impl FnMut(::dioxus_core::Event<$data>) + 'a) -> ::dioxus_core::Attribute<'a> {
|
pub fn $name<'a, E: ::dioxus_core::EventReturn<T>, T>(_cx: &'a ::dioxus_core::ScopeState, _f: impl FnMut(::dioxus_core::Event<$data>) -> E + 'a) -> ::dioxus_core::Attribute<'a> {
|
||||||
::dioxus_core::Attribute {
|
::dioxus_core::Attribute {
|
||||||
name: stringify!($name),
|
name: stringify!($name),
|
||||||
value: _cx.listener(_f),
|
value: _cx.listener(_f),
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ mod js {
|
|||||||
}
|
}
|
||||||
fn remove_attribute(id: u32, field: &str<u8, attr>, ns: &str<u8, ns_cache>) {
|
fn remove_attribute(id: u32, field: &str<u8, attr>, ns: &str<u8, ns_cache>) {
|
||||||
r#"{name = $field$;
|
r#"{name = $field$;
|
||||||
node = this.nodes[$id$];
|
node = nodes[$id$];
|
||||||
if (ns == "style") {
|
if (ns == "style") {
|
||||||
node.style.removeProperty(name);
|
node.style.removeProperty(name);
|
||||||
} else if (ns !== null && ns !== undefined && ns !== "") {
|
} else if (ns !== null && ns !== undefined && ns !== "") {
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ where
|
|||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
let hot_reload_wait = hot_reload_rx.recv();
|
let hot_reload_wait = hot_reload_rx.recv();
|
||||||
#[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
#[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
||||||
let hot_reload_wait = std::future::pending();
|
let hot_reload_wait: std::future::Pending<Option<()>> = std::future::pending();
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
// poll any futures or suspense
|
// poll any futures or suspense
|
||||||
@@ -157,17 +157,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = hot_reload_wait => {
|
Some(msg) = hot_reload_wait => {
|
||||||
if let Some(msg) = msg {
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
match msg{
|
match msg{
|
||||||
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(new_template) => {
|
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(new_template) => {
|
||||||
vdom.replace_template(new_template);
|
vdom.replace_template(new_template);
|
||||||
}
|
|
||||||
dioxus_hot_reload::HotReloadMsg::Shutdown => {
|
|
||||||
std::process::exit(0);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
dioxus_hot_reload::HotReloadMsg::Shutdown => {
|
||||||
|
std::process::exit(0);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
#[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
||||||
|
let () = msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -20,7 +20,7 @@ use std::{rc::Rc, sync::RwLock};
|
|||||||
use style_attributes::StyleModifier;
|
use style_attributes::StyleModifier;
|
||||||
use taffy::Taffy;
|
use taffy::Taffy;
|
||||||
pub use taffy::{geometry::Point, prelude::*};
|
pub use taffy::{geometry::Point, prelude::*};
|
||||||
use tokio::{select, sync::mpsc::unbounded_channel};
|
use tokio::select;
|
||||||
use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
|
use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
@@ -118,7 +118,7 @@ pub fn render<R: Renderer<Rc<EventData>>>(
|
|||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
let mut hot_reload_rx = {
|
let mut hot_reload_rx = {
|
||||||
let (hot_reload_tx, hot_reload_rx) =
|
let (hot_reload_tx, hot_reload_rx) =
|
||||||
unbounded_channel::<dioxus_hot_reload::HotReloadMsg>();
|
tokio::sync::mpsc::unbounded_channel::<dioxus_hot_reload::HotReloadMsg>();
|
||||||
dioxus_hot_reload::connect(move |msg| {
|
dioxus_hot_reload::connect(move |msg| {
|
||||||
let _ = hot_reload_tx.send(msg);
|
let _ = hot_reload_tx.send(msg);
|
||||||
});
|
});
|
||||||
@@ -215,7 +215,7 @@ pub fn render<R: Renderer<Rc<EventData>>>(
|
|||||||
// #[cfg(all(feature = "hot-reload", debug_assertions))]
|
// #[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
// let hot_reload_wait = hot_reload_rx.recv();
|
// let hot_reload_wait = hot_reload_rx.recv();
|
||||||
// #[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
// #[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
||||||
// let hot_reload_wait = std::future::pending();
|
// let hot_reload_wait: std::future::Pending<Option<()>> = std::future::pending();
|
||||||
|
|
||||||
pin_mut!(wait);
|
pin_mut!(wait);
|
||||||
|
|
||||||
@@ -245,12 +245,18 @@ pub fn render<R: Renderer<Rc<EventData>>>(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Some(msg) = hot_reload_wait => {
|
// Some(msg) = hot_reload_wait => {
|
||||||
// hot_reload_msg = Some(msg);
|
// #[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
|
// {
|
||||||
|
// hot_reload_msg = Some(msg);
|
||||||
|
// }
|
||||||
|
// #[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
||||||
|
// let () = msg;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // if we have a new template, replace the old one
|
// // if we have a new template, replace the old one
|
||||||
|
// #[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
// if let Some(msg) = hot_reload_msg {
|
// if let Some(msg) = hot_reload_msg {
|
||||||
// match msg {
|
// match msg {
|
||||||
// dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
|
// dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
|
||||||
|
|||||||
Reference in new issue
Block a user