Merge branch 'upstream' into simplify-native-core

This commit is contained in:
Evan Almloff committed 2023-02-07 14:15:07 -06:00
commit a2236df773
13 files changed
+69 -26

No files matched your search

+2 -1
View File
@@ -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"] }
+1 -1
View File
@@ -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
View File
@@ -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!"
}
}) })
} }
+3
View File
@@ -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();
+21
View File
@@ -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.
+4 -4
View File
@@ -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
+4 -3
View File
@@ -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);
} }
})) }))
}; };
+2
View File
@@ -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,
+1
View File
@@ -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() {
+1 -1
View File
@@ -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 !== "") {
+11 -10
View File
@@ -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
View File
@@ -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) => {