1use std::{
4 any::TypeId,
5 ops::{
6 Deref,
7 DerefMut,
8 },
9 sync::Arc,
10};
11
12use rustc_hash::{
13 FxHashMap,
14 FxHashSet,
15};
16use shipyard::{
17 error::GetStorage,
18 track::Untracked,
19 Component,
20 Get,
21 IntoBorrow,
22 ScheduledWorkload,
23 SystemModificator,
24 Unique,
25 View,
26 ViewMut,
27 Workload,
28 World,
29};
30
31use crate::{
32 events::EventName,
33 node::{
34 ElementNode,
35 FromAnyValue,
36 NodeType,
37 OwnedAttributeValue,
38 },
39 node_ref::{
40 NodeMask,
41 NodeMaskBuilder,
42 },
43 passes::{
44 Dependant,
45 DirtyNodeStates,
46 PassDirection,
47 TypeErasedState,
48 },
49 prelude::{
50 AttributeMaskBuilder,
51 AttributeName,
52 },
53 tags::TagName,
54 tree::{
55 TreeMut,
56 TreeMutView,
57 TreeRef,
58 TreeRefView,
59 },
60 NodeId,
61 SendAnyMap,
62};
63
64#[derive(Unique)]
66pub(crate) struct SendAnyMapWrapper(SendAnyMap);
67
68impl Deref for SendAnyMapWrapper {
69 type Target = SendAnyMap;
70
71 fn deref(&self) -> &Self::Target {
72 &self.0
73 }
74}
75
76pub(crate) struct NodesDirty<V: FromAnyValue + Send + Sync> {
78 passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
79 nodes_updated: FxHashMap<NodeId, NodeMask>,
80 nodes_created: FxHashSet<NodeId>,
81 pub(crate) passes: Box<[TypeErasedState<V>]>,
82}
83
84impl<V: FromAnyValue + Send + Sync> NodesDirty<V> {
85 fn mark_dirty(&mut self, node_id: NodeId, mask: NodeMask) {
87 self.passes_updated.entry(node_id).or_default().extend(
88 self.passes
89 .iter()
90 .filter_map(|x| x.mask.overlaps(&mask).then_some(x.this_type_id)),
91 );
92 let nodes_updated = &mut self.nodes_updated;
93 if let Some(node) = nodes_updated.get_mut(&node_id) {
94 *node = node.union(&mask);
95 } else {
96 nodes_updated.insert(node_id, mask);
97 }
98 }
99
100 fn mark_parent_added_or_removed(&mut self, node_id: NodeId) {
102 let hm = self.passes_updated.entry(node_id).or_default();
103 for pass in &*self.passes {
104 for &pass in &pass.parent_dependancies_ids {
106 hm.insert(pass);
107 }
108 }
109 }
110
111 fn mark_child_changed(&mut self, node_id: NodeId) {
113 let hm = self.passes_updated.entry(node_id).or_default();
114 for pass in &*self.passes {
115 for &pass in &pass.child_dependancies_ids {
117 hm.insert(pass);
118 }
119 }
120 }
121}
122
123pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
134 pub(crate) world: World,
135 nodes_listening: FxHashMap<EventName, FxHashSet<NodeId>>,
136 pub(crate) dirty_nodes: NodesDirty<V>,
137 workload: ScheduledWorkload,
138 root_id: NodeId,
139 phantom: std::marker::PhantomData<V>,
140}
141
142impl<V: FromAnyValue + Send + Sync> RealDom<V> {
143 pub fn new(tracked_states: impl Into<Box<[TypeErasedState<V>]>>) -> RealDom<V> {
145 let mut tracked_states = tracked_states.into();
146 for i in 1..=tracked_states.len() {
148 let (before, after) = tracked_states.split_at_mut(i);
149 let (current, before) = before.split_last_mut().unwrap();
150 for state in before.iter_mut().chain(after.iter_mut()) {
151 let dependants = Arc::get_mut(&mut state.dependants).unwrap();
152
153 let current_dependant = Dependant {
154 type_id: current.this_type_id,
155 enter_shadow_dom: current.enter_shadow_dom,
156 };
157
158 if current
160 .parent_dependancies_ids
161 .contains(&state.this_type_id)
162 && !dependants.child.contains(¤t_dependant)
163 {
164 dependants.child.push(current_dependant);
165 }
166 if current.child_dependancies_ids.contains(&state.this_type_id)
168 && !dependants.parent.contains(¤t_dependant)
169 {
170 dependants.parent.push(current_dependant);
171 }
172 if current.node_dependancies_ids.contains(&state.this_type_id)
174 && !dependants.node.contains(¤t.this_type_id)
175 {
176 dependants.node.push(current.this_type_id);
177 }
178 }
179 let dependants = Arc::get_mut(&mut current.dependants).unwrap();
181 let current_dependant = Dependant {
182 type_id: current.this_type_id,
183 enter_shadow_dom: current.enter_shadow_dom,
184 };
185 match current.pass_direction {
186 PassDirection::ChildToParent => {
187 if !dependants.parent.contains(¤t_dependant) {
188 dependants.parent.push(current_dependant);
189 }
190 }
191 PassDirection::ParentToChild => {
192 if !dependants.child.contains(¤t_dependant) {
193 dependants.child.push(current_dependant);
194 }
195 }
196 _ => {}
197 }
198 }
199 let workload = construct_workload(&mut tracked_states);
200 let (workload, _) = workload.build().unwrap();
201 let mut world = World::new();
202 let root_node: NodeType<V> = NodeType::Element(ElementNode {
203 tag: TagName::Root,
204 attributes: FxHashMap::default(),
205 listeners: FxHashSet::default(),
206 });
207 let root_id = world.add_entity(root_node);
208 {
209 let mut tree: TreeMutView = world.borrow().unwrap();
210 tree.create_node(root_id);
211 }
212
213 let mut passes_updated = FxHashMap::default();
214 let mut nodes_updated = FxHashMap::default();
215
216 passes_updated.insert(
217 root_id,
218 tracked_states.iter().map(|x| x.this_type_id).collect(),
219 );
220 nodes_updated.insert(root_id, NodeMaskBuilder::ALL.build());
221
222 RealDom {
223 world,
224 nodes_listening: FxHashMap::default(),
225 dirty_nodes: NodesDirty {
226 passes_updated,
227 nodes_updated,
228 passes: tracked_states,
229 nodes_created: [root_id].into_iter().collect(),
230 },
231 workload,
232 root_id,
233 phantom: std::marker::PhantomData,
234 }
235 }
236
237 pub fn deep_clone_node(&mut self, node_id: NodeId) -> NodeMut<V> {
238 let clone_id = self.get_mut(node_id).unwrap().clone_node();
239 self.get_mut(clone_id).unwrap()
240 }
241
242 pub fn tree_ref(&self) -> TreeRefView {
244 self.world.borrow().unwrap()
245 }
246
247 pub fn tree_mut(&self) -> TreeMutView {
249 self.world.borrow().unwrap()
250 }
251
252 pub fn create_node(&mut self, node: impl Into<NodeType<V>>) -> NodeMut<'_, V> {
254 let node = node.into();
255
256 let id = self.world.add_entity(node);
257 self.tree_mut().create_node(id);
258
259 self.dirty_nodes
260 .passes_updated
261 .entry(id)
262 .or_default()
263 .extend(self.dirty_nodes.passes.iter().map(|x| x.this_type_id));
264 self.dirty_nodes
265 .mark_dirty(id, NodeMaskBuilder::ALL.build());
266 self.dirty_nodes.nodes_created.insert(id);
267
268 NodeMut::new(id, self)
269 }
270
271 pub fn is_node_listening(&self, node_id: &NodeId, event: &EventName) -> bool {
272 self.nodes_listening
273 .get(event)
274 .map(|listeners| listeners.contains(node_id))
275 .unwrap_or_default()
276 }
277
278 pub fn get_listeners(&self, event: &EventName) -> Vec<NodeRef<V>> {
279 if let Some(nodes) = self.nodes_listening.get(event) {
280 nodes
281 .iter()
282 .map(|id| NodeRef { id: *id, dom: self })
283 .collect()
284 } else {
285 Vec::new()
286 }
287 }
288
289 pub fn root_id(&self) -> NodeId {
291 self.root_id
292 }
293
294 pub fn contains(&self, id: NodeId) -> bool {
296 self.tree_ref().contains(id)
297 }
298
299 pub fn get(&self, id: NodeId) -> Option<NodeRef<'_, V>> {
301 self.contains(id).then_some(NodeRef { id, dom: self })
302 }
303
304 pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
306 let contains = self.contains(id);
307 contains.then(|| NodeMut::new(id, self))
308 }
309
310 #[inline(always)]
312 fn borrow_raw<'a, B: IntoBorrow>(&'a self) -> Result<B, GetStorage>
313 where
314 B::Borrow: shipyard::Borrow<'a, View = B>,
315 {
316 self.world.borrow()
317 }
318
319 fn borrow_node_type_mut(&self) -> Result<ViewMut<NodeType<V>>, GetStorage> {
321 self.world.borrow()
322 }
323
324 pub fn update_state(&mut self, ctx: SendAnyMap) -> FxHashMap<NodeId, NodeMask> {
326 let passes = std::mem::take(&mut self.dirty_nodes.passes_updated);
327 let nodes_updated = std::mem::take(&mut self.dirty_nodes.nodes_updated);
328
329 let dirty_nodes =
330 DirtyNodeStates::with_passes(self.dirty_nodes.passes.iter().map(|p| p.this_type_id));
331 let tree = self.tree_ref();
332 for (node_id, passes) in passes {
333 if let Some(height) = tree.height(node_id) {
335 for pass in passes {
336 dirty_nodes.insert(pass, node_id, height);
337 }
338 }
339 }
340
341 let _ = self.world.remove_unique::<DirtyNodeStates>();
342 let _ = self.world.remove_unique::<SendAnyMapWrapper>();
343 self.world.add_unique(dirty_nodes);
344 self.world.add_unique(SendAnyMapWrapper(ctx));
345
346 self.workload.run_with_world(&self.world).unwrap();
347
348 nodes_updated
349 }
350
351 pub fn traverse_depth_first_advanced(&self, mut f: impl FnMut(NodeRef<V>) -> bool) {
355 let mut stack = vec![self.root_id()];
356 let tree = self.tree_ref();
357 while let Some(id) = stack.pop() {
358 if let Some(node) = self.get(id) {
359 let traverse_children = f(node);
360 if traverse_children {
361 let children = tree.children_ids_advanced(id, false);
362 stack.extend(children.iter().copied().rev());
363 }
364 }
365 }
366 }
367
368 pub fn traverse_depth_first(&self, mut f: impl FnMut(NodeRef<V>)) {
370 self.traverse_depth_first_advanced(move |node| {
371 f(node);
372 true
373 })
374 }
375
376 pub fn raw_world(&self) -> &World {
378 &self.world
379 }
380
381 pub fn raw_world_mut(&mut self) -> &mut World {
383 &mut self.world
384 }
385}
386
387pub struct ViewEntry<'a, V: Component + Send + Sync> {
389 view: View<'a, V>,
390 id: NodeId,
391}
392
393impl<'a, V: Component + Send + Sync> ViewEntry<'a, V> {
394 fn new(view: View<'a, V>, id: NodeId) -> Self {
395 Self { view, id }
396 }
397}
398
399impl<V: Component + Send + Sync> Deref for ViewEntry<'_, V> {
400 type Target = V;
401
402 fn deref(&self) -> &Self::Target {
403 &self.view[self.id]
404 }
405}
406
407pub struct ViewEntryMut<'a, V: Component<Tracking = Untracked> + Send + Sync> {
409 view: ViewMut<'a, V, Untracked>,
410 id: NodeId,
411}
412
413impl<'a, V: Component<Tracking = Untracked> + Send + Sync> ViewEntryMut<'a, V> {
414 fn new(view: ViewMut<'a, V, Untracked>, id: NodeId) -> Self {
415 Self { view, id }
416 }
417}
418
419impl<V: Component<Tracking = Untracked> + Send + Sync> Deref for ViewEntryMut<'_, V> {
420 type Target = V;
421
422 fn deref(&self) -> &Self::Target {
423 self.view.get(self.id).unwrap()
424 }
425}
426
427impl<V: Component<Tracking = Untracked> + Send + Sync> DerefMut for ViewEntryMut<'_, V> {
428 fn deref_mut(&mut self) -> &mut Self::Target {
429 (&mut self.view).get(self.id).unwrap()
430 }
431}
432
433pub trait NodeImmutable<V: FromAnyValue + Send + Sync = ()>: Sized {
435 fn real_dom(&self) -> &RealDom<V>;
437
438 fn id(&self) -> NodeId;
440
441 #[inline]
443 fn node_type(&self) -> ViewEntry<NodeType<V>> {
444 self.get().unwrap()
445 }
446
447 #[inline(always)]
449 fn get<'a, T: Component + Sync + Send>(&'a self) -> Option<ViewEntry<'a, T>> {
450 let view: View<'a, T> = self.real_dom().borrow_raw().ok()?;
452 view.contains(self.id())
453 .then(|| ViewEntry::new(view, self.id()))
454 }
455
456 #[inline]
458 fn children_ids_advanced(&self, id: NodeId, enter_shadow_dom: bool) -> Vec<NodeId> {
459 self.real_dom()
460 .tree_ref()
461 .children_ids_advanced(id, enter_shadow_dom)
462 }
463
464 #[inline]
466 fn child_ids(&self) -> Vec<NodeId> {
467 self.real_dom().tree_ref().children_ids(self.id())
468 }
469
470 #[inline]
472 fn children(&self) -> Vec<NodeRef<V>> {
473 self.child_ids()
474 .iter()
475 .map(|id| NodeRef {
476 id: *id,
477 dom: self.real_dom(),
478 })
479 .collect()
480 }
481
482 #[inline]
484 fn parent_id(&self) -> Option<NodeId> {
485 self.real_dom().tree_ref().parent_id(self.id())
486 }
487
488 #[inline]
490 fn parent(&self) -> Option<NodeRef<V>> {
491 self.parent_id().map(|id| NodeRef {
492 id,
493 dom: self.real_dom(),
494 })
495 }
496
497 #[inline]
499 fn height(&self) -> u16 {
500 self.real_dom().tree_ref().height(self.id()).unwrap()
501 }
502}
503
504pub struct NodeRef<'a, V: FromAnyValue + Send + Sync = ()> {
506 id: NodeId,
507 dom: &'a RealDom<V>,
508}
509
510impl<V: FromAnyValue + Send + Sync> Clone for NodeRef<'_, V> {
511 fn clone(&self) -> Self {
512 *self
513 }
514}
515
516impl<V: FromAnyValue + Send + Sync> Copy for NodeRef<'_, V> {}
517
518impl<V: FromAnyValue + Send + Sync> NodeImmutable<V> for NodeRef<'_, V> {
519 #[inline(always)]
520 fn real_dom(&self) -> &RealDom<V> {
521 self.dom
522 }
523
524 #[inline(always)]
525 fn id(&self) -> NodeId {
526 self.id
527 }
528}
529
530pub struct NodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
532 id: NodeId,
533 dom: &'a mut RealDom<V>,
534}
535
536impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
537 pub fn new(id: NodeId, dom: &'a mut RealDom<V>) -> Self {
539 Self { id, dom }
540 }
541}
542
543impl<V: FromAnyValue + Send + Sync> NodeImmutable<V> for NodeMut<'_, V> {
544 #[inline(always)]
545 fn real_dom(&self) -> &RealDom<V> {
546 self.dom
547 }
548
549 #[inline(always)]
550 fn id(&self) -> NodeId {
551 self.id
552 }
553}
554
555impl<V: FromAnyValue + Send + Sync> NodeMut<'_, V> {
556 #[inline(always)]
558 pub fn real_dom_mut(&mut self) -> &mut RealDom<V> {
559 self.dom
560 }
561
562 #[inline]
564 pub fn get_mut<T: Component<Tracking = Untracked> + Sync + Send>(
565 &mut self,
566 ) -> Option<ViewEntryMut<T>> {
567 self.dom
569 .dirty_nodes
570 .passes_updated
571 .entry(self.id)
572 .or_default()
573 .insert(TypeId::of::<T>());
574 let view_mut: ViewMut<T> = self.dom.borrow_raw().ok()?;
575 view_mut
576 .contains(self.id)
577 .then_some(ViewEntryMut::new(view_mut, self.id))
578 }
579
580 #[inline]
584 pub fn insert<T: Component + Sync + Send>(&mut self, value: T) {
585 self.dom
587 .dirty_nodes
588 .passes_updated
589 .entry(self.id)
590 .or_default()
591 .insert(TypeId::of::<T>());
592 self.dom.world.add_component(self.id, value);
593 }
594
595 #[inline]
597 pub fn add_child(&mut self, child: NodeId) {
598 self.dom.dirty_nodes.mark_child_changed(self.id);
599 self.dom.dirty_nodes.mark_parent_added_or_removed(child);
600 self.dom.tree_mut().add_child(self.id, child);
601 }
602
603 #[inline]
605 pub fn insert_after(&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_after(old, id);
613 }
614
615 #[inline]
617 pub fn insert_before(&mut self, old: NodeId) {
618 let id = self.id();
619 let parent_id = { self.dom.tree_ref().parent_id(old) };
620 if let Some(parent_id) = parent_id {
621 self.dom.dirty_nodes.mark_child_changed(parent_id);
622 self.dom.dirty_nodes.mark_parent_added_or_removed(id);
623 }
624 self.dom.tree_mut().insert_before(old, id);
625 }
626
627 #[inline]
629 pub fn remove(&mut self) {
630 let id = self.id();
631 {
632 let RealDom {
633 world,
634 nodes_listening,
635 ..
636 } = &mut self.dom;
637 let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
638 if let NodeType::Element(ElementNode { listeners, .. }) = (&mut view).get(id).unwrap() {
639 let listeners = std::mem::take(listeners);
640 for event in listeners {
641 nodes_listening.get_mut(&event).unwrap().remove(&id);
642 }
643 }
644 }
645 let parent_id = { self.dom.tree_ref().parent_id(id) };
646 if let Some(parent_id) = parent_id {
647 self.real_dom_mut()
648 .dirty_nodes
649 .mark_child_changed(parent_id);
650 }
651 let children_ids = self.child_ids();
652 for child in children_ids {
653 self.dom.get_mut(child).unwrap().remove();
654 }
655 self.dom.tree_mut().remove(id);
656 self.real_dom_mut().raw_world_mut().delete_entity(id);
657 }
658
659 #[inline]
661 pub fn add_event_listener(&mut self, event: EventName) {
662 let id = self.id();
663 let RealDom {
664 world,
665 dirty_nodes,
666 nodes_listening,
667 ..
668 } = &mut self.dom;
669 let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
670 let node_type: &mut NodeType<V> = (&mut view).get(self.id).unwrap();
671 if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
672 dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
673 listeners.insert(event);
674 match nodes_listening.get_mut(&event) {
675 Some(hs) => {
676 hs.insert(id);
677 }
678 None => {
679 let mut hs = FxHashSet::default();
680 hs.insert(id);
681 nodes_listening.insert(event, hs);
682 }
683 }
684 }
685 }
686
687 #[inline]
689 pub fn remove_event_listener(&mut self, event: &EventName) {
690 let id = self.id();
691 let RealDom {
692 world,
693 dirty_nodes,
694 nodes_listening,
695 ..
696 } = &mut self.dom;
697 let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
698 let node_type: &mut NodeType<V> = (&mut view).get(self.id).unwrap();
699 if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
700 dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
701 listeners.remove(event);
702
703 nodes_listening.get_mut(event).unwrap().remove(&id);
704 }
705 }
706
707 pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
709 let id = self.id();
710 let RealDom {
711 world, dirty_nodes, ..
712 } = &mut self.dom;
713 let view: ViewMut<NodeType<V>> = world.borrow().unwrap();
714 let node_type = ViewEntryMut::new(view, id);
715 match &*node_type {
716 NodeType::Element(_) => NodeTypeMut::Element(ElementNodeMut {
717 id,
718 element: node_type,
719 dirty_nodes,
720 }),
721 NodeType::Text(_) => NodeTypeMut::Text(TextNodeMut {
722 id,
723 text: node_type,
724 dirty_nodes,
725 }),
726 NodeType::Placeholder => NodeTypeMut::Placeholder,
727 }
728 }
729
730 pub fn set_type(&mut self, new: NodeType<V>) {
732 {
733 let mut view: ViewMut<NodeType<V>> = self.dom.borrow_node_type_mut().unwrap();
734 *(&mut view).get(self.id).unwrap() = new;
735 }
736 self.dom
737 .dirty_nodes
738 .mark_dirty(self.id, NodeMaskBuilder::ALL.build())
739 }
740
741 #[inline]
744 pub fn clone_node(&mut self) -> NodeId {
745 let new_node = self.node_type().clone();
746 let rdom = self.real_dom_mut();
747 let new_id = rdom.create_node(new_node).id();
748
749 let children = self.child_ids();
750 let children = children.to_vec();
751 let rdom = self.real_dom_mut();
752 for child in children {
753 let child_id = rdom.get_mut(child).unwrap().clone_node();
754 rdom.get_mut(new_id).unwrap().add_child(child_id);
755 }
756 new_id
757 }
758}
759
760pub enum NodeTypeMut<'a, V: FromAnyValue + Send + Sync = ()> {
762 Element(ElementNodeMut<'a, V>),
764 Text(TextNodeMut<'a, V>),
766 Placeholder,
768}
769
770pub struct TextNodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
772 id: NodeId,
773 text: ViewEntryMut<'a, NodeType<V>>,
774 dirty_nodes: &'a mut NodesDirty<V>,
775}
776
777impl<V: FromAnyValue + Send + Sync> TextNodeMut<'_, V> {
778 pub fn text(&self) -> &str {
780 match &*self.text {
781 NodeType::Text(text) => text,
782 _ => unreachable!(),
783 }
784 }
785
786 pub fn text_mut(&mut self) -> &mut String {
788 self.dirty_nodes
789 .mark_dirty(self.id, NodeMaskBuilder::new().with_text().build());
790 match &mut *self.text {
791 NodeType::Text(text) => text,
792 _ => unreachable!(),
793 }
794 }
795}
796
797impl<V: FromAnyValue + Send + Sync> Deref for TextNodeMut<'_, V> {
798 type Target = String;
799
800 fn deref(&self) -> &Self::Target {
801 match &*self.text {
802 NodeType::Text(text) => text,
803 _ => unreachable!(),
804 }
805 }
806}
807
808impl<V: FromAnyValue + Send + Sync> DerefMut for TextNodeMut<'_, V> {
809 fn deref_mut(&mut self) -> &mut Self::Target {
810 self.text_mut()
811 }
812}
813
814pub struct ElementNodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
816 id: NodeId,
817 element: ViewEntryMut<'a, NodeType<V>>,
818 dirty_nodes: &'a mut NodesDirty<V>,
819}
820
821impl std::fmt::Debug for ElementNodeMut<'_> {
822 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
823 f.debug_struct("ElementNodeMut")
824 .field("id", &self.id)
825 .field("element", &*self.element)
826 .finish()
827 }
828}
829
830impl<V: FromAnyValue + Send + Sync> ElementNodeMut<'_, V> {
831 fn element_mut(&mut self) -> &mut ElementNode<V> {
833 match &mut *self.element {
834 NodeType::Element(element) => element,
835 _ => unreachable!(),
836 }
837 }
838
839 pub fn set_attribute(
841 &mut self,
842 name: impl Into<AttributeName>,
843 value: impl Into<OwnedAttributeValue<V>>,
844 ) -> Option<OwnedAttributeValue<V>> {
845 let name = name.into();
846 let value = value.into();
847 self.dirty_nodes.mark_dirty(
848 self.id,
849 NodeMaskBuilder::new()
850 .with_attrs(AttributeMaskBuilder::Some(&[name]))
851 .build(),
852 );
853 self.element_mut().attributes.insert(name, value)
854 }
855
856 pub fn remove_attribute(&mut self, name: &AttributeName) -> Option<OwnedAttributeValue<V>> {
858 self.dirty_nodes.mark_dirty(
859 self.id,
860 NodeMaskBuilder::new()
861 .with_attrs(AttributeMaskBuilder::Some(&[*name]))
862 .build(),
863 );
864 self.element_mut().attributes.remove(name)
865 }
866
867 pub fn get_attribute_mut(
869 &mut self,
870 name: &AttributeName,
871 ) -> Option<&mut OwnedAttributeValue<V>> {
872 self.dirty_nodes.mark_dirty(
873 self.id,
874 NodeMaskBuilder::new()
875 .with_attrs(AttributeMaskBuilder::Some(&[*name]))
876 .build(),
877 );
878 self.element_mut().attributes.get_mut(name)
879 }
880}
881
882fn construct_workload<V: FromAnyValue + Send + Sync>(
884 passes: &mut [TypeErasedState<V>],
885) -> Workload {
886 let mut workload = Workload::new("Main Workload");
887 let mut unresloved_workloads = passes
889 .iter_mut()
890 .enumerate()
891 .map(|(i, pass)| {
892 let workload = Some(pass.create_workload());
893 (i, pass, workload)
894 })
895 .collect::<Vec<_>>();
896 for (id, _, workload) in &mut unresloved_workloads {
898 *workload = Some(workload.take().unwrap().tag(id.to_string()));
899 }
900 for i in 0..unresloved_workloads.len() {
902 let (_, pass, _) = &unresloved_workloads[i];
903 let all_dependancies: Vec<_> = pass.combined_dependancy_type_ids().collect();
904 for ty_id in all_dependancies {
905 let &(dependancy_id, _, _) = unresloved_workloads
906 .iter()
907 .find(|(_, pass, _)| pass.this_type_id == ty_id)
908 .unwrap();
909 let (_, _, workload) = &mut unresloved_workloads[i];
910 *workload = workload
911 .take()
912 .map(|workload| workload.after_all(dependancy_id.to_string()));
913 }
914 }
915 for (_, _, mut workload_system) in unresloved_workloads {
917 workload = workload.with_system(workload_system.take().unwrap());
918 }
919 workload
920}