Merge branch 'upstream' into return-from-js

This commit is contained in:
Evan Almloff committed 2022-12-08 11:25:15 -06:00
commit bf47f64852
281 files changed
+16169 -19328

No files matched your search

+50 -38
View File
@@ -1,6 +1,8 @@
use crate::desktop_context::{DesktopContext, UserWindowEvent};
use crate::events::{decode_event, EventMessage};
use dioxus_core::*;
use futures_channel::mpsc::{unbounded, UnboundedSender};
use futures_util::StreamExt;
#[cfg(target_os = "ios")]
use objc::runtime::Object;
use serde_json::Value;
@@ -8,6 +10,7 @@ use std::{
collections::HashMap,
sync::Arc,
sync::{atomic::AtomicBool, Mutex},
time::Duration,
};
use wry::{
self,
@@ -17,11 +20,13 @@ use wry::{
pub(super) struct DesktopController {
pub(super) webviews: HashMap<WindowId, WebView>,
pub(super) sender: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
pub(super) eval_sender: tokio::sync::mpsc::UnboundedSender<Value>,
pub(super) pending_edits: Arc<Mutex<Vec<String>>>,
pub(super) quit_app_on_close: bool,
pub(super) is_ready: Arc<AtomicBool>,
pub(super) proxy: EventLoopProxy<UserWindowEvent>,
pub(super) event_tx: UnboundedSender<serde_json::Value>,
#[cfg(target_os = "ios")]
pub(super) views: Vec<*mut Object>,
}
@@ -35,66 +40,63 @@ impl DesktopController {
proxy: EventLoopProxy<UserWindowEvent>,
) -> Self {
let edit_queue = Arc::new(Mutex::new(Vec::new()));
let (sender, receiver) = futures_channel::mpsc::unbounded::<SchedulerMsg>();
let (event_tx, mut event_rx) = unbounded();
let proxy2 = proxy.clone();
let pending_edits = edit_queue.clone();
let return_sender = sender.clone();
let desktop_context_proxy = proxy.clone();
let (eval_sender, eval_reciever) = tokio::sync::mpsc::unbounded_channel::<Value>();
std::thread::spawn(move || {
// We create the runtime as multithreaded, so you can still "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
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
runtime.block_on(async move {
let mut dom =
VirtualDom::new_with_props_and_scheduler(root, props, (sender, receiver));
let window_context = DesktopContext::new(desktop_context_proxy, eval_reciever);
dom.base_scope().provide_context(window_context);
// allow other proccesses to send the new rsx text to the @dioxusin ipc channel and recieve erros on the @dioxusout channel
#[cfg(any(feature = "hot-reload", debug_assertions))]
crate::hot_reload::init(&dom);
let edits = dom.rebuild();
edit_queue
.lock()
.unwrap()
.push(serde_json::to_string(&edits.edits).unwrap());
// Make sure the window is ready for any new updates
proxy.send_event(UserWindowEvent::Update).unwrap();
let mut dom = VirtualDom::new_with_props(root, props)
.with_root_context(DesktopContext::new(desktop_context_proxy, eval_reciever));
{
let edits = dom.rebuild();
let mut queue = edit_queue.lock().unwrap();
queue.push(serde_json::to_string(&edits).unwrap());
proxy.send_event(UserWindowEvent::EditsReady).unwrap();
}
loop {
dom.wait_for_work().await;
let muts = dom.work_with_deadline(|| false);
for edit in muts {
edit_queue
.lock()
.unwrap()
.push(serde_json::to_string(&edit.edits).unwrap());
tokio::select! {
_ = dom.wait_for_work() => {}
Some(json_value) = event_rx.next() => {
if let Ok(value) = serde_json::from_value::<EventMessage>(json_value) {
let name = value.event.clone();
let el_id = ElementId(value.mounted_dom_id);
if let Some(evt) = decode_event(value) {
dom.handle_event(&name, evt, el_id, dioxus_html::events::event_bubbles(&name));
}
}
}
}
let _ = proxy.send_event(UserWindowEvent::Update);
let muts = dom
.render_with_deadline(tokio::time::sleep(Duration::from_millis(16)))
.await;
edit_queue.lock().unwrap().push(serde_json::to_string(&muts).unwrap());
let _ = proxy.send_event(UserWindowEvent::EditsReady);
}
})
});
Self {
pending_edits,
sender: return_sender,
eval_sender,
webviews: HashMap::new(),
is_ready: Arc::new(AtomicBool::new(false)),
quit_app_on_close: true,
proxy: proxy2,
event_tx,
#[cfg(target_os = "ios")]
views: vec![],
}
@@ -110,13 +112,23 @@ impl DesktopController {
pub(super) fn try_load_ready_webviews(&mut self) {
if self.is_ready.load(std::sync::atomic::Ordering::Relaxed) {
let mut queue = self.pending_edits.lock().unwrap();
let mut new_queue = Vec::new();
{
let mut queue = self.pending_edits.lock().unwrap();
std::mem::swap(&mut new_queue, &mut *queue);
}
let (_id, view) = self.webviews.iter_mut().next().unwrap();
for edit in queue.drain(..) {
for edit in new_queue.drain(..) {
view.evaluate_script(&format!("window.interpreter.handleEdits({})", edit))
.unwrap();
}
}
}
pub(crate) fn set_template(&self, _serialized_template: String) {
todo!("hot reloading currently WIP")
}
}