1use crate::fyrox::core::pool::ErasedHandle;
22use crate::fyrox::core::variable::InheritableVariable;
23use crate::fyrox::graph::{SceneGraph, SceneGraphNode};
24use crate::fyrox::{
25 core::{
26 algebra::Vector2,
27 pool::{Handle, Ticket},
28 },
29 generic_animation::machine::{
30 layer::MachineLayer, mask::LayerMask, Machine, PoseNode, State, Transition,
31 },
32};
33use crate::{
34 command::{CommandContext, CommandTrait},
35 scene::commands::GameSceneContext,
36 ui_scene::commands::UiSceneContext,
37};
38
39use fyrox::core::reflect::Reflect;
40use std::fmt::Debug;
41
42pub mod blend;
43
44macro_rules! define_spawn_command {
45 ($name:ident, $ent_type:ty, $container:ident) => {
46 #[derive(Debug)]
47 pub enum $name<N: Reflect> {
48 Unknown,
49 NonExecuted {
50 node_handle: Handle<N>,
51 layer_index: usize,
52 state: $ent_type,
53 },
54 Executed {
55 node_handle: Handle<N>,
56 layer_index: usize,
57 handle: Handle<$ent_type>,
58 },
59 Reverted {
60 node_handle: Handle<N>,
61 layer_index: usize,
62 ticket: Ticket<$ent_type>,
63 state: $ent_type,
64 },
65 }
66
67 impl<N: Reflect> $name<N> {
68 pub fn new(node_handle: Handle<N>, layer_index: usize, state: $ent_type) -> Self {
69 Self::NonExecuted {
70 node_handle,
71 layer_index,
72 state,
73 }
74 }
75 }
76
77 impl<N: Reflect> CommandTrait for $name<N> {
78 fn name(&mut self, _context: &dyn CommandContext) -> String {
79 "Add State".to_string()
80 }
81
82 fn execute(&mut self, context: &mut dyn CommandContext) {
83 match std::mem::replace(self, $name::Unknown) {
84 $name::NonExecuted {
85 node_handle,
86 layer_index,
87 state,
88 } => {
89 let machine = fetch_machine(context, node_handle);
90 *self = $name::Executed {
91 node_handle,
92 layer_index,
93 handle: machine.layers_mut()[layer_index].$container().spawn(state),
94 };
95 }
96 $name::Reverted {
97 node_handle,
98 layer_index,
99 ticket,
100 state,
101 } => {
102 let machine = fetch_machine(context, node_handle);
103 *self = $name::Executed {
104 node_handle,
105 layer_index,
106 handle: machine.layers_mut()[layer_index]
107 .$container()
108 .put_back(ticket, state),
109 }
110 }
111 _ => unreachable!(),
112 }
113 }
114
115 fn revert(&mut self, context: &mut dyn CommandContext) {
116 match std::mem::replace(self, $name::Unknown) {
117 $name::Executed {
118 node_handle,
119 layer_index,
120 handle,
121 } => {
122 let machine = fetch_machine(context, node_handle);
123 let (ticket, state) = machine.layers_mut()[layer_index]
124 .$container()
125 .take_reserve(handle);
126 *self = $name::Reverted {
127 node_handle,
128 layer_index,
129 ticket,
130 state,
131 }
132 }
133 _ => unreachable!(),
134 }
135 }
136
137 fn finalize(&mut self, context: &mut dyn CommandContext) {
138 if let $name::Reverted {
139 node_handle,
140 layer_index,
141 ticket,
142 ..
143 } = std::mem::replace(self, $name::Unknown)
144 {
145 let machine = fetch_machine(context, node_handle);
146 machine.layers_mut()[layer_index]
147 .$container()
148 .forget_ticket(ticket)
149 }
150 }
151 }
152 };
153}
154
155define_spawn_command!(AddTransitionCommand, Transition<Handle<N>>, transitions_mut);
156
157#[derive(Debug)]
158pub enum AddStateCommand<N: Reflect> {
159 Unknown,
160 NonExecuted {
161 node_handle: Handle<N>,
162 layer_index: usize,
163 state: State<Handle<N>>,
164 },
165 Executed {
166 node_handle: Handle<N>,
167 layer_index: usize,
168 handle: Handle<State<Handle<N>>>,
169 prev_entry_state: Handle<State<Handle<N>>>,
170 },
171 Reverted {
172 node_handle: Handle<N>,
173 layer_index: usize,
174 ticket: Ticket<State<Handle<N>>>,
175 state: State<Handle<N>>,
176 },
177}
178
179impl<N: Reflect> AddStateCommand<N> {
180 pub fn new(node_handle: Handle<N>, layer_index: usize, state: State<Handle<N>>) -> Self {
181 Self::NonExecuted {
182 node_handle,
183 layer_index,
184 state,
185 }
186 }
187}
188
189pub fn fetch_machine<N: Reflect>(
190 context: &mut dyn CommandContext,
191 node_handle: Handle<N>,
192) -> &mut Machine<Handle<N>> {
193 let context2 = unsafe { &mut *(context as *mut dyn CommandContext) };
197
198 if let Some(game_scene) = context.component_mut::<GameSceneContext>() {
199 game_scene
200 .scene
201 .graph
202 .node_mut(ErasedHandle::from(node_handle).into())
203 .component_mut::<InheritableVariable<Machine<Handle<N>>>>()
204 .unwrap()
205 } else if let Some(ui) = context2.component_mut::<UiSceneContext>() {
206 ui.ui
207 .node_mut(ErasedHandle::from(node_handle).into())
208 .component_mut::<InheritableVariable<Machine<Handle<N>>>>()
209 .unwrap()
210 } else {
211 panic!("Unsupported container!")
212 }
213}
214
215impl<N: Reflect> CommandTrait for AddStateCommand<N> {
216 fn name(&mut self, _context: &dyn CommandContext) -> String {
217 "Add State".to_string()
218 }
219
220 fn execute(&mut self, context: &mut dyn CommandContext) {
221 match std::mem::replace(self, AddStateCommand::Unknown) {
222 AddStateCommand::NonExecuted {
223 node_handle,
224 layer_index,
225 state,
226 } => {
227 let machine = fetch_machine(context, node_handle);
228 let layer = &mut machine.layers_mut()[layer_index];
229
230 let handle = layer.add_state(state);
231
232 let prev_entry_state = layer.entry_state();
233
234 if layer.entry_state().is_none() {
236 layer.set_entry_state(handle);
237 }
238
239 *self = AddStateCommand::Executed {
240 node_handle,
241 layer_index,
242 handle,
243 prev_entry_state,
244 };
245 }
246 AddStateCommand::Reverted {
247 node_handle,
248 layer_index,
249 ticket,
250 state,
251 } => {
252 let machine = fetch_machine(context, node_handle);
253 let layer = &mut machine.layers_mut()[layer_index];
254
255 let handle = layer.states_mut().put_back(ticket, state);
256
257 let prev_entry_state = layer.entry_state();
258
259 if layer.entry_state().is_none() {
261 layer.set_entry_state(handle);
262 }
263
264 *self = AddStateCommand::Executed {
265 node_handle,
266 layer_index,
267 handle,
268 prev_entry_state,
269 }
270 }
271 _ => unreachable!(),
272 }
273 }
274
275 fn revert(&mut self, context: &mut dyn CommandContext) {
276 match std::mem::replace(self, AddStateCommand::Unknown) {
277 AddStateCommand::Executed {
278 node_handle,
279 layer_index,
280 handle,
281 prev_entry_state,
282 } => {
283 let machine = fetch_machine(context, node_handle);
284
285 let layer = &mut machine.layers_mut()[layer_index];
286
287 layer.set_entry_state(prev_entry_state);
288
289 let (ticket, state) = layer.states_mut().take_reserve(handle);
290
291 *self = AddStateCommand::Reverted {
292 node_handle,
293 layer_index,
294 ticket,
295 state,
296 }
297 }
298 _ => unreachable!(),
299 }
300 }
301
302 fn finalize(&mut self, context: &mut dyn CommandContext) {
303 if let AddStateCommand::Reverted {
304 node_handle,
305 layer_index,
306 ticket,
307 ..
308 } = std::mem::replace(self, AddStateCommand::Unknown)
309 {
310 let machine = fetch_machine(context, node_handle);
311 machine.layers_mut()[layer_index]
312 .states_mut()
313 .forget_ticket(ticket)
314 }
315 }
316}
317
318#[derive(Debug)]
319pub enum AddPoseNodeCommand<N: Reflect> {
320 Unknown,
321 NonExecuted {
322 node_handle: Handle<N>,
323 layer_index: usize,
324 node: PoseNode<Handle<N>>,
325 },
326 Executed {
327 node_handle: Handle<N>,
328 layer_index: usize,
329 handle: Handle<PoseNode<Handle<N>>>,
330 prev_root_node: Handle<PoseNode<Handle<N>>>,
331 },
332 Reverted {
333 node_handle: Handle<N>,
334 layer_index: usize,
335 ticket: Ticket<PoseNode<Handle<N>>>,
336 node: PoseNode<Handle<N>>,
337 },
338}
339
340impl<N: Reflect> AddPoseNodeCommand<N> {
341 pub fn new(node_handle: Handle<N>, layer_index: usize, node: PoseNode<Handle<N>>) -> Self {
342 Self::NonExecuted {
343 node_handle,
344 layer_index,
345 node,
346 }
347 }
348}
349
350impl<N: Reflect> CommandTrait for AddPoseNodeCommand<N> {
351 fn name(&mut self, _context: &dyn CommandContext) -> String {
352 "Add Pose Node".to_string()
353 }
354
355 fn execute(&mut self, context: &mut dyn CommandContext) {
356 match std::mem::replace(self, AddPoseNodeCommand::Unknown) {
357 AddPoseNodeCommand::NonExecuted {
358 node_handle,
359 layer_index,
360 node,
361 } => {
362 let machine = fetch_machine(context, node_handle);
363 let layer = &mut machine.layers_mut()[layer_index];
364
365 let parent_state = node.parent_state;
366
367 let handle = layer.add_node(node);
368
369 let parent_state_ref = &mut layer.states_mut()[parent_state];
370 let prev_root_node = parent_state_ref.root;
371 if parent_state_ref.root.is_none() {
372 parent_state_ref.root = handle;
373 }
374
375 *self = AddPoseNodeCommand::Executed {
376 node_handle,
377 layer_index,
378 handle,
379 prev_root_node,
380 };
381 }
382 AddPoseNodeCommand::Reverted {
383 node_handle,
384 layer_index,
385 ticket,
386 node,
387 } => {
388 let machine = fetch_machine(context, node_handle);
389 let layer = &mut machine.layers_mut()[layer_index];
390 let parent_state = node.parent_state;
391
392 let handle = layer.nodes_mut().put_back(ticket, node);
393
394 let parent_state_ref = &mut layer.states_mut()[parent_state];
395 let prev_root_node = parent_state_ref.root;
396 if parent_state_ref.root.is_none() {
397 parent_state_ref.root = handle;
398 }
399
400 *self = AddPoseNodeCommand::Executed {
401 node_handle,
402 layer_index,
403 handle,
404 prev_root_node,
405 }
406 }
407 _ => unreachable!(),
408 }
409 }
410
411 fn revert(&mut self, context: &mut dyn CommandContext) {
412 match std::mem::replace(self, AddPoseNodeCommand::Unknown) {
413 AddPoseNodeCommand::Executed {
414 node_handle,
415 layer_index,
416 handle,
417 prev_root_node,
418 } => {
419 let machine = fetch_machine(context, node_handle);
420 let layer = &mut machine.layers_mut()[layer_index];
421 let (ticket, node) = layer.nodes_mut().take_reserve(handle);
422
423 layer.states_mut()[node.parent_state].root = prev_root_node;
424
425 *self = AddPoseNodeCommand::Reverted {
426 node_handle,
427 layer_index,
428 ticket,
429 node,
430 }
431 }
432 _ => unreachable!(),
433 }
434 }
435
436 fn finalize(&mut self, context: &mut dyn CommandContext) {
437 if let AddPoseNodeCommand::Reverted {
438 node_handle,
439 layer_index,
440 ticket,
441 ..
442 } = std::mem::replace(self, AddPoseNodeCommand::Unknown)
443 {
444 let machine = fetch_machine(context, node_handle);
445 let layer = &mut machine.layers_mut()[layer_index];
446 layer.nodes_mut().forget_ticket(ticket)
447 }
448 }
449}
450
451macro_rules! define_move_command {
452 ($name:ident, $ent_type:ty, $container:ident) => {
453 #[derive(Debug)]
454 pub struct $name<N: Reflect> {
455 absm_node_handle: Handle<N>,
456 layer_index: usize,
457 node: Handle<$ent_type>,
458 old_position: Vector2<f32>,
459 new_position: Vector2<f32>,
460 }
461
462 impl<N: Reflect> $name<N> {
463 pub fn new(
464 absm_node_handle: Handle<N>,
465 node: Handle<$ent_type>,
466 layer_index: usize,
467 old_position: Vector2<f32>,
468 new_position: Vector2<f32>,
469 ) -> Self {
470 Self {
471 absm_node_handle,
472 layer_index,
473 node,
474 old_position,
475 new_position,
476 }
477 }
478
479 fn swap(&mut self) -> Vector2<f32> {
480 let position = self.new_position;
481 std::mem::swap(&mut self.new_position, &mut self.old_position);
482 position
483 }
484
485 fn set_position(&self, context: &mut dyn CommandContext, position: Vector2<f32>) {
486 let machine = fetch_machine(context, self.absm_node_handle);
487 machine.layers_mut()[self.layer_index].$container()[self.node].position = position;
488 }
489 }
490
491 impl<N: Reflect> CommandTrait for $name<N> {
492 fn name(&mut self, _context: &dyn CommandContext) -> String {
493 "Move Entity".to_owned()
494 }
495
496 fn execute(&mut self, context: &mut dyn CommandContext) {
497 let position = self.swap();
498 self.set_position(context, position);
499 }
500
501 fn revert(&mut self, context: &mut dyn CommandContext) {
502 let position = self.swap();
503 self.set_position(context, position);
504 }
505 }
506 };
507}
508
509define_move_command!(MoveStateNodeCommand, State<Handle<N>>, states_mut);
510define_move_command!(MovePoseNodeCommand, PoseNode<Handle<N>>, nodes_mut);
511
512macro_rules! define_free_command {
513 ($name:ident, $ent_type:ty, $container:ident) => {
514 #[derive(Debug)]
515 pub enum $name<N: Reflect> {
516 Unknown,
517 NonExecuted {
518 node_handle: Handle<N>,
519 layer_index: usize,
520 entity_handle: Handle<$ent_type>,
521 },
522 Executed {
523 node_handle: Handle<N>,
524 layer_index: usize,
525 entity: $ent_type,
526 ticket: Ticket<$ent_type>,
527 },
528 Reverted {
529 node_handle: Handle<N>,
530 layer_index: usize,
531 entity_handle: Handle<$ent_type>,
532 },
533 }
534
535 impl<N: Reflect> $name<N> {
536 pub fn new(
537 node_handle: Handle<N>,
538 layer_index: usize,
539 entity_handle: Handle<$ent_type>,
540 ) -> Self {
541 Self::NonExecuted {
542 node_handle,
543 layer_index,
544 entity_handle,
545 }
546 }
547 }
548
549 impl<N: Reflect> CommandTrait for $name<N> {
550 fn name(&mut self, _context: &dyn CommandContext) -> String {
551 "Free Entity".to_owned()
552 }
553
554 fn execute(&mut self, context: &mut dyn CommandContext) {
555 match std::mem::replace(self, Self::Unknown) {
556 Self::NonExecuted {
557 node_handle,
558 layer_index,
559 entity_handle,
560 }
561 | Self::Reverted {
562 node_handle,
563 layer_index,
564 entity_handle,
565 } => {
566 let machine = fetch_machine(context, node_handle);
567 let (ticket, entity) = machine.layers_mut()[layer_index]
568 .$container()
569 .take_reserve(entity_handle);
570 *self = Self::Executed {
571 node_handle,
572 layer_index,
573 entity,
574 ticket,
575 }
576 }
577 _ => unreachable!(),
578 }
579 }
580
581 fn revert(&mut self, context: &mut dyn CommandContext) {
582 match std::mem::replace(self, Self::Unknown) {
583 Self::Executed {
584 node_handle,
585 layer_index,
586 entity,
587 ticket,
588 } => {
589 let machine = fetch_machine(context, node_handle);
590
591 *self = Self::Reverted {
592 node_handle,
593 layer_index,
594 entity_handle: machine.layers_mut()[layer_index]
595 .$container()
596 .put_back(ticket, entity),
597 };
598 }
599 _ => unreachable!(),
600 }
601 }
602
603 fn finalize(&mut self, context: &mut dyn CommandContext) {
604 match std::mem::replace(self, Self::Unknown) {
605 Self::Executed {
606 node_handle,
607 layer_index,
608 ticket,
609 ..
610 } => {
611 let machine = fetch_machine(context, node_handle);
612 machine.layers_mut()[layer_index]
613 .$container()
614 .forget_ticket(ticket);
615 }
616 _ => (),
617 }
618 }
619 }
620 };
621}
622
623define_free_command!(DeleteStateCommand, State<Handle<N>>, states_mut);
624define_free_command!(DeletePoseNodeCommand, PoseNode<Handle<N>>, nodes_mut);
625define_free_command!(
626 DeleteTransitionCommand,
627 Transition<Handle<N>>,
628 transitions_mut
629);
630
631#[macro_export]
632macro_rules! define_push_element_to_collection_command {
633 ($name:ident<$model_handle:ty, $value_type:ty>($self:ident, $context:ident) $get_collection:block) => {
634 #[derive(Debug)]
635 pub struct $name<N: fyrox::core::reflect::Reflect> {
636 pub node_handle: Handle<N>,
637 pub handle: $model_handle,
638 pub layer_index: usize,
639 pub value: Option<$value_type>,
640 }
641
642 impl<N: fyrox::core::reflect::Reflect> $name<N> {
643 pub fn new(node_handle: Handle<N>, handle: $model_handle, layer_index: usize, value: $value_type) -> Self {
644 Self {
645 node_handle,
646 handle,
647 layer_index,
648 value: Some(value)
649 }
650 }
651 }
652
653 impl<N: fyrox::core::reflect::Reflect> CommandTrait for $name<N> {
654 fn name(&mut self, _context: &dyn CommandContext) -> String {
655 "Push Element To Collection".to_string()
656 }
657
658 fn execute(&mut $self, $context: &mut dyn CommandContext) {
659 ($get_collection).push($self.value.take().unwrap());
660 }
661
662 fn revert(&mut $self, $context: &mut dyn CommandContext) {
663 $self.value = Some(($get_collection).pop().unwrap());
664 }
665 }
666 };
667}
668
669#[macro_export]
670macro_rules! define_remove_collection_element_command {
671 ($name:ident<$model_handle:ty, $value_type:ty>($self:ident, $context:ident) $get_collection:block) => {
672 #[derive(Debug)]
673 #[allow(dead_code)]
674 pub struct $name {
675 handle: $model_handle,
676 index: usize,
677 value: Option<$value_type>,
678 }
679
680 impl $name {
681 pub fn new(handle: $model_handle, index: usize) -> Self {
682 Self {
683 handle,
684 value: None,
685 index
686 }
687 }
688 }
689
690 impl CommandTrait for $name {
691 fn name(&mut self, _context: &dyn CommandContext) -> String {
692 "Remove Collection Element".to_string()
693 }
694
695 fn execute(&mut $self, $context: &mut dyn CommandContext) {
696 let collection = $get_collection;
697 $self.value = Some(collection.remove($self.index));
698 }
699
700 fn revert(&mut $self, $context: &mut dyn CommandContext) {
701 let collection = $get_collection;
702 collection.insert($self.index, $self.value.take().unwrap())
703 }
704 }
705 };
706}
707
708#[macro_export]
709macro_rules! define_set_collection_element_command {
710 ($name:ident<$model_handle:ty, $value_type:ty>($self:ident, $context:ident) $swap_value:block) => {
711 #[derive(Debug)]
712 pub struct $name<N: fyrox::core::reflect::Reflect> {
713 pub node_handle: Handle<N>,
714 pub handle: $model_handle,
715 pub layer_index: usize,
716 pub index: usize,
717 pub value: $value_type,
718 }
719
720 impl<N: fyrox::core::reflect::Reflect> $name<N> {
721 pub fn swap(&mut $self, $context: &mut dyn CommandContext) {
722 $swap_value
723 }
724 }
725
726 impl<N: fyrox::core::reflect::Reflect> CommandTrait for $name<N> {
727 fn name(&mut self,
728 #[allow(unused_variables)]
729 $context: &dyn CommandContext
730 ) -> String {
731 "Set Collection Element".to_owned()
732 }
733
734 fn execute(&mut self, $context: &mut dyn CommandContext) {
735 self.swap($context);
736 }
737
738 fn revert(&mut self, $context: &mut dyn CommandContext) {
739 self.swap($context);
740 }
741 }
742 };
743}
744
745#[derive(Debug)]
746pub struct SetMachineEntryStateCommand<N: Reflect> {
747 pub node_handle: Handle<N>,
748 pub layer: usize,
749 pub entry: Handle<State<Handle<N>>>,
750}
751
752impl<N: Reflect> SetMachineEntryStateCommand<N> {
753 fn swap(&mut self, context: &mut dyn CommandContext) {
754 let machine = fetch_machine(context, self.node_handle);
755 let layer = &mut machine.layers_mut()[self.layer];
756
757 let prev = layer.entry_state();
758 layer.set_entry_state(self.entry);
759 self.entry = prev;
760 }
761}
762
763impl<N: Reflect> CommandTrait for SetMachineEntryStateCommand<N> {
764 fn name(&mut self, _context: &dyn CommandContext) -> String {
765 "Set Entry State".to_string()
766 }
767
768 fn execute(&mut self, context: &mut dyn CommandContext) {
769 self.swap(context)
770 }
771
772 fn revert(&mut self, context: &mut dyn CommandContext) {
773 self.swap(context)
774 }
775}
776
777#[macro_export]
778macro_rules! define_absm_swap_command {
779 ($name:ident<$model_type:ty, $value_type:ty>[$($field_name:ident:$field_type:ty),*]($self:ident, $context:ident) $get_field:block) => {
780 #[derive(Debug)]
781 pub struct $name<N:Reflect> {
782 pub node_handle: Handle<N>,
783 pub handle: $model_type,
784 pub value: $value_type,
785 $(
786 pub $field_name: $field_type,
787 )*
788 }
789
790 impl<N:Reflect> $name<N> {
791 fn swap(&mut $self, $context: &mut dyn CommandContext) {
792 let field = $get_field;
793
794 std::mem::swap(field, &mut $self.value);
795 }
796 }
797
798 impl<N:Reflect> CommandTrait for $name<N> {
799 fn name(&mut self, _context: &dyn CommandContext) -> String {
800 stringify!($name).to_string()
801 }
802
803 fn execute(&mut self, context: &mut dyn CommandContext) {
804 self.swap(context)
805 }
806
807 fn revert(&mut self, context: &mut dyn CommandContext) {
808 self.swap(context)
809 }
810 }
811 };
812}
813
814define_absm_swap_command!(SetStateRootPoseCommand<Handle<State<Handle<N>>>, Handle<PoseNode<Handle<N>>>>[layer_index: usize](self, context) {
815 let machine = fetch_machine(context, self.node_handle);
816 &mut machine.layers_mut()[self.layer_index].states_mut()[self.handle].root
817});
818
819#[derive(Debug)]
820pub struct SetLayerNameCommand<N: Reflect> {
821 pub absm_node_handle: Handle<N>,
822 pub layer_index: usize,
823 pub name: String,
824}
825
826impl<N: Reflect> SetLayerNameCommand<N> {
827 fn swap(&mut self, context: &mut dyn CommandContext) {
828 let layer =
829 &mut fetch_machine(context, self.absm_node_handle).layers_mut()[self.layer_index];
830 let prev = layer.name().to_string();
831 layer.set_name(self.name.clone());
832 self.name = prev;
833 }
834}
835
836impl<N: Reflect> CommandTrait for SetLayerNameCommand<N> {
837 fn name(&mut self, _context: &dyn CommandContext) -> String {
838 "Set Layer Name".to_string()
839 }
840
841 fn execute(&mut self, context: &mut dyn CommandContext) {
842 self.swap(context)
843 }
844
845 fn revert(&mut self, context: &mut dyn CommandContext) {
846 self.swap(context)
847 }
848}
849
850#[derive(Debug)]
851pub struct AddLayerCommand<N: Reflect> {
852 pub absm_node_handle: Handle<N>,
853 pub layer: Option<MachineLayer<Handle<N>>>,
854}
855
856impl<N: Reflect> CommandTrait for AddLayerCommand<N> {
857 fn name(&mut self, _context: &dyn CommandContext) -> String {
858 "Add Layer".to_string()
859 }
860
861 fn execute(&mut self, context: &mut dyn CommandContext) {
862 fetch_machine(context, self.absm_node_handle).add_layer(self.layer.take().unwrap());
863 }
864
865 fn revert(&mut self, context: &mut dyn CommandContext) {
866 self.layer = fetch_machine(context, self.absm_node_handle).pop_layer();
867 }
868}
869
870#[derive(Debug)]
871pub struct RemoveLayerCommand<N: Reflect> {
872 pub absm_node_handle: Handle<N>,
873 pub layer_index: usize,
874 pub layer: Option<MachineLayer<Handle<N>>>,
875}
876
877impl<N: Reflect> RemoveLayerCommand<N> {
878 pub fn new(absm_node_handle: Handle<N>, layer_index: usize) -> Self {
879 Self {
880 absm_node_handle,
881 layer_index,
882 layer: None,
883 }
884 }
885}
886
887impl<N: Reflect> CommandTrait for RemoveLayerCommand<N> {
888 fn name(&mut self, _context: &dyn CommandContext) -> String {
889 format!("Remove {} Layer", self.layer_index)
890 }
891
892 fn execute(&mut self, context: &mut dyn CommandContext) {
893 self.layer =
894 Some(fetch_machine(context, self.absm_node_handle).remove_layer(self.layer_index));
895 }
896
897 fn revert(&mut self, context: &mut dyn CommandContext) {
898 fetch_machine(context, self.absm_node_handle)
899 .insert_layer(self.layer_index, self.layer.take().unwrap());
900 }
901}
902
903#[derive(Debug)]
904pub struct SetLayerMaskCommand<N: Reflect> {
905 pub absm_node_handle: Handle<N>,
906 pub layer_index: usize,
907 pub mask: LayerMask<Handle<N>>,
908}
909
910impl<N: Reflect> SetLayerMaskCommand<N> {
911 fn swap(&mut self, context: &mut dyn CommandContext) {
912 let layer =
913 &mut fetch_machine(context, self.absm_node_handle).layers_mut()[self.layer_index];
914 let old = layer.mask().clone();
915 layer.set_mask(std::mem::replace(&mut self.mask, old));
916 }
917}
918
919impl<N: Reflect> CommandTrait for SetLayerMaskCommand<N> {
920 fn name(&mut self, _context: &dyn CommandContext) -> String {
921 "Set Layer Mask".to_string()
922 }
923
924 fn execute(&mut self, context: &mut dyn CommandContext) {
925 self.swap(context)
926 }
927
928 fn revert(&mut self, context: &mut dyn CommandContext) {
929 self.swap(context)
930 }
931}