/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "LyShine_precompiled.h" #include <AzCore/Component/Entity.h> #include <AzCore/Component/EntityUtils.h> #include <AzCore/Component/ComponentApplicationBus.h> #include <AzCore/Component/TransformBus.h> #include <AzCore/Serialization/SerializeContext.h> #include <AzCore/IO/ByteContainerStream.h> #include <AzCore/IO/FileIO.h> #include <AzCore/Serialization/Utils.h> #include <AzCore/Math/Transform.h> #include <AzCore/Asset/AssetDatabase.h> #include <AzFramework/API/ApplicationAPI.h> #include <AzFramework/Entity/EntityContext.h> #include <AzFramework/Entity/GameEntityContextBus.h> #include <AzFramework/Asset/AssetCatalogBus.h> #include <AzFramework/StringFunc/StringFunc.h> #include <LyShine/UiEntityContext.h> //////////////////////////////////////////////////////////////////////////////////////////////////// UiEntityContext::UiEntityContext() : AzFramework::EntityContext(AzFramework::EntityContextId::CreateRandom()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// UiEntityContext::~UiEntityContext() { } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::Activate() { InitContext(); GetRootSlice()->Instantiate(); UiEntityContextRequestBus::Handler::BusConnect(GetContextId()); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::Deactivate() { UiEntityContextRequestBus::Handler::BusDisconnect(); DestroyContext(); } //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* UiEntityContext::GetRootAssetEntity() { return m_rootAsset.Get()->GetEntity(); } //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* UiEntityContext::CloneRootAssetEntity() { AZ::SerializeContext* context = nullptr; EBUS_EVENT_RESULT(context, AZ::ComponentApplicationBus, GetSerializeContext); AZ::Entity* rootAssetEntity = GetRootAssetEntity(); AZ::Entity* clonedRootAssetEntity = context->CloneObject(rootAssetEntity); return clonedRootAssetEntity; } //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* UiEntityContext::CreateUiEntity(const char* name) { AZ::Entity* entity = CreateEntity(name); if (entity) { // we don't currently do anything extra here, UI entities are not automatically // Init'ed and Activate'd when they are created. We wait until the required components // are added before Init and Activate } return entity; } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::AddUiEntity(AZ::Entity* entity) { AZ_Assert(entity, "Supplied entity is invalid."); AddEntity(entity); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::AddUiEntities(const AzFramework::EntityContext::EntityList& entities) { AZ::PrefabAsset* rootSlice = m_rootAsset.Get(); for (AZ::Entity* entity : entities) { AZ_Assert(!AzFramework::EntityIdContextQueryBus::MultiHandler::BusIsConnectedId(entity->GetId()), "Entity already in context."); rootSlice->GetComponent()->AddEntity(entity); } HandleEntitiesAdded(entities); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool UiEntityContext::CloneUiEntities(const AZStd::vector<AZ::EntityId>& sourceEntities, AzFramework::EntityContext::EntityList& resultEntities) { resultEntities.clear(); AZ::PrefabComponent::InstantiatedContainer sourceObjects; for (const AZ::EntityId& id : sourceEntities) { AZ::Entity* entity = nullptr; EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, id); if (entity) { sourceObjects.m_entities.push_back(entity); } } AZ::PrefabComponent::EntityIdToEntityIdMap idMap; AZ::PrefabComponent::InstantiatedContainer* clonedObjects = AZ::Utils::CloneObjectAndFixEntities(&sourceObjects, idMap); if (!clonedObjects) { AZ_Error("UiEntityContext", false, "Failed to clone source entities."); return false; } resultEntities = clonedObjects->m_entities; AddUiEntities(resultEntities); sourceObjects.m_entities.clear(); clonedObjects->m_entities.clear(); delete clonedObjects; return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool UiEntityContext::DestroyUiEntity(AZ::EntityId entityId) { if (DestroyEntity(entityId)) { return true; } return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool UiEntityContext::HandleLoadedRootSliceEntity(AZ::Entity* rootEntity, bool remapIds, AZ::PrefabComponent::EntityIdToEntityIdMap* idRemapTable) { AZ_Assert(m_rootAsset, "The context has not been initialized."); if (!AzFramework::EntityContext::HandleLoadedRootSliceEntity(rootEntity, remapIds, idRemapTable)) { return false; } AZ::PrefabComponent::EntityList entities; GetRootSlice()->GetEntities(entities); GetRootSlice()->SetIsDynamic(true); InitializeEntities(entities); return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::OnContextEntitiesAdded(const AzFramework::EntityContext::EntityList& entities) { EntityContext::OnContextEntitiesAdded(entities); InitializeEntities(entities); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::OnContextEntityRemoved(const AZ::EntityId& entityId) { } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::SetupUiEntity(AZ::Entity* entity) { InitializeEntities({ entity }); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiEntityContext::InitializeEntities(const AzFramework::EntityContext::EntityList& entities) { // UI entities are now automatically activated on creation for (AZ::Entity* entity : entities) { if (entity->GetState() == AZ::Entity::ES_CONSTRUCTED) { entity->Init(); } } for (AZ::Entity* entity : entities) { if (entity->GetState() == AZ::Entity::ES_INIT) { entity->Activate(); } } }