PrefabScriptingTests.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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 <AzToolsFramework/ToolsComponents/TransformComponent.h>
  9. #include <Entity/EntityUtilityComponent.h>
  10. #include <Prefab/PrefabTestComponent.h>
  11. #include <Prefab/PrefabTestDomUtils.h>
  12. #include <Prefab/PrefabTestFixture.h>
  13. namespace UnitTest
  14. {
  15. TemplateId g_globalTemplateId = {};
  16. AZStd::string g_globalPrefabString = "";
  17. class PrefabScriptingTest : public PrefabTestFixture
  18. {
  19. void InitProperties() const
  20. {
  21. AZ::ComponentApplicationRequests* componentApplicationRequests = AZ::Interface<AZ::ComponentApplicationRequests>::Get();
  22. ASSERT_NE(componentApplicationRequests, nullptr);
  23. auto behaviorContext = componentApplicationRequests->GetBehaviorContext();
  24. ASSERT_NE(behaviorContext, nullptr);
  25. behaviorContext->Property("g_globalTemplateId", BehaviorValueProperty(&g_globalTemplateId));
  26. behaviorContext->Property("g_globalPrefabString", BehaviorValueProperty(&g_globalPrefabString));
  27. g_globalTemplateId = TemplateId{};
  28. g_globalPrefabString = AZStd::string{};
  29. }
  30. void SetUpEditorFixtureImpl() override
  31. {
  32. InitProperties();
  33. }
  34. void TearDownEditorFixtureImpl() override
  35. {
  36. g_globalPrefabString.set_capacity(0); // Free all memory
  37. }
  38. };
  39. TEST_F(PrefabScriptingTest, CreatePrefabTemplate_GeneratesComponentsWithTypeNamesAsSerializedIdentifiers)
  40. {
  41. AZ::EntityId entityId;
  42. AzToolsFramework::EntityUtilityBus::BroadcastResult(entityId, &AzToolsFramework::EntityUtilityBus::Events::CreateEditorReadyEntity, "test");
  43. TemplateId templateId1;
  44. PrefabSystemScriptingBus::BroadcastResult(templateId1, &PrefabSystemScriptingBus::Events::CreatePrefabTemplate, AZStd::vector{ entityId }, "test.prefab");
  45. auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
  46. auto instance1 = prefabSystemComponentInterface->InstantiatePrefab(templateId1);
  47. // Clear all templates to reset the system
  48. prefabSystemComponentInterface->RemoveAllTemplates();
  49. TemplateId templateId2;
  50. PrefabSystemScriptingBus::BroadcastResult(templateId2, &PrefabSystemScriptingBus::Events::CreatePrefabTemplate, AZStd::vector{ entityId }, "test.prefab");
  51. auto instance2 = prefabSystemComponentInterface->InstantiatePrefab(templateId2);
  52. auto referenceWrapper1 = instance1->GetContainerEntity();
  53. auto referenceWrapper2 = instance2->GetContainerEntity();
  54. ASSERT_TRUE(referenceWrapper1);
  55. ASSERT_TRUE(referenceWrapper2);
  56. auto transformComponent1 = referenceWrapper1->get().FindComponent<AzToolsFramework::Components::TransformComponent>();
  57. auto transformComponent2 = referenceWrapper2->get().FindComponent<AzToolsFramework::Components::TransformComponent>();
  58. EXPECT_EQ(transformComponent1->GetSerializedIdentifier(), transformComponent1->RTTI_GetTypeName());
  59. EXPECT_EQ(transformComponent2->GetSerializedIdentifier(), transformComponent1->RTTI_GetTypeName());
  60. }
  61. TEST_F(PrefabScriptingTest, PrefabScripting_CreatePrefab)
  62. {
  63. AZ::ScriptContext sc;
  64. auto behaviorContext = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->GetBehaviorContext();
  65. sc.BindTo(behaviorContext);
  66. sc.Execute(R"LUA(
  67. my_id = EntityUtilityBus.Broadcast.CreateEditorReadyEntity("test")
  68. entities = vector_EntityId()
  69. entities:push_back(my_id)
  70. g_globalTemplateId = PrefabSystemScriptingBus.Broadcast.CreatePrefab(entities, "test.prefab")
  71. )LUA");
  72. EXPECT_NE(g_globalTemplateId, TemplateId{});
  73. auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
  74. ASSERT_NE(prefabSystemComponentInterface, nullptr);
  75. TemplateReference templateRef = prefabSystemComponentInterface->FindTemplate(g_globalTemplateId);
  76. EXPECT_TRUE(templateRef);
  77. }
  78. TEST_F(PrefabScriptingTest, PrefabScripting_CreatePrefab_NoEntities)
  79. {
  80. AZ::ScriptContext sc;
  81. auto behaviorContext = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->GetBehaviorContext();
  82. sc.BindTo(behaviorContext);
  83. sc.Execute(R"LUA(
  84. my_id = EntityUtilityBus.Broadcast.CreateEditorReadyEntity("test")
  85. entities = vector_EntityId()
  86. g_globalTemplateId = PrefabSystemScriptingBus.Broadcast.CreatePrefab(entities, "test.prefab")
  87. )LUA");
  88. EXPECT_NE(g_globalTemplateId, TemplateId{});
  89. auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
  90. ASSERT_NE(prefabSystemComponentInterface, nullptr);
  91. TemplateReference templateRef = prefabSystemComponentInterface->FindTemplate(g_globalTemplateId);
  92. EXPECT_TRUE(templateRef);
  93. }
  94. TEST_F(PrefabScriptingTest, PrefabScripting_CreatePrefab_NoPath)
  95. {
  96. AZ::ScriptContext sc;
  97. auto behaviorContext = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->GetBehaviorContext();
  98. sc.BindTo(behaviorContext);
  99. AZ_TEST_START_TRACE_SUPPRESSION;
  100. sc.Execute(R"LUA(
  101. my_id = EntityUtilityBus.Broadcast.CreateEditorReadyEntity("test")
  102. entities = vector_EntityId()
  103. template_id = PrefabSystemScriptingBus.Broadcast.CreatePrefab(entities, "")
  104. )LUA");
  105. /*
  106. error: PrefabSystemComponent::CreateTemplateFromInstance - Attempted to create a prefab template from an instance without a source file path. Unable to proceed.
  107. error: Failed to create a Template associated with file path during CreatePrefab.
  108. error: Failed to create prefab
  109. */
  110. AZ_TEST_STOP_TRACE_SUPPRESSION(3);
  111. }
  112. TEST_F(PrefabScriptingTest, PrefabScripting_SaveToString)
  113. {
  114. AZ::ScriptContext sc;
  115. auto behaviorContext = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->GetBehaviorContext();
  116. sc.BindTo(behaviorContext);
  117. sc.Execute(R"LUA(
  118. my_id = EntityUtilityBus.Broadcast.CreateEditorReadyEntity("test")
  119. entities = vector_EntityId()
  120. entities:push_back(my_id)
  121. template_id = PrefabSystemScriptingBus.Broadcast.CreatePrefab(entities, "test.prefab")
  122. my_result = PrefabLoaderScriptingBus.Broadcast.SaveTemplateToString(template_id)
  123. if my_result:IsSuccess() then
  124. g_globalPrefabString = my_result:GetValue()
  125. end
  126. )LUA");
  127. auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
  128. prefabSystemComponentInterface->RemoveAllTemplates();
  129. EXPECT_STRNE(g_globalPrefabString.c_str(), "");
  130. TemplateId templateFromString = AZ::Interface<PrefabLoaderInterface>::Get()->LoadTemplateFromString(g_globalPrefabString);
  131. EXPECT_NE(templateFromString, InvalidTemplateId);
  132. // Create another entity for comparison purposes
  133. AZ::EntityId entityId;
  134. AzToolsFramework::EntityUtilityBus::BroadcastResult(
  135. entityId, &AzToolsFramework::EntityUtilityBus::Events::CreateEditorReadyEntity, "test");
  136. AZ::Entity* testEntity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(entityId);
  137. // Instantiate the prefab we saved
  138. AZStd::unique_ptr<Instance> instance = prefabSystemComponentInterface->InstantiatePrefab(templateFromString);
  139. EXPECT_NE(instance, nullptr);
  140. AZStd::vector<const AZ::Entity*> loadedEntities;
  141. // Get the entities from the instance
  142. instance->GetConstEntities(
  143. [&loadedEntities](const AZ::Entity& entity)
  144. {
  145. loadedEntities.push_back(&entity);
  146. return true;
  147. });
  148. // Make sure the instance has an entity with the same number of components as our test entity
  149. EXPECT_EQ(loadedEntities.size(), 1);
  150. EXPECT_EQ(loadedEntities[0]->GetComponents().size(), testEntity->GetComponents().size());
  151. g_globalPrefabString.set_capacity(0); // Free all memory
  152. }
  153. }