Skip to content

Commit

Permalink
Create native module
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Nov 26, 2023
1 parent 03ea5c2 commit dd0e5fb
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 12 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ features = [
[[example]]
name = "counter"
required-features = ["webview"]

[[example]]
name = "native"
required-features = ["webview"]
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ This library provides a generic diffing engine for user-interfaces and other rea
This crate is inspired by Jetpack Compose, [xilem](https://github.com/linebender/xilem), and [dioxus](https://github.com/dioxuslabs/dioxus).


## Web/WebView
```rust
#[derive(PartialEq)]
struct Counter {
Expand All @@ -48,26 +49,29 @@ impl View for Counter {
)
}
}
```

## Web
```rust
fn main() {
concoct::web::run(Counter { initial_value: 0 })
}
```

## Native (WebView)
```rust
fn main() {
// OR

concoct::webview::run(Counter { initial_value: 0 })
}
```

## Native (Wgpu) - Planned
## Native (Wgpu and WebViews)
```rust
#[derive(PartialEq)]
struct App;

impl View for App {
fn view(&mut self) -> impl IntoView {
("Native text", WebView::new("WebView text"))
}
}

fn main() {
concoct::native::run(Counter { initial_value: 0 })
concoct::native::run(App)
}
```

Expand Down
14 changes: 14 additions & 0 deletions examples/native.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use concoct::{native::WebView, use_state, webview::div, IntoView, View};

#[derive(PartialEq)]
struct App;

impl View for App {
fn view(&mut self) -> impl IntoView {
("Native text", WebView::new("WebView text"))
}
}

fn main() {
concoct::native::run(App)
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ pub use use_state::{use_state, UseState};
#[cfg(feature = "html")]
pub mod html;

#[cfg(feature = "native")]
pub mod native;

#[cfg(feature = "web")]
pub mod web;

Expand Down
145 changes: 145 additions & 0 deletions src/native/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use crate::{
html::{Builder, Html, HtmlPlatform},
IntoView, Platform, Tree, View,
};
use std::{cell::RefCell, rc::Rc};
use winit::{
dpi::LogicalSize,
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
use wry::WebViewBuilder;

thread_local! {
static HTML_CONTEXT: RefCell<Option<NativeContext>> = RefCell::default();
}

struct Inner {
web_view: wry::WebView,
}

#[derive(Clone)]
pub struct NativeContext {
inner: Rc<RefCell<Inner>>,
}

impl NativeContext {
pub fn new(web_view: wry::WebView) -> Self {
Self {
inner: Rc::new(RefCell::new(Inner { web_view })),
}
}

pub fn current() -> Self {
HTML_CONTEXT
.try_with(|cx| cx.borrow().as_ref().unwrap().clone())
.unwrap()
}

pub fn enter(self) {
HTML_CONTEXT
.try_with(|cx| *cx.borrow_mut() = Some(self))
.unwrap()
}
}

pub struct NativeView;

impl Platform for NativeView {
fn from_str(&mut self, s: &str) -> Box<dyn crate::AnyView> {
NativeContext::current()
.inner
.borrow()
.web_view
.evaluate_script(&format!(
r#"
var node = document.createTextNode("{s}");
document.body.appendChild(node);
"#
))
.unwrap();
Box::new(())
}
}

#[derive(PartialEq)]
pub struct WebView {}

impl WebView {
pub fn new<C>(content: C) -> Self {
Self {}
}
}

impl View for WebView {
fn view(&mut self) -> impl IntoView {
todo!()
}
}

pub fn run(content: impl IntoView) {
let event_loop = EventLoop::new().unwrap();
let window =
WindowBuilder::new()
.with_inner_size(LogicalSize::new(800, 800))
.build(&event_loop)
.unwrap();

#[allow(unused_mut)]
let mut builder = WebViewBuilder::new(&window);
let web_view = builder
.with_html("<html><body></body></html>")
.unwrap()
.build()
.unwrap();

let cx = NativeContext::new(web_view);
cx.enter();

let mut composition = Tree::new(NativeView, content);
composition.build();

event_loop
.run(move |event, evl| {
evl.set_control_flow(ControlFlow::Poll);

#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
while gtk::events_pending() {
gtk::main_iteration_do(false);
}

match event {
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
))]
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
_webview.set_bounds(wry::Rect {
x: 0,
y: 0,
width: size.width,
height: size.height,
});
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => evl.exit(),
_ => {}
}
})
.unwrap();
}
2 changes: 0 additions & 2 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ impl View for &'static str {
}
}


impl View for String {
fn view(&mut self) -> impl IntoView {
BUILD_CONTEXT
Expand All @@ -33,4 +32,3 @@ impl View for String {
.unwrap();
}
}

0 comments on commit dd0e5fb

Please sign in to comment.