AnimGraphActionCommandTests.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <EMotionFX/CommandSystem/Source/AnimGraphConnectionCommands.h>
  9. #include <EMotionFX/CommandSystem/Source/AnimGraphNodeCommands.h>
  10. #include <EMotionFX/CommandSystem/Source/AnimGraphTriggerActionCommands.h>
  11. #include <EMotionFX/CommandSystem/Source/CommandManager.h>
  12. #include <EMotionFX/Source/AnimGraphMotionNode.h>
  13. #include <EMotionFX/Source/AnimGraphParameterAction.h>
  14. #include <EMotionFX/Source/AnimGraphStateMachine.h>
  15. #include <EMotionFX/Source/AnimGraphStateTransition.h>
  16. #include <EMotionFX/Source/MotionSet.h>
  17. #include <MCore/Source/CommandGroup.h>
  18. #include <MCore/Source/ReflectionSerializer.h>
  19. #include <Tests/AnimGraphFixture.h>
  20. #include <Tests/TestAssetCode/AnimGraphFactory.h>
  21. namespace EMotionFX
  22. {
  23. class AnimGraphActionCommandsFixture
  24. : public AnimGraphFixture
  25. {
  26. public:
  27. void ConstructGraph() override
  28. {
  29. AnimGraphFixture::ConstructGraph();
  30. m_motionNodeAnimGraph = AnimGraphFactory::Create<TwoMotionNodeAnimGraph>();
  31. m_rootStateMachine = m_motionNodeAnimGraph->GetRootStateMachine();
  32. m_stateA = m_motionNodeAnimGraph->GetMotionNodeA();
  33. m_stateB = m_motionNodeAnimGraph->GetMotionNodeB();
  34. m_transition = AddTransition(m_stateA, m_stateB, 1.0f);
  35. m_motionNodeAnimGraph->InitAfterLoading();
  36. }
  37. void TearDown() override
  38. {
  39. m_motionNodeAnimGraph.reset();
  40. AnimGraphFixture::TearDown();
  41. }
  42. AZStd::unique_ptr<TwoMotionNodeAnimGraph> m_motionNodeAnimGraph;
  43. AnimGraphNode* m_stateA = nullptr;
  44. AnimGraphNode* m_stateB = nullptr;
  45. AnimGraphStateTransition* m_transition = nullptr;
  46. };
  47. TEST_F(AnimGraphActionCommandsFixture, AnimGraphActionCommandTests_AddTransitionAction)
  48. {
  49. CommandSystem::CommandManager commandManager;
  50. AZStd::string result;
  51. MCore::CommandGroup commandGroup;
  52. const AZStd::string serializedOriginal = SerializeAnimGraph();
  53. // 1. Add transition action.
  54. CommandSystem::AddTransitionAction(m_transition, azrtti_typeid<AnimGraphParameterAction>());
  55. const AZStd::string serializedAfterAddSingle = SerializeAnimGraph();
  56. EXPECT_EQ(1, m_transition->GetTriggerActionSetup().GetNumActions())
  57. << "There should be exactly one transition action.";
  58. // 2. Add multiple transition actions in a command group.
  59. CommandSystem::AddTransitionAction(m_transition, azrtti_typeid<AnimGraphParameterAction>(), AZStd::nullopt, AZStd::nullopt, &commandGroup);
  60. CommandSystem::AddTransitionAction(m_transition, azrtti_typeid<AnimGraphParameterAction>(), AZStd::nullopt, AZStd::nullopt, &commandGroup);
  61. CommandSystem::AddTransitionAction(m_transition, azrtti_typeid<AnimGraphParameterAction>(), AZStd::nullopt, AZStd::nullopt, &commandGroup);
  62. EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result));
  63. commandGroup.RemoveAllCommands();
  64. EXPECT_EQ(4, m_transition->GetTriggerActionSetup().GetNumActions())
  65. << "There should be exactly four transition actions.";
  66. // 3. Undo add multiple transition actions.
  67. EXPECT_TRUE(commandManager.Undo(result));
  68. EXPECT_EQ(1, m_transition->GetTriggerActionSetup().GetNumActions())
  69. << "There should be exactly one transition action left.";
  70. EXPECT_EQ(serializedAfterAddSingle, SerializeAnimGraph());
  71. // 4. Undo add transition action.
  72. EXPECT_TRUE(commandManager.Undo(result));
  73. EXPECT_EQ(0, m_transition->GetTriggerActionSetup().GetNumActions())
  74. << "There should be no transition action left anymore.";
  75. EXPECT_EQ(serializedOriginal, SerializeAnimGraph());
  76. }
  77. TEST_F(AnimGraphActionCommandsFixture, AnimGraphActionCommandTests_UndoRemoveTransitionWithAction)
  78. {
  79. CommandSystem::CommandManager commandManager;
  80. AZStd::string result;
  81. MCore::CommandGroup commandGroup;
  82. // 1. Add transition action.
  83. CommandSystem::AddTransitionAction(m_transition, azrtti_typeid<AnimGraphParameterAction>());
  84. const AZStd::string serializedAfterAddAction = SerializeAnimGraph();
  85. EXPECT_EQ(1, m_transition->GetTriggerActionSetup().GetNumActions())
  86. << "There should be exactly one transition action.";
  87. // 2. Remove the whole transition including the action.
  88. {
  89. AZStd::vector<EMotionFX::AnimGraphStateTransition*> transitionList;
  90. CommandSystem::DeleteStateTransition(&commandGroup, m_transition, transitionList);
  91. }
  92. EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result));
  93. commandGroup.RemoveAllCommands();
  94. EXPECT_EQ(0, m_rootStateMachine->GetNumTransitions()) << "The transition A->B should be gone.";
  95. // 3. Undo remove transition.
  96. EXPECT_TRUE(commandManager.Undo(result));
  97. EXPECT_EQ(serializedAfterAddAction, SerializeAnimGraph());
  98. }
  99. TEST_F(AnimGraphActionCommandsFixture, AnimGraphActionCommandTests_AddStateAction)
  100. {
  101. CommandSystem::CommandManager commandManager;
  102. AZStd::string result;
  103. MCore::CommandGroup commandGroup;
  104. const AZStd::string serializedOriginal = SerializeAnimGraph();
  105. // 1. Add state action.
  106. CommandSystem::AddStateAction(m_stateA, azrtti_typeid<AnimGraphParameterAction>());
  107. const AZStd::string serializedAfterAddSingle = SerializeAnimGraph();
  108. EXPECT_EQ(1, m_stateA->GetTriggerActionSetup().GetNumActions())
  109. << "There should be exactly one state action.";
  110. // 2. Add multiple state actions in a command group.
  111. CommandSystem::AddStateAction(m_stateA, azrtti_typeid<AnimGraphParameterAction>(), AZStd::nullopt, AZStd::nullopt, &commandGroup);
  112. CommandSystem::AddStateAction(m_stateA, azrtti_typeid<AnimGraphParameterAction>(), AZStd::nullopt, AZStd::nullopt, &commandGroup);
  113. CommandSystem::AddStateAction(m_stateA, azrtti_typeid<AnimGraphParameterAction>(), AZStd::nullopt, AZStd::nullopt, &commandGroup);
  114. EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result));
  115. commandGroup.RemoveAllCommands();
  116. EXPECT_EQ(4, m_stateA->GetTriggerActionSetup().GetNumActions())
  117. << "There should be exactly four state actions.";
  118. // 3. Undo add multiple state actions.
  119. EXPECT_TRUE(commandManager.Undo(result));
  120. EXPECT_EQ(1, m_stateA->GetTriggerActionSetup().GetNumActions())
  121. << "There should be exactly one state action left.";
  122. EXPECT_EQ(serializedAfterAddSingle, SerializeAnimGraph());
  123. // 4. Undo add state action.
  124. EXPECT_TRUE(commandManager.Undo(result));
  125. EXPECT_EQ(0, m_stateA->GetTriggerActionSetup().GetNumActions())
  126. << "There should be no state action left anymore.";
  127. EXPECT_EQ(serializedOriginal, SerializeAnimGraph());
  128. }
  129. // TODO: There is a reflection issue with MCore::ReflectionSerializer::SerializeMembersExcept that is used
  130. // in the remove node command. AZStd::vector<AZStd::pair<AZStd::string, AZStd::string>> is not reflected.
  131. TEST_F(AnimGraphActionCommandsFixture, DISABLED_AnimGraphActionCommandTests_UndoRemoveStateWithAction)
  132. {
  133. CommandSystem::CommandManager commandManager;
  134. AZStd::string result;
  135. MCore::CommandGroup commandGroup;
  136. // 1. Add state action.
  137. CommandSystem::AddStateAction(m_stateA, azrtti_typeid<AnimGraphParameterAction>());
  138. const AZStd::string serializedAfterAddAction = SerializeAnimGraph();
  139. EXPECT_EQ(1, m_stateA->GetTriggerActionSetup().GetNumActions())
  140. << "There should be exactly one state action.";
  141. // 2. Remove the whole state including the action.
  142. CommandSystem::DeleteNodes(&commandGroup, m_motionNodeAnimGraph.get(), { m_stateA });
  143. EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result));
  144. commandGroup.RemoveAllCommands();
  145. EXPECT_EQ(nullptr, m_motionNodeAnimGraph->RecursiveFindNodeByName("A")) << "State A should be gone.";
  146. // 3. Undo remove state.
  147. EXPECT_TRUE(commandManager.Undo(result));
  148. EXPECT_EQ(serializedAfterAddAction, SerializeAnimGraph());
  149. }
  150. } // namespace EMotionFX