Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding net crate #123

Merged
merged 27 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3c5f8fe
Adding async netcode
kokoISnoTarget Aug 20, 2024
d8106dd
Restructuring of the components
kokoISnoTarget Aug 20, 2024
4b338f2
Fixing screenshot example.
kokoISnoTarget Aug 20, 2024
afd4230
Refactor some of the net api
kokoISnoTarget Sep 1, 2024
5075935
Parse stylsheets on the fetch thread.
kokoISnoTarget Sep 1, 2024
54cad68
Make it possible to insert stylesheets at the correct position for un…
kokoISnoTarget Sep 1, 2024
eb74859
improve net api
kokoISnoTarget Sep 5, 2024
a88f239
Use an request method provided by Handler instead of GET
kokoISnoTarget Sep 5, 2024
407942e
improve non_blocking provider
kokoISnoTarget Sep 5, 2024
f5a65ea
Workaround for css loading
kokoISnoTarget Sep 7, 2024
0977cef
Merge main into net
kokoISnoTarget Sep 7, 2024
0f3ef6e
Remove workaround
kokoISnoTarget Sep 10, 2024
effed75
Reset inline nodes
kokoISnoTarget Sep 10, 2024
328194a
Reduce size of Resource
kokoISnoTarget Sep 10, 2024
98bad27
Merge main into net
kokoISnoTarget Sep 10, 2024
5f6bd08
Moving to dynamic dispatch, adding callback, adding traits crate, rem…
kokoISnoTarget Sep 13, 2024
f589134
Merge main into net
kokoISnoTarget Sep 13, 2024
54a9167
fmt, clippy and some git weirdness
kokoISnoTarget Sep 13, 2024
6dea976
Small api teaks
kokoISnoTarget Sep 16, 2024
9792b4a
Fixing double borrow introduced with #132
kokoISnoTarget Sep 16, 2024
21bf9c7
Basic font-face support
kokoISnoTarget Sep 16, 2024
e886dd4
fmt
gitbutler-client Sep 17, 2024
cef520f
Merge main into net, i hope this can get merged
kokoISnoTarget Sep 17, 2024
44f0c7d
git
kokoISnoTarget Sep 17, 2024
eacb380
typo + remove html-escape from dioxus-blitz
kokoISnoTarget Sep 17, 2024
8fd517d
Merge branch 'main' into net
kokoISnoTarget Sep 17, 2024
4d0cbc7
Fix screenshot.rs
kokoISnoTarget Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# members = ["packages/dom"]
# members = ["packages/blitz", "packages/dom", "packages/dioxus-blitz"]
# exclude = ["packages/blitz", "packages/dioxus-blitz"]
members = ["packages/blitz", "packages/dom", "packages/dioxus-blitz"]
members = ["packages/blitz", "packages/dom", "packages/dioxus-blitz", "packages/net", "packages/traits"]
resolver = "2"

[workspace.dependencies]
Expand Down Expand Up @@ -55,6 +55,8 @@ incremental = false
# mozbuild = "0.1.0"
blitz = { path = "./packages/blitz" }
blitz-dom = { path = "./packages/dom" }
blitz-net = { path = "./packages/net" }
blitz-traits = { path = "./packages/traits" }
comrak = { git = "https://github.com/nicoburns/comrak", branch = "tasklist-class", default-features = false, features = ["syntect"] }
png = { version = "0.17" }
dioxus-blitz = { path = "./packages/dioxus-blitz" }
Expand Down
32 changes: 30 additions & 2 deletions examples/screenshot.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
//! Load first CLI argument as a url. Fallback to google.com if no CLI argument is provided.

use blitz::render_to_buffer;
use blitz_dom::util::Resource;
use blitz_dom::{HtmlDocument, Viewport};
use blitz_net::{MpscCallback, Provider};
use blitz_traits::net::{SharedCallback, SharedProvider};
use reqwest::Url;
use std::sync::Arc;
use std::{
fs::File,
io::Write,
path::{Path, PathBuf},
time::Instant,
};
use tokio::runtime::Handle;

const USER_AGENT: &str = "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0";

