feat: get desktop working with just creation

This commit is contained in:
Jonathan Kelley committed 2022-11-15 18:32:48 -08:00
1 parent 8caabb97d8
commit e8ae830cf2
16 files changed
+1301 -329

No files matched your search

+12 -7
View File
@@ -47,6 +47,7 @@ impl VirtualDom {
// todo: adjust dynamic nodes to be in the order of roots and then leaves (ie BFS)
let mut dynamic_attrs = template.template.attr_paths.iter().enumerate().peekable();
let mut dynamic_nodes = template.template.node_paths.iter().enumerate().peekable();
let cur_scope = self.scope_stack.last().copied().unwrap();
let mut on_stack = 0;
for (root_idx, root) in template.template.roots.iter().enumerate() {
@@ -78,21 +79,25 @@ impl VirtualDom {
});
loop {
let attribute = &template.dynamic_attrs[attr_id];
let attribute = template.dynamic_attrs.get(attr_id).unwrap();
attribute.mounted_element.set(id);
match attribute.value {
match &attribute.value {
AttributeValue::Text(value) => mutations.push(SetAttribute {
name: attribute.name,
value,
value: *value,
id,
}),
AttributeValue::Bool(value) => mutations.push(SetBoolAttribute {
name: attribute.name,
value,
value: *value,
id,
}),
AttributeValue::Listener(_) => mutations.push(NewEventListener {
event_name: attribute.name,
scope: cur_scope,
id,
}),
AttributeValue::Listener(_) => todo!("create listener attributes"),
AttributeValue::Float(_) => todo!(),
AttributeValue::Int(_) => todo!(),
AttributeValue::Any(_) => todo!(),
@@ -138,8 +143,8 @@ impl VirtualDom {
let id = self.next_element(template);
mutations.push(CreatePlaceholder { id })
}
TemplateNode::Text(value) => mutations.push(CreateText { value }),
TemplateNode::DynamicText { .. } => mutations.push(CreateText {
TemplateNode::Text(value) => mutations.push(CreateTextNode { value }),
TemplateNode::DynamicText { .. } => mutations.push(CreateTextNode {
value: "placeholder",
}),
+1 -1
View File
@@ -189,7 +189,7 @@ impl<'b> VirtualDom {
(DynamicNode::Text { id: lid, .. }, right) => {
let m = self.create_dynamic_node(muts, right_template, right, idx);
muts.push(Mutation::Replace { id: lid.get(), m });
muts.push(Mutation::ReplaceWith { id: lid.get(), m });
}
(DynamicNode::Placeholder(_), DynamicNode::Placeholder(_)) => todo!(),
+11 -4
View File
@@ -6,11 +6,18 @@ use std::{
rc::Rc,
};
pub struct UiEvent<T> {
bubble_state: Cell<bool>,
data: Rc<T>,
pub struct UiEvent<T: 'static> {
pub(crate) bubble_state: Cell<bool>,
pub(crate) data: Rc<T>,
}
impl<T> Clone for UiEvent<T> {
fn clone(&self) -> Self {
Self {
bubble_state: self.bubble_state.clone(),
data: self.data.clone(),
}
}
}
impl<T> UiEvent<T> {
pub fn cancel_bubble(&self) {
self.bubble_state.set(false);
+68 -45
View File
@@ -1,4 +1,4 @@
use crate::arena::ElementId;
use crate::{arena::ElementId, ScopeId};
#[derive(Debug)]
pub struct Mutations<'a> {
@@ -35,9 +35,61 @@ impl std::ops::DerefMut for Mutations<'_> {
each subtree has its own numbering scheme
*/
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serialize",
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type")
)]
#[derive(Debug, PartialEq, Eq)]
pub enum Mutation<'a> {
AppendChildren {
m: usize,
},
AssignId {
path: &'static [u8],
id: ElementId,
},
CreateElement {
name: &'a str,
namespace: Option<&'a str>,
id: ElementId,
},
CreatePlaceholder {
id: ElementId,
},
CreateTextNode {
value: &'a str,
},
HydrateText {
path: &'static [u8],
value: &'a str,
id: ElementId,
},
LoadTemplate {
name: &'static str,
index: usize,
},
// Take the current element and replace it with the element with the given id.
ReplaceWith {
id: ElementId,
m: usize,
},
ReplacePlaceholder {
m: usize,
path: &'static [u8],
},
SaveTemplate {
name: &'static str,
m: usize,
},
SetAttribute {
name: &'a str,
value: &'a str,
@@ -50,20 +102,8 @@ pub enum Mutation<'a> {
id: ElementId,
},
LoadTemplate {
name: &'static str,
index: usize,
},
SaveTemplate {
name: &'static str,
m: usize,
},
HydrateText {
path: &'static [u8],
SetInnerText {
value: &'a str,
id: ElementId,
},
SetText {
@@ -71,41 +111,24 @@ pub enum Mutation<'a> {
id: ElementId,
},
ReplacePlaceholder {
m: usize,
path: &'static [u8],
},
/// Create a new Event Listener.
NewEventListener {
/// The name of the event to listen for.
event_name: &'a str,
AssignId {
path: &'static [u8],
/// The ID of the node to attach the listener to.
scope: ScopeId,
/// The ID of the node to attach the listener to.
id: ElementId,
},
// Take the current element and replace it with the element with the given id.
Replace {
/// Remove an existing Event Listener.
RemoveEventListener {
/// The ID of the node to remove.
id: ElementId,
m: usize,
},
CreateElement {
name: &'a str,
namespace: Option<&'a str>,
id: ElementId,
},
SetInnerText {
value: &'a str,
},
CreateText {
value: &'a str,
},
CreatePlaceholder {
id: ElementId,
},
AppendChildren {
m: usize,
/// The name of the event to remove.
event: &'a str,
},
}
+23 -1
View File
@@ -1,8 +1,9 @@
use crate::{any_props::AnyProps, arena::ElementId, ScopeId, ScopeState};
use crate::{any_props::AnyProps, arena::ElementId, ScopeId, ScopeState, UiEvent};
use std::{
any::{Any, TypeId},
cell::{Cell, RefCell},
hash::Hasher,
rc::Rc,
};
pub type TemplateId = &'static str;
@@ -154,6 +155,27 @@ pub enum AttributeValue<'a> {
None,
}
impl<'a> AttributeValue<'a> {
pub fn new_listener<T: 'static>(
cx: &'a ScopeState,
mut f: impl FnMut(UiEvent<T>) + 'a,
) -> AttributeValue<'a> {
let f = cx.bump().alloc(move |a: &dyn Any| {
a.downcast_ref::<UiEvent<T>>()
.map(|a| f(a.clone()))
.unwrap_or_else(|| {
panic!(
"Expected UiEvent<{}>, got {:?}",
std::any::type_name::<T>(),
a
)
})
}) as &mut dyn FnMut(&dyn Any);
AttributeValue::Listener(RefCell::new(f))
}
}
impl<'a> std::fmt::Debug for AttributeValue<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
+9 -4
View File
@@ -9,7 +9,7 @@ use crate::{
nodes::{Template, TemplateId},
scheduler::{SuspenseBoundary, SuspenseId},
scopes::{ScopeId, ScopeState},
Attribute, AttributeValue, Element, EventPriority, Scope, SuspenseContext,
Attribute, AttributeValue, Element, EventPriority, Scope, SuspenseContext, UiEvent,
};
use futures_util::{pin_mut, FutureExt, StreamExt};
use slab::Slab;
@@ -288,10 +288,10 @@ impl VirtualDom {
///
///
///
pub fn handle_event(
pub fn handle_event<T: 'static>(
&mut self,
name: &str,
event: &dyn Any,
data: Rc<T>,
element: ElementId,
bubbles: bool,
priority: EventPriority,
@@ -304,6 +304,11 @@ impl VirtualDom {
- send event to virtualdom
*/
let event = UiEvent {
bubble_state: std::cell::Cell::new(true),
data,
};
let path = &self.elements[element.0];
let template = unsafe { &*path.template };
let dynamic = &template.dynamic_nodes[path.element];
@@ -339,7 +344,7 @@ impl VirtualDom {
for listener in listeners {
if let AttributeValue::Listener(listener) = &listener.value {
(listener.borrow_mut())(event)
(listener.borrow_mut())(&event.clone())
}
}