Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
@@ -0,0 +1,64 @@
/*
* 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 <AzToolsFramework/Application/EditorEntityManager.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
namespace AzToolsFramework
{
void EditorEntityManager::Start()
{
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
AZ_Assert(m_prefabPublicInterface, "EditorEntityManager - Could not retrieve instance of PrefabPublicInterface");
AZ::Interface<EditorEntityAPI>::Register(this);
}
EditorEntityManager::~EditorEntityManager()
{
// Attempting to Unregister if we never registerd (e.g. if Start() was never called) throws an error, so check that first
EditorEntityAPI* editorEntityInterface = AZ::Interface<EditorEntityAPI>::Get();
if (editorEntityInterface == this)
{
AZ::Interface<EditorEntityAPI>::Unregister(this);
}
}
void EditorEntityManager::DeleteSelected()
{
EntityIdList selectedEntities;
ToolsApplicationRequestBus::BroadcastResult(selectedEntities, &ToolsApplicationRequests::GetSelectedEntities);
m_prefabPublicInterface->DeleteEntitiesInInstance(selectedEntities);
}
void EditorEntityManager::DeleteEntityById(AZ::EntityId entityId)
{
DeleteEntities({entityId});
}
void EditorEntityManager::DeleteEntities(const EntityIdList& entities)
{
m_prefabPublicInterface->DeleteEntitiesInInstance(entities);
}
void EditorEntityManager::DeleteEntityAndAllDescendants(AZ::EntityId entityId)
{
DeleteEntitiesAndAllDescendants({entityId});
}
void EditorEntityManager::DeleteEntitiesAndAllDescendants(const EntityIdList& entities)
{
m_prefabPublicInterface->DeleteEntitiesAndAllDescendantsInInstance(entities);
}
}
@@ -0,0 +1,39 @@
/*
* 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.
*
*/
#pragma once
#include <AzToolsFramework/API/EditorEntityAPI.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
namespace AzToolsFramework
{
class EditorEntityManager
: public EditorEntityAPI
{
public:
~EditorEntityManager();
void Start();
// EditorEntityAPI...
void DeleteSelected() override;
void DeleteEntityById(AZ::EntityId entityId) override;
void DeleteEntities(const EntityIdList& entities) override;
void DeleteEntityAndAllDescendants(AZ::EntityId entityId) override;
void DeleteEntitiesAndAllDescendants(const EntityIdList& entities) override;
private:
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
};
}
@@ -68,6 +68,8 @@
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
#include <AzToolsFramework/Render/EditorIntersectorComponent.h>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiSystemComponent.h>
#include <AzToolsFramework/Undo/UndoCacheInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <QtWidgets/QMessageBox>
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QFileInfo::d_ptr': class 'QSharedDataPointer<QFileInfoPrivate>' needs to have dll-interface to be used by clients of class 'QFileInfo'
@@ -78,7 +80,6 @@ AZ_POP_DISABLE_OVERRIDE_WARNING
#include <QJsonObject>
#include <QMap>
// Not possible to use AZCore's operator new overrides until we address the overall problems
// with allocators, or more likely convert AzToolsFramework to a DLL and restrict overloading to
// within the DLL. Since this is currently linked as a lib, overriding new and delete would require
@@ -95,9 +96,6 @@ namespace AzToolsFramework
static const char* s_startupLogWindow = "Startup";
static const char* s_prefabSystemKey = "/Amazon/Editor/Preferences/EnablePrefabSystem";
static const char* s_legacySlicesAssertKey = "/Amazon/Editor/Preferences/ShouldAssertForLegacySlicesUsage";
template<typename IdContainerType>
void DeleteEntities(const IdContainerType& entityIds)
{
@@ -341,8 +339,9 @@ namespace AzToolsFramework
, m_isInIsolationMode(false)
{
ToolsApplicationRequests::Bus::Handler::BusConnect();
m_engineConfigImpl.reset(new ToolsApplication::EngineConfigImpl(AzToolsFramework::Internal::s_startupLogWindow,
AzToolsFramework::Internal::s_engineConfigFileName));
m_engineConfigImpl.reset(new ToolsApplication::EngineConfigImpl(AzToolsFramework::Internal::s_startupLogWindow, AzToolsFramework::Internal::s_engineConfigFileName));
m_undoCache.RegisterToUndoCacheInterface();
}
ToolsApplication::~ToolsApplication()
@@ -393,6 +392,11 @@ namespace AzToolsFramework
{
Application::Start(descriptor, startupParameters);
InitializeEngineConfig();
m_editorEntityManager.Start();
m_editorEntityAPI = AZ::Interface<EditorEntityAPI>::Get();
AZ_Assert(m_editorEntityAPI, "ToolsApplication - Could not retrieve instance of EditorEntityAPI");
}
void ToolsApplication::InitializeEngineConfig()
@@ -416,7 +420,11 @@ namespace AzToolsFramework
{
FlushUndo();
m_undoCache.Clear();
auto undoCacheInterface = AZ::Interface<UndoSystem::UndoCacheInterface>::Get();
if (undoCacheInterface)
{
undoCacheInterface->Clear();
}
delete m_undoStack;
m_undoStack = nullptr;
@@ -426,6 +434,19 @@ namespace AzToolsFramework
m_highlightedEntities.set_capacity(0);
m_dirtyEntities = {};
bool isPrefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (isPrefabSystemEnabled)
{
// This resets the editor context thereby asking the systems that own the entities to destroy them. By doing this, we are
// duly giving the authority to delete the entities to the systems that owns them, rather than leaving it to the
// ComponentApplication to do the cleanup.
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequestBus::Events::ResetEditorContext);
}
GetSerializeContext()->DestroyEditContext();
Application::Stop();
@@ -554,7 +575,11 @@ namespace AzToolsFramework
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
m_undoCache.PurgeCache(entity->GetId());
auto undoCacheInterface = AZ::Interface<UndoSystem::UndoCacheInterface>::Get();
if (undoCacheInterface)
{
undoCacheInterface->PurgeCache(entity->GetId());
}
MarkEntityDeselected(entity->GetId());
SetEntityHighlighted(entity->GetId(), false);
@@ -724,7 +749,6 @@ namespace AzToolsFramework
void ToolsApplication::SetEntityHighlighted(AZ::EntityId entityId, bool highlighted)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_Assert(entityId.IsValid(), "Attempting to mark an invalid entity as highlighted.");
auto foundIter = AZStd::find(m_highlightedEntities.begin(), m_highlightedEntities.end(), entityId);
if (foundIter != m_highlightedEntities.end())
@@ -893,16 +917,34 @@ namespace AzToolsFramework
void ToolsApplication::DeleteSelected()
{
if (IsPrefabSystemEnabled())
{
m_editorEntityAPI->DeleteSelected();
return;
}
Internal::DeleteEntities(m_selectedEntities);
}
void ToolsApplication::DeleteEntityAndAllDescendants(AZ::EntityId entityId)
{
if (IsPrefabSystemEnabled())
{
m_editorEntityAPI->DeleteEntityAndAllDescendants(entityId);
return;
}
DeleteEntitiesAndAllDescendants({ entityId });
}
void ToolsApplication::DeleteEntitiesAndAllDescendants(const EntityIdList& entities)
{
if (IsPrefabSystemEnabled())
{
m_editorEntityAPI->DeleteEntitiesAndAllDescendants(entities);
return;
}
const EntityIdSet entitiesAndDescendants = GatherEntitiesAndAllDescendents(entities);
Internal::DeleteEntities(entitiesAndDescendants);
}
@@ -1367,11 +1409,23 @@ namespace AzToolsFramework
void ToolsApplication::DeleteEntityById(AZ::EntityId entityId)
{
if (IsPrefabSystemEnabled())
{
m_editorEntityAPI->DeleteEntityById(entityId);
return;
}
DeleteEntities({ entityId });
}
void ToolsApplication::DeleteEntities(const EntityIdList& entities)
{
if (IsPrefabSystemEnabled())
{
m_editorEntityAPI->DeleteEntities(entities);
return;
}
Internal::DeleteEntities(entities);
}
@@ -1572,7 +1626,6 @@ namespace AzToolsFramework
else
{
// we're at the root
// only undo at bottom of scope (first invoked ScopedUndoBatch in
// chain/hierarchy must go out of scope)
CreateUndosForDirtyEntities();
@@ -1612,48 +1665,68 @@ namespace AzToolsFramework
return;
}
// If the current undo batch has commands in it, then we have to check that we do not add duplicates
// However if it starts out empty, we can just add things straight from the Set to the undo batch
bool mustCheckDuplicates = !m_currentBatchUndo->GetChildren().empty();
for (AZ::EntityId entityId : m_dirtyEntities)
if (!IsPrefabSystemEnabled())
{
AZ::Entity* entity = nullptr;
EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, entityId);
// If the current undo batch has commands in it, then we have to check that we do not add duplicates
// However if it starts out empty, we can just add things straight from the Set to the undo batch
bool mustCheckDuplicates = !m_currentBatchUndo->GetChildren().empty();
if (entity)
for (AZ::EntityId entityId : m_dirtyEntities)
{
EntityStateCommand* state = nullptr;
AZ::Entity* entity = nullptr;
EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, entityId);
if (mustCheckDuplicates)
if (entity)
{
// Check if this entity is already in the current undo batch
state = azdynamic_cast<EntityStateCommand*>(m_currentBatchUndo->Find(
static_cast<AZ::u64>(entityId), AZ::AzTypeInfo<EntityStateCommand>::Uuid()));
EntityStateCommand* state = nullptr;
if (mustCheckDuplicates)
{
// Check if this entity is already in the current undo batch
state = azdynamic_cast<EntityStateCommand*>(
m_currentBatchUndo->Find(static_cast<AZ::u64>(entityId), AZ::AzTypeInfo<EntityStateCommand>::Uuid()));
}
if (!state)
{
state = aznew EntityStateCommand(static_cast<AZ::u64>(entityId));
state->SetParent(m_currentBatchUndo);
// capture initial state of entity (before undo)
state->Capture(entity, true);
}
// capture last state of entity (after undo) - for redo
state->Capture(entity, false);
}
if (!state)
{
state = aznew EntityStateCommand(static_cast<AZ::u64>(entityId));
state->SetParent(m_currentBatchUndo);
// capture initial state of entity (before undo)
state->Capture(entity, true);
}
// capture last state of entity (after undo) - for redo
state->Capture(entity, false);
m_undoCache.UpdateCache(entityId);
}
}
else
{
auto prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
if (prefabPublicInterface)
{
// Compared to the preemptive undo cache, we can avoid the duplicate check.
// Multiple changes to the same entity are just split between different undo nodes.
for (AZ::EntityId entityId : m_dirtyEntities)
{
prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityId, m_currentBatchUndo);
}
}
m_undoCache.UpdateCache(entityId);
}
}
void ToolsApplication::ConsistencyCheckUndoCache()
{
for (auto && entityEntry : m_entities)
auto undoCacheInterface = AZ::Interface<UndoSystem::UndoCacheInterface>::Get();
if (undoCacheInterface)
{
m_undoCache.Validate((entityEntry.second)->GetId());
for (auto&& entityEntry : m_entities)
{
undoCacheInterface->Validate((entityEntry.second)->GetId());
}
}
}
@@ -1769,26 +1842,6 @@ namespace AzToolsFramework
return m_engineConfigImpl->GetEngineVersion();
}
bool ToolsApplication::IsLegacySliceSystemEnabled() const
{
bool value = false;
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Get(value, Internal::s_prefabSystemKey);
}
return !value;
}
bool ToolsApplication::ShouldAssertForLegacySlicesUsage() const
{
bool value = false;
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Get(value, Internal::s_legacySlicesAssertKey);
}
return value;
}
void ToolsApplication::CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName)
{
if (!entityName || !entityName[0])
@@ -17,12 +17,19 @@
#include <AzFramework/Application/Application.h>
#include <AzFramework/Asset/SimpleAsset.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/API/EditorEntityAPI.h>
#include <AzToolsFramework/Application/EditorEntityManager.h>
#include <AzToolsFramework/Commands/PreemptiveUndoCache.h>
#pragma once
namespace AzToolsFramework
{
namespace UndoSystem
{
class UndoCacheInterface;
}
class ToolsApplication
: public AzFramework::Application
, public ToolsApplicationRequests::Bus::Handler
@@ -145,8 +152,6 @@ namespace AzToolsFramework
bool IsEditorInIsolationMode() override;
const char* GetEngineRootPath() const override;
const char* GetEngineVersion() const override;
bool IsLegacySliceSystemEnabled() const override;
bool ShouldAssertForLegacySlicesUsage() const override;
void CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName) override;
@@ -183,6 +188,12 @@ namespace AzToolsFramework
class EngineConfigImpl;
AZStd::unique_ptr<EngineConfigImpl> m_engineConfigImpl;
EditorEntityAPI* m_editorEntityAPI = nullptr;
EditorEntityManager m_editorEntityManager;
UndoSystem::UndoCacheInterface* m_undoCacheInterface = nullptr;
};
} // namespace AzToolsFramework