Merge branch 'development' into cmake/warn_virtual
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -26,6 +26,19 @@ namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
static constexpr const char s_saveAllPrefabsKey[] = "/O3DE/Preferences/Prefabs/SaveAllPrefabs";
|
||||
|
||||
void PrefabLoader::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Enum<SaveAllPrefabsPreference>()
|
||||
->Value("Ask every time", SaveAllPrefabsPreference::AskEveryTime)
|
||||
->Value("Save all", SaveAllPrefabsPreference::SaveAll)
|
||||
->Value("Save none", SaveAllPrefabsPreference::SaveNone);
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabLoader::RegisterPrefabLoaderInterface()
|
||||
{
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
@@ -657,6 +670,24 @@ namespace AzToolsFramework
|
||||
return finalPath;
|
||||
}
|
||||
|
||||
SaveAllPrefabsPreference PrefabLoader::GetSaveAllPrefabsPreference() const
|
||||
{
|
||||
SaveAllPrefabsPreference saveAllPrefabsPreference = SaveAllPrefabsPreference::AskEveryTime;
|
||||
if (auto* registry = AZ::SettingsRegistry::Get())
|
||||
{
|
||||
registry->GetObject(saveAllPrefabsPreference, s_saveAllPrefabsKey);
|
||||
}
|
||||
return saveAllPrefabsPreference;
|
||||
}
|
||||
|
||||
void PrefabLoader::SetSaveAllPrefabsPreference(SaveAllPrefabsPreference saveAllPrefabsPreference)
|
||||
{
|
||||
if (auto* registry = AZ::SettingsRegistry::Get())
|
||||
{
|
||||
registry->SetObject(s_saveAllPrefabsKey, saveAllPrefabsPreference);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::IO::Path PrefabLoaderInterface::GeneratePath()
|
||||
{
|
||||
return AZStd::string::format("Prefab_%s", AZ::Entity::MakeId().ToString().c_str());
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace AzToolsFramework
|
||||
AZ_CLASS_ALLOCATOR(PrefabLoader, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(PrefabLoader, "{A302B072-4DC4-4B7E-9188-226F56A3429C8}", PrefabLoaderInterface);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PrefabLoaderInterface interface implementation
|
||||
|
||||
@@ -108,6 +110,9 @@ namespace AzToolsFramework
|
||||
//! Returns if the path is a valid path for a prefab
|
||||
static bool IsValidPrefabPath(AZ::IO::PathView path);
|
||||
|
||||
SaveAllPrefabsPreference GetSaveAllPrefabsPreference() const override;
|
||||
void SetSaveAllPrefabsPreference(SaveAllPrefabsPreference saveAllPrefabsPreference) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Copies the template dom provided and manipulates it into the proper format to be saved to disk.
|
||||
|
||||
@@ -17,6 +17,13 @@ namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
enum class SaveAllPrefabsPreference
|
||||
{
|
||||
AskEveryTime,
|
||||
SaveAll,
|
||||
SaveNone
|
||||
};
|
||||
|
||||
/*!
|
||||
* PrefabLoaderInterface
|
||||
* Interface for saving/loading Prefab files.
|
||||
@@ -84,6 +91,9 @@ namespace AzToolsFramework
|
||||
//! The path will always use the '/' separator.
|
||||
virtual AZ::IO::Path GenerateRelativePath(AZ::IO::PathView path) = 0;
|
||||
|
||||
virtual SaveAllPrefabsPreference GetSaveAllPrefabsPreference() const = 0;
|
||||
virtual void SetSaveAllPrefabsPreference(SaveAllPrefabsPreference saveAllPrefabsPreference) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
// Generates a new path
|
||||
@@ -93,3 +103,8 @@ namespace AzToolsFramework
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(AzToolsFramework::Prefab::SaveAllPrefabsPreference, "{7E61EA82-4DE4-4A3F-945F-C8FEDC1114B5}");
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::Reflect(context);
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::EditorInfoRemover::Reflect(context);
|
||||
PrefabPublicRequestHandler::Reflect(context);
|
||||
PrefabLoader::Reflect(context);
|
||||
|
||||
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
@@ -369,9 +370,11 @@ namespace AzToolsFramework
|
||||
PrefabDom& PrefabSystemComponent::FindTemplateDom(TemplateId templateId)
|
||||
{
|
||||
AZStd::optional<AZStd::reference_wrapper<Template>> findTemplateResult = FindTemplate(templateId);
|
||||
AZ_Assert(findTemplateResult.has_value(),
|
||||
AZ_Assert(
|
||||
findTemplateResult.has_value(),
|
||||
"PrefabSystemComponent::FindTemplateDom - Unable to retrieve Prefab template with id: '%llu'. "
|
||||
"Template could not be found", templateId);
|
||||
"Template could not be found",
|
||||
templateId);
|
||||
|
||||
AZ_Assert(findTemplateResult->get().IsValid(),
|
||||
"PrefabSystemComponent::FindTemplateDom - Unable to retrieve Prefab template with id: '%llu'. "
|
||||
@@ -526,12 +529,10 @@ namespace AzToolsFramework
|
||||
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
AZStd::string_view instanceName(instanceIterator->name.GetString(), instanceIterator->name.GetStringLength());
|
||||
const AZStd::string& targetTemplateFilePath = targetTemplate.GetFilePath().Native();
|
||||
const AZStd::string& sourceTemplateFilePath = sourceTemplate.GetFilePath().Native();
|
||||
#endif
|
||||
|
||||
LinkId newLinkId = CreateUniqueLinkId();
|
||||
Link newLink(newLinkId);
|
||||
@@ -753,6 +754,89 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
bool PrefabSystemComponent::AreDirtyTemplatesPresent(TemplateId rootTemplateId)
|
||||
{
|
||||
TemplateReference prefabTemplate = FindTemplate(rootTemplateId);
|
||||
|
||||
if (!prefabTemplate.has_value())
|
||||
{
|
||||
AZ_Assert(false, "Template with id %llu is not found", rootTemplateId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsTemplateDirty(rootTemplateId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const Template::Links& linkIds = prefabTemplate->get().GetLinks();
|
||||
|
||||
for (LinkId linkId : linkIds)
|
||||
{
|
||||
auto linkIterator = m_linkIdMap.find(linkId);
|
||||
if (linkIterator != m_linkIdMap.end())
|
||||
{
|
||||
return AreDirtyTemplatesPresent(linkIterator->second.GetSourceTemplateId());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrefabSystemComponent::SaveAllDirtyTemplates(TemplateId rootTemplateId)
|
||||
{
|
||||
AZStd::set<AZ::IO::PathView> dirtyTemplatePaths = GetDirtyTemplatePaths(rootTemplateId);
|
||||
|
||||
for (AZ::IO::PathView dirtyTemplatePath : dirtyTemplatePaths)
|
||||
{
|
||||
auto dirtyTemplateIterator = m_templateFilePathToIdMap.find(dirtyTemplatePath);
|
||||
if (dirtyTemplateIterator == m_templateFilePathToIdMap.end())
|
||||
{
|
||||
AZ_Assert(false, "Template id for template with path '%s' is not found.", dirtyTemplatePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_prefabLoader.SaveTemplate(dirtyTemplateIterator->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::set<AZ::IO::PathView> PrefabSystemComponent::GetDirtyTemplatePaths(TemplateId rootTemplateId)
|
||||
{
|
||||
AZStd::vector<AZ::IO::PathView> dirtyTemplatePathVector;
|
||||
GetDirtyTemplatePathsHelper(rootTemplateId, dirtyTemplatePathVector);
|
||||
AZStd::set<AZ::IO::PathView> dirtyTemplatePaths;
|
||||
dirtyTemplatePaths.insert(dirtyTemplatePathVector.begin(), dirtyTemplatePathVector.end());
|
||||
return AZStd::move(dirtyTemplatePaths);
|
||||
}
|
||||
|
||||
void PrefabSystemComponent::GetDirtyTemplatePathsHelper(
|
||||
TemplateId rootTemplateId, AZStd::vector<AZ::IO::PathView>& dirtyTemplatePaths)
|
||||
{
|
||||
TemplateReference prefabTemplate = FindTemplate(rootTemplateId);
|
||||
|
||||
if (!prefabTemplate.has_value())
|
||||
{
|
||||
AZ_Assert(false, "Template with id %llu is not found", rootTemplateId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsTemplateDirty(rootTemplateId))
|
||||
{
|
||||
dirtyTemplatePaths.emplace_back(prefabTemplate->get().GetFilePath());
|
||||
}
|
||||
|
||||
const Template::Links& linkIds = prefabTemplate->get().GetLinks();
|
||||
|
||||
for (LinkId linkId : linkIds)
|
||||
{
|
||||
auto linkIterator = m_linkIdMap.find(linkId);
|
||||
if (linkIterator != m_linkIdMap.end())
|
||||
{
|
||||
GetDirtyTemplatePathsHelper(linkIterator->second.GetSourceTemplateId(), dirtyTemplatePaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PrefabSystemComponent::ConnectTemplates(
|
||||
Link& link,
|
||||
TemplateId sourceTemplateId,
|
||||
@@ -770,10 +854,8 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
#endif
|
||||
|
||||
AZStd::string_view instanceName(instanceIterator->name.GetString(), instanceIterator->name.GetStringLength());
|
||||
|
||||
@@ -783,10 +865,9 @@ namespace AzToolsFramework
|
||||
|
||||
PrefabDomValue& instance = instanceIterator->value;
|
||||
AZ_Assert(instance.IsObject(), "Nested instance DOM provided is not a valid JSON object.");
|
||||
[[maybe_unused]] PrefabDomValueReference sourceTemplateName = PrefabDomUtils::FindPrefabDomValue(instance, PrefabDomUtils::SourceName);
|
||||
PrefabDomValueReference sourceTemplateName = PrefabDomUtils::FindPrefabDomValue(instance, PrefabDomUtils::SourceName);
|
||||
AZ_Assert(sourceTemplateName, "Couldn't find source template name in the DOM of the nested instance while creating a link.");
|
||||
AZ_Assert(
|
||||
sourceTemplateName->get() == sourceTemplate.GetFilePath().c_str(),
|
||||
AZ_Assert(sourceTemplateName->get() == sourceTemplate.GetFilePath().c_str(),
|
||||
"The name of the source template in the nested instance DOM does not match the name of the source template already loaded");
|
||||
|
||||
PrefabDomValueReference patchesReference = PrefabDomUtils::FindPrefabDomValue(instance, PrefabDomUtils::PatchesName);
|
||||
|
||||
@@ -183,6 +183,12 @@ namespace AzToolsFramework
|
||||
*/
|
||||
void SetTemplateDirtyFlag(const TemplateId& templateId, bool dirty) override;
|
||||
|
||||
bool AreDirtyTemplatesPresent(TemplateId rootTemplateId) override;
|
||||
|
||||
void SaveAllDirtyTemplates(TemplateId rootTemplateId) override;
|
||||
|
||||
AZStd::set<AZ::IO::PathView> GetDirtyTemplatePaths(TemplateId rootTemplateId) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@@ -335,6 +341,9 @@ namespace AzToolsFramework
|
||||
*/
|
||||
bool RemoveLinkFromTargetTemplate(const LinkId& linkId, const Link& link);
|
||||
|
||||
// Helper function for GetDirtyTemplatePaths(). It uses vector to speed up iteration times.
|
||||
void GetDirtyTemplatePathsHelper(TemplateId rootTemplateId, AZStd::vector<AZ::IO::PathView>& dirtyTemplatePaths);
|
||||
|
||||
// A container for mapping Templates to the Links they may propagate changes to.
|
||||
AZStd::unordered_map<TemplateId, AZStd::unordered_set<LinkId>> m_templateToLinkIdsMap;
|
||||
|
||||
|
||||
+15
-1
@@ -9,11 +9,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Link/Link.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabIdTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Template/Template.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -50,6 +51,19 @@ namespace AzToolsFramework
|
||||
virtual bool IsTemplateDirty(const TemplateId& templateId) = 0;
|
||||
virtual void SetTemplateDirtyFlag(const TemplateId& templateId, bool dirty) = 0;
|
||||
|
||||
//! Recursive function to check if the template is dirty or if any dirty templates are presents in the links of the template.
|
||||
//! @param rootTemplateId The id of the template provided as the beginning template to check the outgoing links.
|
||||
virtual bool AreDirtyTemplatesPresent(TemplateId rootTemplateId) = 0;
|
||||
|
||||
//! Recursive function to save if the template is dirty and save all the dirty templates in the links of the template.
|
||||
//! @param rootTemplateId The id of the template provided as the beginning template to check the outgoing links.
|
||||
virtual void SaveAllDirtyTemplates(TemplateId rootTemplateId) = 0;
|
||||
|
||||
//! Recursive function that fetches the set of dirty templates given a starting template to check for outgoing links.
|
||||
//! @param rootTemplateId The id of the template provided as the beginning template to check the outgoing links.
|
||||
//! @return The set of dirty template paths populated.
|
||||
virtual AZStd::set<AZ::IO::PathView> GetDirtyTemplatePaths(TemplateId rootTemplateId) = 0;
|
||||
|
||||
virtual PrefabDom& FindTemplateDom(TemplateId templateId) = 0;
|
||||
virtual void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) = 0;
|
||||
virtual void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0;
|
||||
|
||||
Reference in New Issue
Block a user