Merge branch 'development' of https://github.com/aws-lumberyard-dev/o3de into mnaumov/LYN-3904

Signed-off-by: Mikhail Naumov <mnaumov@amazon.com>
This commit is contained in:
Mikhail Naumov
2021-08-18 12:11:54 -07:00
38 changed files with 486 additions and 372 deletions
@@ -366,7 +366,7 @@ bool SpinBoxWatcher::filterSpinBoxEvents(QAbstractSpinBox* spinBox, QEvent* even
{
// To prevent the event being turned into a focus event, be sure to install an
// AzQtComponents::GlobalEventFilter on your QApplication instance.
event->ignore();
event->accept();
return true;
}
@@ -15,6 +15,7 @@
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <Prefab/PrefabDomUtils.h>
namespace AzToolsFramework
{
@@ -81,6 +82,15 @@ namespace AzToolsFramework
result.Combine(resultInstances);
}
PrefabDomUtils::LinkIdMetadata* subPathLinkId = context.GetMetadata().Find<PrefabDomUtils::LinkIdMetadata>();
if (subPathLinkId)
{
AZ::ScopedContextPath subPathSource(context, "m_linkId");
result = ContinueStoringToJsonObjectField(
outputValue, "LinkId", &(instance->m_linkId), &InvalidLinkId, azrtti_typeid<decltype(instance->m_linkId)>(), context);
}
return context.Report(result,
result.GetProcessing() == JSR::Processing::Completed ? "Successfully stored Instance information for Prefab." :
"Failed to store Instance information for Prefab.");
@@ -88,6 +88,11 @@ namespace AzToolsFramework
settings.m_keepDefaults = true;
}
if ((flags & StoreFlags::StoreLinkIds) != StoreFlags::None)
{
settings.m_metadata.Create<LinkIdMetadata>();
}
AZStd::string scratchBuffer;
auto issueReportingCallback = [&scratchBuffer]
(AZStd::string_view message, AZ::JsonSerializationResult::ResultCode result,
@@ -45,7 +45,11 @@ namespace AzToolsFramework
//! By default an instance will be stored with default values. In cases where we want to store less json without defaults
//! such as saving to disk, this flag will control that behavior.
StripDefaultValues = 1 << 0
StripDefaultValues = 1 << 0,
//! We do not save linkIds to file. However when loading a level we want to temporarily save
//! linkIds to instance dom so any nested prefabs will have linkIds correctly set.
StoreLinkIds = 1 << 1
};
AZ_DEFINE_ENUM_BITWISE_OPERATORS(StoreFlags);
@@ -150,6 +154,14 @@ namespace AzToolsFramework
[[maybe_unused]] const AZStd::string_view printMessage,
[[maybe_unused]] const AzToolsFramework::Prefab::PrefabDomValue& prefabDomValue);
//! An empty struct for passing to JsonSerializerSettings.m_metadata that is consumed by InstanceSerializer::Store.
//! If present in metadata, linkIds will be stored to instance dom.
struct LinkIdMetadata
{
AZ_RTTI(LinkIdMetadata, "{8FF7D299-14E3-41D4-90C5-393A240FAE7C}");
virtual ~LinkIdMetadata() {}
};
} // namespace PrefabDomUtils
} // namespace Prefab
} // namespace AzToolsFramework
@@ -300,7 +300,7 @@ namespace AzToolsFramework
}
PrefabDom storedPrefabDom(&loadedTemplateDom->get().GetAllocator());
if (!PrefabDomUtils::StoreInstanceInPrefabDom(loadedPrefabInstance, storedPrefabDom))
if (!PrefabDomUtils::StoreInstanceInPrefabDom(loadedPrefabInstance, storedPrefabDom, PrefabDomUtils::StoreFlags::StoreLinkIds))
{
return false;
}
@@ -61,7 +61,7 @@ namespace AzToolsFramework
m_prefabUndoCache.Destroy();
}
PrefabOperationResult PrefabPublicHandler::CreatePrefabInMemory(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
PrefabOperationResult PrefabPublicHandler::CreatePrefabInMemory(const EntityIdList& entityIds, AZ::IO::PathView filePath)
{
EntityList inputEntityList, topLevelEntities;
AZ::EntityId commonRootEntityId;
@@ -264,7 +264,7 @@ namespace AzToolsFramework
return AZ::Success();
}
PrefabOperationResult PrefabPublicHandler::CreatePrefabInDisk(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
PrefabOperationResult PrefabPublicHandler::CreatePrefabInDisk(const EntityIdList& entityIds, AZ::IO::PathView filePath)
{
auto result = CreatePrefabInMemory(entityIds, filePath);
if (result.IsSuccess())
@@ -43,9 +43,9 @@ namespace AzToolsFramework
// PrefabPublicInterface...
PrefabOperationResult CreatePrefabInDisk(
const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) override;
const EntityIdList& entityIds, AZ::IO::PathView filePath) override;
PrefabOperationResult CreatePrefabInMemory(
const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) override;
const EntityIdList& entityIds, AZ::IO::PathView filePath) override;
InstantiatePrefabResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
@@ -47,7 +47,7 @@ namespace AzToolsFramework
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
*/
virtual PrefabOperationResult CreatePrefabInDisk(
const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) = 0;
const EntityIdList& entityIds, AZ::IO::PathView filePath) = 0;
/**
* Create a prefab out of the entities provided, at the path provided, and keep it in memory.
@@ -57,7 +57,7 @@ namespace AzToolsFramework
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
*/
virtual PrefabOperationResult CreatePrefabInMemory(
const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) = 0;
const EntityIdList& entityIds, AZ::IO::PathView filePath) = 0;
/**
* Instantiate a prefab from a prefab file.
@@ -11,13 +11,20 @@
#include <AzCore/Component/EntityId.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/string/string_view.h>
namespace AzToolsFramework
{
using EntityIdList = AZStd::vector<AZ::EntityId>;
namespace Prefab
{
using PrefabOperationResult = AZ::Outcome<void, AZStd::string>;
using InstantiatePrefabResult = AZ::Outcome<AZ::EntityId, AZStd::string>;
/**
* The primary purpose of this bus is to facilitate writing automated tests for prefabs.
* It calls PrefabPublicInterface internally to talk to the prefab system.
@@ -40,14 +47,25 @@ namespace AzToolsFramework
/**
* Create a prefab out of the entities provided, at the path provided, and keep it in memory.
* Automatically detects descendants of entities, and discerns between entities and child instances.
* Return whether the creation succeeded or not.
*/
virtual bool CreatePrefabInMemory(
const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath) = 0;
virtual PrefabOperationResult CreatePrefabInMemory(
const EntityIdList& entityIds, AZStd::string_view filePath) = 0;
/**
* Instantiate a prefab from a prefab file.
* Return the container entity id of the prefab instantiated if instantiation succeeded.
*/
virtual AZ::EntityId InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0;
virtual InstantiatePrefabResult InstantiatePrefab(
AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0;
/**
* Deletes all entities and their descendants from the owning instance. Bails if the entities don't
* all belong to the same instance.
* Return whether the deletion succeeded or not.
*/
virtual PrefabOperationResult DeleteEntitiesAndAllDescendantsInInstance(const EntityIdList& entityIds) = 0;
};
using PrefabPublicRequestBus = AZ::EBus<PrefabPublicRequests>;
@@ -25,6 +25,7 @@ namespace AzToolsFramework
->Attribute(AZ::Script::Attributes::Module, "prefab")
->Event("CreatePrefabInMemory", &PrefabPublicRequests::CreatePrefabInMemory)
->Event("InstantiatePrefab", &PrefabPublicRequests::InstantiatePrefab)
->Event("DeleteEntitiesAndAllDescendantsInInstance", &PrefabPublicRequests::DeleteEntitiesAndAllDescendantsInInstance)
;
}
}
@@ -44,36 +45,20 @@ namespace AzToolsFramework
m_prefabPublicInterface = nullptr;
}
bool PrefabPublicRequestHandler::CreatePrefabInMemory(const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath)
PrefabOperationResult PrefabPublicRequestHandler::CreatePrefabInMemory(const EntityIdList& entityIds, AZStd::string_view filePath)
{
auto createPrefabOutcome = m_prefabPublicInterface->CreatePrefabInMemory(entityIds, filePath);
if (!createPrefabOutcome.IsSuccess())
{
AZ_Error("CreatePrefabInMemory", false,
"Failed to create Prefab on file path '%.*s'. Error message: %s.",
AZ_STRING_ARG(filePath),
createPrefabOutcome.GetError().c_str());
return false;
}
return true;
return m_prefabPublicInterface->CreatePrefabInMemory(entityIds, filePath);
}
AZ::EntityId PrefabPublicRequestHandler::InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position)
InstantiatePrefabResult PrefabPublicRequestHandler::InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position)
{
auto instantiatePrefabOutcome = m_prefabPublicInterface->InstantiatePrefab(filePath, parent, position);
if (!instantiatePrefabOutcome.IsSuccess())
{
AZ_Error("InstantiatePrefab", false,
"Failed to instantiate Prefab on file path '%.*s'. Error message: %s.",
AZ_STRING_ARG(filePath),
instantiatePrefabOutcome.GetError().c_str());
return AZ::EntityId();
}
return instantiatePrefabOutcome.GetValue();
return m_prefabPublicInterface->InstantiatePrefab(filePath, parent, position);
}
PrefabOperationResult PrefabPublicRequestHandler::DeleteEntitiesAndAllDescendantsInInstance(const EntityIdList& entityIds)
{
return m_prefabPublicInterface->DeleteEntitiesAndAllDescendantsInInstance(entityIds);
}
} // namespace Prefab
} // namespace AzToolsFramework
@@ -31,8 +31,9 @@ namespace AzToolsFramework
void Connect();
void Disconnect();
bool CreatePrefabInMemory(const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath) override;
AZ::EntityId InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
PrefabOperationResult CreatePrefabInMemory(const EntityIdList& entityIds, AZStd::string_view filePath) override;
InstantiatePrefabResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
PrefabOperationResult DeleteEntitiesAndAllDescendantsInInstance(const EntityIdList& entityIds) override;
private:
PrefabPublicInterface* m_prefabPublicInterface = nullptr;