Ver código fonte

Experiment with call syntax only working for copy types

Jonathan Kelley 1 ano atrás
pai
commit
33bba24867

+ 2 - 2
examples/calculator.rs

@@ -22,7 +22,7 @@ fn app() -> Element {
     let val = use_signal(|| String::from("0"));
 
     let input_digit = move |num: u8| {
-        if *val() == "0" {
+        if val.cloned() == "0" {
             val.set(String::new());
         }
 
@@ -94,7 +94,7 @@ fn app() -> Element {
                                     class: "calculator-key key-percent",
                                     onclick: move |_| {
                                         val.set(
-                                            format!("{}", calc_val(val().as_str()) / 100.0)
+                                            format!("{}", calc_val(val.cloned().as_str()) / 100.0)
                                         );
                                     },
                                     "%"

+ 2 - 2
examples/compose.rs

@@ -22,7 +22,7 @@ fn app() -> Element {
     let open_compose_window = move |evt: MouseEvent| {
         let tx = handle.tx();
         dioxus_desktop::window().new_window(
-            VirtualDom::new_with_props(compose, Rc::new(move |s| tx.unbounded_send(s))),
+            VirtualDom::new_with_props(compose, Rc::new(move |s| tx.unbounded_send(s).unwrap())),
             Default::default(),
         );
     };
@@ -50,7 +50,7 @@ fn compose(send: Rc<dyn Fn(String)>) -> Element {
 
             button {
                 onclick: move |_| {
-                    send(user_input.get().clone());
+                    send(user_input.cloned());
                     dioxus_desktop::window().close();
                 },
                 "Click to send"

+ 1 - 1
examples/control_focus.rs

@@ -12,7 +12,7 @@ fn app() -> Element {
 
     use_future(move || async move {
         let mut focused = 0;
-        if *running() {
+        if running() {
             loop {
                 tokio::time::sleep(std::time::Duration::from_millis(10)).await;
                 if let Some(element) = elements.with(|f| f.get(focused).cloned()) {

+ 1 - 1
examples/disabled.rs

@@ -11,7 +11,7 @@ fn app() -> Element {
         div {
             button { onclick: move |_| disabled.toggle(),
                 "click to "
-                if *disabled() { "enable" } else { "disable" }
+                if disabled() { "enable" } else { "disable" }
                 " the lower button"
             }
 

+ 3 - 1
examples/dog_app.rs

@@ -33,7 +33,9 @@ fn app() -> Element {
         Some(resp) => rsx! {
             h1 { "Select a dog breed!" }
             div { height: "500px", display: "flex",
-                ul { flex: "50%", {breed_list} }
+                ul { flex: "50%", {breed_list.value().cloned().unwrap_or_else(|| rsx! {
+                    "loading breeds..."
+                })} }
                 div { flex: "50%", BreedPic { breed } }
             }
         },

+ 0 - 28
examples/heavy_compute.rs

@@ -1,28 +0,0 @@
-//! This example shows that you can place heavy work on the main thread, and then
-//!
-//! You *should* be using `tokio::spawn_blocking` instead.
-//!
-//! Your app runs in an async runtime (Tokio), so you should avoid blocking
-//! the rendering of the VirtualDom.
-//!
-//!
-
-use dioxus::prelude::*;
-
-fn main() {
-    dioxus_desktop::launch(app);
-}
-
-fn app() -> Element {
-    // This is discouraged
-    std::thread::sleep(std::time::Duration::from_millis(2_000));
-
-    // This is suggested
-    tokio::task::spawn_blocking(move || {
-        std::thread::sleep(std::time::Duration::from_millis(2_000));
-    });
-
-    rsx! {
-        div { "Hello, world!" }
-    }
-}

+ 1 - 1
examples/login_form.rs

@@ -31,7 +31,7 @@ fn app() -> Element {
 
     rsx! {
         h1 { "Login" }
-        form { onsubmit: onsubmit,
+        form { onsubmit,
             input { r#type: "text", id: "username", name: "username" }
             label { "Username" }
             br {}

+ 1 - 1
examples/read_size.rs

@@ -45,7 +45,7 @@ fn app() -> Element {
             height: "50%",
             background_color: "red",
             onmounted: move |cx| div_element.set(Some(cx.inner().clone())),
-            "This element is {*dimensions():?}"
+            "This element is {dimensions():?}"
         }
 
         button {

+ 1 - 1
examples/scroll_to_top.rs

@@ -20,7 +20,7 @@ fn app() -> Element {
 
             button {
                 onclick: move |_| async move {
-                    if let Some(header) = header_element.read().as_ref().cloned() {
+                    if let Some(header) = header_element.cloned() {
                         let _ = header.scroll_to(ScrollBehavior::Smooth).await;
                     }
                 },

+ 3 - 3
examples/signals.rs

@@ -14,7 +14,7 @@ fn app() -> Element {
     // Signals are backed by a runtime that is designed to deeply integrate with Dioxus apps
     use_future(|| async move {
         loop {
-            if running.value() {
+            if running.cloned() {
                 count += 1;
             }
             tokio::time::sleep(Duration::from_millis(400)).await;
@@ -26,11 +26,11 @@ fn app() -> Element {
         button { onclick: move |_| count += 1, "Up high!" }
         button { onclick: move |_| count -= 1, "Down low!" }
         button { onclick: move |_| running.toggle(), "Toggle counter" }
-        button { onclick: move |_| saved_values.push(count.value().to_string()), "Save this value" }
+        button { onclick: move |_| saved_values.push(count.cloned().to_string()), "Save this value" }
         button { onclick: move |_| saved_values.write().clear(), "Clear saved values" }
 
         // We can do boolean operations on the current signal value
-        if count.value() > 5 {
+        if count() > 5 {
             h2 { "High five!" }
         }
 

+ 2 - 3
examples/spread.rs

@@ -1,8 +1,7 @@
-use dioxus::{dioxus_core::NoOpMutations, prelude::*};
+use dioxus::prelude::*;
 
 fn main() {
-    let mut dom = VirtualDom::new(app);
-    let _ = dom.rebuild(&mut NoOpMutations);
+    let mut dom = VirtualDom::prebuilt(app);
     let html = dioxus_ssr::render(&dom);
 
     println!("{}", html);

+ 2 - 3
examples/ssr.rs

@@ -2,12 +2,11 @@
 //!
 //! This example shows how we can render the Dioxus Virtualdom using SSR.
 
-use dioxus::{core::NoOpMutations, prelude::*};
+use dioxus::prelude::*;
 
 fn main() {
     // We can render VirtualDoms
-    let mut vdom = VirtualDom::new(app);
-    let _ = vdom.rebuild(&mut NoOpMutations);
+    let mut vdom = VirtualDom::prebuilt(app);
     println!("{}", dioxus_ssr::render(&vdom));
 
     // Or we can render rsx! calls themselves

+ 1 - 1
examples/svg.rs

@@ -31,7 +31,7 @@ fn Dice() -> Element {
     ];
 
     let value = use_signal(|| 5);
-    let active_dots = use_selector(move || &DOTS_FOR_VALUE[(*value() - 1) as usize]);
+    let active_dots = use_selector(move || &DOTS_FOR_VALUE[(value() - 1) as usize]);
 
     rsx! {
         svg {

+ 14 - 13
examples/todomvc.rs

@@ -26,12 +26,13 @@ pub fn app() -> Element {
     let filter = use_signal(|| FilterState::All);
 
     let active_todo_count =
-        use_selector(move || todos().values().filter(|item| !item.checked).count());
+        use_selector(move || todos.read().values().filter(|item| !item.checked).count());
 
     let filtered_todos = use_selector(move || {
-        let mut filtered_todos = todos()
+        let mut filtered_todos = todos
+            .read()
             .iter()
-            .filter(|(_, item)| match *filter() {
+            .filter(|(_, item)| match filter() {
                 FilterState::All => true,
                 FilterState::Active => !item.checked,
                 FilterState::Completed => item.checked,
@@ -49,7 +50,7 @@ pub fn app() -> Element {
             style { {include_str!("./assets/todomvc.css")} }
             TodoHeader { todos }
             section { class: "main",
-                if !todos().is_empty() {
+                if !todos.read().is_empty() {
                     input {
                         id: "toggle-all",
                         class: "toggle-all",
@@ -69,7 +70,7 @@ pub fn app() -> Element {
                         TodoEntry { key: "{id}", id, todos }
                     }
                 }
-                if !todos().is_empty() {
+                if !todos.read().is_empty() {
                     ListFooter { active_todo_count, todos, filter }
                 }
             }
@@ -84,8 +85,8 @@ pub fn TodoHeader(todos: Signal<HashMap<u32, TodoItem>>) -> Element {
     let mut todo_id = use_signal(|| 0);
 
     let onkeydown = move |evt: KeyboardEvent| {
-        if evt.key() == Key::Enter && !draft().is_empty() {
-            let id = *todo_id();
+        if evt.key() == Key::Enter && !draft.read().is_empty() {
+            let id = todo_id();
             let todo = TodoItem {
                 id,
                 checked: false,
@@ -115,11 +116,11 @@ pub fn TodoHeader(todos: Signal<HashMap<u32, TodoItem>>) -> Element {
 #[component]
 pub fn TodoEntry(todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
     let is_editing = use_signal(|| false);
-    let checked = use_selector(move || todos().get(&id).unwrap().checked);
-    let contents = use_selector(move || todos().get(&id).unwrap().contents.clone());
+    let checked = use_selector(move || todos.read().get(&id).unwrap().checked);
+    let contents = use_selector(move || todos.read().get(&id).unwrap().contents.clone());
 
     rsx! {
-        li { class: if *checked() { "completed" }, class: if *is_editing() { "editing"},
+        li { class: if checked() { "completed" }, class: if is_editing() { "editing"},
             div { class: "view",
                 input {
                     class: "toggle",
@@ -140,7 +141,7 @@ pub fn TodoEntry(todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
                     prevent_default: "onclick"
                 }
             }
-            if *is_editing() {
+            if is_editing() {
                 input {
                     class: "edit",
                     value: "{contents}",
@@ -165,7 +166,7 @@ pub fn ListFooter(
     active_todo_count: ReadOnlySignal<usize>,
     filter: Signal<FilterState>,
 ) -> Element {
-    let show_clear_completed = use_selector(move || todos().values().any(|todo| todo.checked));
+    let show_clear_completed = use_selector(move || todos.read().values().any(|todo| todo.checked));
 
     rsx! {
         footer { class: "footer",
@@ -188,7 +189,7 @@ pub fn ListFooter(
                     li {
                         a {
                             href: url,
-                            class: if *filter() == state { "selected" },
+                            class: if filter() == state { "selected" },
                             onclick: move |_| filter.set(state),
                             prevent_default: "onclick",
                             {state_text}

+ 4 - 4
examples/window_event.rs

@@ -34,8 +34,8 @@ fn app() -> Element {
                     class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0",
                     onmousedown: |evt| evt.stop_propagation(),
                     onclick: move |_| {
-                        window().set_fullscreen(!*fullscreen());
-                        window().set_resizable(*fullscreen());
+                        window().set_fullscreen(!fullscreen());
+                        window().set_resizable(fullscreen());
                         fullscreen.toggle();
                     },
                     "Fullscreen"
@@ -58,7 +58,7 @@ fn app() -> Element {
                         class: "inline-flex items-center text-white bg-green-500 border-0 py-1 px-3 hover:bg-green-700 rounded",
                         onmousedown: |evt| evt.stop_propagation(),
                         onclick: move |_| {
-                            window().set_always_on_top(!*always_on_top());
+                            window().set_always_on_top(!always_on_top());
                             always_on_top.toggle();
                         },
                         "Always On Top"
@@ -69,7 +69,7 @@ fn app() -> Element {
                         class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded",
                         onmousedown: |evt| evt.stop_propagation(),
                         onclick: move |_| {
-                            window().set_decorations(!*decorations());
+                            window().set_decorations(!decorations());
                             decorations.toggle();
                         },
                         "Set Decorations"

+ 1 - 1
examples/window_focus.rs

@@ -28,7 +28,7 @@ fn app() -> Element {
             display: "flex",
             flex_direction: "column",
             align_items: "center",
-            if *focused() {
+            if focused() {
                 "This window is focused!"
             } else {
                 "This window is not focused!"

+ 1 - 1
packages/signals/examples/dependancies.rs

@@ -19,7 +19,7 @@ fn app() -> Element {
 
     let local_state = use_signal(|| 0);
     let computed = use_selector_with_dependencies((local_state.get(),), move |(local_state,)| {
-        local_state * 2 + signal.value()
+        local_state * 2 + signal.cloned()
     });
     println!("Running app");
 

+ 11 - 8
packages/signals/src/signal.rs

@@ -330,7 +330,7 @@ impl<T: Clone + 'static> Signal<T> {
     /// Get the current value of the signal. This will subscribe the current scope to the signal.
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn value(&self) -> T {
+    pub fn cloned(&self) -> T {
         self.read().clone()
     }
 }
@@ -338,7 +338,7 @@ impl<T: Clone + 'static> Signal<T> {
 impl Signal<bool> {
     /// Invert the boolean value of the signal. This will trigger an update on all subscribers.
     pub fn toggle(&self) {
-        self.set(!self.value());
+        self.set(!self.cloned());
     }
 }
 
@@ -348,8 +348,8 @@ impl<T: 'static> PartialEq for Signal<T> {
     }
 }
 
-impl<T> Deref for Signal<T> {
-    type Target = dyn Fn() -> GenerationalRef<T>;
+impl<T: Copy> Deref for Signal<T> {
+    type Target = dyn Fn() -> T;
 
     fn deref(&self) -> &Self::Target {
         // https://github.com/dtolnay/case-studies/tree/master/callable-types
@@ -357,7 +357,10 @@ impl<T> Deref for Signal<T> {
         // First we create a closure that captures something with the Same in memory layout as Self (MaybeUninit<Self>).
         let uninit_callable = MaybeUninit::<Self>::uninit();
         // Then move that value into the closure. We assume that the closure now has a in memory layout of Self.
-        let uninit_closure = move || Self::read(unsafe { &*uninit_callable.as_ptr() });
+        let uninit_closure = move || {
+            let res = Self::read(unsafe { &*uninit_callable.as_ptr() });
+            res.clone()
+        };
 
         // Check that the size of the closure is the same as the size of Self in case the compiler changed the layout of the closure.
         let size_of_closure = std::mem::size_of_val(&uninit_closure);
@@ -483,8 +486,8 @@ impl<T: 'static> PartialEq for ReadOnlySignal<T> {
     }
 }
 
-impl<T> Deref for ReadOnlySignal<T> {
-    type Target = dyn Fn() -> GenerationalRef<T>;
+impl<T: Copy> Deref for ReadOnlySignal<T> {
+    type Target = dyn Fn() -> T;
 
     fn deref(&self) -> &Self::Target {
         // https://github.com/dtolnay/case-studies/tree/master/callable-types
@@ -492,7 +495,7 @@ impl<T> Deref for ReadOnlySignal<T> {
         // First we create a closure that captures something with the Same in memory layout as Self (MaybeUninit<Self>).
         let uninit_callable = MaybeUninit::<Self>::uninit();
         // Then move that value into the closure. We assume that the closure now has a in memory layout of Self.
-        let uninit_closure = move || Self::read(unsafe { &*uninit_callable.as_ptr() });
+        let uninit_closure = move || Self::read(unsafe { &*uninit_callable.as_ptr() }).clone();
 
         // Check that the size of the closure is the same as the size of Self in case the compiler changed the layout of the closure.
         let size_of_closure = std::mem::size_of_val(&uninit_closure);

+ 1 - 1
packages/signals/tests/selector.rs

@@ -29,7 +29,7 @@ fn memos_rerun() {
                 selector(move || {
                     counter.borrow_mut().effect += 1;
                     println!("Signal: {:?}", signal);
-                    signal.value()
+                    signal.cloned()
                 })
             });
             assert_eq!(memo.value(), 0);