Files
o3de/Code/Framework/AzFramework/AzFramework/Scene/SceneSystemComponent.cpp
T
2021-04-23 09:43:40 -07:00

201 lines
7.7 KiB
C++

/*
* 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 <AzFramework/Scene/SceneSystemComponent.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzFramework/Scene/Scene.h>
namespace AzFramework
{
void SceneSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<SceneSystemComponent, AZ::Component>();
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<SceneSystemComponent>(
"Scene System Component", "System component responsible for owning scenes")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Editor")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
;
}
}
}
SceneSystemComponent::SceneSystemComponent() = default;
SceneSystemComponent::~SceneSystemComponent() = default;
void SceneSystemComponent::Activate()
{
// Connect busses
SceneSystemRequestBus::Handler::BusConnect();
}
void SceneSystemComponent::Deactivate()
{
// Disconnect Busses
SceneSystemRequestBus::Handler::BusDisconnect();
}
void SceneSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("SceneSystemComponentService", 0xd8975435));
}
void SceneSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("SceneSystemComponentService", 0xd8975435));
}
AZ::Outcome<Scene*, AZStd::string> SceneSystemComponent::CreateScene(AZStd::string_view name)
{
Scene* existingScene = GetScene(name);
if (existingScene)
{
return AZ::Failure<AZStd::string>("A scene already exists with this name.");
}
auto newScene = AZStd::make_unique<Scene>(name);
Scene* scenePointer = newScene.get();
m_scenes.push_back(AZStd::move(newScene));
SceneSystemNotificationBus::Broadcast(&SceneSystemNotificationBus::Events::SceneCreated, *scenePointer);
return AZ::Success(scenePointer);
}
Scene* SceneSystemComponent::GetScene(AZStd::string_view name)
{
auto sceneIterator = AZStd::find_if(m_scenes.begin(), m_scenes.end(),
[name](auto& scene) -> bool
{
return scene->GetName() == name;
}
);
return sceneIterator == m_scenes.end() ? nullptr : sceneIterator->get();
}
AZStd::vector<Scene*> SceneSystemComponent::GetAllScenes()
{
AZStd::vector<Scene*> scenes;
scenes.resize_no_construct(m_scenes.size());
for (size_t i = 0; i < m_scenes.size(); ++i)
{
scenes.at(i) = m_scenes.at(i).get();
}
return scenes;
}
bool SceneSystemComponent::RemoveScene(AZStd::string_view name)
{
for (size_t i = 0; i < m_scenes.size(); ++i)
{
auto& scenePtr = m_scenes.at(i);
if (scenePtr->GetName() == name)
{
// Remove any entityContext mappings.
Scene* scene = scenePtr.get();
for (auto entityContextScenePairIt = m_entityContextToScenes.begin(); entityContextScenePairIt != m_entityContextToScenes.end();)
{
AZStd::pair<EntityContextId, Scene*>& pair = *entityContextScenePairIt;
if (pair.second == scene)
{
// swap and pop back.
*entityContextScenePairIt = m_entityContextToScenes.back();
m_entityContextToScenes.pop_back();
}
else
{
++entityContextScenePairIt;
}
}
SceneSystemNotificationBus::Broadcast(&SceneSystemNotificationBus::Events::SceneAboutToBeRemoved, *scene);
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::SceneAboutToBeRemoved);
m_scenes.erase(&scenePtr);
return true;
}
}
AZ_Warning("SceneSystemComponent", false, "Attempting to remove scene name \"%.*s\", but that scene was not found.", static_cast<int>(name.size()), name.data());
return false;
}
bool SceneSystemComponent::SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene)
{
Scene* existingSceneForEntityContext = GetSceneFromEntityContextId(entityContextId);
if (existingSceneForEntityContext)
{
// This entity context is already mapped and must be unmapped explictely before it can be changed.
char entityContextIdString[EntityContextId::MaxStringBuffer];
entityContextId.ToString(entityContextIdString, sizeof(entityContextIdString));
AZ_Warning("SceneSystemComponent", false, "Failed to set a scene for entity context %s, scene is already set for that entity context.", entityContextIdString);
return false;
}
m_entityContextToScenes.emplace_back(entityContextId, scene);
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::EntityContextMapped, entityContextId);
return true;
}
bool SceneSystemComponent::RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene)
{
if (!scene || entityContextId.IsNull())
{
return false;
}
for (auto entityContextScenePairIt = m_entityContextToScenes.begin(); entityContextScenePairIt != m_entityContextToScenes.end();)
{
AZStd::pair<EntityContextId, Scene*>& pair = *entityContextScenePairIt;
if (!(pair.first == entityContextId && pair.second == scene))
{
++entityContextScenePairIt;
}
else
{
// swap and pop back.
*entityContextScenePairIt = m_entityContextToScenes.back();
m_entityContextToScenes.pop_back();
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::EntityContextUnmapped, entityContextId);
return true;
}
}
char entityContextIdString[EntityContextId::MaxStringBuffer];
entityContextId.ToString(entityContextIdString, sizeof(entityContextIdString));
AZ_Warning("SceneSystemComponent", false, "Failed to remove scene \"%.*s\" for entity context %s, entity context is not currently mapped to that scene.", static_cast<int>(scene->GetName().size()), scene->GetName().data(), entityContextIdString);
return false;
}
Scene* SceneSystemComponent::GetSceneFromEntityContextId(EntityContextId entityContextId)
{
for (AZStd::pair<EntityContextId, Scene*>& pair : m_entityContextToScenes)
{
if (pair.first == entityContextId)
{
return pair.second;
}
}
return nullptr;
}
} // AzFramework