chore: clean up interpreter and bindings

This commit is contained in:
Jonathan Kelley committed 2022-12-05 16:47:04 -08:00
1 parent 7b1cdb7d85
commit b182a6ee75
17 files changed
+34 -108

No files matched your search

+2
View File
@@ -406,6 +406,8 @@ fn app(cx: Scope) -> Element {
wrap_through: "a", wrap_through: "a",
writing_mode: "a", writing_mode: "a",
z_index: "a", z_index: "a",
"This example isn't quite useful yet"
} }
}) })
} }
+2 -6
View File
@@ -29,9 +29,7 @@ fn app(cx: Scope) -> Element {
cx.render(rsx! { cx.render(rsx! {
div { div {
Child1 { Child1 { text: first }
text: first
}
} }
}) })
} }
@@ -59,9 +57,7 @@ struct C2Props<'a> {
fn Child2<'a>(cx: Scope<'a, C2Props<'a>>) -> Element { fn Child2<'a>(cx: Scope<'a, C2Props<'a>>) -> Element {
cx.render(rsx! { cx.render(rsx! {
Child3 { Child3 { text: cx.props.text }
text: cx.props.text
}
}) })
} }
+5 -8
View File
@@ -22,10 +22,10 @@ pub struct TodoItem {
} }
pub fn app(cx: Scope<()>) -> Element { pub fn app(cx: Scope<()>) -> Element {
let todos = use_state(&cx, im_rc::HashMap::<u32, TodoItem>::default); let todos = use_state(cx, im_rc::HashMap::<u32, TodoItem>::default);
let filter = use_state(&cx, || FilterState::All); let filter = use_state(cx, || FilterState::All);
let draft = use_state(&cx, || "".to_string()); let draft = use_state(cx, || "".to_string());
let todo_id = use_state(&cx, || 0); let todo_id = use_state(cx, || 0);
// Filter the todos based on the filter state // Filter the todos based on the filter state
let mut filtered_todos = todos let mut filtered_todos = todos
@@ -58,7 +58,6 @@ pub fn app(cx: Scope<()>) -> Element {
value: "{draft}", value: "{draft}",
autofocus: "true", autofocus: "true",
oninput: move |evt| { oninput: move |evt| {
println!("calling oninput");
draft.set(evt.value.clone()); draft.set(evt.value.clone());
}, },
onkeydown: move |evt| { onkeydown: move |evt| {
@@ -117,15 +116,13 @@ pub struct TodoEntryProps<'a> {
} }
pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element { pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element {
let is_editing = use_state(&cx, || false); let is_editing = use_state(cx, || false);
let todos = cx.props.todos.get(); let todos = cx.props.todos.get();
let todo = &todos[&cx.props.id]; let todo = &todos[&cx.props.id];
let completed = if todo.checked { "completed" } else { "" }; let completed = if todo.checked { "completed" } else { "" };
let editing = if **is_editing { "editing" } else { "" }; let editing = if **is_editing { "editing" } else { "" };
println!("rendering todo entry");
cx.render(rsx!{ cx.render(rsx!{
li { li {
class: "{completed} {editing}", class: "{completed} {editing}",
-4
View File
@@ -45,8 +45,6 @@ impl VirtualDom {
let entry = self.elements.vacant_entry(); let entry = self.elements.vacant_entry();
let id = entry.key(); let id = entry.key();
println!("claiming {:?}", id);
entry.insert(ElementRef { entry.insert(ElementRef {
template: template as *const _ as *mut _, template: template as *const _ as *mut _,
path, path,
@@ -67,8 +65,6 @@ impl VirtualDom {
); );
} }
println!("Reclaiming {:?}", el.0);
self.elements.try_remove(el.0) self.elements.try_remove(el.0)
} }
+4 -1
View File
@@ -277,7 +277,10 @@ pub enum TemplateAttribute<'a> {
/// The attribute in this position is actually determined dynamically at runtime /// The attribute in this position is actually determined dynamically at runtime
/// ///
/// This is the index into the dynamic_attributes field on the container VNode /// This is the index into the dynamic_attributes field on the container VNode
Dynamic(usize), Dynamic {
/// The index
id: usize,
},
} }
/// An attribute on a DOM node, such as `id="my-thing"` or `href="https://example.com"` /// An attribute on a DOM node, such as `id="my-thing"` or `href="https://example.com"`
+2 -6
View File
@@ -76,12 +76,8 @@ impl DesktopController {
.render_with_deadline(tokio::time::sleep(Duration::from_millis(16))) .render_with_deadline(tokio::time::sleep(Duration::from_millis(16)))
.await; .await;
{ edit_queue.lock().unwrap().push(serde_json::to_string(&muts).unwrap());
let mut queue = edit_queue.lock().unwrap(); let _ = proxy.send_event(UserWindowEvent::EditsReady);
queue.push(serde_json::to_string(&muts.templates).unwrap());
queue.push(serde_json::to_string(&muts.edits).unwrap());
let _ = proxy.send_event(UserWindowEvent::EditsReady);
}
} }
}) })
}); });
-2
View File
@@ -211,8 +211,6 @@ pub(super) fn handler(
}; };
let window = webview.window(); let window = webview.window();
println!("user_event: {:?}", user_event);
match user_event { match user_event {
Initialize | EditsReady => desktop.try_load_ready_webviews(), Initialize | EditsReady => desktop.try_load_ready_webviews(),
CloseWindow => *control_flow = ControlFlow::Exit, CloseWindow => *control_flow = ControlFlow::Exit,
-1
View File
@@ -42,7 +42,6 @@ macro_rules! match_data {
) => { ) => {
match $name { match $name {
$( $($mname)|* => { $( $($mname)|* => {
println!("casting to type {:?}", std::any::TypeId::of::<$tip>());
let val: $tip = from_value::<$tip>($m).ok()?; let val: $tip = from_value::<$tip>($m).ok()?;
Rc::new(val) as Rc<dyn Any> Rc::new(val) as Rc<dyn Any>
})* })*
+5 -4
View File
@@ -1,19 +1,20 @@
use dioxus_core::VirtualDom; use dioxus_core::VirtualDom;
use interprocess::local_socket::{LocalSocketListener, LocalSocketStream}; use interprocess::local_socket::LocalSocketStream;
// use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use std::time::Duration; use std::time::Duration;
use std::{sync::Arc, sync::Mutex}; use std::{sync::Arc, sync::Mutex};
fn handle_error(connection: std::io::Result<LocalSocketStream>) -> Option<LocalSocketStream> { fn _handle_error(connection: std::io::Result<LocalSocketStream>) -> Option<LocalSocketStream> {
connection connection
.map_err(|error| eprintln!("Incoming connection failed: {}", error)) .map_err(|error| eprintln!("Incoming connection failed: {}", error))
.ok() .ok()
} }
pub(crate) fn init(dom: &VirtualDom) { pub(crate) fn _init(_dom: &VirtualDom) {
let latest_in_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> = let latest_in_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
Arc::new(Mutex::new(None)); Arc::new(Mutex::new(None));
let latest_in_connection_handle = latest_in_connection.clone(); let _latest_in_connection_handle = latest_in_connection.clone();
// connect to processes for incoming data // connect to processes for incoming data
std::thread::spawn(move || { std::thread::spawn(move || {
-1
View File
@@ -153,7 +153,6 @@ pub fn launch_with_props<P: 'static + Send>(root: Component<P>, props: P, mut cf
} }
"initialize" => { "initialize" => {
is_ready.store(true, std::sync::atomic::Ordering::Relaxed); is_ready.store(true, std::sync::atomic::Ordering::Relaxed);
println!("initializing...");
let _ = proxy.send_event(UserWindowEvent::EditsReady); let _ = proxy.send_event(UserWindowEvent::EditsReady);
} }
"browser_open" => { "browser_open" => {
-1
View File
@@ -1,5 +1,4 @@
use dioxus_core::ScopeState; use dioxus_core::ScopeState;
use std::rc::Rc;
/// Consume some context in the tree, providing a sharable handle to the value /// Consume some context in the tree, providing a sharable handle to the value
pub fn use_context<T: 'static + Clone>(cx: &ScopeState) -> Option<&T> { pub fn use_context<T: 'static + Clone>(cx: &ScopeState) -> Option<&T> {
+2 -2
View File
@@ -12,7 +12,7 @@ extern "C" {
pub fn new(arg: Element) -> Interpreter; pub fn new(arg: Element) -> Interpreter;
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn SaveTemplate(this: &Interpreter, nodes: Vec<Node>, name: &str); pub fn SaveTemplate(this: &Interpreter, template: JsValue);
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn MountToRoot(this: &Interpreter); pub fn MountToRoot(this: &Interpreter);
@@ -58,8 +58,8 @@ extern "C" {
this: &Interpreter, this: &Interpreter,
name: &str, name: &str,
id: u32, id: u32,
handler: &Function,
bubbles: bool, bubbles: bool,
handler: &Function,
); );
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
+7 -15
View File
@@ -137,7 +137,7 @@ export class Interpreter {
this.stack.push(el); this.stack.push(el);
this.nodes[root] = el; this.nodes[root] = el;
} }
NewEventListener(event_name, root, handler, bubbles) { NewEventListener(event_name, root, bubbles, handler) {
const element = this.nodes[root]; const element = this.nodes[root];
element.setAttribute("data-dioxus-id", `${root}`); element.setAttribute("data-dioxus-id", `${root}`);
this.listeners.create(event_name, element, handler, bubbles); this.listeners.create(event_name, element, handler, bubbles);
@@ -210,7 +210,7 @@ export class Interpreter {
} }
} }
handleEdits(edits) { handleEdits(edits) {
// a json blob of things
for (let template of edits.templates) { for (let template of edits.templates) {
this.SaveTemplate(template); this.SaveTemplate(template);
} }
@@ -219,15 +219,15 @@ export class Interpreter {
this.handleEdit(edit); this.handleEdit(edit);
} }
} }
SaveTemplate(template) { SaveTemplate(template) {
console.log("saving template", template);
let roots = []; let roots = [];
for (let root of template.roots) { for (let root of template.roots) {
roots.push(this.MakeTemplateNode(root)); roots.push(this.MakeTemplateNode(root));
} }
console.log("saving template", template.name, roots);
this.templates[template.name] = roots; this.templates[template.name] = roots;
} }
MakeTemplateNode(node) { MakeTemplateNode(node) {
console.log("making template node", node); console.log("making template node", node);
switch (node.type) { switch (node.type) {
@@ -340,17 +340,12 @@ export class Interpreter {
this.RemoveAttribute(edit.id, edit.name, edit.ns); this.RemoveAttribute(edit.id, edit.name, edit.ns);
break; break;
case "RemoveEventListener": case "RemoveEventListener":
this.RemoveEventListener(edit.id, edit.event_name); this.RemoveEventListener(edit.id, edit.name);
break; break;
case "NewEventListener": case "NewEventListener":
// console.log("creating listener! ", edit);
// this handler is only provided on desktop implementations since this // this handler is only provided on desktop implementations since this
// method is not used by the web implementation // method is not used by the web implementation
let handler = (event) => { let handler = (event) => {
console.log("event", event);
let target = event.target; let target = event.target;
if (target != null) { if (target != null) {
let realId = target.getAttribute(`data-dioxus-id`); let realId = target.getAttribute(`data-dioxus-id`);
@@ -431,17 +426,14 @@ export class Interpreter {
} }
window.ipc.postMessage( window.ipc.postMessage(
serializeIpcMessage("user_event", { serializeIpcMessage("user_event", {
event: edit.event_name, event: edit.name,
mounted_dom_id: parseInt(realId), mounted_dom_id: parseInt(realId),
contents: contents, contents: contents,
}) })
); );
} }
}; };
this.NewEventListener(edit.name, edit.id, event_bubbles(edit.name), handler);
console.log("adding event listener", edit);
this.NewEventListener(edit.event_name, edit.id, handler, event_bubbles(edit.event_name));
break; break;
} }
} }
+1 -1
View File
@@ -217,7 +217,7 @@ impl<'a> DynamicContext<'a> {
let ct = self.dynamic_attributes.len(); let ct = self.dynamic_attributes.len();
self.dynamic_attributes.push(attr); self.dynamic_attributes.push(attr);
self.attr_paths.push(self.current_path.clone()); self.attr_paths.push(self.current_path.clone());
Some(quote! { ::dioxus::core::TemplateAttribute::Dynamic(#ct) }) Some(quote! { ::dioxus::core::TemplateAttribute::Dynamic { id: #ct } })
} }
}); });
+1 -1
View File
@@ -65,7 +65,7 @@ impl StringCache {
TemplateAttribute::Static { name, value, .. } => { TemplateAttribute::Static { name, value, .. } => {
write!(chain, " {}=\"{}\"", name, value)?; write!(chain, " {}=\"{}\"", name, value)?;
} }
TemplateAttribute::Dynamic(index) => { TemplateAttribute::Dynamic { id: index } => {
chain.segments.push(Segment::Attr(*index)) chain.segments.push(Segment::Attr(*index))
} }
} }
+1
View File
@@ -30,6 +30,7 @@ futures-util = "0.3.19"
smallstr = "0.2.0" smallstr = "0.2.0"
futures-channel = "0.3.21" futures-channel = "0.3.21"
serde_json = { version = "1.0" } serde_json = { version = "1.0" }
serde-wasm-bindgen = "0.4.5"
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3.56" version = "0.3.56"
+2 -55
View File
@@ -53,61 +53,8 @@ impl WebsysDom {
log::debug!("Loading templates {:?}", templates); log::debug!("Loading templates {:?}", templates);
for template in templates { for template in templates {
let mut roots = vec![]; self.interpreter
.SaveTemplate(serde_wasm_bindgen::to_value(&template).unwrap());
for root in template.roots {
roots.push(self.create_template_node(root))
}
self.interpreter.SaveTemplate(roots, template.name);
}
}
fn create_template_node(&self, v: &TemplateNode) -> web_sys::Node {
use TemplateNode::*;
match v {
Element {
tag,
namespace,
attrs,
children,
..
} => {
let el = match namespace {
Some(ns) => self.document.create_element_ns(Some(ns), tag).unwrap(),
None => self.document.create_element(tag).unwrap(),
};
for attr in *attrs {
if let TemplateAttribute::Static {
name,
value,
namespace,
} = attr
{
match namespace {
Some(ns) if *ns == "style" => el
.dyn_ref::<HtmlElement>()
.unwrap()
.style()
.set_property(name, value)
.unwrap(),
Some(ns) => el.set_attribute_ns(Some(ns), name, value).unwrap(),
None => el.set_attribute(name, value).unwrap(),
}
}
}
for child in *children {
el.append_child(&self.create_template_node(child));
}
el.dyn_into().unwrap()
}
Text { text: t } => self.document.create_text_node(t).dyn_into().unwrap(),
DynamicText { id: _ } => self.document.create_text_node("p").dyn_into().unwrap(),
Dynamic { id: _ } => {
let el = self.document.create_element("pre").unwrap();
el.toggle_attribute("hidden");
el.dyn_into().unwrap()
}
} }
} }