diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp index e5ab403ea6..8da926cd08 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp @@ -66,7 +66,16 @@ namespace AzToolsFramework bool Template::IsValid() const { - return !m_prefabDom.IsNull() && !m_filePath.empty(); + if (m_prefabDom.IsNull() || m_filePath.empty()) + { + return false; + } + else if (!m_prefabDom.IsObject()) + { + return false; + } + auto source = m_prefabDom.FindMember(PrefabDomUtils::SourceName); + return (source != m_prefabDom.MemberEnd()); } bool Template::IsLoadedWithErrors() const @@ -175,6 +184,26 @@ namespace AzToolsFramework return findInstancesResult->get(); } + bool Template::IsProcedural() const + { + if (m_isProcedural.has_value()) + { + return m_isProcedural.value(); + } + else if (!IsValid()) + { + return false; + } + auto source = m_prefabDom.FindMember(PrefabDomUtils::SourceName); + if (!source->value.IsString()) + { + return false; + } + AZ::IO::PathView path(source->value.GetString()); + m_isProcedural = AZStd::make_optional(path.Extension().Match(".procprefab")); + return m_isProcedural.value(); + } + const AZ::IO::Path& Template::GetFilePath() const { return m_filePath; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.h index f7a41431f8..9453edfabc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.h @@ -65,6 +65,9 @@ namespace AzToolsFramework const AZ::IO::Path& GetFilePath() const; void SetFilePath(const AZ::IO::PathView& path); + // To tell if this Template was created from an product asset + bool IsProcedural() const; + private: // Container for keeping links representing the Template's nested instances. Links m_links; @@ -80,6 +83,9 @@ namespace AzToolsFramework // Flag to tell if this Template has changes that have yet to be saved to file. bool m_isDirty = false; + + // Flag to tell if this Template was generated outside the Editor + mutable AZStd::optional m_isProcedural; }; } // namespace Prefab } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/ProceduralPrefabAssetTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/ProceduralPrefabAssetTests.cpp index 0b9e73bbac..fb53fa962a 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/ProceduralPrefabAssetTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/ProceduralPrefabAssetTests.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace UnitTest { @@ -132,4 +133,32 @@ namespace UnitTest EXPECT_TRUE(outputValue.HasMember("member")); EXPECT_STREQ(outputValue.FindMember("member")->value.GetString(), "value"); } + + TEST_F(ProceduralPrefabAssetTest, Template_IsProcPrefab_DefaultsToNotProcPrefab) + { + AzToolsFramework::Prefab::PrefabDom dom; + dom.SetObject(); + dom.AddMember("Source", "foo.prefab", dom.GetAllocator()); + AzToolsFramework::Prefab::Template fooTemplate("foo", AZStd::move(dom)); + EXPECT_FALSE(fooTemplate.IsProcedural()); + } + + TEST_F(ProceduralPrefabAssetTest, Template_IsProcPrefab_DomDrivesFlagToTrue) + { + AzToolsFramework::Prefab::PrefabDom dom; + dom.SetObject(); + dom.AddMember("Source", "foo.procprefab", dom.GetAllocator()); + AzToolsFramework::Prefab::Template fooTemplate("foo", AZStd::move(dom)); + EXPECT_TRUE(fooTemplate.IsProcedural()); + // the second time should use the cached version of the flag + EXPECT_TRUE(fooTemplate.IsProcedural()); + } + + TEST_F(ProceduralPrefabAssetTest, Template_IsProcPrefab_FailsWithNoSource) + { + AzToolsFramework::Prefab::PrefabDom dom; + dom.SetObject(); + AzToolsFramework::Prefab::Template fooTemplate("foo", AZStd::move(dom)); + EXPECT_FALSE(fooTemplate.IsProcedural()); + } }