chore: cleanup workspace
This commit is contained in:
1 parent
3bedcb93ca
commit
8f0bb5dc5b
54 files changed
+691
-1822
No files matched your search
@@ -0,0 +1,43 @@
|
||||
//! webview dom
|
||||
|
||||
use dioxus_core::{DomEdit, RealDom, RealDomNode, ScopeId};
|
||||
use DomEdit::*;
|
||||
|
||||
pub struct WebviewRegistry {}
|
||||
|
||||
impl WebviewRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WebviewDom<'bump> {
|
||||
pub edits: Vec<DomEdit<'bump>>,
|
||||
pub node_counter: u64,
|
||||
pub registry: WebviewRegistry,
|
||||
}
|
||||
impl WebviewDom<'_> {
|
||||
pub fn new(registry: WebviewRegistry) -> Self {
|
||||
Self {
|
||||
edits: Vec::new(),
|
||||
node_counter: 0,
|
||||
registry,
|
||||
}
|
||||
}
|
||||
|
||||
// Finish using the dom (for its edit list) and give back the node and event registry
|
||||
pub fn consume(self) -> WebviewRegistry {
|
||||
self.registry
|
||||
}
|
||||
}
|
||||
impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
|
||||
fn raw_node_as_any(&self) -> &mut dyn std::any::Any {
|
||||
todo!()
|
||||
// self.edits.push(PushRoot { root });
|
||||
}
|
||||
|
||||
fn request_available_node(&mut self) -> RealDomNode {
|
||||
self.node_counter += 1;
|
||||
RealDomNode::from_u64(self.node_counter)
|
||||
}
|
||||
}
|
||||
+216
-56
@@ -1,70 +1,230 @@
|
||||
use dioxus::virtual_dom::VirtualDom;
|
||||
pub use dioxus_core as dioxus;
|
||||
use dioxus_core::{events::EventTrigger, prelude::FC};
|
||||
use dioxus_core::*;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use wry::application::event::{Event, WindowEvent};
|
||||
use wry::application::event_loop::{ControlFlow, EventLoop};
|
||||
use wry::application::window::Fullscreen;
|
||||
use wry::application::{
|
||||
dpi::LogicalSize,
|
||||
event::StartCause,
|
||||
platform::ios::{ScreenEdge, WindowBuilderExtIOS, WindowExtIOS},
|
||||
};
|
||||
use wry::webview::WebViewBuilder;
|
||||
use wry::{
|
||||
application::window::{Window, WindowBuilder},
|
||||
webview::{RpcRequest, RpcResponse},
|
||||
};
|
||||
mod dom;
|
||||
use dom::*;
|
||||
|
||||
pub struct IosRenderer {
|
||||
internal_dom: VirtualDom,
|
||||
fn init_logging() {
|
||||
simple_logger::SimpleLogger::new().init().unwrap();
|
||||
}
|
||||
|
||||
impl IosRenderer {
|
||||
pub async fn run(&mut self) -> dioxus_core::error::Result<()> {
|
||||
let (sender, mut receiver) = async_channel::unbounded::<EventTrigger>();
|
||||
static HTML_CONTENT: &'static str = include_str!("./../../webview/src/index.html");
|
||||
|
||||
// let body_element = prepare_websys_dom();
|
||||
pub fn launch(root: FC<()>, builder: fn(WindowBuilder) -> WindowBuilder) -> anyhow::Result<()> {
|
||||
launch_with_props(root, (), builder)
|
||||
}
|
||||
pub fn launch_with_props<P: Properties + 'static>(
|
||||
root: FC<P>,
|
||||
props: P,
|
||||
builder: fn(WindowBuilder) -> WindowBuilder,
|
||||
) -> anyhow::Result<()> {
|
||||
WebviewRenderer::run(root, props, builder)
|
||||
}
|
||||
|
||||
let mut patch_machine = interpreter::PatchMachine::new(body_element.clone(), move |ev| {
|
||||
log::debug!("Event trigger! {:#?}", ev);
|
||||
let mut c = sender.clone();
|
||||
// wasm_bindgen_futures::spawn_local(async move {
|
||||
// c.send(ev).await.unwrap();
|
||||
// });
|
||||
});
|
||||
let root_node = body_element.first_child().unwrap();
|
||||
patch_machine.stack.push(root_node.clone());
|
||||
/// The `WebviewRenderer` provides a way of rendering a Dioxus Virtual DOM through a bridge to a Webview instance.
|
||||
/// Components used in WebviewRenderer instances can directly use system libraries, access the filesystem, and multithread with ease.
|
||||
pub struct WebviewRenderer<T> {
|
||||
/// The root component used to render the Webview
|
||||
root: FC<T>,
|
||||
}
|
||||
enum RpcEvent<'a> {
|
||||
Initialize {
|
||||
//
|
||||
edits: Vec<DomEdit<'a>>,
|
||||
},
|
||||
}
|
||||
|
||||
// todo: initialize the event registry properly on the root
|
||||
impl<T: Properties + 'static> WebviewRenderer<T> {
|
||||
pub fn run(
|
||||
root: FC<T>,
|
||||
props: T,
|
||||
user_builder: fn(WindowBuilder) -> WindowBuilder,
|
||||
) -> anyhow::Result<()> {
|
||||
Self::run_with_edits(root, props, user_builder, None)
|
||||
}
|
||||
|
||||
let edits = self.internal_dom.rebuild()?;
|
||||
log::debug!("Received edits: {:#?}", edits);
|
||||
edits.iter().for_each(|edit| {
|
||||
log::debug!("patching with {:?}", edit);
|
||||
patch_machine.handle_edit(edit);
|
||||
});
|
||||
pub fn run_with_edits(
|
||||
root: FC<T>,
|
||||
props: T,
|
||||
user_builder: fn(WindowBuilder) -> WindowBuilder,
|
||||
redits: Option<Vec<DomEdit<'static>>>,
|
||||
) -> anyhow::Result<()> {
|
||||
// pub fn run_with_edits(
|
||||
// root: FC<T>,
|
||||
// props: T,
|
||||
// user_builder: fn(WindowBuilder) -> WindowBuilder,
|
||||
// redits: Option<Vec<DomEdit<'static>>>,
|
||||
// ) -> anyhow::Result<()> {
|
||||
let mut weviews = HashMap::new();
|
||||
|
||||
patch_machine.reset();
|
||||
let root_node = body_element.first_child().unwrap();
|
||||
patch_machine.stack.push(root_node.clone());
|
||||
let vir = VirtualDom::new_with_props(root, props);
|
||||
|
||||
// log::debug!("patch stack size {:?}", patch_machine.stack);
|
||||
let vdom = Arc::new(RwLock::new(vir));
|
||||
|
||||
// Event loop waits for the receiver to finish up
|
||||
// TODO! Connect the sender to the virtual dom's suspense system
|
||||
// Suspense is basically an external event that can force renders to specific nodes
|
||||
while let Ok(event) = receiver.recv().await {
|
||||
log::debug!("Stack before entrance {:#?}", patch_machine.stack.top());
|
||||
// log::debug!("patch stack size before {:#?}", patch_machine.stack);
|
||||
// patch_machine.reset();
|
||||
// patch_machine.stack.push(root_node.clone());
|
||||
let edits = self.internal_dom.progress_with_event(event)?;
|
||||
log::debug!("Received edits: {:#?}", edits);
|
||||
let event_loop = EventLoop::new();
|
||||
event_loop.run(move |event, event_loop, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
for edit in &edits {
|
||||
log::debug!("edit stream {:?}", edit);
|
||||
// log::debug!("Stream stack {:#?}", patch_machine.stack.top());
|
||||
patch_machine.handle_edit(edit);
|
||||
match event {
|
||||
Event::NewEvents(StartCause::Init) => {
|
||||
println!("Init");
|
||||
|
||||
let window = user_builder(WindowBuilder::new())
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
let registry = Arc::new(RwLock::new(Some(WebviewRegistry::new())));
|
||||
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
let window_id = window.id();
|
||||
|
||||
let vdom = vdom.clone();
|
||||
let weview = WebViewBuilder::new(window)
|
||||
.unwrap()
|
||||
// .with_visible(false)
|
||||
// .with_transparent(true)
|
||||
.with_url(&format!("data:text/html,{}", HTML_CONTENT))
|
||||
.unwrap()
|
||||
.with_rpc_handler(move |_window: &Window, mut req: RpcRequest| {
|
||||
match req.method.as_str() {
|
||||
"initiate" => {
|
||||
// let edits = if let Some(edits) = &redits {
|
||||
// serde_json::to_value(edits).unwrap()
|
||||
// } else
|
||||
let edits = {
|
||||
let mut lock = vdom.write().unwrap();
|
||||
let mut reg_lock = registry.write().unwrap();
|
||||
|
||||
// Create the thin wrapper around the registry to collect the edits into
|
||||
let mut real =
|
||||
dom::WebviewDom::new(reg_lock.take().unwrap());
|
||||
|
||||
// Serialize the edit stream
|
||||
let edits = {
|
||||
let mut edits = Vec::new();
|
||||
lock.rebuild(&mut real, &mut edits).unwrap();
|
||||
serde_json::to_value(edits).unwrap()
|
||||
};
|
||||
|
||||
// Give back the registry into its slot
|
||||
*reg_lock = Some(real.consume());
|
||||
edits
|
||||
};
|
||||
|
||||
// Return the edits into the webview runtime
|
||||
Some(RpcResponse::new_result(req.id.take(), Some(edits)))
|
||||
}
|
||||
"user_event" => {
|
||||
let mut lock = vdom.write().unwrap();
|
||||
let mut reg_lock = registry.write().unwrap();
|
||||
|
||||
// Create the thin wrapper around the registry to collect the edits into
|
||||
let mut real = dom::WebviewDom::new(reg_lock.take().unwrap());
|
||||
|
||||
// Serialize the edit stream
|
||||
let edits = {
|
||||
let mut edits = Vec::new();
|
||||
lock.rebuild(&mut real, &mut edits).unwrap();
|
||||
serde_json::to_value(edits).unwrap()
|
||||
};
|
||||
|
||||
// Give back the registry into its slot
|
||||
*reg_lock = Some(real.consume());
|
||||
|
||||
// Return the edits into the webview runtime
|
||||
Some(RpcResponse::new_result(req.id.take(), Some(edits)))
|
||||
}
|
||||
_ => todo!("this message failed"),
|
||||
}
|
||||
})
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// let weview = WebViewBuilder::new(window)
|
||||
// .unwrap()
|
||||
// .with_url("https://tauri.studio")
|
||||
// .unwrap()
|
||||
// .build()
|
||||
// .unwrap();
|
||||
weviews.insert(window_id, weview);
|
||||
}
|
||||
Event::Resumed => {
|
||||
println!("applicationDidBecomeActive");
|
||||
}
|
||||
Event::Suspended => {
|
||||
println!("applicationWillResignActive");
|
||||
}
|
||||
Event::LoopDestroyed => {
|
||||
println!("applicationWillTerminate");
|
||||
}
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::Touch(touch),
|
||||
..
|
||||
} => {
|
||||
println!("touch on {:?} {:?}", window_id, touch);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// log::debug!("patch stack size after {:#?}", patch_machine.stack);
|
||||
patch_machine.reset();
|
||||
// our root node reference gets invalidated
|
||||
// not sure why
|
||||
// for now, just select the first child again.
|
||||
// eventually, we'll just make our own root element instead of using body
|
||||
// or just use body directly IDEK
|
||||
let root_node = body_element.first_child().unwrap();
|
||||
patch_machine.stack.push(root_node.clone());
|
||||
}
|
||||
|
||||
Ok(()) // should actually never return from this, should be an error, rustc just cant see it
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
init_logging();
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
let mut weviews = HashMap::new();
|
||||
|
||||
event_loop.run(move |event, event_loop, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::NewEvents(StartCause::Init) => {
|
||||
println!("Init");
|
||||
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
let window_id = window.id();
|
||||
|
||||
let weview = WebViewBuilder::new(window)
|
||||
.unwrap()
|
||||
.with_url("https://tauri.studio")
|
||||
.unwrap()
|
||||
.build()
|
||||
.unwrap();
|
||||
weviews.insert(window_id, weview);
|
||||
}
|
||||
Event::Resumed => {
|
||||
println!("applicationDidBecomeActive");
|
||||
}
|
||||
Event::Suspended => {
|
||||
println!("applicationWillResignActive");
|
||||
}
|
||||
Event::LoopDestroyed => {
|
||||
println!("applicationWillTerminate");
|
||||
}
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::Touch(touch),
|
||||
..
|
||||
} => {
|
||||
println!("touch on {:?} {:?}", window_id, touch);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use dioxus::virtual_dom::VirtualDom;
|
||||
pub use dioxus_core as dioxus;
|
||||
use dioxus_core::{events::EventTrigger, prelude::FC};
|
||||
|
||||
pub struct IosRenderer {
|
||||
internal_dom: VirtualDom,
|
||||
}
|
||||
|
||||
impl IosRenderer {
|
||||
pub async fn run(&mut self) -> dioxus_core::error::Result<()> {
|
||||
let (sender, mut receiver) = async_channel::unbounded::<EventTrigger>();
|
||||
|
||||
// let body_element = prepare_websys_dom();
|
||||
|
||||
let mut patch_machine = interpreter::PatchMachine::new(body_element.clone(), move |ev| {
|
||||
log::debug!("Event trigger! {:#?}", ev);
|
||||
let mut c = sender.clone();
|
||||
// wasm_bindgen_futures::spawn_local(async move {
|
||||
// c.send(ev).await.unwrap();
|
||||
// });
|
||||
});
|
||||
let root_node = body_element.first_child().unwrap();
|
||||
patch_machine.stack.push(root_node.clone());
|
||||
|
||||
// todo: initialize the event registry properly on the root
|
||||
|
||||
let edits = self.internal_dom.rebuild()?;
|
||||
log::debug!("Received edits: {:#?}", edits);
|
||||
edits.iter().for_each(|edit| {
|
||||
log::debug!("patching with {:?}", edit);
|
||||
patch_machine.handle_edit(edit);
|
||||
});
|
||||
|
||||
patch_machine.reset();
|
||||
let root_node = body_element.first_child().unwrap();
|
||||
patch_machine.stack.push(root_node.clone());
|
||||
|
||||
// log::debug!("patch stack size {:?}", patch_machine.stack);
|
||||
|
||||
// Event loop waits for the receiver to finish up
|
||||
// TODO! Connect the sender to the virtual dom's suspense system
|
||||
// Suspense is basically an external event that can force renders to specific nodes
|
||||
while let Ok(event) = receiver.recv().await {
|
||||
log::debug!("Stack before entrance {:#?}", patch_machine.stack.top());
|
||||
// log::debug!("patch stack size before {:#?}", patch_machine.stack);
|
||||
// patch_machine.reset();
|
||||
// patch_machine.stack.push(root_node.clone());
|
||||
let edits = self.internal_dom.progress_with_event(event)?;
|
||||
log::debug!("Received edits: {:#?}", edits);
|
||||
|
||||
for edit in &edits {
|
||||
log::debug!("edit stream {:?}", edit);
|
||||
// log::debug!("Stream stack {:#?}", patch_machine.stack.top());
|
||||
patch_machine.handle_edit(edit);
|
||||
}
|
||||
|
||||
// log::debug!("patch stack size after {:#?}", patch_machine.stack);
|
||||
patch_machine.reset();
|
||||
// our root node reference gets invalidated
|
||||
// not sure why
|
||||
// for now, just select the first child again.
|
||||
// eventually, we'll just make our own root element instead of using body
|
||||
// or just use body directly IDEK
|
||||
let root_node = body_element.first_child().unwrap();
|
||||
patch_machine.stack.push(root_node.clone());
|
||||
}
|
||||
|
||||
Ok(()) // should actually never return from this, should be an error, rustc just cant see it
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user