1use std::{collections::HashMap, path::PathBuf};
2
3use pax_manifest::{
4 pax_runtime_api::ToPaxValue, ComponentDefinition, ComponentTemplate,
5 ControlFlowRepeatPredicateDefinition, ExpressionInfo, NodeLocation, NodeType, PaxManifest,
6 SettingElement, SettingsBlockElement, TemplateNodeDefinition, TemplateNodeId,
7 TimelineDefinition, Token, TreeIndexPosition, TreeLocation, TypeId,
8 UniqueTemplateNodeIdentifier, ValueDefinition,
9};
10use serde_derive::{Deserialize, Serialize};
11
12use crate::orm::{
13 Command, MoveToComponentEntry, ReloadType, Request, Response, SubTrees, Undo, UndoRedoCommand,
14};
15
16#[derive(Serialize, Deserialize, Clone, Default, Debug)]
17pub struct NodeData {
18 pub unique_node_identifier: UniqueTemplateNodeIdentifier,
19 pub cached_node: TemplateNodeDefinition,
20}
21
22#[derive(Serialize, Deserialize, Clone, Debug, Default)]
23pub struct ControlFlowSettingsDefinitionUpdate {
24 pub repeat_predicate_definition: Option<Option<ControlFlowRepeatPredicateDefinition>>,
25 pub repeat_source_expression: Option<Option<ExpressionInfo>>,
26 pub conditional_expression: Option<Option<ExpressionInfo>>,
27 pub slot_index_expression: Option<Option<ExpressionInfo>>,
28}
29
30#[derive(Serialize, Deserialize, Clone, Debug)]
31pub struct AddTemplateNodeRequest {
32 containing_component_type_id: TypeId,
33 template_node_type_id: TypeId,
34 node_data: NodeType,
35 location: Option<NodeLocation>,
36
37 _cached_node_data: Option<NodeData>,
39}
40
41impl AddTemplateNodeRequest {
42 pub fn new(
43 containing_component_type_id: TypeId,
44 template_node_type_id: TypeId,
45 node_data: NodeType,
46 location: Option<NodeLocation>,
47 ) -> Self {
48 Self {
49 containing_component_type_id,
50 template_node_type_id,
51 node_data,
52 location,
53 _cached_node_data: None,
54 }
55 }
56}
57
58#[derive(Serialize, Deserialize, Clone)]
59pub struct AddTemplateNodeResponse {
60 pub command_id: Option<usize>,
61 pub uni: UniqueTemplateNodeIdentifier,
62}
63
64impl Request for AddTemplateNodeRequest {
65 type Response = AddTemplateNodeResponse;
66}
67
68impl Response for AddTemplateNodeResponse {
69 fn set_id(&mut self, id: usize) {
70 self.command_id = Some(id);
71 }
72 fn get_id(&self) -> usize {
73 self.command_id.unwrap()
74 }
75 fn get_reload_type(&self) -> Option<ReloadType> {
76 Some(ReloadType::Tree)
77 }
78}
79
80impl Command<AddTemplateNodeRequest> for AddTemplateNodeRequest {
81 fn execute(&mut self, manifest: &mut PaxManifest) -> Result<AddTemplateNodeResponse, String> {
82 let component = manifest
83 .components
84 .get_mut(&self.containing_component_type_id)
85 .ok_or_else(|| format!("Component {} not found", self.containing_component_type_id))?;
86 if component.is_primitive || component.is_struct_only_component {
87 return Err("Component doesn't accept template nodes.".to_string());
88 }
89
90 let mut template_node = TemplateNodeDefinition {
91 type_id: self.template_node_type_id.clone(),
92 ..Default::default()
93 };
94
95 match &self.node_data {
96 NodeType::Template(settings) => {
97 template_node.settings = Some(settings.clone());
98 }
99 NodeType::ControlFlow(control_flow_settings) => {
100 template_node.control_flow_settings = Some(*control_flow_settings.clone());
101 }
102 NodeType::Comment(raw_comment_string) => {
103 template_node.raw_comment_string = Some(raw_comment_string.clone());
104 }
105 }
106
107 let mut node_data = NodeData {
108 cached_node: template_node.clone(),
109 ..Default::default()
110 };
111
112 node_data.unique_node_identifier = if let Some(template) = &mut component.template {
113 if let Some(location) = &self.location {
114 template.add_at(template_node, location.clone())
115 } else {
116 template.add(template_node)
117 }
118 } else {
119 let mut template =
120 ComponentTemplate::new(self.containing_component_type_id.clone(), None);
121 let uni = if let Some(location) = &self.location {
122 template.add_at(template_node, location.clone())
123 } else {
124 template.add(template_node)
125 };
126 component.template = Some(template);
127 uni
128 };
129
130 self._cached_node_data = Some(node_data.clone());
131
132 Ok(AddTemplateNodeResponse {
133 command_id: None,
134 uni: node_data.unique_node_identifier.clone(),
135 })
136 }
137
138 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
139 Some(UndoRedoCommand::AddTemplateNodeRequest(Box::new(
140 self.clone(),
141 )))
142 }
143}
144
145impl Undo for AddTemplateNodeRequest {
146 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
147 let component = manifest
148 .components
149 .get_mut(&self.containing_component_type_id)
150 .unwrap();
151
152 let cached_data = self._cached_node_data.clone().unwrap();
153 if let Some(template) = &mut component.template {
154 template.remove_node(cached_data.unique_node_identifier.get_template_node_id());
155 template.set_next_id(
156 cached_data
157 .unique_node_identifier
158 .get_template_node_id()
159 .as_usize(),
160 );
161 }
162 Ok(())
163 }
164}
165
166#[derive(Serialize, Deserialize, Clone, Debug)]
167pub struct UpdateTemplateNodeRequest {
168 uni: UniqueTemplateNodeIdentifier,
169 updated_properties: HashMap<Token, Option<ValueDefinition>>,
170 updated_classes: HashMap<String, bool>,
171 new_type_id: Option<TypeId>,
172 new_location: Option<NodeLocation>,
173 control_flow_updates: ControlFlowSettingsDefinitionUpdate,
174 _cached_node_data: Option<NodeData>,
176 _cached_move: Option<MoveTemplateNodeRequest>,
177}
178
179impl UpdateTemplateNodeRequest {
180 pub fn new(
181 uni: UniqueTemplateNodeIdentifier,
182 new_type_id: Option<TypeId>,
183 updated_properties: HashMap<Token, Option<ValueDefinition>>,
184 updated_classes: HashMap<String, bool>,
185 new_location: Option<NodeLocation>,
186 control_flow_updates: ControlFlowSettingsDefinitionUpdate,
187 ) -> Self {
188 Self {
189 uni,
190 updated_properties,
191 updated_classes,
192 new_location,
193 new_type_id,
194 _cached_node_data: None,
195 _cached_move: None,
196 control_flow_updates,
197 }
198 }
199}
200
201pub struct UpdateTemplateNodeResponse {
202 pub command_id: Option<usize>,
203 _affected_component_type_id: TypeId,
204 _affected_unique_node_identifier: UniqueTemplateNodeIdentifier,
205 _reload_type: ReloadType,
206}
207
208impl Request for UpdateTemplateNodeRequest {
209 type Response = UpdateTemplateNodeResponse;
210}
211
212impl Response for UpdateTemplateNodeResponse {
213 fn set_id(&mut self, id: usize) {
214 self.command_id = Some(id);
215 }
216 fn get_id(&self) -> usize {
217 self.command_id.unwrap()
218 }
219 fn get_reload_type(&self) -> Option<ReloadType> {
220 Some(self._reload_type.clone())
221 }
222}
223
224impl Command<UpdateTemplateNodeRequest> for UpdateTemplateNodeRequest {
225 fn execute(
226 &mut self,
227 manifest: &mut PaxManifest,
228 ) -> Result<UpdateTemplateNodeResponse, String> {
229 let uni = self.uni.clone();
230 let containing_component = uni.get_containing_component_type_id().clone();
231 let component = manifest
232 .components
233 .get_mut(&containing_component)
234 .ok_or_else(|| {
235 format!(
236 "Component {} not found",
237 self.uni.get_containing_component_type_id()
238 )
239 })?;
240 if component.is_primitive || component.is_struct_only_component {
241 return Err("Component doesn't accept template nodes.".to_string());
242 }
243
244 if let Some(template) = &mut component.template {
245 template.update_node_properties(
246 &uni.get_template_node_id(),
247 self.updated_properties.clone(),
248 );
249 template.update_classes(&uni.get_template_node_id(), self.updated_classes.clone());
250 template.update_control_flow_properties(
251 &uni.get_template_node_id(),
252 self.control_flow_updates
253 .repeat_predicate_definition
254 .clone(),
255 self.control_flow_updates.repeat_source_expression.clone(),
256 self.control_flow_updates.conditional_expression.clone(),
257 self.control_flow_updates.slot_index_expression.clone(),
258 );
259 self.updated_properties
262 .remove(&Token::new_without_location("elements".to_string()));
263 self._cached_node_data = Some(NodeData {
264 unique_node_identifier: uni.clone(),
265 cached_node: template
266 .get_node(&uni.get_template_node_id())
267 .ok_or_else(|| "Cannot update node that doesn't exist".to_string())?
268 .clone(),
269 });
270
271 if let Some(new_type) = &self.new_type_id {
272 template.update_node_type_id(&uni.get_template_node_id(), new_type);
273 }
274
275 if let Some(location) = &self.new_location {
276 let mut move_request = MoveTemplateNodeRequest::new(uni.clone(), location.clone());
277 move_request.execute(manifest)?;
278 self._cached_move = Some(move_request.clone());
279 }
280 }
281
282 Ok(UpdateTemplateNodeResponse {
283 command_id: None,
284 _affected_component_type_id: uni.get_containing_component_type_id(),
285 _affected_unique_node_identifier: uni,
286 _reload_type: if !self.updated_classes.is_empty() {
288 ReloadType::Tree
289 } else {
290 ReloadType::Node(self.uni.clone(), {
291 let mut updated: Vec<_> = self
292 .updated_properties
293 .keys()
294 .map(|t| t.token_value.clone())
295 .collect();
296 updated.sort_unstable();
297 updated
298 })
299 },
300 })
301 }
302
303 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
304 Some(UndoRedoCommand::UpdateTemplateNodeRequest(Box::new(
305 self.clone(),
306 )))
307 }
308}
309
310impl Undo for UpdateTemplateNodeRequest {
311 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
312 if let Some(move_request) = &mut self._cached_move {
313 move_request.undo(manifest).unwrap();
314 }
315
316 let component = manifest
317 .components
318 .get_mut(&self.uni.get_containing_component_type_id())
319 .unwrap();
320
321 if let Some(template) = &mut component.template {
322 if let Some(data) = &self._cached_node_data {
323 template.set_node(self.uni.get_template_node_id(), data.cached_node.clone());
324 }
325 }
326 Ok(())
327 }
328}
329
330#[derive(Serialize, Deserialize, Clone, Debug)]
331pub struct MoveTemplateNodeRequest {
332 uni: UniqueTemplateNodeIdentifier,
333 new_location: NodeLocation,
334 _cached_old_position: Option<NodeLocation>,
336}
337
338impl MoveTemplateNodeRequest {
339 pub fn new(uni: UniqueTemplateNodeIdentifier, new_location: NodeLocation) -> Self {
340 Self {
341 uni,
342 new_location,
343 _cached_old_position: None,
344 }
345 }
346}
347
348pub struct MoveTemplateNodeResponse {
349 command_id: Option<usize>,
350 _affected_component_type_id: TypeId,
351}
352
353impl Request for MoveTemplateNodeRequest {
354 type Response = MoveTemplateNodeResponse;
355}
356
357impl Response for MoveTemplateNodeResponse {
358 fn set_id(&mut self, id: usize) {
359 self.command_id = Some(id);
360 }
361 fn get_id(&self) -> usize {
362 self.command_id.unwrap()
363 }
364 fn get_reload_type(&self) -> Option<ReloadType> {
365 Some(ReloadType::Tree)
366 }
367}
368
369impl Command<MoveTemplateNodeRequest> for MoveTemplateNodeRequest {
370 fn execute(&mut self, manifest: &mut PaxManifest) -> Result<MoveTemplateNodeResponse, String> {
371 let uni = self.uni.clone();
372 let requested_component = self.new_location.get_type_id();
373
374 let current_component = manifest
375 .components
376 .get_mut(&uni.get_containing_component_type_id())
377 .ok_or_else(|| {
378 format!(
379 "Component {} not found",
380 self.uni.get_containing_component_type_id()
381 )
382 })?;
383 if current_component.is_primitive || current_component.is_struct_only_component {
384 return Err("Component doesn't accept template nodes.".to_string());
385 }
386 if current_component.template.is_none() {
387 return Err("Component doesn't have a template.".to_string());
388 }
389
390 let template = current_component.template.as_mut().unwrap();
391
392 if *requested_component != uni.get_containing_component_type_id() {
393 return Err("Cannot move node to a different component.".to_string());
394 }
395
396 self._cached_old_position = template.get_location(&self.uni.get_template_node_id());
397 template.move_node(&uni.get_template_node_id(), self.new_location.clone());
398
399 Ok(MoveTemplateNodeResponse {
400 command_id: None,
401 _affected_component_type_id: uni.get_containing_component_type_id(),
402 })
403 }
404
405 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
406 Some(UndoRedoCommand::MoveTemplateNodeRequest(Box::new(
407 self.clone(),
408 )))
409 }
410}
411
412impl Undo for MoveTemplateNodeRequest {
413 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
414 let component = manifest
415 .components
416 .get_mut(&self.uni.get_containing_component_type_id())
417 .unwrap();
418
419 if let Some(template) = &mut component.template {
420 if let Some(location) = &self._cached_old_position {
421 template.move_node(&self.uni.get_template_node_id(), location.clone());
422 }
423 }
424 Ok(())
425 }
426}
427
428#[derive(Serialize, Deserialize, Clone, Debug)]
429pub struct PasteSubTreeRequest {
430 new_location: NodeLocation,
431 subtrees: SubTrees,
432 _cached_template: Option<ComponentTemplate>,
433}
434
435impl PasteSubTreeRequest {
436 pub fn new(new_location: NodeLocation, subtrees: SubTrees) -> Self {
437 Self {
438 new_location,
439 subtrees,
440 _cached_template: None,
441 }
442 }
443}
444
445pub struct PasteSubTreeResponse {
446 command_id: Option<usize>,
447 root_ids: Vec<TemplateNodeId>,
448 _affected_component_type_id: TypeId,
449}
450
451impl PasteSubTreeResponse {
452 pub fn get_created(&self) -> &[TemplateNodeId] {
453 &self.root_ids
454 }
455}
456
457impl Request for PasteSubTreeRequest {
458 type Response = PasteSubTreeResponse;
459}
460
461impl Response for PasteSubTreeResponse {
462 fn set_id(&mut self, id: usize) {
463 self.command_id = Some(id);
464 }
465 fn get_id(&self) -> usize {
466 self.command_id.unwrap()
467 }
468 fn get_reload_type(&self) -> Option<ReloadType> {
469 Some(ReloadType::Tree)
470 }
471}
472
473impl Command<PasteSubTreeRequest> for PasteSubTreeRequest {
474 fn execute(&mut self, manifest: &mut PaxManifest) -> Result<PasteSubTreeResponse, String> {
475 let type_id = self.new_location.get_type_id();
476 let component = manifest
477 .components
478 .get_mut(type_id)
479 .ok_or_else(|| format!("Component {} not found", type_id))?;
480 if component.is_primitive || component.is_struct_only_component {
481 return Err("Component doesn't accept template nodes.".to_string());
482 }
483 if component.template.is_none() {
484 return Err("Component doesn't have a template.".to_string());
485 }
486
487 let template = component.template.as_mut().unwrap();
488 self._cached_template = Some(template.clone());
489
490 let mut root_ids = vec![];
491 for r in self.subtrees.roots.iter().rev() {
492 let def = self
493 .subtrees
494 .nodes
495 .get(r)
496 .ok_or_else(|| "Node not found".to_string())?;
497 let id = template
498 .add_at(def.clone(), self.new_location.clone())
499 .get_template_node_id();
500 root_ids.push(id.clone());
501 let mut to_visit = vec![];
502 if let Some(children) = self.subtrees.children.get(r) {
503 to_visit.push((id, children.clone()));
504 }
505 while let Some((id, children)) = to_visit.pop() {
506 for c in children {
507 let c_def = self
508 .subtrees
509 .nodes
510 .get(&c)
511 .ok_or_else(|| "Child node not found".to_string())?;
512 let c_id = template
513 .add_child_back(id.clone(), c_def.clone())
514 .get_template_node_id();
515 if let Some(c_children) = self.subtrees.children.get(&c) {
516 to_visit.push((c_id, c_children.clone()));
517 }
518 }
519 }
520 }
521
522 Ok(PasteSubTreeResponse {
523 command_id: None,
524 root_ids,
525 _affected_component_type_id: type_id.clone(),
526 })
527 }
528
529 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
530 Some(UndoRedoCommand::PasteSubTreeRequest(Box::new(self.clone())))
531 }
532}
533
534impl Undo for PasteSubTreeRequest {
535 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
536 let component = manifest
537 .components
538 .get_mut(&self.new_location.type_id)
539 .unwrap();
540 component.template.clone_from(&self._cached_template);
541 Ok(())
542 }
543}
544
545#[derive(Serialize, Deserialize, Clone, Debug)]
546pub struct RemoveTemplateNodeRequest {
547 uni: UniqueTemplateNodeIdentifier,
548 _cached_template: Option<ComponentTemplate>,
550}
551
552impl RemoveTemplateNodeRequest {
553 pub fn new(uni: UniqueTemplateNodeIdentifier) -> Self {
554 RemoveTemplateNodeRequest {
555 uni,
556 _cached_template: None,
557 }
558 }
559}
560
561pub struct RemoveTemplateNodeResponse {
562 command_id: Option<usize>,
563 _affected_component_type_id: TypeId,
564}
565
566impl Request for RemoveTemplateNodeRequest {
567 type Response = RemoveTemplateNodeResponse;
568}
569
570impl Response for RemoveTemplateNodeResponse {
571 fn set_id(&mut self, id: usize) {
572 self.command_id = Some(id);
573 }
574 fn get_id(&self) -> usize {
575 self.command_id.unwrap()
576 }
577 fn get_reload_type(&self) -> Option<ReloadType> {
578 Some(ReloadType::Tree)
579 }
580}
581
582impl Command<RemoveTemplateNodeRequest> for RemoveTemplateNodeRequest {
583 fn execute(
584 &mut self,
585 manifest: &mut PaxManifest,
586 ) -> Result<RemoveTemplateNodeResponse, String> {
587 let component = manifest
588 .components
589 .get_mut(&self.uni.get_containing_component_type_id())
590 .ok_or_else(|| {
591 format!(
592 "Component {} not found",
593 self.uni.get_containing_component_type_id()
594 )
595 })?;
596 if component.is_primitive || component.is_struct_only_component {
597 unreachable!("Component doesn't accept template nodes.");
598 }
599
600 if let Some(template) = &mut component.template {
601 self._cached_template = Some(template.clone());
602 template.remove_node(self.uni.get_template_node_id());
603 };
604
605 Ok(RemoveTemplateNodeResponse {
606 command_id: None,
607 _affected_component_type_id: self.uni.get_containing_component_type_id(),
608 })
609 }
610
611 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
612 Some(UndoRedoCommand::RemoveTemplateNodeRequest(Box::new(
613 self.clone(),
614 )))
615 }
616}
617
618impl Undo for RemoveTemplateNodeRequest {
619 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
620 let component = manifest
621 .components
622 .get_mut(&self.uni.get_containing_component_type_id())
623 .ok_or_else(|| {
624 format!(
625 "Component {} not found",
626 self.uni.get_containing_component_type_id()
627 )
628 })?;
629 component.template.clone_from(&self._cached_template);
630 Ok(())
631 }
632}
633
634pub struct GetTemplateNodeRequest {
635 pub uni: UniqueTemplateNodeIdentifier,
636}
637
638pub struct GetTemplateNodeResponse {
639 pub command_id: Option<usize>,
640 pub node: Option<TemplateNodeDefinition>,
641}
642
643impl Request for GetTemplateNodeRequest {
644 type Response = GetTemplateNodeResponse;
645}
646
647impl Response for GetTemplateNodeResponse {
648 fn set_id(&mut self, id: usize) {
649 self.command_id = Some(id);
650 }
651 fn get_id(&self) -> usize {
652 self.command_id.unwrap()
653 }
654}
655
656impl Command<GetTemplateNodeRequest> for GetTemplateNodeRequest {
657 fn execute(
658 &mut self,
659 manifest: &mut PaxManifest,
660 ) -> Result<<GetTemplateNodeRequest as Request>::Response, String> {
661 let component = manifest
662 .components
663 .get_mut(&self.uni.get_containing_component_type_id())
664 .ok_or_else(|| {
665 format!(
666 "Component {} not found",
667 self.uni.get_containing_component_type_id()
668 )
669 })?;
670
671 let mut node = None;
672 if let Some(template) = &component.template {
673 if let Some(n) = template.get_node(&self.uni.get_template_node_id()) {
674 node = Some(n.clone());
675 }
676 }
677
678 Ok(GetTemplateNodeResponse {
679 command_id: None,
680 node,
681 })
682 }
683}
684
685pub struct GetChildrenRequest {
686 pub uni: UniqueTemplateNodeIdentifier,
687}
688
689pub struct GetChildrenResponse {
690 command_id: Option<usize>,
691 #[allow(unused)]
692 pub children: Vec<UniqueTemplateNodeIdentifier>,
693}
694
695impl Request for GetChildrenRequest {
696 type Response = GetChildrenResponse;
697}
698
699impl Response for GetChildrenResponse {
700 fn set_id(&mut self, id: usize) {
701 self.command_id = Some(id);
702 }
703 fn get_id(&self) -> usize {
704 self.command_id.unwrap()
705 }
706}
707
708impl Command<GetChildrenRequest> for GetChildrenRequest {
709 fn execute(
710 &mut self,
711 manifest: &mut PaxManifest,
712 ) -> Result<<GetChildrenRequest as Request>::Response, String> {
713 let component = manifest
714 .components
715 .get_mut(&self.uni.get_containing_component_type_id())
716 .unwrap();
717
718 let mut children = vec![];
719 if let Some(template) = &component.template {
720 if let Some(n) = template.get_children(&self.uni.get_template_node_id()) {
721 children = n
722 .iter()
723 .map(|tnid| {
724 UniqueTemplateNodeIdentifier::build(
725 self.uni.get_containing_component_type_id(),
726 tnid.clone(),
727 )
728 })
729 .collect();
730 }
731 }
732
733 Ok(GetChildrenResponse {
734 command_id: None,
735 children,
736 })
737 }
738}
739
740pub struct GetAllTemplateNodeRequest {
741 component_type_id: TypeId,
742}
743
744pub struct GetAllTemplateNodeResponse {
745 command_id: Option<usize>,
746 #[allow(unused)]
747 nodes: Option<Vec<TemplateNodeDefinition>>,
748}
749
750impl Request for GetAllTemplateNodeRequest {
751 type Response = GetAllTemplateNodeResponse;
752}
753
754impl Response for GetAllTemplateNodeResponse {
755 fn set_id(&mut self, id: usize) {
756 self.command_id = Some(id);
757 }
758 fn get_id(&self) -> usize {
759 self.command_id.unwrap()
760 }
761}
762
763impl Command<GetAllTemplateNodeRequest> for GetAllTemplateNodeRequest {
764 fn execute(
765 &mut self,
766 manifest: &mut PaxManifest,
767 ) -> Result<<GetAllTemplateNodeRequest as Request>::Response, String> {
768 let component = manifest
769 .components
770 .get_mut(&self.component_type_id)
771 .unwrap();
772
773 let mut nodes = None;
774 if let Some(template) = &component.template {
775 nodes = Some(template.get_nodes_owned());
776 }
777
778 Ok(GetAllTemplateNodeResponse {
779 command_id: None,
780 nodes,
781 })
782 }
783}
784
785#[derive(Serialize, Deserialize, Clone)]
786pub struct ReplaceTemplateRequest {
787 component_type_id: TypeId,
788 new_template: ComponentTemplate,
789 settings_block: Vec<SettingsBlockElement>,
790 #[serde(default)]
791 timelines: Vec<TimelineDefinition>,
792 _cached_prev_template: Option<ComponentTemplate>,
793 _cached_prev_settings_block: Option<Vec<SettingsBlockElement>>,
794 #[serde(default)]
795 _cached_prev_timelines: Option<Vec<TimelineDefinition>>,
796}
797
798impl ReplaceTemplateRequest {
799 pub fn new(
800 component_type_id: TypeId,
801 new_template: ComponentTemplate,
802 settings_block: Vec<SettingsBlockElement>,
803 timelines: Vec<TimelineDefinition>,
804 ) -> Self {
805 Self {
806 component_type_id,
807 new_template,
808 settings_block,
809 timelines,
810 _cached_prev_template: None,
811 _cached_prev_settings_block: None,
812 _cached_prev_timelines: None,
813 }
814 }
815}
816
817pub struct ReplaceTemplateResponse {
818 command_id: Option<usize>,
819 _affected_component_type_id: TypeId,
820}
821
822impl Response for ReplaceTemplateResponse {
823 fn set_id(&mut self, id: usize) {
824 self.command_id = Some(id);
825 }
826 fn get_id(&self) -> usize {
827 self.command_id.unwrap()
828 }
829 fn get_reload_type(&self) -> Option<ReloadType> {
830 Some(ReloadType::Tree)
831 }
832}
833
834impl Request for ReplaceTemplateRequest {
835 type Response = ReplaceTemplateResponse;
836}
837
838impl Command<ReplaceTemplateRequest> for ReplaceTemplateRequest {
839 fn execute(&mut self, manifest: &mut PaxManifest) -> Result<ReplaceTemplateResponse, String> {
840 let component = manifest
841 .components
842 .get_mut(&self.component_type_id)
843 .unwrap();
844
845 self._cached_prev_template.clone_from(&component.template);
846 self._cached_prev_settings_block
847 .clone_from(&component.settings);
848 self._cached_prev_timelines = Some(component.timelines.clone());
849
850 component.template = Some(self.new_template.clone());
851 component.settings = Some(self.settings_block.clone());
852 component.timelines.clone_from(&self.timelines);
853
854 Ok(ReplaceTemplateResponse {
855 command_id: None,
856 _affected_component_type_id: self.component_type_id.clone(),
857 })
858 }
859
860 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
861 Some(UndoRedoCommand::ReplaceTemplateRequest(Box::new(
862 self.clone(),
863 )))
864 }
865}
866
867impl Undo for ReplaceTemplateRequest {
868 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
869 let component = manifest
870 .components
871 .get_mut(&self.component_type_id)
872 .unwrap();
873 component.template.clone_from(&self._cached_prev_template);
874 component
875 .settings
876 .clone_from(&self._cached_prev_settings_block);
877 component.timelines = self._cached_prev_timelines.clone().unwrap_or_default();
878 Ok(())
879 }
880}
881
882#[derive(Serialize, Deserialize, Clone, Debug)]
883pub struct SerializedTemplateNodeSubtree {
884 pub node: TemplateNodeDefinition,
885 pub children: Vec<SerializedTemplateNodeSubtree>,
886}
887
888#[derive(Serialize, Deserialize, Clone)]
889pub struct ReplaceNodeSubtreeRequest {
890 uni: UniqueTemplateNodeIdentifier,
891 new_subtree: Option<SerializedTemplateNodeSubtree>,
892 reload_uni: Option<UniqueTemplateNodeIdentifier>,
893 _cached_template: Option<ComponentTemplate>,
894}
895
896impl ReplaceNodeSubtreeRequest {
897 pub fn new(
898 uni: UniqueTemplateNodeIdentifier,
899 new_subtree: Option<SerializedTemplateNodeSubtree>,
900 reload_uni: Option<UniqueTemplateNodeIdentifier>,
901 ) -> Self {
902 Self {
903 uni,
904 new_subtree,
905 reload_uni,
906 _cached_template: None,
907 }
908 }
909}
910
911pub struct ReplaceNodeSubtreeResponse {
912 command_id: Option<usize>,
913 _affected_component_type_id: TypeId,
914 reload_type: ReloadType,
915}
916
917impl Request for ReplaceNodeSubtreeRequest {
918 type Response = ReplaceNodeSubtreeResponse;
919}
920
921impl Response for ReplaceNodeSubtreeResponse {
922 fn set_id(&mut self, id: usize) {
923 self.command_id = Some(id);
924 }
925
926 fn get_id(&self) -> usize {
927 self.command_id.unwrap()
928 }
929
930 fn get_reload_type(&self) -> Option<ReloadType> {
931 Some(self.reload_type.clone())
932 }
933}
934
935impl Command<ReplaceNodeSubtreeRequest> for ReplaceNodeSubtreeRequest {
936 fn execute(
937 &mut self,
938 manifest: &mut PaxManifest,
939 ) -> Result<ReplaceNodeSubtreeResponse, String> {
940 let component = manifest
941 .components
942 .get_mut(&self.uni.get_containing_component_type_id())
943 .ok_or_else(|| {
944 format!(
945 "Component {} not found",
946 self.uni.get_containing_component_type_id()
947 )
948 })?;
949 if component.is_primitive || component.is_struct_only_component {
950 return Err("Component doesn't accept template nodes.".to_string());
951 }
952
953 let template = component
954 .template
955 .as_mut()
956 .ok_or_else(|| "Component has no template".to_string())?;
957 self._cached_template = Some(template.clone());
958
959 match &self.new_subtree {
960 Some(new_subtree) => {
961 replace_template_node_subtree(
962 template,
963 self.uni.get_template_node_id(),
964 new_subtree,
965 )?;
966 }
967 None => {
968 template.remove_node(self.uni.get_template_node_id());
969 }
970 }
971
972 Ok(ReplaceNodeSubtreeResponse {
973 command_id: None,
974 _affected_component_type_id: self.uni.get_containing_component_type_id(),
975 reload_type: self
976 .reload_uni
977 .clone()
978 .map(ReloadType::Subtree)
979 .unwrap_or(ReloadType::Tree),
980 })
981 }
982
983 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
984 Some(UndoRedoCommand::ReplaceNodeSubtreeRequest(Box::new(
985 self.clone(),
986 )))
987 }
988}
989
990impl Undo for ReplaceNodeSubtreeRequest {
991 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
992 let component = manifest
993 .components
994 .get_mut(&self.uni.get_containing_component_type_id())
995 .ok_or_else(|| {
996 format!(
997 "Component {} not found",
998 self.uni.get_containing_component_type_id()
999 )
1000 })?;
1001 let template = component
1002 .template
1003 .as_mut()
1004 .ok_or_else(|| "Component has no template".to_string())?;
1005 if let Some(cached_template) = &self._cached_template {
1006 *template = cached_template.clone();
1007 }
1008 Ok(())
1009 }
1010}
1011
1012fn replace_template_node_subtree(
1013 template: &mut ComponentTemplate,
1014 target_id: TemplateNodeId,
1015 new_subtree: &SerializedTemplateNodeSubtree,
1016) -> Result<(), String> {
1017 if template.get_node(&target_id).is_none() {
1018 return Err(format!("Template node {} does not exist", target_id));
1019 }
1020
1021 let existing_children = template.get_children(&target_id).unwrap_or_default();
1022 for child in existing_children {
1023 template.remove_node(child);
1024 }
1025
1026 template.set_node(target_id.clone(), new_subtree.node.clone());
1027 append_template_subtree_children(template, &target_id, &new_subtree.children);
1028 Ok(())
1029}
1030
1031fn append_template_subtree_children(
1032 template: &mut ComponentTemplate,
1033 parent_id: &TemplateNodeId,
1034 children: &[SerializedTemplateNodeSubtree],
1035) {
1036 for child in children {
1037 let child_uni = template.add_child_back(parent_id.clone(), child.node.clone());
1038 append_template_subtree_children(
1039 template,
1040 &child_uni.get_template_node_id(),
1041 &child.children,
1042 );
1043 }
1044}
1045
1046#[derive(Serialize, Deserialize, Clone, Debug)]
1047pub struct ConvertToComponentRequest {
1048 subtrees_roots: Vec<MoveToComponentEntry>,
1050 new_component_number: usize,
1051 x: f64,
1052 y: f64,
1053 width: f64,
1054 height: f64,
1055
1056 _cached_template: Option<ComponentTemplate>,
1058 _cached_add: Option<AddTemplateNodeRequest>,
1059 _cached_new_component_type_id: Option<TypeId>,
1060}
1061
1062impl ConvertToComponentRequest {
1063 pub fn new(
1064 subtrees_roots: Vec<MoveToComponentEntry>,
1065 new_component_number: usize,
1066 x: f64,
1067 y: f64,
1068 width: f64,
1069 height: f64,
1070 ) -> Self {
1071 Self {
1072 subtrees_roots,
1073 new_component_number,
1074 x,
1075 y,
1076 width,
1077 height,
1078 _cached_template: None,
1079 _cached_add: None,
1080 _cached_new_component_type_id: None,
1081 }
1082 }
1083}
1084
1085impl Request for ConvertToComponentRequest {
1086 type Response = ConvertToComponentResponse;
1087}
1088
1089#[derive(Serialize, Deserialize, Clone)]
1090pub struct ConvertToComponentResponse {
1091 command_id: Option<usize>,
1092 pub uni: UniqueTemplateNodeIdentifier,
1093 pub new_component_type_id: TypeId,
1094}
1095
1096impl Response for ConvertToComponentResponse {
1097 fn set_id(&mut self, id: usize) {
1098 self.command_id = Some(id);
1099 }
1100 fn get_id(&self) -> usize {
1101 self.command_id.unwrap()
1102 }
1103 fn get_reload_type(&self) -> Option<ReloadType> {
1104 Some(ReloadType::Tree)
1105 }
1106}
1107
1108impl Command<ConvertToComponentRequest> for ConvertToComponentRequest {
1109 fn execute(
1110 &mut self,
1111 manifest: &mut PaxManifest,
1112 ) -> Result<ConvertToComponentResponse, String> {
1113 if self.subtrees_roots.is_empty() {
1114 return Err("No subtrees provided".to_string());
1115 }
1116
1117 let new_component_identifier = format!("NewComponent{}", self.new_component_number);
1118 let new_component_file_name = format!("new_component_{}.pax", self.new_component_number);
1119 let new_component_type_id = TypeId::build_blank_component(&new_component_identifier);
1120
1121 let (module_path, ul_path) = {
1122 let ul_bind = manifest.components.get(&manifest.main_component_type_id);
1123 let ul = ul_bind.expect("Main component not found").clone();
1124 (
1125 ul.module_path.clone(),
1126 ul.template
1127 .as_ref()
1128 .expect("Main component template not found")
1129 .get_file_path()
1130 .expect("Main component file path not found")
1131 .clone(),
1132 )
1133 };
1134
1135 let new_component_path = PathBuf::from(ul_path)
1136 .parent()
1137 .expect("Main component path has no parent")
1138 .join(new_component_file_name)
1139 .to_str()
1140 .map(|s| s.to_string());
1141
1142 let current_component_type_id = self.subtrees_roots[0]
1143 .id
1144 .get_containing_component_type_id()
1145 .clone();
1146 let binding = manifest.components.get_mut(¤t_component_type_id);
1147 let current_component = binding.expect("Component not found");
1148 let current_component_template = current_component
1149 .template
1150 .as_mut()
1151 .expect("Component template not found");
1152
1153 self._cached_template = Some(current_component_template.clone());
1154
1155 let mut new_template =
1156 ComponentTemplate::new(new_component_type_id.clone(), new_component_path);
1157
1158 fn add_subtree_to_new_template(
1159 current_template: &ComponentTemplate,
1160 new_template: &mut ComponentTemplate,
1161 node_id: TemplateNodeId,
1162 node_location: NodeLocation,
1163 root_bounds: Vec<MoveToComponentEntry>,
1164 ) {
1165 let mut node = current_template
1166 .get_node(&node_id)
1167 .expect("Node not found")
1168 .clone();
1169
1170 let relevant_bounds = root_bounds
1171 .iter()
1172 .filter(|entry| entry.id.get_template_node_id() == node_id)
1173 .collect::<Vec<_>>();
1174
1175 if let Some(e) = relevant_bounds.first() {
1176 if let Some(settings) = &mut node.settings {
1177 update_position_if_exists(e.x, e.y, settings);
1178 }
1179 }
1180
1181 let new_node_id = new_template.add_at(node, node_location.clone());
1182 for child in current_template.get_children(&node_id).unwrap_or_default() {
1183 let location = NodeLocation::new(
1184 node_location.type_id.clone(),
1185 TreeLocation::Parent(new_node_id.get_template_node_id().clone()),
1186 TreeIndexPosition::Bottom,
1187 );
1188 add_subtree_to_new_template(
1189 current_template,
1190 new_template,
1191 child,
1192 location,
1193 root_bounds.clone(),
1194 );
1195 }
1196 }
1197
1198 let mut ids_with_location = self
1200 .subtrees_roots
1201 .iter()
1202 .map(|entry| {
1203 let template_node_id = entry.id.get_template_node_id();
1204 let location = current_component_template
1205 .get_location(&template_node_id)
1206 .expect("Location not found")
1207 .clone();
1208 (template_node_id, location)
1209 })
1210 .collect::<Vec<_>>();
1211
1212 ids_with_location.sort_by(|a, b| a.1.cmp(&b.1));
1213
1214 let new_component_location = ids_with_location.first().unwrap().1.clone();
1215
1216 let mut processed_ids: Vec<TemplateNodeId> = vec![];
1217 let new_bounds = self
1218 .subtrees_roots
1219 .iter()
1220 .map(|e| {
1221 let mut new_entry = e.clone();
1222 new_entry.x -= self.x;
1223 new_entry.y -= self.y;
1224 new_entry
1225 })
1226 .collect::<Vec<_>>();
1227
1228 for (id, nl) in ids_with_location {
1229 let new_location = NodeLocation::new(
1230 new_component_type_id.clone(),
1231 nl.tree_location.clone(),
1232 TreeIndexPosition::Bottom,
1233 );
1234 add_subtree_to_new_template(
1235 current_component_template,
1236 &mut new_template,
1237 id.clone(),
1238 new_location,
1239 new_bounds.clone(),
1240 );
1241 current_component_template.remove_node(id.clone());
1242 processed_ids.push(id);
1243 }
1244
1245 let new_component = ComponentDefinition {
1246 type_id: new_component_type_id.clone(),
1247 is_main_component: false,
1248 is_primitive: false,
1249 is_struct_only_component: false,
1250 module_path,
1251 primitive_instance_import_path: None,
1252 template: Some(new_template),
1253 settings: None,
1254 timelines: vec![],
1255 route_branch: None,
1256 };
1257
1258 manifest
1259 .components
1260 .insert(new_component_type_id.clone(), new_component);
1261
1262 self._cached_new_component_type_id = Some(new_component_type_id.clone());
1263
1264 let settings = {
1265 let mut settings: Vec<SettingElement> = Vec::new();
1266 settings.push(SettingElement::Setting(
1267 Token::new_without_location("x".to_string()),
1268 ValueDefinition::LiteralValue(self.x.to_pax_value()),
1269 ));
1270 settings.push(SettingElement::Setting(
1271 Token::new_without_location("y".to_string()),
1272 ValueDefinition::LiteralValue(self.y.to_pax_value()),
1273 ));
1274 settings.push(SettingElement::Setting(
1275 Token::new_without_location("width".to_string()),
1276 ValueDefinition::LiteralValue(self.width.to_pax_value()),
1277 ));
1278 settings.push(SettingElement::Setting(
1279 Token::new_without_location("height".to_string()),
1280 ValueDefinition::LiteralValue(self.height.to_pax_value()),
1281 ));
1282 settings
1283 };
1284
1285 let mut add_request = AddTemplateNodeRequest::new(
1286 current_component_type_id.clone(),
1287 new_component_type_id.clone(),
1288 NodeType::Template(settings),
1289 Some(new_component_location),
1290 );
1291 let response = add_request.execute(manifest)?;
1292
1293 self._cached_add = Some(add_request);
1294
1295 Ok(ConvertToComponentResponse {
1296 command_id: None,
1297 uni: response.uni,
1298 new_component_type_id,
1299 })
1300 }
1301
1302 fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
1303 Some(UndoRedoCommand::ConvertToComponentRequest(Box::new(
1304 self.clone(),
1305 )))
1306 }
1307}
1308
1309impl Undo for ConvertToComponentRequest {
1310 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
1311 if let Some(add_request) = &mut self._cached_add {
1312 add_request.undo(manifest).unwrap();
1313 }
1314
1315 if let Some(new_component_type_id) = &self._cached_new_component_type_id {
1316 manifest.components.remove(new_component_type_id);
1317 }
1318
1319 if let Some(template) = &self._cached_template {
1320 let binding = manifest
1321 .components
1322 .get_mut(&self.subtrees_roots[0].id.get_containing_component_type_id());
1323 let current_component = binding.expect("Component not found");
1324 current_component.template = Some(template.clone());
1325 }
1326
1327 Ok(())
1328 }
1329}
1330
1331#[derive(Serialize, Deserialize, Clone)]
1333pub struct SwapMainComponentRequest {
1334 new_component: ComponentDefinition,
1335 _cached_main_component: Option<ComponentDefinition>,
1336}
1337
1338impl SwapMainComponentRequest {
1339 pub fn new(new_componnet: ComponentDefinition) -> Self {
1340 Self {
1341 new_component: new_componnet,
1342 _cached_main_component: None,
1343 }
1344 }
1345}
1346
1347pub struct SwapMainComponentResponse {
1348 command_id: Option<usize>,
1349}
1350
1351impl Request for SwapMainComponentRequest {
1352 type Response = SwapMainComponentResponse;
1353}
1354
1355impl Response for SwapMainComponentResponse {
1356 fn set_id(&mut self, id: usize) {
1357 self.command_id = Some(id);
1358 }
1359 fn get_id(&self) -> usize {
1360 self.command_id.unwrap()
1361 }
1362
1363 fn get_reload_type(&self) -> Option<ReloadType> {
1364 Some(ReloadType::Tree)
1365 }
1366}
1367
1368impl Command<SwapMainComponentRequest> for SwapMainComponentRequest {
1369 fn execute(&mut self, manifest: &mut PaxManifest) -> Result<SwapMainComponentResponse, String> {
1370 let main_component = manifest
1371 .components
1372 .get_mut(&manifest.main_component_type_id)
1373 .unwrap();
1374
1375 self._cached_main_component = Some(main_component.clone());
1376
1377 manifest.components.insert(
1378 self.new_component.type_id.clone(),
1379 self.new_component.clone(),
1380 );
1381 manifest.main_component_type_id = self.new_component.type_id.clone();
1382 Ok(SwapMainComponentResponse { command_id: None })
1383 }
1384}
1385
1386impl Undo for SwapMainComponentRequest {
1387 fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
1388 manifest.components.remove(&self.new_component.type_id);
1389 manifest.main_component_type_id = self
1390 ._cached_main_component
1391 .as_ref()
1392 .unwrap()
1393 .type_id
1394 .clone();
1395 manifest.components.insert(
1396 self._cached_main_component
1397 .as_ref()
1398 .unwrap()
1399 .type_id
1400 .clone(),
1401 self._cached_main_component.as_ref().unwrap().clone(),
1402 );
1403 Ok(())
1404 }
1405}
1406
1407#[derive(Serialize, Deserialize, Debug, Clone)]
1408pub enum NodeAction {
1409 Add(AddTemplateNodeRequest),
1410 Update(UpdateTemplateNodeRequest),
1411 Remove(RemoveTemplateNodeRequest),
1412 Move(PasteSubTreeRequest),
1413}
1414
1415pub fn update_position_if_exists(new_x: f64, new_y: f64, settings: &mut [SettingElement]) {
1416 for setting in settings.iter_mut() {
1417 if let SettingElement::Setting(key, value) = setting {
1418 if key.token_value == "x" {
1419 *value = ValueDefinition::LiteralValue(new_x.to_pax_value())
1420 }
1421 if key.token_value == "y" {
1422 *value = ValueDefinition::LiteralValue(new_y.to_pax_value())
1423 }
1424 }
1425 }
1426}