3
0

EntityTestbed.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 <AzCore/Memory/AllocationRecords.h>
  9. #include <AzCore/IO/Streamer/StreamerComponent.h>
  10. #include <AzCore/Asset/AssetManagerComponent.h>
  11. #include <AzCore/Serialization/Utils.h>
  12. #include <AzCore/Component/EntityUtils.h>
  13. #include <AzCore/PlatformIncl.h>
  14. #include <AzCore/UnitTest/TestTypes.h>
  15. #include <AzFramework/Entity/EntityContextBus.h>
  16. #include <AzFramework/Entity/EntityContext.h>
  17. #include <AzFramework/IO/LocalFileIO.h>
  18. #include <AzFramework/Application/Application.h>
  19. #include <AzFramework/Asset/AssetCatalogComponent.h>
  20. #include <AzFramework/Asset/AssetCatalogBus.h>
  21. //#include <AzToolsFramework/UI/Outliner/OutlinerWidget.hxx>
  22. #include <AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.h>
  23. #include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
  24. #include <AzToolsFramework/Entity/EditorEntityContextBus.h>
  25. #include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
  26. #include <AzToolsFramework/Application/ToolsApplication.h>
  27. #include <QtWidgets/QMainWindow>
  28. #include <QtWidgets/QApplication>
  29. #include <QtWidgets/QVBoxLayout>
  30. #include <QtWidgets/QPushButton>
  31. #include <QtWidgets/QFileDialog>
  32. #include <QtCore/QTimer>
  33. #pragma once
  34. namespace UnitTest
  35. {
  36. using namespace AZ;
  37. class EntityTestbed
  38. : public LeakDetectionFixture
  39. , public QObject
  40. {
  41. public:
  42. class TestbedApplication
  43. : public AzToolsFramework::ToolsApplication
  44. {
  45. public:
  46. AZ_CLASS_ALLOCATOR(TestbedApplication, AZ::SystemAllocator);
  47. TestbedApplication(EntityTestbed& testbed)
  48. : m_testbed(testbed) {}
  49. EntityTestbed& m_testbed;
  50. };
  51. QTimer* m_tickBusTimer = nullptr;
  52. TestbedApplication* m_componentApplication = nullptr;
  53. AZ::Entity* m_systemEntity = nullptr;
  54. QApplication* m_qtApplication = nullptr;
  55. QWidget* m_window = nullptr;
  56. //AzToolsFramework::OutlinerWidget* m_outliner = nullptr;
  57. AzToolsFramework::EntityPropertyEditor* m_propertyEditor = nullptr;
  58. AZ::u32 m_entityCounter = 0;
  59. AZ::IO::LocalFileIO m_localFileIO;
  60. virtual ~EntityTestbed()
  61. {
  62. if (m_tickBusTimer)
  63. {
  64. m_tickBusTimer->stop();
  65. delete m_tickBusTimer;
  66. m_tickBusTimer = nullptr;
  67. }
  68. Destroy();
  69. }
  70. virtual void OnSetup() {}
  71. virtual void OnAddButtons(QHBoxLayout& layout) { (void)layout; }
  72. virtual void OnEntityAdded(AZ::Entity& entity) { (void)entity; }
  73. virtual void OnEntityRemoved(AZ::Entity& entity) { (void)entity; }
  74. virtual void OnReflect(AZ::SerializeContext& context, AZ::Entity& systemEntity) { (void)context; (void)systemEntity; }
  75. virtual void OnDestroy() {}
  76. void Run(int argc = 0, char** argv = nullptr)
  77. {
  78. SetupComponentApplication();
  79. m_qtApplication = new QApplication(argc, argv);
  80. m_tickBusTimer = new QTimer(this);
  81. m_qtApplication->connect(m_tickBusTimer, &QTimer::timeout,
  82. []()
  83. {
  84. AZ::TickBus::ExecuteQueuedEvents();
  85. AZ::TickBus::Broadcast(&AZ::TickBus::Events::OnTick, 0.3f, AZ::ScriptTimePoint());
  86. }
  87. );
  88. m_tickBusTimer->start();
  89. SetupUI();
  90. OnSetup();
  91. m_window->show();
  92. m_qtApplication->exec();
  93. }
  94. void SetupUI()
  95. {
  96. m_window = new QWidget();
  97. //m_outliner = aznew AzToolsFramework::OutlinerWidget(nullptr);
  98. m_propertyEditor = aznew AzToolsFramework::EntityPropertyEditor(nullptr);
  99. AZ::SerializeContext* serializeContext = nullptr;
  100. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  101. m_window->setMinimumHeight(600);
  102. m_propertyEditor->setMinimumWidth(600);
  103. //m_outliner->setMinimumWidth(100);
  104. QVBoxLayout* leftLayout = new QVBoxLayout();
  105. QHBoxLayout* outlinerLayout = new QHBoxLayout();
  106. QHBoxLayout* outlinerButtonLayout = new QHBoxLayout();
  107. //outlinerLayout->addWidget(m_outliner);
  108. leftLayout->addLayout(outlinerLayout);
  109. leftLayout->addLayout(outlinerButtonLayout);
  110. QVBoxLayout* rightLayout = new QVBoxLayout();
  111. QHBoxLayout* propertyLayout = new QHBoxLayout();
  112. QHBoxLayout* propertyButtonLayout = new QHBoxLayout();
  113. propertyLayout->addWidget(m_propertyEditor);
  114. rightLayout->addLayout(propertyLayout);
  115. rightLayout->addLayout(propertyButtonLayout);
  116. QHBoxLayout* mainLayout = new QHBoxLayout();
  117. m_window->setLayout(mainLayout);
  118. mainLayout->addLayout(leftLayout, 1);
  119. mainLayout->addLayout(rightLayout, 3);
  120. // Add default buttons.
  121. QPushButton* addEntity = new QPushButton(QString("Create"));
  122. QPushButton* deleteEntities = new QPushButton(QString("Delete"));
  123. outlinerButtonLayout->addWidget(addEntity);
  124. outlinerButtonLayout->addWidget(deleteEntities);
  125. m_qtApplication->connect(addEntity, &QPushButton::pressed, [ this ]() { this->AddEntity(); });
  126. m_qtApplication->connect(deleteEntities, &QPushButton::pressed, [ this ]() { this->DeleteSelected(); });
  127. // Test-specific buttons.
  128. OnAddButtons(*outlinerButtonLayout);
  129. }
  130. void SetupComponentApplication()
  131. {
  132. AZ::ComponentApplication::Descriptor desc;
  133. desc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL;
  134. desc.m_useExistingAllocator = true;
  135. m_componentApplication = aznew TestbedApplication(*this);
  136. AZ::IO::FileIOBase::SetInstance(&m_localFileIO);
  137. m_componentApplication->Start(desc);
  138. AZ::SerializeContext* serializeContext = m_componentApplication->GetSerializeContext();
  139. serializeContext->CreateEditContext();
  140. AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor();
  141. const char* dir = m_componentApplication->GetExecutableFolder();
  142. m_localFileIO.SetAlias("@products@", dir);
  143. m_localFileIO.SetAlias("@projectroot@", dir);
  144. }
  145. void Destroy()
  146. {
  147. OnDestroy();
  148. //delete m_outliner;
  149. delete m_propertyEditor;
  150. delete m_window;
  151. delete m_qtApplication;
  152. delete m_componentApplication;
  153. //m_outliner = nullptr;
  154. m_propertyEditor = nullptr;
  155. m_window = nullptr;
  156. m_qtApplication = nullptr;
  157. m_componentApplication = nullptr;
  158. if (AZ::Data::AssetManager::IsReady())
  159. {
  160. AZ::Data::AssetManager::Destroy();
  161. }
  162. AZ::IO::FileIOBase::SetInstance(nullptr);
  163. }
  164. void AddEntity()
  165. {
  166. AZStd::string entityName = AZStd::string::format("Entity%u", m_entityCounter);
  167. AZ::EntityId entityId;
  168. AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(entityId, &AzToolsFramework::EditorEntityContextRequests::CreateNewEditorEntity, entityName.c_str());
  169. ++m_entityCounter;
  170. AZ::Entity* entity = nullptr;
  171. AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
  172. entity->Deactivate();
  173. OnEntityAdded(*entity);
  174. entity->Activate();
  175. }
  176. void DeleteSelected()
  177. {
  178. AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(
  179. &AzToolsFramework::ToolsApplicationRequests::Bus::Events::DeleteSelected);
  180. }
  181. void SaveRoot()
  182. {
  183. const QString saveAs = QFileDialog::getSaveFileName(nullptr,
  184. QString("Save As..."), QString("."), QString("Xml Files (*.xml)"));
  185. if (!saveAs.isEmpty())
  186. {
  187. AZ::SliceComponent* rootSlice;
  188. AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::BroadcastResult(
  189. rootSlice, &AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Events::GetEditorRootSlice);
  190. AZ::Utils::SaveObjectToFile(saveAs.toUtf8().constData(), AZ::DataStream::ST_XML, rootSlice->GetEntity());
  191. }
  192. }
  193. void ResetRoot()
  194. {
  195. AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
  196. &AzToolsFramework::EditorEntityContextRequestBus::Events::ResetEditorContext);
  197. }
  198. };
  199. } // namespace UnitTest;