chore: clean up interpreter and bindings
This commit is contained in:
1 parent
7b1cdb7d85
commit
b182a6ee75
17 files changed
+34
-108
No files matched your search
@@ -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"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -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
@@ -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}",
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"`
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
})*
|
})*
|
||||||
|
|||||||
@@ -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 || {
|
||||||
|
|||||||
@@ -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,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> {
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 } })
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user