Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,236 @@
/*
* 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/Prefab/Link/Link.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
namespace AzToolsFramework
{
namespace Prefab
{
Link::Link(const Link& other)
: m_sourceTemplateId(other.m_sourceTemplateId)
, m_targetTemplateId(other.m_targetTemplateId)
, m_instanceName(other.m_instanceName)
, m_id(other.m_id)
, m_prefabSystemComponentInterface(other.m_prefabSystemComponentInterface)
{
AZ_Assert(m_prefabSystemComponentInterface != nullptr,
"Prefab System Component Interface could not be found. "
"It is a requirement for the Link class. Check that it is being correctly initialized.");
m_linkDom.CopyFrom(
other.m_linkDom, m_linkDom.GetAllocator());
}
Link::Link()
: Link(InvalidLinkId)
{
}
Link::Link(LinkId linkId)
{
m_id = linkId;
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
AZ_Assert(m_prefabSystemComponentInterface != nullptr,
"Prefab System Component Interface could not be found. "
"It is a requirement for the Link class. Check that it is being correctly initialized.");
}
Link& Link::operator=(const Link& other)
{
if (this != &other)
{
m_sourceTemplateId = other.m_targetTemplateId;
m_targetTemplateId = other.m_sourceTemplateId;
m_instanceName = other.m_instanceName;
m_id = other.m_id;
m_prefabSystemComponentInterface = other.m_prefabSystemComponentInterface;
AZ_Assert(m_prefabSystemComponentInterface != nullptr,
"Prefab System Component Interface could not be found. "
"It is a requirement for the Link class. Check that it is being correctly initialized.");
m_linkDom.CopyFrom(
other.m_linkDom, m_linkDom.GetAllocator());
}
return *this;
}
Link::Link(Link&& other) noexcept
: m_id(AZStd::move(other.m_id))
, m_sourceTemplateId(AZStd::move(other.m_sourceTemplateId))
, m_targetTemplateId(AZStd::move(other.m_targetTemplateId))
, m_instanceName(AZStd::move(other.m_instanceName))
, m_prefabSystemComponentInterface(AZStd::move(other.m_prefabSystemComponentInterface))
{
other.m_prefabSystemComponentInterface = nullptr;
m_linkDom.Swap(other.m_linkDom);
}
Link& Link::operator=(Link&& other) noexcept
{
if (this != &other)
{
m_id = AZStd::move(other.m_id);
m_sourceTemplateId = AZStd::move(other.m_targetTemplateId);
m_targetTemplateId = AZStd::move(other.m_sourceTemplateId);
m_instanceName = AZStd::move(other.m_instanceName);
m_prefabSystemComponentInterface = AZStd::move(other.m_prefabSystemComponentInterface);
AZ_Assert(m_prefabSystemComponentInterface != nullptr,
"Prefab System Component Interface could not be found. "
"It is a requirement for the Link class. Check that it is being correctly initialized.");
other.m_prefabSystemComponentInterface = nullptr;
m_linkDom.Swap(other.m_linkDom);
}
return *this;
}
void Link::SetSourceTemplateId(TemplateId id)
{
m_sourceTemplateId = id;
}
void Link::SetTargetTemplateId(TemplateId id)
{
m_targetTemplateId = id;
}
void Link::SetTemplatePatches(const PrefabDomValue& patches)
{
PrefabDom newPatches;
newPatches.CopyFrom(patches, newPatches.GetAllocator());
m_linkDom.Swap(newPatches);
}
void Link::SetInstanceName(const char* instanceName)
{
m_instanceName = instanceName;
}
bool Link::IsValid() const
{
return
m_targetTemplateId != InvalidTemplateId &&
m_sourceTemplateId != InvalidTemplateId &&
!m_instanceName.empty();
}
const TemplateId& Link::GetSourceTemplateId() const
{
return m_sourceTemplateId;
}
const TemplateId& Link::GetTargetTemplateId() const
{
return m_targetTemplateId;
}
LinkId Link::GetId() const
{
return m_id;
}
PrefabDom& Link::GetLinkDom()
{
return m_linkDom;
}
const PrefabDom& Link::GetLinkDom() const
{
return m_linkDom;
}
PrefabDomPath Link::GetInstancePath() const
{
return PrefabDomUtils::GetPrefabDomInstancePath(m_instanceName.c_str());
}
const AZStd::string& Link::GetInstanceName() const
{
return m_instanceName;
}
bool Link::UpdateTarget()
{
PrefabDomValue& linkedInstanceDom = GetLinkedInstanceDom();
PrefabDom& targetTemplatePrefabDom = m_prefabSystemComponentInterface->FindTemplateDom(m_targetTemplateId);
PrefabDom& sourceTemplatePrefabDom = m_prefabSystemComponentInterface->FindTemplateDom(m_sourceTemplateId);
// Copy the source template dom so that the actual template DOM does not change and only the linked instance DOM does.
PrefabDom sourceTemplateDomCopy;
sourceTemplateDomCopy.CopyFrom(sourceTemplatePrefabDom, sourceTemplatePrefabDom.GetAllocator());
PrefabDomValueReference patchesReference = PrefabDomUtils::FindPrefabDomValue(m_linkDom, PrefabDomUtils::PatchesName);
if (!patchesReference.has_value())
{
if (AZ::JsonSerialization::Compare(linkedInstanceDom, sourceTemplateDomCopy) != AZ::JsonSerializerCompareResult::Equal)
{
linkedInstanceDom.CopyFrom(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator());
}
}
else
{
AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch(
linkedInstanceDom,
targetTemplatePrefabDom.GetAllocator(),
sourceTemplatePrefabDom,
patchesReference->get(),
AZ::JsonMergeApproach::JsonPatch);
if (applyPatchResult.GetProcessing() != AZ::JsonSerializationResult::Processing::Completed)
{
AZ_Error("Prefab", false,
"Link::UpdateTarget - "
"ApplyPatches failed for Prefab DOM from source Template '%u' and target Template '%u'.",
m_sourceTemplateId, m_targetTemplateId);
return false;
}
}
// This is a guardrail to ensure the linked instance dom always has the LinkId value
// in case the template copy or the patch application removed it.
AddLinkIdToInstanceDom(linkedInstanceDom, targetTemplatePrefabDom.GetAllocator());
return true;
}
PrefabDomValue& Link::GetLinkedInstanceDom()
{
AZ_Assert(IsValid(), "Link::GetLinkDom - Trying to get DOM of an invalid link.");
PrefabDom& targetTemplatePrefabDom = m_prefabSystemComponentInterface->FindTemplateDom(m_targetTemplateId);
PrefabDomPath instancePath = GetInstancePath();
PrefabDomValue* instanceValue = instancePath.Get(targetTemplatePrefabDom);
AZ_Assert(instanceValue,"Link::GetLinkDom - Invalid value for instance pointed by the link in template with id '%u'.",
m_targetTemplateId);
return *instanceValue;
}
void Link::AddLinkIdToInstanceDom(PrefabDomValue& instanceDom)
{
PrefabDom& targetTemplatePrefabDom = m_prefabSystemComponentInterface->FindTemplateDom(m_targetTemplateId);
AddLinkIdToInstanceDom(instanceDom, targetTemplatePrefabDom.GetAllocator());
}
void Link::AddLinkIdToInstanceDom(PrefabDomValue& instanceDom, PrefabDom::AllocatorType& allocator)
{
PrefabDomValueReference linkIdReference = PrefabDomUtils::FindPrefabDomValue(instanceDom, PrefabDomUtils::LinkIdName);
if (!linkIdReference.has_value())
{
AZ_Assert(instanceDom.IsObject(), "Link Id '%u' cannot be added because the DOM of the instance is not an object.", m_id);
instanceDom.AddMember(rapidjson::StringRef(PrefabDomUtils::LinkIdName), rapidjson::Value().SetUint64(m_id), allocator);
}
}
} // namespace Prefab
} // namespace AzToolsFramework
@@ -0,0 +1,109 @@
/*
* 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 <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzToolsFramework/Prefab/PrefabDomTypes.h>
#include <AzToolsFramework/Prefab/PrefabIdTypes.h>
namespace AzToolsFramework
{
namespace Prefab
{
// A prefab template is the primary product of loading a prefab file from disk.
class Template;
class Link;
class PrefabSystemComponentInterface;
using LinkReference = AZStd::optional<AZStd::reference_wrapper<Link>>;
// A link is the primary point of communication between prefab templates.
class Link
{
public:
AZ_CLASS_ALLOCATOR(Link, AZ::SystemAllocator, 0);
AZ_RTTI(Link, "{49230756-7BAA-4456-8DFE-0E18CB887DB5}");
Link();
Link(LinkId linkId);
Link(const Link& other);
Link& operator=(const Link& other);
Link(Link&& other) noexcept;
Link& operator=(Link&& other) noexcept;
virtual ~Link() noexcept = default;
void SetSourceTemplateId(TemplateId id);
void SetTargetTemplateId(TemplateId id);
void SetTemplatePatches(const PrefabDomValue& patches);
void SetInstanceName(const char* instanceName);
bool IsValid() const;
const TemplateId& GetSourceTemplateId() const;
const TemplateId& GetTargetTemplateId() const;
LinkId GetId() const;
PrefabDom& GetLinkDom();
const PrefabDom& GetLinkDom() const;
PrefabDomPath GetInstancePath() const;
const AZStd::string& GetInstanceName() const;
bool UpdateTarget();
/**
* Get the DOM of the instance that the link points to.
*
* @return The DOM of the linked instance
*/
PrefabDomValue& GetLinkedInstanceDom();
/**
* Adds a linkId name,value object to the DOM of an instance.
*
* @param instanceDomValue The DOM value of the instance within the target template DOM.
*/
void AddLinkIdToInstanceDom(PrefabDomValue& instanceDomValue);
private:
/**
* Adds a linkId name,value object to the DOM of an instance.
*
* @param instanceDomValue The DOM value of the instance within the target template DOM.
* @param allocator The allocator used while adding the linkId object to the instance DOM.
*/
void AddLinkIdToInstanceDom(PrefabDomValue& instanceDomValue, PrefabDom::AllocatorType& allocator);
// Target template id for propagation during updating templates.
TemplateId m_targetTemplateId = InvalidTemplateId;
// Source template id for unlink templates if needed.
TemplateId m_sourceTemplateId = InvalidTemplateId;
// JSON patches for overrides in Template.
PrefabDom m_linkDom;
// Name of the nested instance of target Template.
AZStd::string m_instanceName;
LinkId m_id = InvalidLinkId;
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
};
} // namespace Prefab
} // namespace AzToolsFramework