create driven example for tui renderer
This commit is contained in:
1 parent
c805bc25af
commit
71e34452da
10 files changed
+276
-34
No files matched your search
@@ -2,7 +2,10 @@ use dioxus_core::{BorrowedAttributeValue, ElementId, Mutations, TemplateNode};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use crate::{
|
||||
node::{ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue},
|
||||
node::{
|
||||
ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
|
||||
TextNode,
|
||||
},
|
||||
prelude::NodeImmutable,
|
||||
real_dom::NodeTypeMut,
|
||||
NodeId, NodeMut, RealDom,
|
||||
@@ -83,7 +86,10 @@ impl DioxusState {
|
||||
self.stack.push(node_id);
|
||||
}
|
||||
CreateTextNode { value, id } => {
|
||||
let node_data = NodeType::Text(value.to_string());
|
||||
let node_data = NodeType::Text(TextNode {
|
||||
listeners: FxHashSet::default(),
|
||||
text: value.to_string(),
|
||||
});
|
||||
let node = rdom.create_node(node_data);
|
||||
let node_id = node.id();
|
||||
self.set_element_id(node, id);
|
||||
@@ -97,7 +103,10 @@ impl DioxusState {
|
||||
if let NodeTypeMut::Text(text) = node.node_type_mut() {
|
||||
*text = value.to_string();
|
||||
} else {
|
||||
node.set_type(NodeType::Text(value.to_string()));
|
||||
node.set_type(NodeType::Text(TextNode {
|
||||
text: value.to_string(),
|
||||
listeners: FxHashSet::default(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
LoadTemplate { name, index, id } => {
|
||||
@@ -153,14 +162,12 @@ impl DioxusState {
|
||||
element.remove_attributes(&OwnedAttributeDiscription {
|
||||
name: name.to_string(),
|
||||
namespace: ns.map(|s| s.to_string()),
|
||||
volatile: false,
|
||||
});
|
||||
} else {
|
||||
element.set_attribute(
|
||||
OwnedAttributeDiscription {
|
||||
name: name.to_string(),
|
||||
namespace: ns.map(|s| s.to_string()),
|
||||
volatile: false,
|
||||
},
|
||||
OwnedAttributeValue::from(value),
|
||||
);
|
||||
@@ -219,7 +226,6 @@ fn create_template_node(rdom: &mut RealDom, node: &TemplateNode) -> NodeId {
|
||||
OwnedAttributeDiscription {
|
||||
namespace: namespace.map(|s| s.to_string()),
|
||||
name: name.to_string(),
|
||||
volatile: false,
|
||||
},
|
||||
OwnedAttributeValue::Text(value.to_string()),
|
||||
)),
|
||||
@@ -235,9 +241,16 @@ fn create_template_node(rdom: &mut RealDom, node: &TemplateNode) -> NodeId {
|
||||
}
|
||||
node_id
|
||||
}
|
||||
TemplateNode::Text { text } => rdom.create_node(NodeType::Text(text.to_string())).id(),
|
||||
TemplateNode::Text { text } => rdom
|
||||
.create_node(NodeType::Text(TextNode {
|
||||
text: text.to_string(),
|
||||
..Default::default()
|
||||
}))
|
||||
.id(),
|
||||
TemplateNode::Dynamic { .. } => rdom.create_node(NodeType::Placeholder).id(),
|
||||
TemplateNode::DynamicText { .. } => rdom.create_node(NodeType::Text(String::new())).id(),
|
||||
TemplateNode::DynamicText { .. } => {
|
||||
rdom.create_node(NodeType::Text(TextNode::default())).id()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,8 @@ pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
|
||||
pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>;
|
||||
pub type SendAnyMap = anymap::Map<dyn Any + Send + Sync + 'static>;
|
||||
|
||||
pub trait Renderer<V: FromAnyValue + Send + Sync, E> {
|
||||
pub trait Renderer<E, V: FromAnyValue + Send + Sync = ()> {
|
||||
fn render(&mut self, root: NodeMut<V>);
|
||||
fn handle_event(&mut self, node: NodeMut<V>, event: &str, value: E);
|
||||
fn poll_async(&mut self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
||||
Box::pin(async {})
|
||||
}
|
||||
fn handle_event(&mut self, node: NodeMut<V>, event: &str, value: E, bubbles: bool);
|
||||
fn poll_async(&mut self) -> Pin<Box<dyn Future<Output = ()> + Send>>;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use std::{any::Any, fmt::Debug};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ElementNode<V: FromAnyValue = ()> {
|
||||
pub tag: String,
|
||||
pub namespace: Option<String>,
|
||||
@@ -9,10 +9,25 @@ pub struct ElementNode<V: FromAnyValue = ()> {
|
||||
pub listeners: FxHashSet<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TextNode {
|
||||
pub text: String,
|
||||
pub listeners: FxHashSet<String>,
|
||||
}
|
||||
|
||||
impl TextNode {
|
||||
pub fn new(text: String) -> Self {
|
||||
Self {
|
||||
text,
|
||||
listeners: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A type of node with data specific to the node type. The types are a subset of the [VNode] types.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NodeType<V: FromAnyValue = ()> {
|
||||
Text(String),
|
||||
Text(TextNode),
|
||||
Element(ElementNode<V>),
|
||||
Placeholder,
|
||||
}
|
||||
@@ -21,7 +36,6 @@ pub enum NodeType<V: FromAnyValue = ()> {
|
||||
pub struct OwnedAttributeDiscription {
|
||||
pub name: String,
|
||||
pub namespace: Option<String>,
|
||||
pub volatile: bool,
|
||||
}
|
||||
|
||||
/// An attribute on a DOM node, such as `id="my-thing"` or
|
||||
|
||||
@@ -73,10 +73,11 @@ impl<'a, V: FromAnyValue> NodeView<'a, V> {
|
||||
self.mask
|
||||
.text
|
||||
.then_some(match &self.inner {
|
||||
NodeType::Text(text) => Some(&**text),
|
||||
NodeType::Text(text) => Some(&text.text),
|
||||
_ => None,
|
||||
})
|
||||
.flatten()
|
||||
.map(|x| &**x)
|
||||
}
|
||||
|
||||
/// Get the listeners if it is enabled in the mask
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::rc::Rc;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use crate::node::{
|
||||
ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
|
||||
ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue, TextNode,
|
||||
};
|
||||
use crate::node_ref::{NodeMask, NodeMaskBuilder};
|
||||
use crate::node_watcher::NodeWatcher;
|
||||
@@ -487,6 +487,19 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
||||
|
||||
pub fn remove(&mut self) {
|
||||
let id = self.id();
|
||||
if let NodeType::Element(ElementNode { listeners, .. })
|
||||
| NodeType::Text(TextNode { listeners, .. }) =
|
||||
self.dom.get_state_mut_raw::<NodeType<V>>(id).unwrap()
|
||||
{
|
||||
let listeners = std::mem::take(listeners);
|
||||
for event in listeners {
|
||||
self.dom
|
||||
.nodes_listening
|
||||
.get_mut(&event)
|
||||
.unwrap()
|
||||
.remove(&id);
|
||||
}
|
||||
}
|
||||
self.mark_removed();
|
||||
if let Some(parent_id) = self.real_dom_mut().tree.parent_id(id) {
|
||||
self.real_dom_mut()
|
||||
@@ -519,7 +532,9 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
||||
pub fn add_event_listener(&mut self, event: &str) {
|
||||
let id = self.id();
|
||||
let node_type: &mut NodeType<V> = self.dom.tree.get_mut(self.id).unwrap();
|
||||
if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
|
||||
if let NodeType::Element(ElementNode { listeners, .. })
|
||||
| NodeType::Text(TextNode { listeners, .. }) = node_type
|
||||
{
|
||||
self.dom
|
||||
.dirty_nodes
|
||||
.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
|
||||
@@ -540,7 +555,9 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
||||
pub fn remove_event_listener(&mut self, event: &str) {
|
||||
let id = self.id();
|
||||
let node_type: &mut NodeType<V> = self.dom.tree.get_mut(self.id).unwrap();
|
||||
if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
|
||||
if let NodeType::Element(ElementNode { listeners, .. })
|
||||
| NodeType::Text(TextNode { listeners, .. }) = node_type
|
||||
{
|
||||
self.dom
|
||||
.dirty_nodes
|
||||
.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
|
||||
@@ -579,7 +596,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
||||
NodeType::Text(text) => {
|
||||
dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_text().build());
|
||||
|
||||
NodeTypeMut::Text(text)
|
||||
NodeTypeMut::Text(&mut text.text)
|
||||
}
|
||||
NodeType::Placeholder => NodeTypeMut::Placeholder,
|
||||
}
|
||||
|
||||
@@ -262,12 +262,7 @@ pub struct TreeStateViewEntry<'a, 'b> {
|
||||
impl<'a, 'b> AnyMapLike<'a> for TreeStateViewEntry<'a, 'b> {
|
||||
fn get<T: Any + Sync + Send>(self) -> Option<&'a T> {
|
||||
let slab = self.view.get_slab();
|
||||
dbg!(slab.is_some());
|
||||
slab.and_then(|slab| {
|
||||
let r = slab.get(self.id);
|
||||
dbg!(r.is_some());
|
||||
r
|
||||
})
|
||||
slab.and_then(|slab| slab.get(self.id))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user