Expand Down Expand Up @@ -46,13 +51,36 @@ async fn main() {
.and_then(|arg| arg.parse().ok())
.unwrap_or(1200);

let (mut recv, callback) = MpscCallback::new();
let net = Arc::new(Provider::new(
Handle::current(),
Arc::new(callback) as SharedCallback<Resource>,
));

timer.time("Setup document prerequisites");

// Create HtmlDocument
let mut document = HtmlDocument::from_html(&html, Some(url.clone()), Vec::new());
let mut document = HtmlDocument::from_html(
&html,
Some(url.clone()),
Vec::new(),
Arc::clone(&net) as SharedProvider<Resource>,
);

timer.time("Parsed document");

document
.as_mut()
.set_viewport(Viewport::new(width * scale, height * scale, scale as f32));

timer.time("Created document (+ fetched assets)");
while let Some(res) = recv.recv().await {
document.as_mut().load_resource(res);
if net.is_empty() {
break;
}
}

timer.time("Fetched assets");

// Compute style, layout, etc for HtmlDocument
document.as_mut().resolve();
Expand Down
2 changes: 2 additions & 0 deletions packages/dioxus-blitz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ style = { workspace = true }
tracing = { workspace = true, optional = true }
blitz = { path = "../blitz" }
blitz-dom = { path = "../dom" }
blitz-net = { path = "../net" }
blitz-traits = { path = "../traits" }
url = { version = "2.5.0", features = ["serde"] }
ureq = "2.9"
rustc-hash = "1.1.0"
Expand Down
11 changes: 6 additions & 5 deletions packages/dioxus-blitz/src/documents/dioxus_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use rustc_hash::FxHashMap;
use style::{
data::{ElementData, ElementStyles},
properties::{style_structs::Font, ComputedValues},
stylesheets::Origin,
};

use super::event_handler::{NativeClickData, NativeConverter, NativeFormData};
Expand Down Expand Up @@ -269,7 +270,7 @@ impl DioxusDocument {
root_node.children.push(html_element_id);

// Include default and user-specified stylesheets
doc.add_stylesheet(DEFAULT_CSS);
doc.add_user_agent_stylesheet(DEFAULT_CSS);

let state = DioxusState::create(&mut doc);
let mut doc = Self {
Expand Down Expand Up @@ -492,7 +493,8 @@ impl WriteMutations for MutationWriter<'_> {
let parent = self.doc.get_node(parent).unwrap();
if let NodeData::Element(ref element) = parent.raw_dom_data {
if element.name.local.as_ref() == "style" {
self.doc.add_stylesheet(value);
let sheet = self.doc.make_stylesheet(value, Origin::Author);
self.doc.add_stylesheet_for_node(sheet, parent.id);
}
}
}
Expand Down Expand Up @@ -617,16 +619,15 @@ impl WriteMutations for MutationWriter<'_> {
// todo: this is very inefficient for inline styles - lots of string cloning going on
let changed = text.content != value;
text.content = value.to_string();
let contents = text.content.clone();

if let Some(parent) = node.parent {
// if the text is the child of a style element, we want to put the style into the stylesheet cache
let parent = self.doc.get_node(parent).unwrap();
if let NodeData::Element(ref element) = parent.raw_dom_data {
// Only set stylsheets if the text content has *changed* - we need to unload
if changed && element.name.local.as_ref() == "style" {
self.doc.add_stylesheet(value);
self.doc.remove_stylehsheet(&contents);
let sheet = self.doc.make_stylesheet(value, Origin::Author);
self.doc.add_stylesheet_for_node(sheet, parent.id);
}
}
}
Expand Down
104 changes: 82 additions & 22 deletions packages/dioxus-blitz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,29 @@ mod menu;
#[cfg(feature = "accessibility")]
mod accessibility;

use crate::application::Application;
pub use crate::documents::DioxusDocument;
pub use crate::waker::BlitzEvent;
use crate::waker::BlitzWindowEvent;
use crate::window::View;
pub use crate::window::WindowConfig;
use blitz_dom::util::Resource;
use blitz_dom::{DocumentLike, HtmlDocument};
use blitz_net::Provider;
use blitz_traits::net::SharedCallback;
use dioxus::prelude::{ComponentFunction, Element, VirtualDom};
use std::ops::DerefMut;
use std::sync::{Arc, Mutex};
use tokio::runtime::Runtime;
use url::Url;
use winit::event_loop::EventLoopProxy;
use winit::window::WindowId;
use winit::{
dpi::LogicalSize,
event_loop::{ControlFlow, EventLoop},
window::Window,
};

use crate::application::Application;
use crate::window::View;

pub use crate::documents::DioxusDocument;
pub use crate::waker::BlitzEvent;
pub use crate::window::WindowConfig;

pub mod exports {
pub use dioxus;
}
Expand Down Expand Up @@ -67,7 +74,14 @@ pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
let vdom = VirtualDom::new_with_props(root, props);
let document = DioxusDocument::new(vdom);

launch_with_document(document)
// Turn on the runtime and enter it
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();

let _guard = rt.enter();
launch_with_document(document, rt, None)
}

pub fn launch_url(url: &str) {
Expand Down Expand Up @@ -99,11 +113,25 @@ pub fn launch_static_html(html: &str) {
}

pub fn launch_static_html_cfg(html: &str, cfg: Config) {
let document = HtmlDocument::from_html(html, cfg.base_url, cfg.stylesheets);
launch_with_document(document)
// Turn on the runtime and enter it
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();

let _guard = rt.enter();

let net_callback = Arc::new(Callback::new());
let net = Provider::new(
rt.handle().clone(),
Arc::clone(&net_callback) as SharedCallback<Resource>,
);

let document = HtmlDocument::from_html(html, cfg.base_url, cfg.stylesheets, Arc::new(net));
launch_with_document(document, rt, Some(net_callback));
}

fn launch_with_document(doc: impl DocumentLike) {
fn launch_with_document(doc: impl DocumentLike, rt: Runtime, net_callback: Option<Arc<Callback>>) {
let mut window_attrs = Window::default_attributes();
if !cfg!(all(target_os = "android", target_os = "ios")) {
window_attrs.inner_size = Some(
Expand All @@ -114,20 +142,12 @@ fn launch_with_document(doc: impl DocumentLike) {
.into(),
);
}
let window = WindowConfig::new(doc);
let window = WindowConfig::new(doc, net_callback);

launch_with_window(window)
launch_with_window(window, rt)
}

fn launch_with_window<Doc: DocumentLike + 'static>(window: WindowConfig<Doc>) {
// Turn on the runtime and enter it
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();

let _guard = rt.enter();

fn launch_with_window<Doc: DocumentLike + 'static>(window: WindowConfig<Doc>, rt: Runtime) {
// Build an event loop for the application
let mut ev_builder = EventLoop::<BlitzEvent>::with_user_event();
#[cfg(target_os = "android")]
Expand Down Expand Up @@ -182,3 +202,43 @@ pub fn set_android_app(app: android_activity::AndroidApp) {
pub fn current_android_app(app: android_activity::AndroidApp) -> AndroidApp {
ANDROID_APP.get().unwrap().clone()
}

pub struct Callback(Mutex<CallbackInner>);
enum CallbackInner {
Window(WindowId, EventLoopProxy<BlitzEvent>),
Queue(Vec<Resource>),
}
impl Callback {
fn new() -> Self {
Self(Mutex::new(CallbackInner::Queue(Vec::new())))
}
fn init(self: Arc<Self>, window_id: WindowId, proxy: &EventLoopProxy<BlitzEvent>) {
let old = std::mem::replace(
self.0.lock().unwrap().deref_mut(),
CallbackInner::Window(window_id, proxy.clone()),
);
match old {
CallbackInner::Window(..) => {}
CallbackInner::Queue(mut queue) => queue
.drain(..)
.for_each(|res| Self::send_event(&window_id, proxy, res)),
}
}
fn send_event(window_id: &WindowId, proxy: &EventLoopProxy<BlitzEvent>, data: Resource) {
proxy
.send_event(BlitzEvent::Window {
window_id: *window_id,
data: BlitzWindowEvent::ResourceLoad(data),
})
.unwrap()
}
}
impl blitz_traits::net::Callback for Callback {
type Data = Resource;
fn call(self: Arc<Self>, data: Self::Data) {
match self.0.lock().unwrap().deref_mut() {
CallbackInner::Window(wid, proxy) => Self::send_event(wid, proxy, data),
CallbackInner::Queue(queue) => queue.push(data),
}
}
}
12 changes: 10 additions & 2 deletions packages/dioxus-blitz/src/waker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use winit::{event_loop::EventLoopProxy, window::WindowId};
#[cfg(feature = "accessibility")]
use accesskit_winit::Event as AccessibilityEvent;
use accesskit_winit::WindowEvent as AccessibilityWindowEvent;
use blitz_dom::util::Resource;

#[derive(Debug, Clone)]
pub enum BlitzEvent {
Window {
window_id: WindowId,
data: BlitzWindowEvent,
},

/// A hotreload event, basically telling us to update our templates.
#[cfg(all(
feature = "hot-reload",
Expand All @@ -22,6 +22,14 @@ pub enum BlitzEvent {
))]
HotReloadEvent(dioxus_hot_reload::HotReloadMsg),
}
impl From<(WindowId, Resource)> for BlitzEvent {
fn from((window_id, resource): (WindowId, Resource)) -> Self {
BlitzEvent::Window {
window_id,
data: BlitzWindowEvent::ResourceLoad(resource),
}
}
}

#[cfg(feature = "accessibility")]
impl From<AccessibilityEvent> for BlitzEvent {
Expand All @@ -37,7 +45,7 @@ impl From<AccessibilityEvent> for BlitzEvent {
#[derive(Debug, Clone)]
pub enum BlitzWindowEvent {
Poll,

ResourceLoad(Resource),
/// An accessibility event from `accesskit`.
#[cfg(feature = "accessibility")]
Accessibility(Arc<AccessibilityWindowEvent>),
Expand Down
26 changes: 22 additions & 4 deletions packages/dioxus-blitz/src/window.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::accessibility::AccessibilityState;
use crate::stylo_to_winit;
use crate::waker::{create_waker, BlitzEvent, BlitzWindowEvent};
use crate::{stylo_to_winit, Callback};
use blitz::{Devtools, Renderer};
use blitz_dom::events::{EventData, RendererEvent};
use blitz_dom::{DocumentLike, Viewport};
Expand All @@ -22,18 +22,28 @@ use crate::menu::init_menu;
pub struct WindowConfig<Doc: DocumentLike> {
doc: Doc,
attributes: WindowAttributes,
callback: Option<Arc<Callback>>,
}

impl<Doc: DocumentLike> WindowConfig<Doc> {
pub fn new(doc: Doc) -> Self {
pub fn new(doc: Doc, callback: Option<Arc<Callback>>) -> Self {
WindowConfig {
doc,
attributes: Window::default_attributes(),
callback,
}
}

pub fn with_attributes(doc: Doc, attributes: WindowAttributes) -> Self {
WindowConfig { doc, attributes }
pub fn with_attributes(
doc: Doc,
attributes: WindowAttributes,
callback: Option<Arc<Callback>>,
) -> Self {
WindowConfig {
doc,
attributes,
callback,
}
}
}

Expand Down Expand Up @@ -75,6 +85,10 @@ impl<Doc: DocumentLike> View<Doc> {
) -> Self {
let winit_window = Arc::from(event_loop.create_window(config.attributes).unwrap());

if let Some(callback) = config.callback {
callback.init(winit_window.id(), proxy);
}

// TODO: make this conditional on text input focus
winit_window.set_ime_allowed(true);

Expand Down Expand Up @@ -237,6 +251,10 @@ impl<Doc: DocumentLike> View<Doc> {
BlitzWindowEvent::Poll => {
self.poll();
}
BlitzWindowEvent::ResourceLoad(resource) => {
self.dom.as_mut().load_resource(resource);
self.request_redraw();
}
#[cfg(feature = "accessibility")]
BlitzWindowEvent::Accessibility(accessibility_event) => {
match &*accessibility_event {
Expand Down
2 changes: 1 addition & 1 deletion packages/dom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ default = ["tracing"]
tracing = ["dep:tracing"]

[dependencies]
blitz-traits = { path = "../traits" }
style = { workspace = true, features = ["servo"] }
selectors = { workspace = true }
style_config = { workspace = true }
Expand All @@ -26,7 +27,6 @@ string_cache = "0.8.7"
html-escape = "0.2.13"
url = { version = "2.5.0", features = ["serde"] }
data-url = "0.3.1"
ureq = "2.9"
image = "0.25.2"
winit = { version = "0.30.4", default-features = false }
usvg = "0.42.0"
Loading