|
@@ -18,7 +18,9 @@
|
|
|
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
|
|
#include <AzCore/StringFunc/StringFunc.h>
|
|
|
|
|
|
+#include <AzFramework/Asset/AssetSystemBus.h>
|
|
|
#include <AzFramework/FileFunc/FileFunc.h>
|
|
|
+#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
|
|
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
|
|
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
|
|
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
|
@@ -112,7 +114,7 @@ namespace AzToolsFramework
|
|
|
return InvalidTemplateId;
|
|
|
}
|
|
|
|
|
|
- AZ::IO::Path relativePath = GetRelativePathToProject(originPath);
|
|
|
+ AZ::IO::Path relativePath = GenerateRelativePath(originPath);
|
|
|
|
|
|
// Cyclical dependency detected if the prefab file is already part of the progressed
|
|
|
// file path set.
|
|
@@ -385,21 +387,100 @@ namespace AzToolsFramework
|
|
|
AZ::IO::Path pathWithOSSeparator = AZ::IO::Path(path).MakePreferred();
|
|
|
if (pathWithOSSeparator.IsAbsolute())
|
|
|
{
|
|
|
+ // If an absolute path was passed in, just return it as-is.
|
|
|
return path;
|
|
|
}
|
|
|
|
|
|
- return AZ::IO::Path(m_projectPathWithOsSeparator).Append(pathWithOSSeparator);
|
|
|
+ // A relative path was passed in, so try to turn it back into an absolute path.
|
|
|
+
|
|
|
+ AZ::IO::Path fullPath;
|
|
|
+
|
|
|
+ bool pathFound = false;
|
|
|
+ AZ::Data::AssetInfo assetInfo;
|
|
|
+ AZStd::string rootFolder;
|
|
|
+ AZStd::string inputPath(path.Native());
|
|
|
+
|
|
|
+ // Given an input path that's expected to exist, try to look it up.
|
|
|
+ AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
|
|
+ pathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath,
|
|
|
+ inputPath.c_str(), assetInfo, rootFolder);
|
|
|
+
|
|
|
+ if (pathFound)
|
|
|
+ {
|
|
|
+ // The asset system provided us with a valid root folder and relative path, so return it.
|
|
|
+ fullPath = AZ::IO::Path(rootFolder) / assetInfo.m_relativePath;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If for some reason the Asset system couldn't provide a relative path, provide some fallback logic.
|
|
|
+
|
|
|
+ // Check to see if the AssetProcessor is ready. If it *is* and we didn't get a path, print an error then follow
|
|
|
+ // the fallback logic. If it's *not* ready, we're probably either extremely early in a tool startup flow or inside
|
|
|
+ // a unit test, so just execute the fallback logic without an error.
|
|
|
+ [[maybe_unused]] bool assetProcessorReady = false;
|
|
|
+ AzFramework::AssetSystemRequestBus::BroadcastResult(
|
|
|
+ assetProcessorReady, &AzFramework::AssetSystemRequestBus::Events::AssetProcessorIsReady);
|
|
|
+
|
|
|
+ AZ_Error(
|
|
|
+ "Prefab", !assetProcessorReady, "Full source path for '%.*s' could not be determined. Using fallback logic.",
|
|
|
+ AZ_STRING_ARG(path.Native()));
|
|
|
+
|
|
|
+ // If a relative path was passed in, make it relative to the project root.
|
|
|
+ fullPath = AZ::IO::Path(m_projectPathWithOsSeparator).Append(pathWithOSSeparator);
|
|
|
+ }
|
|
|
+
|
|
|
+ return fullPath;
|
|
|
}
|
|
|
|
|
|
- AZ::IO::Path PrefabLoader::GetRelativePathToProject(AZ::IO::PathView path)
|
|
|
+ AZ::IO::Path PrefabLoader::GenerateRelativePath(AZ::IO::PathView path)
|
|
|
{
|
|
|
- AZ::IO::Path pathWithOSSeparator = AZ::IO::Path(path.Native()).MakePreferred();
|
|
|
- if (!pathWithOSSeparator.IsAbsolute())
|
|
|
+ bool pathFound = false;
|
|
|
+
|
|
|
+ AZStd::string relativePath;
|
|
|
+ AZStd::string rootFolder;
|
|
|
+ AZ::IO::Path finalPath;
|
|
|
+
|
|
|
+ // The asset system allows for paths to be relative to multiple root folders, using a priority system.
|
|
|
+ // This request will make the input path relative to the most appropriate, highest-priority root folder.
|
|
|
+ AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
|
|
+ pathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GenerateRelativeSourcePath, path.Native(),
|
|
|
+ relativePath, rootFolder);
|
|
|
+
|
|
|
+ if (pathFound && !relativePath.empty())
|
|
|
{
|
|
|
- return path;
|
|
|
+ // A relative path was generated successfully, so return it.
|
|
|
+ finalPath = relativePath;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If for some reason the Asset system couldn't provide a relative path, provide some fallback logic.
|
|
|
+
|
|
|
+ // Check to see if the AssetProcessor is ready. If it *is* and we didn't get a path, print an error then follow
|
|
|
+ // the fallback logic. If it's *not* ready, we're probably either extremely early in a tool startup flow or inside
|
|
|
+ // a unit test, so just execute the fallback logic without an error.
|
|
|
+ [[maybe_unused]] bool assetProcessorReady = false;
|
|
|
+ AzFramework::AssetSystemRequestBus::BroadcastResult(
|
|
|
+ assetProcessorReady, &AzFramework::AssetSystemRequestBus::Events::AssetProcessorIsReady);
|
|
|
+
|
|
|
+ AZ_Error("Prefab", !assetProcessorReady,
|
|
|
+ "Relative source path for '%.*s' could not be determined. Using project path as relative root.",
|
|
|
+ AZ_STRING_ARG(path.Native()));
|
|
|
+
|
|
|
+ AZ::IO::Path pathWithOSSeparator = AZ::IO::Path(path.Native()).MakePreferred();
|
|
|
+
|
|
|
+ if (pathWithOSSeparator.IsAbsolute())
|
|
|
+ {
|
|
|
+ // If an absolute path was passed in, make it relative to the project path.
|
|
|
+ finalPath = AZ::IO::Path(path.Native(), '/').MakePreferred().LexicallyRelative(m_projectPathWithSlashSeparator);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If a relative path was passed in, just return it.
|
|
|
+ finalPath = path;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return AZ::IO::Path(path.Native(), '/').MakePreferred().LexicallyRelative(m_projectPathWithSlashSeparator);
|
|
|
+ return finalPath;
|
|
|
}
|
|
|
|
|
|
AZ::IO::Path PrefabLoaderInterface::GeneratePath()
|