real_dom.rs 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063
  1. //! A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
  2. use rustc_hash::{FxHashMap, FxHashSet};
  3. use shipyard::error::GetStorage;
  4. use shipyard::track::Untracked;
  5. use shipyard::{Component, Get, IntoBorrow, ScheduledWorkload, Unique, View, ViewMut, Workload};
  6. use shipyard::{SystemModificator, World};
  7. use std::any::TypeId;
  8. use std::collections::VecDeque;
  9. use std::ops::{Deref, DerefMut};
  10. use std::sync::{Arc, RwLock};
  11. use crate::node::{
  12. ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue, TextNode,
  13. };
  14. use crate::node_ref::{NodeMask, NodeMaskBuilder};
  15. use crate::node_watcher::NodeWatcher;
  16. use crate::passes::{DirtyNodeStates, PassDirection, TypeErasedState};
  17. use crate::prelude::AttributeMaskBuilder;
  18. use crate::tree::{TreeMut, TreeMutView, TreeRef, TreeRefView};
  19. use crate::NodeId;
  20. use crate::{FxDashSet, SendAnyMap};
  21. /// The context passes can receive when they are executed
  22. #[derive(Unique)]
  23. pub(crate) struct SendAnyMapWrapper(SendAnyMap);
  24. impl Deref for SendAnyMapWrapper {
  25. type Target = SendAnyMap;
  26. fn deref(&self) -> &Self::Target {
  27. &self.0
  28. }
  29. }
  30. /// The nodes that were changed when updating the state of the RealDom
  31. #[derive(Unique, Default)]
  32. pub(crate) struct DirtyNodesResult(FxDashSet<NodeId>);
  33. impl Deref for DirtyNodesResult {
  34. type Target = FxDashSet<NodeId>;
  35. fn deref(&self) -> &Self::Target {
  36. &self.0
  37. }
  38. }
  39. /// The nodes that have been marked as dirty in the RealDom
  40. pub(crate) struct NodesDirty<V: FromAnyValue + Send + Sync> {
  41. passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
  42. nodes_updated: FxHashMap<NodeId, NodeMask>,
  43. pub(crate) passes: Box<[TypeErasedState<V>]>,
  44. }
  45. impl<V: FromAnyValue + Send + Sync> NodesDirty<V> {
  46. /// Mark a node as dirty
  47. fn mark_dirty(&mut self, node_id: NodeId, mask: NodeMask) {
  48. self.passes_updated.entry(node_id).or_default().extend(
  49. self.passes
  50. .iter()
  51. .filter_map(|x| x.mask.overlaps(&mask).then_some(x.this_type_id)),
  52. );
  53. let nodes_updated = &mut self.nodes_updated;
  54. if let Some(node) = nodes_updated.get_mut(&node_id) {
  55. *node = node.union(&mask);
  56. } else {
  57. nodes_updated.insert(node_id, mask);
  58. }
  59. }
  60. /// Mark a node that has had a parent changed
  61. fn mark_parent_added_or_removed(&mut self, node_id: NodeId) {
  62. let hm = self.passes_updated.entry(node_id).or_default();
  63. for pass in &*self.passes {
  64. // If any of the states in this node depend on the parent then mark them as dirty
  65. for &pass in &pass.parent_dependancies_ids {
  66. hm.insert(pass);
  67. }
  68. }
  69. }
  70. /// Mark a node as having a child added or removed
  71. fn mark_child_changed(&mut self, node_id: NodeId) {
  72. let hm = self.passes_updated.entry(node_id).or_default();
  73. for pass in &*self.passes {
  74. // If any of the states in this node depend on the children then mark them as dirty
  75. for &pass in &pass.child_dependancies_ids {
  76. hm.insert(pass);
  77. }
  78. }
  79. }
  80. }
  81. type NodeWatchers<V> = Arc<RwLock<Vec<Box<dyn NodeWatcher<V> + Send + Sync>>>>;
  82. /// A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
  83. /// The render state passes from parent to children and or accumulates state from children to parents.
  84. /// To get started:
  85. /// 1) Implement [crate::passes::State] for each part of your state that you want to compute incrementally
  86. /// 2) Create a RealDom [RealDom::new], passing in each state you created
  87. /// 3) Update the state of the RealDom by adding and modifying nodes
  88. /// 4) Call [RealDom::update_state] to update the state of incrementally computed values on each node
  89. ///
  90. /// # Custom attribute values
  91. /// To allow custom values to be passed into attributes implement FromAnyValue on a type that can represent your custom value and specify the V generic to be that type. If you have many different custom values, it can be useful to use a enum type to represent the varients.
  92. pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
  93. pub(crate) world: World,
  94. nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
  95. pub(crate) dirty_nodes: NodesDirty<V>,
  96. node_watchers: NodeWatchers<V>,
  97. workload: ScheduledWorkload,
  98. root_id: NodeId,
  99. phantom: std::marker::PhantomData<V>,
  100. }
  101. impl<V: FromAnyValue + Send + Sync> RealDom<V> {
  102. /// Create a new RealDom with the given states that will be inserted and updated when needed
  103. pub fn new(tracked_states: impl Into<Box<[TypeErasedState<V>]>>) -> RealDom<V> {
  104. let mut tracked_states = tracked_states.into();
  105. // resolve dependants for each pass
  106. for i in 1..=tracked_states.len() {
  107. let (before, after) = tracked_states.split_at_mut(i);
  108. let (current, before) = before.split_last_mut().unwrap();
  109. for state in before.iter_mut().chain(after.iter_mut()) {
  110. let dependants = Arc::get_mut(&mut state.dependants).unwrap();
  111. // If this node depends on the other state as a parent, then the other state should update its children of the current type when it is invalidated
  112. if current
  113. .parent_dependancies_ids
  114. .contains(&state.this_type_id)
  115. && !dependants.child.contains(&current.this_type_id)
  116. {
  117. dependants.child.push(current.this_type_id);
  118. }
  119. // If this node depends on the other state as a child, then the other state should update its parent of the current type when it is invalidated
  120. if current.child_dependancies_ids.contains(&state.this_type_id)
  121. && !dependants.parent.contains(&current.this_type_id)
  122. {
  123. dependants.parent.push(current.this_type_id);
  124. }
  125. // If this node depends on the other state as a sibling, then the other state should update its siblings of the current type when it is invalidated
  126. if current.node_dependancies_ids.contains(&state.this_type_id)
  127. && !dependants.node.contains(&current.this_type_id)
  128. {
  129. dependants.node.push(current.this_type_id);
  130. }
  131. }
  132. // If the current state depends on itself, then it should update itself when it is invalidated
  133. let dependants = Arc::get_mut(&mut current.dependants).unwrap();
  134. match current.pass_direction {
  135. PassDirection::ChildToParent => {
  136. if !dependants.parent.contains(&current.this_type_id) {
  137. dependants.parent.push(current.this_type_id);
  138. }
  139. }
  140. PassDirection::ParentToChild => {
  141. if !dependants.child.contains(&current.this_type_id) {
  142. dependants.child.push(current.this_type_id);
  143. }
  144. }
  145. _ => {}
  146. }
  147. }
  148. let workload = construct_workload(&mut tracked_states);
  149. let (workload, _) = workload.build().unwrap();
  150. let mut world = World::new();
  151. let root_node: NodeType<V> = NodeType::Element(ElementNode {
  152. tag: "Root".to_string(),
  153. namespace: Some("Root".to_string()),
  154. attributes: FxHashMap::default(),
  155. listeners: FxHashSet::default(),
  156. });
  157. let root_id = world.add_entity(root_node);
  158. {
  159. let mut tree: TreeMutView = world.borrow().unwrap();
  160. tree.create_node(root_id);
  161. }
  162. let mut passes_updated = FxHashMap::default();
  163. let mut nodes_updated = FxHashMap::default();
  164. passes_updated.insert(
  165. root_id,
  166. tracked_states.iter().map(|x| x.this_type_id).collect(),
  167. );
  168. nodes_updated.insert(root_id, NodeMaskBuilder::ALL.build());
  169. RealDom {
  170. world,
  171. nodes_listening: FxHashMap::default(),
  172. dirty_nodes: NodesDirty {
  173. passes_updated,
  174. nodes_updated,
  175. passes: tracked_states,
  176. },
  177. node_watchers: Default::default(),
  178. workload,
  179. root_id,
  180. phantom: std::marker::PhantomData,
  181. }
  182. }
  183. /// Get a reference to the tree.
  184. pub fn tree_ref(&self) -> TreeRefView {
  185. self.world.borrow().unwrap()
  186. }
  187. /// Get a mutable reference to the tree.
  188. pub fn tree_mut(&self) -> TreeMutView {
  189. self.world.borrow().unwrap()
  190. }
  191. /// Create a new node of the given type in the dom and return a mutable reference to it.
  192. pub fn create_node(&mut self, node: impl Into<NodeType<V>>) -> NodeMut<'_, V> {
  193. let id = self.world.add_entity(node.into());
  194. self.tree_mut().create_node(id);
  195. self.dirty_nodes
  196. .passes_updated
  197. .entry(id)
  198. .or_default()
  199. .extend(self.dirty_nodes.passes.iter().map(|x| x.this_type_id));
  200. self.dirty_nodes
  201. .mark_dirty(id, NodeMaskBuilder::ALL.build());
  202. let watchers = self.node_watchers.clone();
  203. for watcher in &*watchers.read().unwrap() {
  204. watcher.on_node_added(NodeMut::new(id, self));
  205. }
  206. NodeMut::new(id, self)
  207. }
  208. /// Find all nodes that are listening for an event, sorted by there height in the dom progressing starting at the bottom and progressing up.
  209. /// This can be useful to avoid creating duplicate events.
  210. pub fn get_listening_sorted(&self, event: &str) -> Vec<NodeRef<V>> {
  211. if let Some(nodes) = self.nodes_listening.get(event) {
  212. let mut listening: Vec<_> = nodes
  213. .iter()
  214. .map(|id| (*id, self.tree_ref().height(*id).unwrap()))
  215. .collect();
  216. listening.sort_by(|(_, h1), (_, h2)| h1.cmp(h2).reverse());
  217. listening
  218. .into_iter()
  219. .map(|(id, _)| NodeRef { id, dom: self })
  220. .collect()
  221. } else {
  222. Vec::new()
  223. }
  224. }
  225. /// Returns the id of the root node.
  226. pub fn root_id(&self) -> NodeId {
  227. self.root_id
  228. }
  229. /// Check if a node exists in the dom.
  230. pub fn contains(&self, id: NodeId) -> bool {
  231. self.tree_ref().contains(id)
  232. }
  233. /// Get a reference to a node.
  234. pub fn get(&self, id: NodeId) -> Option<NodeRef<'_, V>> {
  235. self.contains(id).then_some(NodeRef { id, dom: self })
  236. }
  237. /// Get a mutable reference to a node.
  238. pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
  239. let contains = self.contains(id);
  240. contains.then(|| NodeMut::new(id, self))
  241. }
  242. /// Borrow a component from the world without updating the dirty nodes.
  243. fn borrow_raw<'a, B: IntoBorrow>(&'a self) -> Result<B, GetStorage>
  244. where
  245. B::Borrow: shipyard::Borrow<'a, View = B>,
  246. {
  247. self.world.borrow()
  248. }
  249. /// Borrow a component from the world without updating the dirty nodes.
  250. fn borrow_node_type_mut(&self) -> Result<ViewMut<NodeType<V>>, GetStorage> {
  251. self.world.borrow()
  252. }
  253. /// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
  254. pub fn update_state(
  255. &mut self,
  256. ctx: SendAnyMap,
  257. ) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
  258. let passes = std::mem::take(&mut self.dirty_nodes.passes_updated);
  259. let nodes_updated = std::mem::take(&mut self.dirty_nodes.nodes_updated);
  260. let dirty_nodes =
  261. DirtyNodeStates::with_passes(self.dirty_nodes.passes.iter().map(|p| p.this_type_id));
  262. let tree = self.tree_ref();
  263. for (node_id, passes) in passes {
  264. // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
  265. if let Some(height) = tree.height(node_id) {
  266. for pass in passes {
  267. dirty_nodes.insert(pass, node_id, height);
  268. }
  269. }
  270. }
  271. let _ = self.world.remove_unique::<DirtyNodeStates>();
  272. let _ = self.world.remove_unique::<SendAnyMapWrapper>();
  273. self.world.add_unique(dirty_nodes);
  274. self.world.add_unique(SendAnyMapWrapper(ctx));
  275. self.world.add_unique(DirtyNodesResult::default());
  276. self.workload.run_with_world(&self.world).unwrap();
  277. let dirty = self.world.remove_unique::<DirtyNodesResult>().unwrap();
  278. (dirty.0, nodes_updated)
  279. }
  280. /// Traverses the dom in a depth first manner, calling the provided function on each node.
  281. pub fn traverse_depth_first(&self, mut f: impl FnMut(NodeRef<V>)) {
  282. let mut stack = vec![self.root_id()];
  283. let tree = self.tree_ref();
  284. while let Some(id) = stack.pop() {
  285. if let Some(node) = self.get(id) {
  286. f(node);
  287. let children = tree.children_ids(id);
  288. stack.extend(children.iter().copied().rev());
  289. }
  290. }
  291. }
  292. /// Traverses the dom in a breadth first manner, calling the provided function on each node.
  293. pub fn traverse_breadth_first(&self, mut f: impl FnMut(NodeRef<V>)) {
  294. let mut queue = VecDeque::new();
  295. queue.push_back(self.root_id());
  296. let tree = self.tree_ref();
  297. while let Some(id) = queue.pop_front() {
  298. if let Some(node) = self.get(id) {
  299. f(node);
  300. let children = tree.children_ids(id);
  301. for id in children {
  302. queue.push_back(id);
  303. }
  304. }
  305. }
  306. }
  307. /// Traverses the dom in a depth first manner mutably, calling the provided function on each node.
  308. pub fn traverse_depth_first_mut(&mut self, mut f: impl FnMut(NodeMut<V>)) {
  309. let mut stack = vec![self.root_id()];
  310. while let Some(id) = stack.pop() {
  311. let tree = self.tree_ref();
  312. let mut children = tree.children_ids(id);
  313. drop(tree);
  314. children.reverse();
  315. if let Some(node) = self.get_mut(id) {
  316. let node = node;
  317. f(node);
  318. stack.extend(children.iter());
  319. }
  320. }
  321. }
  322. /// Traverses the dom in a breadth first manner mutably, calling the provided function on each node.
  323. pub fn traverse_breadth_first_mut(&mut self, mut f: impl FnMut(NodeMut<V>)) {
  324. let mut queue = VecDeque::new();
  325. queue.push_back(self.root_id());
  326. while let Some(id) = queue.pop_front() {
  327. let tree = self.tree_ref();
  328. let children = tree.children_ids(id);
  329. drop(tree);
  330. if let Some(node) = self.get_mut(id) {
  331. f(node);
  332. for id in children {
  333. queue.push_back(id);
  334. }
  335. }
  336. }
  337. }
  338. /// Adds a [`NodeWatcher`] to the dom. Node watchers are called whenever a node is created or removed.
  339. pub fn add_node_watcher(&mut self, watcher: impl NodeWatcher<V> + 'static + Send + Sync) {
  340. self.node_watchers.write().unwrap().push(Box::new(watcher));
  341. }
  342. /// Returns a reference to the underlying world. Any changes made to the world will not update the reactive system.
  343. pub fn raw_world(&self) -> &World {
  344. &self.world
  345. }
  346. /// Returns a mutable reference to the underlying world. Any changes made to the world will not update the reactive system.
  347. pub fn raw_world_mut(&mut self) -> &mut World {
  348. &mut self.world
  349. }
  350. }
  351. /// A reference to a tracked component in a node.
  352. pub struct ViewEntry<'a, V: Component + Send + Sync> {
  353. view: View<'a, V>,
  354. id: NodeId,
  355. }
  356. impl<'a, V: Component + Send + Sync> ViewEntry<'a, V> {
  357. fn new(view: View<'a, V>, id: NodeId) -> Self {
  358. Self { view, id }
  359. }
  360. }
  361. impl<'a, V: Component + Send + Sync> Deref for ViewEntry<'a, V> {
  362. type Target = V;
  363. fn deref(&self) -> &Self::Target {
  364. &self.view[self.id]
  365. }
  366. }
  367. /// A mutable reference to a tracked component in a node.
  368. pub struct ViewEntryMut<'a, V: Component<Tracking = Untracked> + Send + Sync> {
  369. view: ViewMut<'a, V, Untracked>,
  370. id: NodeId,
  371. }
  372. impl<'a, V: Component<Tracking = Untracked> + Send + Sync> ViewEntryMut<'a, V> {
  373. fn new(view: ViewMut<'a, V, Untracked>, id: NodeId) -> Self {
  374. Self { view, id }
  375. }
  376. }
  377. impl<'a, V: Component<Tracking = Untracked> + Send + Sync> Deref for ViewEntryMut<'a, V> {
  378. type Target = V;
  379. fn deref(&self) -> &Self::Target {
  380. self.view.get(self.id).unwrap()
  381. }
  382. }
  383. impl<'a, V: Component<Tracking = Untracked> + Send + Sync> DerefMut for ViewEntryMut<'a, V> {
  384. fn deref_mut(&mut self) -> &mut Self::Target {
  385. (&mut self.view).get(self.id).unwrap()
  386. }
  387. }
  388. /// A immutable view of a node
  389. pub trait NodeImmutable<V: FromAnyValue + Send + Sync = ()>: Sized {
  390. /// Get the real dom this node was created in
  391. fn real_dom(&self) -> &RealDom<V>;
  392. /// Get the id of the current node
  393. fn id(&self) -> NodeId;
  394. /// Get the type of the current node
  395. #[inline]
  396. fn node_type(&self) -> ViewEntry<NodeType<V>> {
  397. self.get().unwrap()
  398. }
  399. /// Get a component from the current node
  400. #[inline]
  401. fn get<'a, T: Component + Sync + Send>(&'a self) -> Option<ViewEntry<'a, T>> {
  402. // self.real_dom().tree.get(self.id())
  403. let view: View<'a, T> = self.real_dom().borrow_raw().ok()?;
  404. view.contains(self.id())
  405. .then(|| ViewEntry::new(view, self.id()))
  406. }
  407. /// Get the ids of the children of the current node
  408. #[inline]
  409. fn child_ids(&self) -> Vec<NodeId> {
  410. self.real_dom().tree_ref().children_ids(self.id())
  411. }
  412. /// Get the children of the current node
  413. #[inline]
  414. fn children(&self) -> Vec<NodeRef<V>> {
  415. self.child_ids()
  416. .iter()
  417. .map(|id| NodeRef {
  418. id: *id,
  419. dom: self.real_dom(),
  420. })
  421. .collect()
  422. }
  423. /// Get the id of the parent of the current node
  424. #[inline]
  425. fn parent_id(&self) -> Option<NodeId> {
  426. self.real_dom().tree_ref().parent_id(self.id())
  427. }
  428. /// Get the parent of the current node
  429. #[inline]
  430. fn parent(&self) -> Option<NodeRef<V>> {
  431. self.parent_id().map(|id| NodeRef {
  432. id,
  433. dom: self.real_dom(),
  434. })
  435. }
  436. /// Get the node after the current node
  437. #[inline]
  438. fn next(&self) -> Option<NodeRef<V>> {
  439. let parent = self.parent_id()?;
  440. let children = self.real_dom().tree_ref().children_ids(parent);
  441. let index = children.iter().position(|id| *id == self.id())?;
  442. if index + 1 < children.len() {
  443. Some(NodeRef {
  444. id: children[index + 1],
  445. dom: self.real_dom(),
  446. })
  447. } else {
  448. None
  449. }
  450. }
  451. /// Get the node before the current node
  452. #[inline]
  453. fn prev(&self) -> Option<NodeRef<V>> {
  454. let parent = self.parent_id()?;
  455. let children = self.real_dom().tree_ref().children_ids(parent);
  456. let index = children.iter().position(|id| *id == self.id())?;
  457. if index > 0 {
  458. Some(NodeRef {
  459. id: children[index - 1],
  460. dom: self.real_dom(),
  461. })
  462. } else {
  463. None
  464. }
  465. }
  466. /// Get the height of the current node in the tree (the number of nodes between the current node and the root)
  467. #[inline]
  468. fn height(&self) -> u16 {
  469. self.real_dom().tree_ref().height(self.id()).unwrap()
  470. }
  471. }
  472. /// An immutable reference to a node in a RealDom
  473. pub struct NodeRef<'a, V: FromAnyValue + Send + Sync = ()> {
  474. id: NodeId,
  475. dom: &'a RealDom<V>,
  476. }
  477. impl<'a, V: FromAnyValue + Send + Sync> Clone for NodeRef<'a, V> {
  478. fn clone(&self) -> Self {
  479. Self {
  480. id: self.id,
  481. dom: self.dom,
  482. }
  483. }
  484. }
  485. impl<'a, V: FromAnyValue + Send + Sync> Copy for NodeRef<'a, V> {}
  486. impl<'a, V: FromAnyValue + Send + Sync> NodeImmutable<V> for NodeRef<'a, V> {
  487. #[inline(always)]
  488. fn real_dom(&self) -> &RealDom<V> {
  489. self.dom
  490. }
  491. #[inline(always)]
  492. fn id(&self) -> NodeId {
  493. self.id
  494. }
  495. }
  496. /// A mutable refrence to a node in the RealDom that tracks what States need to be updated
  497. pub struct NodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
  498. id: NodeId,
  499. dom: &'a mut RealDom<V>,
  500. }
  501. impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
  502. /// Create a new mutable refrence to a node in a RealDom
  503. pub fn new(id: NodeId, dom: &'a mut RealDom<V>) -> Self {
  504. Self { id, dom }
  505. }
  506. }
  507. impl<'a, V: FromAnyValue + Send + Sync> NodeImmutable<V> for NodeMut<'a, V> {
  508. #[inline(always)]
  509. fn real_dom(&self) -> &RealDom<V> {
  510. self.dom
  511. }
  512. #[inline(always)]
  513. fn id(&self) -> NodeId {
  514. self.id
  515. }
  516. }
  517. impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
  518. /// Get the real dom this node was created in mutably
  519. #[inline(always)]
  520. pub fn real_dom_mut(&mut self) -> &mut RealDom<V> {
  521. self.dom
  522. }
  523. /// Get the parent of this node mutably
  524. #[inline]
  525. pub fn parent_mut(&mut self) -> Option<NodeMut<V>> {
  526. self.parent_id().map(|id| NodeMut { id, dom: self.dom })
  527. }
  528. /// Get a component from the current node mutably
  529. #[inline]
  530. pub fn get_mut<T: Component<Tracking = Untracked> + Sync + Send>(
  531. &mut self,
  532. ) -> Option<ViewEntryMut<T>> {
  533. // mark the node state as dirty
  534. self.dom
  535. .dirty_nodes
  536. .passes_updated
  537. .entry(self.id)
  538. .or_default()
  539. .insert(TypeId::of::<T>());
  540. let view_mut: ViewMut<T> = self.dom.borrow_raw().ok()?;
  541. view_mut
  542. .contains(self.id)
  543. .then_some(ViewEntryMut::new(view_mut, self.id))
  544. }
  545. /// Insert a custom component into this node
  546. ///
  547. /// Note: Components that implement State and are added when the RealDom is created will automatically be created
  548. #[inline]
  549. pub fn insert<T: Component + Sync + Send>(&mut self, value: T) {
  550. // mark the node state as dirty
  551. self.dom
  552. .dirty_nodes
  553. .passes_updated
  554. .entry(self.id)
  555. .or_default()
  556. .insert(TypeId::of::<T>());
  557. self.dom.world.add_component(self.id, value);
  558. }
  559. /// Get the next node
  560. #[inline]
  561. pub fn next_mut(self) -> Option<NodeMut<'a, V>> {
  562. let parent = self.parent_id()?;
  563. let children = self.dom.tree_mut().children_ids(parent);
  564. let index = children.iter().position(|id| *id == self.id)?;
  565. if index + 1 < children.len() {
  566. Some(NodeMut::new(children[index + 1], self.dom))
  567. } else {
  568. None
  569. }
  570. }
  571. /// Get the previous node
  572. #[inline]
  573. pub fn prev_mut(self) -> Option<NodeMut<'a, V>> {
  574. let parent = self.parent_id()?;
  575. let children = self.dom.tree_ref().children_ids(parent);
  576. let index = children.iter().position(|id| *id == self.id)?;
  577. if index > 0 {
  578. Some(NodeMut::new(children[index - 1], self.dom))
  579. } else {
  580. None
  581. }
  582. }
  583. /// Add the given node to the end of this nodes children
  584. #[inline]
  585. pub fn add_child(&mut self, child: NodeId) {
  586. self.dom.dirty_nodes.mark_child_changed(self.id);
  587. self.dom.dirty_nodes.mark_parent_added_or_removed(child);
  588. self.dom.tree_mut().add_child(self.id, child);
  589. NodeMut::new(child, self.dom).mark_moved();
  590. }
  591. /// Insert this node after the given node
  592. #[inline]
  593. pub fn insert_after(&mut self, old: NodeId) {
  594. let id = self.id();
  595. let parent_id = { self.dom.tree_ref().parent_id(old) };
  596. if let Some(parent_id) = parent_id {
  597. self.dom.dirty_nodes.mark_child_changed(parent_id);
  598. self.dom.dirty_nodes.mark_parent_added_or_removed(id);
  599. }
  600. self.dom.tree_mut().insert_after(old, id);
  601. self.mark_moved();
  602. }
  603. /// Insert this node before the given node
  604. #[inline]
  605. pub fn insert_before(&mut self, old: NodeId) {
  606. let id = self.id();
  607. let parent_id = { self.dom.tree_ref().parent_id(old) };
  608. if let Some(parent_id) = parent_id {
  609. self.dom.dirty_nodes.mark_child_changed(parent_id);
  610. self.dom.dirty_nodes.mark_parent_added_or_removed(id);
  611. }
  612. self.dom.tree_mut().insert_before(old, id);
  613. self.mark_moved();
  614. }
  615. /// Remove this node from the RealDom
  616. #[inline]
  617. pub fn remove(&mut self) {
  618. let id = self.id();
  619. {
  620. let RealDom {
  621. world,
  622. nodes_listening,
  623. ..
  624. } = &mut self.dom;
  625. let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
  626. if let NodeType::Element(ElementNode { listeners, .. })
  627. | NodeType::Text(TextNode { listeners, .. }) = (&mut view).get(id).unwrap()
  628. {
  629. let listeners = std::mem::take(listeners);
  630. for event in listeners {
  631. nodes_listening.get_mut(&event).unwrap().remove(&id);
  632. }
  633. }
  634. }
  635. self.mark_removed();
  636. let parent_id = { self.dom.tree_ref().parent_id(id) };
  637. if let Some(parent_id) = parent_id {
  638. self.real_dom_mut()
  639. .dirty_nodes
  640. .mark_child_changed(parent_id);
  641. }
  642. let children_ids = self.child_ids();
  643. let children_ids_vec = children_ids.to_vec();
  644. for child in children_ids_vec {
  645. self.dom.get_mut(child).unwrap().remove();
  646. }
  647. self.dom.tree_mut().remove(id);
  648. self.real_dom_mut().raw_world_mut().delete_entity(id);
  649. }
  650. /// Replace this node with a different node
  651. #[inline]
  652. pub fn replace(mut self, new: NodeId) {
  653. self.mark_removed();
  654. if let Some(parent_id) = self.parent_id() {
  655. self.real_dom_mut()
  656. .dirty_nodes
  657. .mark_child_changed(parent_id);
  658. self.real_dom_mut()
  659. .dirty_nodes
  660. .mark_parent_added_or_removed(new);
  661. }
  662. let id = self.id();
  663. self.dom.tree_mut().replace(id, new);
  664. }
  665. /// Add an event listener
  666. #[inline]
  667. pub fn add_event_listener(&mut self, event: &str) {
  668. let id = self.id();
  669. let RealDom {
  670. world,
  671. dirty_nodes,
  672. nodes_listening,
  673. ..
  674. } = &mut self.dom;
  675. let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
  676. let node_type: &mut NodeType<V> = (&mut view).get(self.id).unwrap();
  677. if let NodeType::Element(ElementNode { listeners, .. })
  678. | NodeType::Text(TextNode { listeners, .. }) = node_type
  679. {
  680. dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
  681. listeners.insert(event.to_string());
  682. match nodes_listening.get_mut(event) {
  683. Some(hs) => {
  684. hs.insert(id);
  685. }
  686. None => {
  687. let mut hs = FxHashSet::default();
  688. hs.insert(id);
  689. nodes_listening.insert(event.to_string(), hs);
  690. }
  691. }
  692. }
  693. }
  694. /// Remove an event listener
  695. #[inline]
  696. pub fn remove_event_listener(&mut self, event: &str) {
  697. let id = self.id();
  698. let RealDom {
  699. world,
  700. dirty_nodes,
  701. nodes_listening,
  702. ..
  703. } = &mut self.dom;
  704. let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
  705. let node_type: &mut NodeType<V> = (&mut view).get(self.id).unwrap();
  706. if let NodeType::Element(ElementNode { listeners, .. })
  707. | NodeType::Text(TextNode { listeners, .. }) = node_type
  708. {
  709. dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
  710. listeners.remove(event);
  711. nodes_listening.get_mut(event).unwrap().remove(&id);
  712. }
  713. }
  714. /// mark that this node was removed for the incremental system
  715. fn mark_removed(&mut self) {
  716. let watchers = self.dom.node_watchers.clone();
  717. for watcher in &*watchers.read().unwrap() {
  718. watcher.on_node_removed(NodeMut::new(self.id(), self.dom));
  719. }
  720. }
  721. /// mark that this node was moved for the incremental system
  722. fn mark_moved(&mut self) {
  723. let watchers = self.dom.node_watchers.clone();
  724. for watcher in &*watchers.read().unwrap() {
  725. watcher.on_node_moved(NodeMut::new(self.id(), self.dom));
  726. }
  727. }
  728. /// Get a mutable reference to the type of the current node
  729. pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
  730. let id = self.id();
  731. let RealDom {
  732. world, dirty_nodes, ..
  733. } = &mut self.dom;
  734. let view: ViewMut<NodeType<V>> = world.borrow().unwrap();
  735. let node_type = ViewEntryMut::new(view, id);
  736. match &*node_type {
  737. NodeType::Element(_) => NodeTypeMut::Element(ElementNodeMut {
  738. id,
  739. element: node_type,
  740. dirty_nodes,
  741. }),
  742. NodeType::Text(_) => NodeTypeMut::Text(TextNodeMut {
  743. id,
  744. text: node_type,
  745. dirty_nodes,
  746. }),
  747. NodeType::Placeholder => NodeTypeMut::Placeholder,
  748. }
  749. }
  750. /// Set the type of the current node
  751. pub fn set_type(&mut self, new: NodeType<V>) {
  752. {
  753. let mut view: ViewMut<NodeType<V>> = self.dom.borrow_node_type_mut().unwrap();
  754. *(&mut view).get(self.id).unwrap() = new;
  755. }
  756. self.dom
  757. .dirty_nodes
  758. .mark_dirty(self.id, NodeMaskBuilder::ALL.build())
  759. }
  760. /// Clone a node and it's children and returns the id of the new node.
  761. /// This is more effecient than creating the node from scratch because it can pre-allocate the memory required.
  762. #[inline]
  763. pub fn clone_node(&mut self) -> NodeId {
  764. let new_node = self.node_type().clone();
  765. let rdom = self.real_dom_mut();
  766. let new_id = rdom.create_node(new_node).id();
  767. let children = self.child_ids();
  768. let children = children.to_vec();
  769. let rdom = self.real_dom_mut();
  770. for child in children {
  771. let child_id = rdom.get_mut(child).unwrap().clone_node();
  772. rdom.get_mut(new_id).unwrap().add_child(child_id);
  773. }
  774. new_id
  775. }
  776. }
  777. /// A mutable refrence to the type of a node in the RealDom
  778. pub enum NodeTypeMut<'a, V: FromAnyValue + Send + Sync = ()> {
  779. /// An element node
  780. Element(ElementNodeMut<'a, V>),
  781. /// A text node
  782. Text(TextNodeMut<'a, V>),
  783. /// A placeholder node
  784. Placeholder,
  785. }
  786. /// A mutable refrence to a text node in the RealDom
  787. pub struct TextNodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
  788. id: NodeId,
  789. text: ViewEntryMut<'a, NodeType<V>>,
  790. dirty_nodes: &'a mut NodesDirty<V>,
  791. }
  792. impl<V: FromAnyValue + Send + Sync> TextNodeMut<'_, V> {
  793. /// Get the underlying test of the node
  794. pub fn text(&self) -> &str {
  795. match &*self.text {
  796. NodeType::Text(text) => &text.text,
  797. _ => unreachable!(),
  798. }
  799. }
  800. /// Get the underlying text mutably
  801. pub fn text_mut(&mut self) -> &mut String {
  802. self.dirty_nodes
  803. .mark_dirty(self.id, NodeMaskBuilder::new().with_text().build());
  804. match &mut *self.text {
  805. NodeType::Text(text) => &mut text.text,
  806. _ => unreachable!(),
  807. }
  808. }
  809. }
  810. impl<V: FromAnyValue + Send + Sync> Deref for TextNodeMut<'_, V> {
  811. type Target = String;
  812. fn deref(&self) -> &Self::Target {
  813. match &*self.text {
  814. NodeType::Text(text) => &text.text,
  815. _ => unreachable!(),
  816. }
  817. }
  818. }
  819. impl<V: FromAnyValue + Send + Sync> DerefMut for TextNodeMut<'_, V> {
  820. fn deref_mut(&mut self) -> &mut Self::Target {
  821. self.text_mut()
  822. }
  823. }
  824. /// A mutable refrence to a text Element node in the RealDom
  825. pub struct ElementNodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
  826. id: NodeId,
  827. element: ViewEntryMut<'a, NodeType<V>>,
  828. dirty_nodes: &'a mut NodesDirty<V>,
  829. }
  830. impl<V: FromAnyValue + Send + Sync> ElementNodeMut<'_, V> {
  831. /// Get the current element
  832. fn element(&self) -> &ElementNode<V> {
  833. match &*self.element {
  834. NodeType::Element(element) => element,
  835. _ => unreachable!(),
  836. }
  837. }
  838. /// Get the current element mutably (does not mark anything as dirty)
  839. fn element_mut(&mut self) -> &mut ElementNode<V> {
  840. match &mut *self.element {
  841. NodeType::Element(element) => element,
  842. _ => unreachable!(),
  843. }
  844. }
  845. /// Get the tag of the element
  846. pub fn tag(&self) -> &str {
  847. &self.element().tag
  848. }
  849. /// Get a mutable reference to the tag of the element
  850. pub fn tag_mut(&mut self) -> &mut String {
  851. self.dirty_nodes
  852. .mark_dirty(self.id, NodeMaskBuilder::new().with_tag().build());
  853. &mut self.element_mut().tag
  854. }
  855. /// Get a reference to the namespace the element is in
  856. pub fn namespace(&self) -> Option<&str> {
  857. self.element().namespace.as_deref()
  858. }
  859. /// Get a mutable reference to the namespace the element is in
  860. pub fn namespace_mut(&mut self) -> &mut Option<String> {
  861. self.dirty_nodes
  862. .mark_dirty(self.id, NodeMaskBuilder::new().with_namespace().build());
  863. &mut self.element_mut().namespace
  864. }
  865. /// Get a reference to all of the attributes currently set on the element
  866. pub fn attributes(&self) -> &FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>> {
  867. &self.element().attributes
  868. }
  869. /// Set an attribute in the element
  870. pub fn set_attribute(
  871. &mut self,
  872. name: impl Into<OwnedAttributeDiscription>,
  873. value: impl Into<OwnedAttributeValue<V>>,
  874. ) -> Option<OwnedAttributeValue<V>> {
  875. let name = name.into();
  876. let value = value.into();
  877. self.dirty_nodes.mark_dirty(
  878. self.id,
  879. NodeMaskBuilder::new()
  880. .with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
  881. .build(),
  882. );
  883. self.element_mut().attributes.insert(name, value)
  884. }
  885. /// Remove an attribute from the element
  886. pub fn remove_attribute(
  887. &mut self,
  888. name: &OwnedAttributeDiscription,
  889. ) -> Option<OwnedAttributeValue<V>> {
  890. self.dirty_nodes.mark_dirty(
  891. self.id,
  892. NodeMaskBuilder::new()
  893. .with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
  894. .build(),
  895. );
  896. self.element_mut().attributes.remove(name)
  897. }
  898. /// Get an attribute of the element
  899. pub fn get_attribute_mut(
  900. &mut self,
  901. name: &OwnedAttributeDiscription,
  902. ) -> Option<&mut OwnedAttributeValue<V>> {
  903. self.dirty_nodes.mark_dirty(
  904. self.id,
  905. NodeMaskBuilder::new()
  906. .with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
  907. .build(),
  908. );
  909. self.element_mut().attributes.get_mut(name)
  910. }
  911. /// Get the set of all events the element is listening to
  912. pub fn listeners(&self) -> &FxHashSet<String> {
  913. &self.element().listeners
  914. }
  915. }
  916. // Create a workload from all of the passes. This orders the passes so that each pass will only run at most once.
  917. fn construct_workload<V: FromAnyValue + Send + Sync>(
  918. passes: &mut [TypeErasedState<V>],
  919. ) -> Workload {
  920. let mut workload = Workload::new("Main Workload");
  921. // Assign a unique index to keep track of each pass
  922. let mut unresloved_workloads = passes
  923. .iter_mut()
  924. .enumerate()
  925. .map(|(i, pass)| {
  926. let workload = Some(pass.create_workload());
  927. (i, pass, workload)
  928. })
  929. .collect::<Vec<_>>();
  930. // set all the labels
  931. for (id, _, workload) in &mut unresloved_workloads {
  932. *workload = Some(workload.take().unwrap().tag(id.to_string()));
  933. }
  934. // mark any dependancies
  935. for i in 0..unresloved_workloads.len() {
  936. let (_, pass, _) = &unresloved_workloads[i];
  937. let all_dependancies: Vec<_> = pass.combined_dependancy_type_ids().collect();
  938. for ty_id in all_dependancies {
  939. let &(dependancy_id, _, _) = unresloved_workloads
  940. .iter()
  941. .find(|(_, pass, _)| pass.this_type_id == ty_id)
  942. .unwrap();
  943. let (_, _, workload) = &mut unresloved_workloads[i];
  944. *workload = workload
  945. .take()
  946. .map(|workload| workload.after_all(dependancy_id.to_string()));
  947. }
  948. }
  949. // Add all of the passes
  950. for (_, _, mut workload_system) in unresloved_workloads {
  951. workload = workload.with_system(workload_system.take().unwrap());
  952. }
  953. workload
  954. }