wip: cut down on errors

This commit is contained in:
Jonathan Kelley committed 2021-07-13 16:48:11 -04:00
1 parent 996247a164
commit 775e9e29b8
6 files changed
+142 -198

No files matched your search

+19 -19
View File
@@ -20,14 +20,14 @@ dioxus-ssr = { path = "./packages/ssr", optional = true }
[features] [features]
default = [ default = [
"core", "core",
"atoms",
"macro", "macro",
"ssr",
"hooks", "hooks",
"router",
"html", "html",
"web", # "atoms",
"desktop", # "ssr",
# "router",
# "web",
# "desktop",
] ]
atoms = [] atoms = []
macro = ["dioxus-core-macro"] macro = ["dioxus-core-macro"]
@@ -43,17 +43,17 @@ core = []
[dev-dependencies] [dev-dependencies]
futures = "0.3.15" # futures = "0.3.15"
log = "0.4.14" # log = "0.4.14"
num-format = "0.4.0" # num-format = "0.4.0"
separator = "0.4.1" # separator = "0.4.1"
serde = { version = "1.0.126", features = ["derive"] } # serde = { version = "1.0.126", features = ["derive"] }
surf = "2.2.0" # surf = "2.2.0"
env_logger = "*" # env_logger = "*"
async-std = { version = "1.9.0", features = ["attributes"] } # async-std = { version = "1.9.0", features = ["attributes"] }
im-rc = "15.0.0" # im-rc = "15.0.0"
rand = { version = "0.8.4", features = ["small_rng"] } # rand = { version = "0.8.4", features = ["small_rng"] }
fxhash = "0.2.1" # fxhash = "0.2.1"
[workspace] [workspace]
@@ -62,9 +62,9 @@ members = [
"packages/core-macro", "packages/core-macro",
"packages/html", "packages/html",
"packages/hooks", "packages/hooks",
"packages/web", # "packages/web",
"packages/webview", # "packages/webview",
"packages/ssr", # "packages/ssr",
# "packages/atoms", # "packages/atoms",
# "packages/docsite", # "packages/docsite",
] ]
+12
View File
@@ -22,3 +22,15 @@ const App: FC<()> = |cx| {
todo!() todo!()
}; };
const Task: FC<()> = |cx| {
//
let s = cx.use_task(|| async { "hello world".to_string() });
todo!()
};
fn use_mut<P, T>(cx: Context<P>, f: impl FnOnce() -> T) -> &mut T {
todo!()
}
+92 -16
View File
@@ -2,9 +2,12 @@ use crate::hooklist::HookList;
use crate::{arena::SharedArena, innerlude::*}; use crate::{arena::SharedArena, innerlude::*};
use appendlist::AppendList; use appendlist::AppendList;
use bumpalo::Bump; use bumpalo::Bump;
use futures_util::{pin_mut, FutureExt};
use slotmap::DefaultKey; use slotmap::DefaultKey;
use slotmap::SlotMap; use slotmap::SlotMap;
use std::borrow::BorrowMut;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::{Arc, RwLock};
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
cell::{Cell, RefCell}, cell::{Cell, RefCell},
@@ -39,9 +42,9 @@ use std::{
pub struct Context<'src, T> { pub struct Context<'src, T> {
pub props: &'src T, pub props: &'src T,
pub scope: &'src Scope, pub scope: &'src Scope,
pub tasks: &'src RefCell<Vec<&'src mut PinnedTask>>, pub tasks: &'src RefCell<Vec<&'src mut dyn Future<Output = ()>>>,
} }
pub type PinnedTask = Pin<Box<dyn Future<Output = ()>>>; // pub type PinnedTask = Pin<Box<dyn Future<Output = ()>>>;
impl<'src, T> Copy for Context<'src, T> {} impl<'src, T> Copy for Context<'src, T> {}
impl<'src, T> Clone for Context<'src, T> { impl<'src, T> Clone for Context<'src, T> {
@@ -263,18 +266,6 @@ Any function prefixed with "use" should not be called conditionally.
) )
} }
pub fn suspend<Output: 'src, Fut: FnOnce(SuspendedContext, Output) -> VNode<'src> + 'src>(
&'src self,
fut: &'src mut Pin<Box<dyn Future<Output = Output> + 'static>>,
callback: Fut,
) -> VNode<'src> {
use futures_util::FutureExt;
match fut.now_or_never() {
Some(out) => callback(SuspendedContext {}, out),
None => NodeFactory::suspended(),
}
}
/// `submit_task` will submit the future to be polled. /// `submit_task` will submit the future to be polled.
/// ///
/// This is useful when you have some async task that needs to be progressed. /// This is useful when you have some async task that needs to be progressed.
@@ -289,11 +280,96 @@ Any function prefixed with "use" should not be called conditionally.
/// ///
/// ///
/// ///
pub fn submit_task(&self, task: &'src mut PinnedTask) -> TaskHandle { pub fn submit_task(&self, task: Pin<Box<dyn Future<Output = ()>>>) -> TaskHandle {
self.tasks.borrow_mut().push(task); // let r = task.then(|f| async {
// //
// });
// self.use_hook(|| Box::new(r), |_| {}, |_| {});
// *task = task.then(|f| async {
// //
// t
// // ()
// });
todo!();
// let new_fut = task.then(|f| async {
// //
// ()
// });
// self.tasks.borrow_mut().push(new_fut);
TaskHandle { _p: PhantomData {} } TaskHandle { _p: PhantomData {} }
} }
/// Awaits the given task, forcing the component to re-render when the value is ready.
///
///
pub fn use_task<Out, Fut: 'static>(
&self,
task_initializer: impl FnOnce() -> Fut + 'src,
) -> &mut Option<Out>
where
Out: 'static,
Fut: Future<Output = Out>,
{
struct TaskHook<T> {
task_dump: Rc<RefCell<Option<T>>>,
value: Option<T>,
}
// whenever the task is complete, save it into th
self.use_hook(
move || {
let task_fut = task_initializer();
let task_dump = Rc::new(RefCell::new(None));
let slot = task_dump.clone();
self.submit_task(Box::pin(task_fut.then(move |output| async move {
*slot.as_ref().borrow_mut() = Some(output);
})));
TaskHook {
task_dump,
value: None,
}
},
|hook| {
if let Some(val) = hook.task_dump.as_ref().borrow_mut().take() {
hook.value = Some(val);
}
&mut hook.value
},
|_| {},
)
}
/// Asynchronously render new nodes once the given future has completed.
///
///
///
///
/// # Easda
///
///
/// # Example
///
pub fn suspend<Out, Fut: 'static>(
&'src self,
task_initializer: impl FnOnce() -> Fut + 'src,
callback: impl FnOnce(SuspendedContext, Out) -> VNode<'src> + 'src,
) -> VNode<'src>
where
Out: 'src,
Fut: Future<Output = Out>,
{
todo!()
// use futures_util::FutureExt;
// match fut.now_or_never() {
// Some(out) => callback(SuspendedContext {}, out),
// None => NodeFactory::suspended(),
// }
}
} }
pub struct TaskHandle<'src> { pub struct TaskHandle<'src> {
+11 -14
View File
@@ -343,9 +343,8 @@ where
match &node.kind { match &node.kind {
VNodeKind::Text(text) => { VNodeKind::Text(text) => {
let real_id = self.dom.create_text_node(text.text); let real_id = self.dom.create_text_node(text.text);
todo!() node.dom_id.set(real_id);
// text.dom_id.set(real_id); CreateMeta::new(text.is_static, 1)
// CreateMeta::new(text.is_static, 1)
} }
VNodeKind::Element(el) => { VNodeKind::Element(el) => {
// we have the potential to completely eliminate working on this node in the future(!) // we have the potential to completely eliminate working on this node in the future(!)
@@ -371,7 +370,7 @@ where
} else { } else {
self.dom.create_element(tag_name, None) self.dom.create_element(tag_name, None)
}; };
// dom_id.set(real_id); node.dom_id.set(real_id);
listeners.iter().enumerate().for_each(|(idx, listener)| { listeners.iter().enumerate().for_each(|(idx, listener)| {
listener.mounted_node.set(real_id); listener.mounted_node.set(real_id);
@@ -397,12 +396,12 @@ where
// Notice: this is a web-specific optimization and may be changed in the future // Notice: this is a web-specific optimization and may be changed in the future
// //
// TODO move over // TODO move over
// if children.len() == 1 { if children.len() == 1 {
// if let VNodeKind::Text(text) = &children[0] { if let VNodeKind::Text(text) = &children[0].kind {
// self.dom.set_text(text.text); self.dom.set_text(text.text);
// return; return CreateMeta::new(is_static, 1);
// } }
// } }
for child in *children { for child in *children {
let child_meta = self.create(child); let child_meta = self.create(child);
@@ -499,9 +498,8 @@ where
} }
VNodeKind::Suspended => { VNodeKind::Suspended => {
todo!(); let id = self.dom.create_placeholder();
// let id = self.dom.create_placeholder(); node.dom_id.set(id);
// real.set(id);
CreateMeta::new(false, 1) CreateMeta::new(false, 1)
} }
} }
@@ -603,7 +601,6 @@ impl<'a, 'bump, Dom: RealDom<'bump>> DiffMachine<'a, 'bump, Dom> {
old: &'bump [Attribute<'bump>], old: &'bump [Attribute<'bump>],
new: &'bump [Attribute<'bump>], new: &'bump [Attribute<'bump>],
namespace: Option<&'bump str>, namespace: Option<&'bump str>,
// is_namespaced: bool,
) { ) {
// Do O(n^2) passes to add/update and remove attributes, since // Do O(n^2) passes to add/update and remove attributes, since
// there are almost always very few attributes. // there are almost always very few attributes.
+1 -1
View File
@@ -296,7 +296,7 @@ impl<'a> NodeFactory<'a> {
// submit any async tasks to the scope // submit any async tasks to the scope
for task in tasks.borrow_mut().drain(..) { for task in tasks.borrow_mut().drain(..) {
scp.submit_task(task); // scp.submit_task(task);
} }
let g2 = unsafe { std::mem::transmute(res) }; let g2 = unsafe { std::mem::transmute(res) };
+7 -148
View File
@@ -5,6 +5,10 @@ use std::sync::{Arc, RwLock};
use dioxus_core::*; use dioxus_core::*;
use wry::application::event::{Event, WindowEvent};
use wry::application::event_loop::{ControlFlow, EventLoop};
use wry::application::window::Fullscreen;
use wry::webview::WebViewBuilder;
use wry::{ use wry::{
application::window::{Window, WindowBuilder}, application::window::{Window, WindowBuilder},
webview::{RpcRequest, RpcResponse}, webview::{RpcRequest, RpcResponse},
@@ -57,15 +61,6 @@ impl<T: Properties + 'static> WebviewRenderer<T> {
user_builder: impl FnOnce(WindowBuilder) -> WindowBuilder, user_builder: impl FnOnce(WindowBuilder) -> WindowBuilder,
redits: Option<Vec<DomEdit<'static>>>, redits: Option<Vec<DomEdit<'static>>>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
use wry::{
application::{
event::{Event, StartCause, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
},
webview::WebViewBuilder,
};
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
let window = user_builder(WindowBuilder::new()).build(&event_loop)?; let window = user_builder(WindowBuilder::new()).build(&event_loop)?;
@@ -78,7 +73,7 @@ impl<T: Properties + 'static> WebviewRenderer<T> {
let webview = WebViewBuilder::new(window)? let webview = WebViewBuilder::new(window)?
.with_url(&format!("data:text/html,{}", HTML_CONTENT))? .with_url(&format!("data:text/html,{}", HTML_CONTENT))?
.with_rpc_handler(move |window: &Window, mut req: RpcRequest| { .with_rpc_handler(move |_window: &Window, mut req: RpcRequest| {
match req.method.as_str() { match req.method.as_str() {
"initiate" => { "initiate" => {
let edits = if let Some(edits) = &redits { let edits = if let Some(edits) = &redits {
@@ -144,45 +139,6 @@ impl<T: Properties + 'static> WebviewRenderer<T> {
} }
} }
}); });
// let mut view = web_view::builder()
// .invoke_handler(|view, arg| {
// let handle = view.handle();
// sender
// .send(InnerEvent::Initiate(handle))
// .expect("should not fail");
// Ok(())
// })
// .content(web_view::Content::Html(HTML_CONTENT))
// .user_data(())
// .title(title)
// .size(width, height)
// .resizable(resizable)
// .debug(debug)
// .frameless(frameless)
// .visible(visible)
// .min_size(min_width, min_height)
// .build()
// .unwrap();
// loop {
// view.step()
// .expect("should not fail")
// .expect("should not fail");
// std::thread::sleep(std::time::Duration::from_millis(15));
// if let Ok(event) = receiver.try_recv() {
// if let InnerEvent::Initiate(handle) = event {
// let editlist = ref_edits.clone();
// handle
// .dispatch(move |view| {
// let escaped = escape(&editlist);
// view.eval(&format!("EditListReceived({});", escaped))
// })
// .expect("Dispatch failed");
// }
// }
// }
} }
/// Create a new text-renderer instance from a functional component root. /// Create a new text-renderer instance from a functional component root.
@@ -200,12 +156,12 @@ impl<T: Properties + 'static> WebviewRenderer<T> {
} }
/// Pass new args to the root function /// Pass new args to the root function
pub fn update(&mut self, new_val: T) { pub fn update(&mut self, _new_val: T) {
todo!() todo!()
} }
/// Modify the root function in place, forcing a re-render regardless if the props changed /// Modify the root function in place, forcing a re-render regardless if the props changed
pub fn update_mut(&mut self, modifier: impl Fn(&mut T)) { pub fn update_mut(&mut self, _modifier: impl Fn(&mut T)) {
todo!() todo!()
} }
} }
@@ -221,15 +177,6 @@ struct MessageParameters {
} }
fn HANDLER(window: &Window, mut req: RpcRequest) -> Option<RpcResponse> { fn HANDLER(window: &Window, mut req: RpcRequest) -> Option<RpcResponse> {
use wry::{
application::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::{Fullscreen, Window, WindowBuilder},
},
webview::{RpcRequest, RpcResponse, WebViewBuilder},
};
let mut response = None; let mut response = None;
if &req.method == "fullscreen" { if &req.method == "fullscreen" {
if let Some(params) = req.params.take() { if let Some(params) = req.params.take() {
@@ -262,91 +209,3 @@ fn HANDLER(window: &Window, mut req: RpcRequest) -> Option<RpcResponse> {
response response
} }
pub struct DioxusWebviewBuilder<'a> {
pub(crate) title: &'a str,
pub(crate) width: i32,
pub(crate) height: i32,
pub(crate) resizable: bool,
pub(crate) debug: bool,
pub(crate) frameless: bool,
pub(crate) visible: bool,
pub(crate) min_width: i32,
pub(crate) min_height: i32,
}
impl<'a> DioxusWebviewBuilder<'a> {
fn new() -> Self {
#[cfg(debug_assertions)]
let debug = true;
#[cfg(not(debug_assertions))]
let debug = false;
DioxusWebviewBuilder {
title: "Application",
width: 800,
height: 600,
resizable: true,
debug,
frameless: false,
visible: true,
min_width: 300,
min_height: 300,
}
}
/// Sets the title of the WebView window.
///
/// Defaults to `"Application"`.
pub fn title(mut self, title: &'a str) -> Self {
self.title = title;
self
}
/// Sets the size of the WebView window.
///
/// Defaults to 800 x 600.
pub fn size(mut self, width: i32, height: i32) -> Self {
self.width = width;
self.height = height;
self
}
/// Sets the resizability of the WebView window. If set to false, the window cannot be resized.
///
/// Defaults to `true`.
pub fn resizable(mut self, resizable: bool) -> Self {
self.resizable = resizable;
self
}
/// Enables or disables debug mode.
///
/// Defaults to `true` for debug builds, `false` for release builds.
pub fn debug(mut self, debug: bool) -> Self {
self.debug = debug;
self
}
/// The window crated will be frameless
///
/// defaults to `false`
pub fn frameless(mut self, frameless: bool) -> Self {
self.frameless = frameless;
self
}
/// Set the visibility of the WebView window.
///
/// defaults to `true`
pub fn visible(mut self, visible: bool) -> Self {
self.visible = visible;
self
}
/// Sets the minimum size of the WebView window.
///
/// Defaults to 300 x 300.
pub fn min_size(mut self, width: i32, height: i32) -> Self {
self.min_width = width;
self.min_height = height;
self
}
}