mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-27 06:30:20 +00:00
feat: get interpreter working on desktop
This commit is contained in:
parent
c86cbd69da
commit
58b0519c2f
3 changed files with 17 additions and 73 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::desktop_context::{DesktopContext, UserWindowEvent};
|
use crate::desktop_context::{DesktopContext, UserWindowEvent};
|
||||||
use crate::events::{decode_event, EventMessage};
|
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
|
use dioxus_html::HtmlEvent;
|
||||||
use futures_channel::mpsc::{unbounded, UnboundedSender};
|
use futures_channel::mpsc::{unbounded, UnboundedSender};
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
|
@ -50,6 +50,7 @@ impl DesktopController {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
// We create the runtime as multithreaded, so you can still "tokio::spawn" onto multiple threads
|
// We create the runtime as multithreaded, so you can still "tokio::spawn" onto multiple threads
|
||||||
// I'd personally not require tokio to be built-in to Dioxus-Desktop, but the DX is worse without it
|
// I'd personally not require tokio to be built-in to Dioxus-Desktop, but the DX is worse without it
|
||||||
|
|
||||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
|
@ -69,12 +70,14 @@ impl DesktopController {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = dom.wait_for_work() => {}
|
_ = dom.wait_for_work() => {}
|
||||||
Some(json_value) = event_rx.next() => {
|
Some(json_value) = event_rx.next() => {
|
||||||
if let Ok(value) = serde_json::from_value::<EventMessage>(json_value) {
|
if let Ok(value) = serde_json::from_value::<HtmlEvent>(json_value) {
|
||||||
let name = value.event.clone();
|
let HtmlEvent {
|
||||||
let el_id = ElementId(value.mounted_dom_id);
|
name,
|
||||||
if let Some(evt) = decode_event(value) {
|
element,
|
||||||
dom.handle_event(&name, evt, el_id, dioxus_html::events::event_bubbles(&name));
|
bubbles,
|
||||||
}
|
data
|
||||||
|
} = value;
|
||||||
|
dom.handle_event(&name, data.into_any(), element, bubbles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +86,10 @@ impl DesktopController {
|
||||||
.render_with_deadline(tokio::time::sleep(Duration::from_millis(16)))
|
.render_with_deadline(tokio::time::sleep(Duration::from_millis(16)))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
edit_queue.lock().unwrap().push(serde_json::to_string(&muts).unwrap());
|
edit_queue
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push(serde_json::to_string(&muts).unwrap());
|
||||||
let _ = proxy.send_event(UserWindowEvent::EditsReady);
|
let _ = proxy.send_event(UserWindowEvent::EditsReady);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
//! Convert a serialized event to an event trigger
|
//! Convert a serialized event to an event trigger
|
||||||
|
|
||||||
use dioxus_html::events::*;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::from_value;
|
|
||||||
use std::any::Any;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub(crate) struct IpcMessage {
|
pub(crate) struct IpcMessage {
|
||||||
|
@ -31,61 +27,3 @@ pub(crate) fn parse_ipc_message(payload: &str) -> Option<IpcMessage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! match_data {
|
|
||||||
(
|
|
||||||
$m:ident;
|
|
||||||
$name:ident;
|
|
||||||
$(
|
|
||||||
$tip:ty => $($mname:literal)|* ;
|
|
||||||
)*
|
|
||||||
) => {
|
|
||||||
match $name {
|
|
||||||
$( $($mname)|* => {
|
|
||||||
let val: $tip = from_value::<$tip>($m).ok()?;
|
|
||||||
Rc::new(val) as Rc<dyn Any>
|
|
||||||
})*
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct EventMessage {
|
|
||||||
pub contents: serde_json::Value,
|
|
||||||
pub event: String,
|
|
||||||
pub mounted_dom_id: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_event(value: EventMessage) -> Option<Rc<dyn Any>> {
|
|
||||||
let val = value.contents;
|
|
||||||
let name = value.event.as_str();
|
|
||||||
type DragData = MouseData;
|
|
||||||
|
|
||||||
let evt = match_data! { val; name;
|
|
||||||
MouseData => "click" | "contextmenu" | "dblclick" | "doubleclick" | "mousedown" | "mouseenter" | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup";
|
|
||||||
ClipboardData => "copy" | "cut" | "paste";
|
|
||||||
CompositionData => "compositionend" | "compositionstart" | "compositionupdate";
|
|
||||||
KeyboardData => "keydown" | "keypress" | "keyup";
|
|
||||||
FocusData => "blur" | "focus" | "focusin" | "focusout";
|
|
||||||
FormData => "change" | "input" | "invalid" | "reset" | "submit";
|
|
||||||
DragData => "drag" | "dragend" | "dragenter" | "dragexit" | "dragleave" | "dragover" | "dragstart" | "drop";
|
|
||||||
PointerData => "pointerlockchange" | "pointerlockerror" | "pointerdown" | "pointermove" | "pointerup" | "pointerover" | "pointerout" | "pointerenter" | "pointerleave" | "gotpointercapture" | "lostpointercapture";
|
|
||||||
SelectionData => "selectstart" | "selectionchange" | "select";
|
|
||||||
TouchData => "touchcancel" | "touchend" | "touchmove" | "touchstart";
|
|
||||||
ScrollData => "scroll";
|
|
||||||
WheelData => "wheel";
|
|
||||||
MediaData => "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied"
|
|
||||||
| "encrypted" | "ended" | "interruptbegin" | "interruptend" | "loadeddata"
|
|
||||||
| "loadedmetadata" | "loadstart" | "pause" | "play" | "playing" | "progress"
|
|
||||||
| "ratechange" | "seeked" | "seeking" | "stalled" | "suspend" | "timeupdate"
|
|
||||||
| "volumechange" | "waiting" | "error" | "load" | "loadend" | "timeout";
|
|
||||||
AnimationData => "animationstart" | "animationend" | "animationiteration";
|
|
||||||
TransitionData => "transitionend";
|
|
||||||
ToggleData => "toggle";
|
|
||||||
// ImageData => "load" | "error";
|
|
||||||
// OtherData => "abort" | "afterprint" | "beforeprint" | "beforeunload" | "hashchange" | "languagechange" | "message" | "offline" | "online" | "pagehide" | "pageshow" | "popstate" | "rejectionhandled" | "storage" | "unhandledrejection" | "unload" | "userproximity" | "vrdisplayactivate" | "vrdisplayblur" | "vrdisplayconnect" | "vrdisplaydeactivate" | "vrdisplaydisconnect" | "vrdisplayfocus" | "vrdisplaypointerrestricted" | "vrdisplaypointerunrestricted" | "vrdisplaypresentchange";
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(evt)
|
|
||||||
}
|
|
||||||
|
|
|
@ -430,9 +430,9 @@ class Interpreter {
|
||||||
}
|
}
|
||||||
window.ipc.postMessage(
|
window.ipc.postMessage(
|
||||||
serializeIpcMessage("user_event", {
|
serializeIpcMessage("user_event", {
|
||||||
event: edit.name,
|
name: edit.name,
|
||||||
mounted_dom_id: parseInt(realId),
|
element: parseInt(realId),
|
||||||
contents: contents,
|
data: contents,
|
||||||
bubbles,
|
bubbles,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue