Skip to main content

fyroxed_base/plugins/absm/command/
mod.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21use 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    // SAFETY: Borrow checker cannot resolve lifetime properly in the following `if` chain.
194    // This is safe to do, because there's only one mutable reference anyway. Should be fixed
195    // with Polonius.
196    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                // Set entry state if it wasn't set yet.
235                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                // Set entry state if it wasn't set yet.
260                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}