PrefabEditorEntityOwnershipService.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  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/Component/Entity.h>
  9. #include <AzCore/Component/TransformBus.h>
  10. #include <AzCore/Script/ScriptSystemBus.h>
  11. #include <AzCore/Serialization/Utils.h>
  12. #include <AzCore/StringFunc/StringFunc.h>
  13. #include <AzFramework/API/ApplicationAPI.h>
  14. #include <AzFramework/Entity/GameEntityContextBus.h>
  15. #include <AzFramework/Spawnable/RootSpawnableInterface.h>
  16. #include <AzToolsFramework/API/EditorAssetSystemAPI.h>
  17. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  18. #include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h>
  19. #include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
  20. #include <AzToolsFramework/Prefab/Instance/Instance.h>
  21. #include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
  22. #include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
  23. #include <AzToolsFramework/Prefab/PrefabDomUtils.h>
  24. #include <AzToolsFramework/Prefab/PrefabLoader.h>
  25. #include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
  26. #include <AzToolsFramework/Prefab/PrefabUndoHelpers.h>
  27. #include <AzToolsFramework/Prefab/Spawnable/PrefabConverterStackProfileNames.h>
  28. namespace AzToolsFramework
  29. {
  30. PrefabEditorEntityOwnershipService::PrefabEditorEntityOwnershipService(const AzFramework::EntityContextId& entityContextId,
  31. AZ::SerializeContext* serializeContext)
  32. : m_entityContextId(entityContextId)
  33. , m_serializeContext(serializeContext)
  34. {
  35. AzFramework::ApplicationRequests::Bus::BroadcastResult(
  36. m_shouldAssertForLegacySlicesUsage, &AzFramework::ApplicationRequests::ShouldAssertForLegacySlicesUsage);
  37. AZ::Interface<PrefabEditorEntityOwnershipInterface>::Register(this);
  38. }
  39. PrefabEditorEntityOwnershipService::~PrefabEditorEntityOwnershipService()
  40. {
  41. AZ::Interface<PrefabEditorEntityOwnershipInterface>::Unregister(this);
  42. }
  43. void PrefabEditorEntityOwnershipService::Initialize()
  44. {
  45. m_prefabSystemComponent = AZ::Interface<Prefab::PrefabSystemComponentInterface>::Get();
  46. AZ_Assert(m_prefabSystemComponent != nullptr,
  47. "Couldn't get prefab system component, it's a requirement for PrefabEntityOwnership system to work");
  48. m_loaderInterface = AZ::Interface<Prefab::PrefabLoaderInterface>::Get();
  49. AZ_Assert(m_loaderInterface != nullptr,
  50. "Couldn't get prefab loader interface, it's a requirement for PrefabEntityOwnership system to work");
  51. m_rootInstance = AZStd::unique_ptr<Prefab::Instance>(m_prefabSystemComponent->CreatePrefab({}, {}, "newLevel.prefab"));
  52. m_sliceOwnershipService.BusConnect(m_entityContextId);
  53. m_sliceOwnershipService.m_shouldAssertForLegacySlicesUsage = m_shouldAssertForLegacySlicesUsage;
  54. m_editorSliceOwnershipService.BusConnect();
  55. m_editorSliceOwnershipService.m_shouldAssertForLegacySlicesUsage = m_shouldAssertForLegacySlicesUsage;
  56. }
  57. bool PrefabEditorEntityOwnershipService::IsInitialized()
  58. {
  59. return m_rootInstance != nullptr;
  60. }
  61. void PrefabEditorEntityOwnershipService::Destroy()
  62. {
  63. StopPlayInEditor();
  64. m_editorSliceOwnershipService.BusDisconnect();
  65. m_sliceOwnershipService.BusDisconnect();
  66. if (m_rootInstance != nullptr)
  67. {
  68. m_rootInstance.reset();
  69. m_prefabSystemComponent->RemoveAllTemplates();
  70. }
  71. }
  72. void PrefabEditorEntityOwnershipService::Reset()
  73. {
  74. m_isRootPrefabAssigned = false;
  75. if (m_rootInstance)
  76. {
  77. AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
  78. &AzToolsFramework::ToolsApplicationRequestBus::Events::ClearDirtyEntities);
  79. Prefab::TemplateId templateId = m_rootInstance->GetTemplateId();
  80. m_rootInstance->Reset();
  81. if (templateId != Prefab::InvalidTemplateId)
  82. {
  83. m_rootInstance->SetTemplateId(Prefab::InvalidTemplateId);
  84. m_prefabSystemComponent->RemoveAllTemplates();
  85. }
  86. m_rootInstance->SetContainerEntityName("Level");
  87. }
  88. AzFramework::EntityOwnershipServiceNotificationBus::Event(
  89. m_entityContextId, &AzFramework::EntityOwnershipServiceNotificationBus::Events::OnEntityOwnershipServiceReset);
  90. }
  91. void PrefabEditorEntityOwnershipService::AddEntity(AZ::Entity* entity)
  92. {
  93. AZ_Assert(IsInitialized(), "Tried to add an entity without initializing the Entity Ownership Service");
  94. ScopedUndoBatch undoBatch("Undo adding entity");
  95. Prefab::PrefabDom instanceDomBeforeUpdate;
  96. Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, instanceDomBeforeUpdate);
  97. m_rootInstance->AddEntity(*entity);
  98. HandleEntitiesAdded({ entity });
  99. AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, m_rootInstance->m_containerEntity->GetId());
  100. Prefab::PrefabUndoHelpers::UpdatePrefabInstance(
  101. *m_rootInstance, "Undo adding entity", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
  102. }
  103. void PrefabEditorEntityOwnershipService::AddEntities(const EntityList& entities)
  104. {
  105. AZ_Assert(IsInitialized(), "Tried to add entities without initializing the Entity Ownership Service");
  106. ScopedUndoBatch undoBatch("Undo adding entities");
  107. Prefab::PrefabDom instanceDomBeforeUpdate;
  108. Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, instanceDomBeforeUpdate);
  109. for (AZ::Entity* entity : entities)
  110. {
  111. m_rootInstance->AddEntity(*entity);
  112. }
  113. HandleEntitiesAdded(entities);
  114. for (AZ::Entity* entity : entities)
  115. {
  116. AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, m_rootInstance->m_containerEntity->GetId());
  117. }
  118. Prefab::PrefabUndoHelpers::UpdatePrefabInstance(
  119. *m_rootInstance, "Undo adding entities", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
  120. }
  121. bool PrefabEditorEntityOwnershipService::DestroyEntity(AZ::Entity* entity)
  122. {
  123. return DestroyEntityById(entity->GetId());
  124. }
  125. bool PrefabEditorEntityOwnershipService::DestroyEntityById(AZ::EntityId entityId)
  126. {
  127. AZ_Assert(IsInitialized(), "Tried to destroy an entity without initializing the Entity Ownership Service");
  128. AZ_Assert(m_entitiesRemovedCallback, "Callback function for DestroyEntityById has not been set.");
  129. OnEntityRemoved(entityId);
  130. return true;
  131. }
  132. void PrefabEditorEntityOwnershipService::GetNonPrefabEntities(EntityList& entities)
  133. {
  134. m_rootInstance->GetEntities(
  135. [&entities](const AZStd::unique_ptr<AZ::Entity>& entity)
  136. {
  137. entities.emplace_back(entity.get());
  138. return true;
  139. });
  140. }
  141. bool PrefabEditorEntityOwnershipService::GetAllEntities(EntityList& entities)
  142. {
  143. m_rootInstance->GetAllEntitiesInHierarchy(
  144. [&entities](const AZStd::unique_ptr<AZ::Entity>& entity)
  145. {
  146. entities.emplace_back(entity.get());
  147. return true;
  148. });
  149. return true;
  150. }
  151. void PrefabEditorEntityOwnershipService::InstantiateAllPrefabs()
  152. {
  153. }
  154. void PrefabEditorEntityOwnershipService::HandleEntitiesAdded(const EntityList& entities)
  155. {
  156. AZ_Assert(m_entitiesAddedCallback, "Callback function for AddEntity has not been set.");
  157. for (const AZ::Entity* entity : entities)
  158. {
  159. AzFramework::SliceEntityRequestBus::MultiHandler::BusConnect(entity->GetId());
  160. }
  161. m_entitiesAddedCallback(entities);
  162. }
  163. bool PrefabEditorEntityOwnershipService::LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename)
  164. {
  165. Reset();
  166. const size_t bufSize = stream.GetLength();
  167. AZStd::unique_ptr<char[]> buf(new char[bufSize]);
  168. AZ::IO::SizeType bytes = stream.Read(bufSize, buf.get());
  169. Prefab::TemplateId templateId = m_loaderInterface->LoadTemplateFromString(AZStd::string_view(buf.get(), bytes), filename);
  170. if (templateId == Prefab::InvalidTemplateId)
  171. {
  172. AZ_Error("Prefab", false, "Couldn't load prefab content from '%.*s'", AZ_STRING_ARG(filename));
  173. return false;
  174. }
  175. m_rootInstance->SetTemplateId(templateId);
  176. m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GenerateRelativePath(filename));
  177. m_rootInstance->SetContainerEntityName("Level");
  178. m_prefabSystemComponent->PropagateTemplateChanges(templateId);
  179. m_isRootPrefabAssigned = true;
  180. return true;
  181. }
  182. bool PrefabEditorEntityOwnershipService::LoadFromStream(
  183. [[maybe_unused]] AZ::IO::GenericStream& stream,
  184. [[maybe_unused]] bool remapIds,
  185. [[maybe_unused]] EntityIdToEntityIdMap* idRemapTable,
  186. [[maybe_unused]] const AZ::ObjectStream::FilterDescriptor& filterDesc)
  187. {
  188. return false;
  189. }
  190. bool PrefabEditorEntityOwnershipService::SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename)
  191. {
  192. AZ::IO::Path relativePath = m_loaderInterface->GenerateRelativePath(filename);
  193. m_rootInstance->SetTemplateSourcePath(relativePath);
  194. m_prefabSystemComponent->UpdateTemplateFilePath(m_rootInstance->GetTemplateId(), relativePath);
  195. AZStd::string out;
  196. if (!m_loaderInterface->SaveTemplateToString(m_rootInstance->GetTemplateId(), out))
  197. {
  198. return false;
  199. }
  200. const size_t bytesToWrite = out.size();
  201. const size_t bytesWritten = stream.Write(bytesToWrite, out.data());
  202. if(bytesWritten != bytesToWrite)
  203. {
  204. return false;
  205. }
  206. m_prefabSystemComponent->SetTemplateDirtyFlag(m_rootInstance->GetTemplateId(), false);
  207. return true;
  208. }
  209. void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename)
  210. {
  211. AZ::IO::Path relativePath = m_loaderInterface->GenerateRelativePath(filename);
  212. AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
  213. m_rootInstance->SetTemplateSourcePath(relativePath);
  214. AZStd::string watchFolder;
  215. AZ::Data::AssetInfo assetInfo;
  216. bool sourceInfoFound = false;
  217. AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
  218. sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, templateFilename.c_str(),
  219. assetInfo, watchFolder);
  220. if (sourceInfoFound)
  221. {
  222. AZStd::string fullPath;
  223. AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath);
  224. // Get the default prefab and copy the Dom over to the new template being saved
  225. Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str());
  226. Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId);
  227. Prefab::PrefabDom levelDefaultDom;
  228. levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
  229. Prefab::PrefabDomPath sourcePath("/Source");
  230. sourcePath.Set(levelDefaultDom, relativePath.c_str());
  231. templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(levelDefaultDom));
  232. }
  233. else
  234. {
  235. m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
  236. HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
  237. AzToolsFramework::Prefab::PrefabDom dom;
  238. bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
  239. if (!success)
  240. {
  241. AZ_Error(
  242. "Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
  243. return;
  244. }
  245. templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
  246. }
  247. if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
  248. {
  249. AZ_Error("Prefab", false, "Couldn't create new template id '%i' when creating new level '%.*s'", templateId, AZ_STRING_ARG(filename));
  250. return;
  251. }
  252. Prefab::TemplateId prevTemplateId = m_rootInstance->GetTemplateId();
  253. m_rootInstance->SetTemplateId(templateId);
  254. if (prevTemplateId != Prefab::InvalidTemplateId && templateId != prevTemplateId)
  255. {
  256. // Make sure we only have one level template loaded at a time
  257. m_prefabSystemComponent->RemoveTemplate(prevTemplateId);
  258. }
  259. m_prefabSystemComponent->PropagateTemplateChanges(templateId);
  260. m_isRootPrefabAssigned = true;
  261. }
  262. bool PrefabEditorEntityOwnershipService::IsRootPrefabAssigned() const
  263. {
  264. return m_isRootPrefabAssigned;
  265. }
  266. Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::CreatePrefab(
  267. const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
  268. AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder)
  269. {
  270. if (!instanceToParentUnder)
  271. {
  272. instanceToParentUnder = *m_rootInstance;
  273. }
  274. AZStd::unique_ptr<Prefab::Instance> createdPrefabInstance = m_prefabSystemComponent->CreatePrefab(
  275. entities, AZStd::move(nestedPrefabInstances), filePath, nullptr, instanceToParentUnder, false);
  276. if (createdPrefabInstance)
  277. {
  278. Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(
  279. AZStd::move(createdPrefabInstance));
  280. AZ::Entity* containerEntity = addedInstance.m_containerEntity.get();
  281. containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
  282. HandleEntitiesAdded({containerEntity});
  283. HandleEntitiesAdded(entities);
  284. return addedInstance;
  285. }
  286. return AZStd::nullopt;
  287. }
  288. Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::InstantiatePrefab(
  289. AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder)
  290. {
  291. if (!instanceToParentUnder)
  292. {
  293. instanceToParentUnder = *m_rootInstance;
  294. }
  295. AZStd::unique_ptr<Prefab::Instance> instantiatedPrefabInstance =
  296. m_prefabSystemComponent->InstantiatePrefab(filePath, instanceToParentUnder);
  297. if (instantiatedPrefabInstance)
  298. {
  299. Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(
  300. AZStd::move(instantiatedPrefabInstance));
  301. HandleEntitiesAdded({addedInstance.m_containerEntity.get()});
  302. return addedInstance;
  303. }
  304. return AZStd::nullopt;
  305. }
  306. Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::GetRootPrefabInstance()
  307. {
  308. AZ_Assert(m_rootInstance, "A valid root prefab instance couldn't be found in PrefabEditorEntityOwnershipService.");
  309. if (m_rootInstance)
  310. {
  311. return *m_rootInstance;
  312. }
  313. return AZStd::nullopt;
  314. }
  315. Prefab::TemplateId PrefabEditorEntityOwnershipService::GetRootPrefabTemplateId()
  316. {
  317. AZ_Assert(m_rootInstance, "A valid root prefab instance couldn't be found in PrefabEditorEntityOwnershipService.");
  318. return m_rootInstance ? m_rootInstance->GetTemplateId() : Prefab::InvalidTemplateId;
  319. }
  320. const Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer::SpawnableAssets& PrefabEditorEntityOwnershipService::GetPlayInEditorAssetData() const
  321. {
  322. return m_playInEditorData.m_assetsCache.GetAllInMemorySpawnableAssets();
  323. }
  324. void PrefabEditorEntityOwnershipService::OnEntityRemoved(AZ::EntityId entityId)
  325. {
  326. AzFramework::SliceEntityRequestBus::MultiHandler::BusDisconnect(entityId);
  327. m_entitiesRemovedCallback({ entityId });
  328. }
  329. void PrefabEditorEntityOwnershipService::SetEntitiesAddedCallback(OnEntitiesAddedCallback onEntitiesAddedCallback)
  330. {
  331. m_entitiesAddedCallback = AZStd::move(onEntitiesAddedCallback);
  332. }
  333. void PrefabEditorEntityOwnershipService::SetEntitiesRemovedCallback(OnEntitiesRemovedCallback onEntitiesRemovedCallback)
  334. {
  335. m_entitiesRemovedCallback = AZStd::move(onEntitiesRemovedCallback);
  336. }
  337. void PrefabEditorEntityOwnershipService::SetValidateEntitiesCallback(ValidateEntitiesCallback validateEntitiesCallback)
  338. {
  339. m_validateEntitiesCallback = AZStd::move(validateEntitiesCallback);
  340. }
  341. void PrefabEditorEntityOwnershipService::StartPlayInEditor()
  342. {
  343. // This is a workaround until the replacement for GameEntityContext is done
  344. AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnPreGameEntitiesStarted);
  345. if (m_rootInstance && !m_playInEditorData.m_isEnabled)
  346. {
  347. // Construct the runtime entities and products
  348. bool readyToCreateRootSpawnable = m_playInEditorData.m_assetsCache.IsActivated();
  349. if (!readyToCreateRootSpawnable &&
  350. !m_playInEditorData.m_assetsCache.Activate(Prefab::PrefabConversionUtils::PlayInEditor))
  351. {
  352. AZ_Error("Prefab", false, "Failed to create a prefab processing stack from key '%.*s'.", AZ_STRING_ARG(Prefab::PrefabConversionUtils::PlayInEditor));
  353. return;
  354. }
  355. auto createRootSpawnableResult = m_playInEditorData.m_assetsCache.CreateInMemorySpawnableAsset(m_rootInstance->GetTemplateId(), DefaultMainSpawnableName, true);
  356. if (createRootSpawnableResult.IsSuccess())
  357. {
  358. // make sure that PRE_NOTIFY assets get their notify before we activate, so that we can preserve the order of
  359. // (load asset) -> (notify) -> (init) -> (activate)
  360. AZ::Data::AssetManager::Instance().DispatchEvents();
  361. m_playInEditorData.m_entities.Reset(createRootSpawnableResult.GetValue());
  362. m_playInEditorData.m_entities.SpawnAllEntities();
  363. // This is a workaround until the replacement for GameEntityContext is done
  364. AzFramework::GameEntityContextEventBus::Broadcast(
  365. &AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesStarted);
  366. }
  367. else
  368. {
  369. AZ_Error("Prefab", false, "Failed to create the root spawnable due to the error: '%.*s'", AZ_STRING_ARG(createRootSpawnableResult.GetError()));
  370. return;
  371. }
  372. m_rootInstance->GetAllEntitiesInHierarchy([this](AZStd::unique_ptr<AZ::Entity>& entity)
  373. {
  374. AZ_Assert(entity, "Invalid entity found in root instance while starting play in editor.");
  375. if (entity->GetState() == AZ::Entity::State::Active)
  376. {
  377. entity->Deactivate();
  378. m_playInEditorData.m_deactivatedEntities.push_back(entity.get());
  379. }
  380. return true;
  381. });
  382. m_playInEditorData.m_isEnabled = true;
  383. }
  384. }
  385. void PrefabEditorEntityOwnershipService::StopPlayInEditor()
  386. {
  387. if (m_rootInstance && m_playInEditorData.m_isEnabled)
  388. {
  389. AZ_Assert(
  390. m_playInEditorData.m_entities.IsSet(),
  391. "Invalid Game Mode Entities Container encountered after play-in-editor stopped. "
  392. "Confirm that the container was initialized correctly");
  393. m_playInEditorData.m_entities.DespawnAllEntities();
  394. m_playInEditorData.m_entities.Alert(
  395. [allSpawnableAssetData = m_playInEditorData.m_assetsCache.MoveAllInMemorySpawnableAssets(),
  396. deactivatedEntities = AZStd::move(m_playInEditorData.m_deactivatedEntities)]([[maybe_unused]] uint32_t generation) mutable
  397. {
  398. auto end = deactivatedEntities.rend();
  399. for (auto it = deactivatedEntities.rbegin(); it != end; ++it)
  400. {
  401. AZ_Assert(*it, "Invalid entity added to list for re-activation after play-in-editor stopped.");
  402. (*it)->Activate();
  403. }
  404. for (auto& [spawnableName, spawnableAssetData] : allSpawnableAssetData)
  405. {
  406. for (auto& asset : spawnableAssetData.m_assets)
  407. {
  408. asset.Release();
  409. AZ::Data::AssetCatalogRequestBus::Broadcast(
  410. &AZ::Data::AssetCatalogRequestBus::Events::UnregisterAsset, asset.GetId());
  411. }
  412. }
  413. AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
  414. // This is a workaround until the replacement for GameEntityContext is done
  415. AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesReset);
  416. });
  417. m_playInEditorData.m_entities.Clear();
  418. // Game entity cleanup is queued onto the next tick via the DespawnEntities call.
  419. // To avoid both game entities and Editor entities active at the same time
  420. // we flush the tick queue to ensure the game entities are cleared first.
  421. // The Alert callback that follows the DespawnEntities call will then reactivate the editor entities
  422. // This should be considered temporary as a move to a less rigid event sequence that supports async entity clean up
  423. // is the desired direction forward.
  424. AZ::TickBus::ExecuteQueuedEvents();
  425. }
  426. m_playInEditorData.m_isEnabled = false;
  427. }
  428. //////////////////////////////////////////////////////////////////////////
  429. // Slice Buses implementation with Assert(false), this will exist only during Slice->Prefab
  430. // development to pinpoint and replace specific calls to Slice system
  431. AZ::SliceComponent::SliceInstanceAddress PrefabEditorEntityOwnershipService::GetOwningSlice()
  432. {
  433. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  434. return AZ::SliceComponent::SliceInstanceAddress();
  435. }
  436. AZ::Data::AssetId UnimplementedSliceEntityOwnershipService::CurrentlyInstantiatingSlice()
  437. {
  438. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  439. return {};
  440. }
  441. bool UnimplementedSliceEntityOwnershipService::HandleRootEntityReloadedFromStream(
  442. AZ::Entity*, bool, AZ::SliceComponent::EntityIdToEntityIdMap*)
  443. {
  444. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  445. return false;
  446. }
  447. AZ::SliceComponent* UnimplementedSliceEntityOwnershipService::GetRootSlice()
  448. {
  449. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  450. return nullptr;
  451. }
  452. const AZ::SliceComponent::EntityIdToEntityIdMap& UnimplementedSliceEntityOwnershipService::GetLoadedEntityIdMap()
  453. {
  454. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  455. static AZ::SliceComponent::EntityIdToEntityIdMap dummy;
  456. return dummy;
  457. }
  458. AZ::EntityId UnimplementedSliceEntityOwnershipService::FindLoadedEntityIdMapping(const AZ::EntityId&) const
  459. {
  460. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  461. return AZ::EntityId();
  462. }
  463. AzFramework::SliceInstantiationTicket UnimplementedSliceEntityOwnershipService::InstantiateSlice(
  464. const AZ::Data::Asset<AZ::Data::AssetData>&,
  465. const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper&,
  466. const AZ::Data::AssetFilterCB&)
  467. {
  468. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  469. return AzFramework::SliceInstantiationTicket();
  470. }
  471. AZ::SliceComponent::SliceInstanceAddress UnimplementedSliceEntityOwnershipService::CloneSliceInstance(
  472. AZ::SliceComponent::SliceInstanceAddress, AZ::SliceComponent::EntityIdToEntityIdMap&)
  473. {
  474. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  475. return {};
  476. }
  477. void UnimplementedSliceEntityOwnershipService::CancelSliceInstantiation(const AzFramework::SliceInstantiationTicket&)
  478. {
  479. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  480. }
  481. AzFramework::SliceInstantiationTicket UnimplementedSliceEntityOwnershipService::GenerateSliceInstantiationTicket()
  482. {
  483. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  484. return AzFramework::SliceInstantiationTicket();
  485. }
  486. void UnimplementedSliceEntityOwnershipService::SetIsDynamic(bool)
  487. {
  488. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  489. }
  490. const AzFramework::RootSliceAsset& UnimplementedSliceEntityOwnershipService::GetRootAsset() const
  491. {
  492. static AzFramework::RootSliceAsset dummy;
  493. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  494. return dummy;
  495. }
  496. //////////////////////////////////////////////////////////////////////////
  497. AzFramework::SliceInstantiationTicket UnimplementedSliceEditorEntityOwnershipService::InstantiateEditorSlice(
  498. const AZ::Data::Asset<AZ::Data::AssetData>&, const AZ::Transform&)
  499. {
  500. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  501. return AzFramework::SliceInstantiationTicket();
  502. }
  503. AZ::SliceComponent::SliceInstanceAddress UnimplementedSliceEditorEntityOwnershipService::CloneEditorSliceInstance(
  504. AZ::SliceComponent::SliceInstanceAddress, AZ::SliceComponent::EntityIdToEntityIdMap&)
  505. {
  506. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  507. return {};
  508. }
  509. AZ::SliceComponent::SliceInstanceAddress UnimplementedSliceEditorEntityOwnershipService::CloneSubSliceInstance(
  510. const AZ::SliceComponent::SliceInstanceAddress&, const AZStd::vector<AZ::SliceComponent::SliceInstanceAddress>&,
  511. const AZ::SliceComponent::SliceInstanceAddress&, AZ::SliceComponent::EntityIdToEntityIdMap*)
  512. {
  513. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  514. return {};
  515. }
  516. AZ::SliceComponent::SliceInstanceAddress UnimplementedSliceEditorEntityOwnershipService::PromoteEditorEntitiesIntoSlice(
  517. const AZ::Data::Asset<AZ::SliceAsset>&, const AZ::SliceComponent::EntityIdToEntityIdMap&)
  518. {
  519. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  520. return {};
  521. }
  522. void UnimplementedSliceEditorEntityOwnershipService::DetachSliceEntities(const EntityIdList&)
  523. {
  524. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  525. }
  526. void UnimplementedSliceEditorEntityOwnershipService::DetachSliceInstances(const AZ::SliceComponent::SliceInstanceAddressSet&)
  527. {
  528. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  529. }
  530. void UnimplementedSliceEditorEntityOwnershipService::DetachSubsliceInstances(const AZ::SliceComponent::SliceInstanceEntityIdRemapList&)
  531. {
  532. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  533. }
  534. void UnimplementedSliceEditorEntityOwnershipService::RestoreSliceEntity(
  535. AZ::Entity*, const AZ::SliceComponent::EntityRestoreInfo&, SliceEntityRestoreType)
  536. {
  537. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  538. }
  539. void UnimplementedSliceEditorEntityOwnershipService::ResetEntitiesToSliceDefaults(EntityIdList)
  540. {
  541. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  542. }
  543. AZ::SliceComponent* UnimplementedSliceEditorEntityOwnershipService::GetEditorRootSlice()
  544. {
  545. AZ_Assert(!m_shouldAssertForLegacySlicesUsage, "Slice usage with Prefab code enabled");
  546. return nullptr;
  547. }
  548. }