Merging latest origin
This commit is contained in:
@@ -269,13 +269,13 @@ namespace AZ
|
||||
{
|
||||
for (auto& [assetId, dependentAsset] : m_dependencies)
|
||||
{
|
||||
if (dependentAsset->IsReady())
|
||||
if (dependentAsset->IsReady() || dependentAsset->IsError())
|
||||
{
|
||||
HandleReadyAsset(dependentAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (auto asset = m_rootAsset.GetStrongReference(); asset.IsReady())
|
||||
if (auto asset = m_rootAsset.GetStrongReference(); asset.IsReady() || asset.IsError())
|
||||
{
|
||||
HandleReadyAsset(asset);
|
||||
}
|
||||
@@ -496,10 +496,10 @@ namespace AZ
|
||||
m_waitingCount -= 1;
|
||||
disconnectEbus = true;
|
||||
|
||||
if (m_waitingAssets.empty())
|
||||
{
|
||||
allReady = true;
|
||||
}
|
||||
}
|
||||
if (m_waitingAssets.empty())
|
||||
{
|
||||
allReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,8 +510,15 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
if (allReady && m_initComplete)
|
||||
// If there are no assets left to be loaded, trigger the final AssetContainer notification (ready or canceled).
|
||||
// We guard against prematurely sending it (m_initComplete) because it's possible for assets to get removed from our waiting
|
||||
// list *while* we're still building up the list, so the list would appear to be empty too soon.
|
||||
// We also guard against sending it multiple times (m_finalNotificationSent), because in some error conditions, it may be
|
||||
// possible to try to remove the same asset multiple times, which if it's the last asset, it could trigger multiple
|
||||
// notifications.
|
||||
if (allReady && m_initComplete && !m_finalNotificationSent)
|
||||
{
|
||||
m_finalNotificationSent = true;
|
||||
if (m_rootAsset)
|
||||
{
|
||||
AssetManagerBus::Broadcast(&AssetManagerBus::Events::OnAssetContainerReady, this);
|
||||
|
||||
@@ -137,6 +137,7 @@ namespace AZ
|
||||
AZStd::atomic_int m_invalidDependencies{ 0 };
|
||||
AZStd::unordered_set<AZ::Data::AssetId> m_unloadedDependencies;
|
||||
AZStd::atomic_bool m_initComplete{ false };
|
||||
AZStd::atomic_bool m_finalNotificationSent{false};
|
||||
|
||||
mutable AZStd::recursive_mutex m_preloadMutex;
|
||||
// AssetId -> List of assets it is still waiting on
|
||||
|
||||
@@ -916,27 +916,49 @@ namespace AZ
|
||||
SetSettingsRegistrySpecializations(specializations);
|
||||
|
||||
AZStd::vector<char> scratchBuffer;
|
||||
// Retrieves the list gem module build targets that the active project depends on
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry,
|
||||
AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
|
||||
// In development builds apply the o3de registry and the command line to allow early overrides. This will
|
||||
// allow developers to override things like default paths or Asset Processor connection settings. Any additional
|
||||
// values will be replaced by later loads, so this step will happen again at the end of loading.
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
// Project User Registry is merged after the command line here to allow make sure the any command line override of the project path
|
||||
// is used for merging the project's user registry
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
#endif
|
||||
//! Retrieves the list gem targets that the project has load dependencies on
|
||||
//! This populates the /Amazon/Gems/<GemName>/SourcePaths array entries which is required
|
||||
//! by the MergeSettingsToRegistry_GemRegistry() function below to locate the gem's root folder
|
||||
//! and merge in the gem's registry files.
|
||||
//! But when running from a pre-built app from the O3DE SDK(Editor/AssetProcessor), the projects binary
|
||||
//! directory is needed in order to located the load dependency registry files
|
||||
//! That project binary folder is generated with the <ProjectRoot>/user/Registry when CMake is configured
|
||||
//! for the project
|
||||
//! Therefore the order of merging must be as follows
|
||||
//! 1. MergeSettingsToRegistry_ProjectUserRegistry - Populates the /Amazon/Project/Settings/Build/project_build_path
|
||||
//! which contains the path to the project binary directory
|
||||
//! 2. MergeSettingsToRegistry_TargetBuildDependencyRegistry - Loads the cmake_dependencies.<project_name>.<application_name>.setreg
|
||||
//! file from the locations in order of
|
||||
//! 1. <executable_directory>/Registry
|
||||
//! 2. <cache_root>/Registry
|
||||
//! 3. <project_build_path>/bin/$<CONFIG>/Registry
|
||||
//! 3. MergeSettingsToRegistry_GemRegistries - Merges the settings registry files from each gem's <GemRoot>/Registry directory
|
||||
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry,
|
||||
AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_EngineRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations)
|
||||
|
||||
@@ -599,6 +599,34 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
? devWriteStorage.value()
|
||||
: projectUserPath.Native());
|
||||
|
||||
// Set the project in-memory build path if the ProjectBuildPath key has been supplied
|
||||
if (AZ::IO::FixedMaxPath projectBuildPath; registry.Get(projectBuildPath.Native(), ProjectBuildPath))
|
||||
{
|
||||
registry.Remove(FilePathKey_ProjectBuildPath);
|
||||
registry.Remove(FilePathKey_ProjectConfigurationBinPath);
|
||||
AZ::IO::FixedMaxPath buildConfigurationPath = normalizedProjectPath / projectBuildPath;
|
||||
if (IO::SystemFile::Exists(buildConfigurationPath.c_str()))
|
||||
{
|
||||
registry.Set(FilePathKey_ProjectBuildPath, buildConfigurationPath.LexicallyNormal().Native());
|
||||
}
|
||||
|
||||
// Add the specific build configuration paths to the Settings Registry
|
||||
// First try <project-build-path>/bin/$<CONFIG> and if that path doesn't exist
|
||||
// try <project-build-path>/bin/$<PLATFORM>/$<CONFIG>
|
||||
buildConfigurationPath /= "bin";
|
||||
if (IO::SystemFile::Exists((buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).c_str()))
|
||||
{
|
||||
registry.Set(FilePathKey_ProjectConfigurationBinPath,
|
||||
(buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native());
|
||||
}
|
||||
else if (IO::SystemFile::Exists((buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).c_str()))
|
||||
{
|
||||
registry.Set(FilePathKey_ProjectConfigurationBinPath,
|
||||
(buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Project name - if it was set via merging project.json use that value, otherwise use the project path's folder name.
|
||||
auto projectNameKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
@@ -689,6 +717,14 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
mergePath /= SettingsRegistryInterface::RegistryFolder;
|
||||
registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer);
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath projectBinPath;
|
||||
if (registry.Get(projectBinPath.Native(), FilePathKey_ProjectConfigurationBinPath))
|
||||
{
|
||||
// Append the project build path path to the project root
|
||||
projectBinPath /= SettingsRegistryInterface::RegistryFolder;
|
||||
registry.MergeSettingsFolder(projectBinPath.Native(), specializations, platform, "", scratchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MergeSettingsToRegistry_EngineRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
@@ -934,7 +970,8 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
"project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
|
||||
OptionKeyToRegsetKey{
|
||||
"project-cache-path",
|
||||
AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}};
|
||||
AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
|
||||
OptionKeyToRegsetKey{"project-build-path", ProjectBuildPath} };
|
||||
|
||||
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
|
||||
|
||||
|
||||
@@ -52,6 +52,14 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! project settings can be stored
|
||||
inline static constexpr char FilePathKey_ProjectUserPath[] = "/Amazon/AzCore/Runtime/FilePaths/SourceProjectUserPath";
|
||||
|
||||
//! User facing key which represents the root of a project cmake build tree. i.e the ${CMAKE_BINARY_DIR}
|
||||
//! A relative path is taking relative to the *project* root, NOT *engine* root.
|
||||
inline constexpr AZStd::string_view ProjectBuildPath = "/Amazon/Project/Settings/Build/project_build_path";
|
||||
//! In-Memory only key which stores an absolute path to the project build directory
|
||||
inline constexpr AZStd::string_view FilePathKey_ProjectBuildPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectBuildPath";
|
||||
//! In-Memory only key which stores the configuration directory containing the built binaries
|
||||
inline constexpr AZStd::string_view FilePathKey_ProjectConfigurationBinPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectConfigurationBinPath";
|
||||
|
||||
//! Development write storage path may be considered temporary or cache storage on some platforms
|
||||
inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage";
|
||||
|
||||
@@ -128,7 +136,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! Callback function that is after a has been filtered through the CommentPrefixFunc
|
||||
//! to determine if the text matches a section header
|
||||
//! returns a view of the section name if the line contains a section
|
||||
//! Otherwise an empty view is returend
|
||||
//! Otherwise an empty view is returned
|
||||
using SectionHeaderFunc = AZStd::function<AZStd::string_view(AZStd::string_view line)>;
|
||||
|
||||
//! Root JSON pointer path to place all key=values pairs of configuration data within
|
||||
|
||||
+4
-4
@@ -17,8 +17,9 @@ namespace AZ
|
||||
{
|
||||
namespace Platform
|
||||
{
|
||||
void GetModulePath(AZ::OSString& path)
|
||||
AZ::IO::FixedMaxPath GetModulePath()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void* OpenModule(const AZ::OSString& fileName, bool&)
|
||||
@@ -26,10 +27,9 @@ namespace AZ
|
||||
// Android 19 does not have RTLD_NOLOAD but it should be OK since only the Editor expects to reopen modules
|
||||
return dlopen(fileName.c_str(), RTLD_NOW);
|
||||
}
|
||||
|
||||
void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath)
|
||||
|
||||
void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&)
|
||||
{
|
||||
fullPath = path + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-12
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <dlfcn.h>
|
||||
@@ -19,15 +18,9 @@ namespace AZ
|
||||
{
|
||||
namespace Platform
|
||||
{
|
||||
void GetModulePath(AZ::OSString& path)
|
||||
AZ::IO::FixedMaxPath GetModulePath()
|
||||
{
|
||||
char exePath[AZ_MAX_PATH_LEN];
|
||||
if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) ==
|
||||
AZ::Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
path = exePath;
|
||||
path.push_back('/');
|
||||
}
|
||||
return AZ::Utils::GetExecutableDirectory();
|
||||
}
|
||||
|
||||
void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen)
|
||||
@@ -40,10 +33,9 @@ namespace AZ
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath)
|
||||
|
||||
void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&)
|
||||
{
|
||||
fullPath = path + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+47
-30
@@ -11,9 +11,11 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Module/DynamicModuleHandle.h>
|
||||
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
|
||||
@@ -21,9 +23,9 @@ namespace AZ
|
||||
{
|
||||
namespace Platform
|
||||
{
|
||||
void GetModulePath(AZ::OSString& path);
|
||||
AZ::IO::FixedMaxPath GetModulePath();
|
||||
void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen);
|
||||
void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath);
|
||||
void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath);
|
||||
}
|
||||
|
||||
class DynamicModuleHandleUnixLike
|
||||
@@ -36,40 +38,55 @@ namespace AZ
|
||||
: DynamicModuleHandle(fullFileName)
|
||||
, m_handle(nullptr)
|
||||
{
|
||||
AZ::OSString path;
|
||||
AZ::OSString fileName;
|
||||
AZ::OSString fullPath = "";
|
||||
AZ::OSString::size_type finalSlash = m_fileName.find_last_of("/");
|
||||
if (finalSlash != AZ::OSString::npos)
|
||||
AZ::IO::FixedMaxPath fullFilePath(AZStd::string_view{m_fileName});
|
||||
if (fullFilePath.HasFilename())
|
||||
{
|
||||
// Path up to and including final slash
|
||||
path = m_fileName.substr(0, finalSlash + 1);
|
||||
// Everything after the final slash
|
||||
// If m_fileName ends in /, the end result is path/lib.dylib, which just fails to load.
|
||||
fileName = m_fileName.substr(finalSlash + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no slash found, assume empty path, only file name
|
||||
path = "";
|
||||
Platform::GetModulePath(path);
|
||||
fileName = m_fileName;
|
||||
AZ::IO::FixedMaxPathString fileNamePath{fullFilePath.Filename().Native()};
|
||||
if (!fileNamePath.starts_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX))
|
||||
{
|
||||
fileNamePath = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileNamePath;
|
||||
}
|
||||
|
||||
if (!fileNamePath.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION))
|
||||
{
|
||||
fileNamePath += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION;
|
||||
}
|
||||
|
||||
fullFilePath.ReplaceFilename(AZStd::string_view(fileNamePath));
|
||||
}
|
||||
|
||||
if (fileName.substr(0, 3) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX)
|
||||
Platform::ConstructModuleFullFileName(fullFilePath);
|
||||
|
||||
// Check if the module exist at the given path within the current working directory
|
||||
// If it doesn't attempt to append the path to the executable path
|
||||
if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str()))
|
||||
{
|
||||
fileName = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileName;
|
||||
auto candidatePath = Platform::GetModulePath() / fullFilePath;
|
||||
if (AZ::IO::SystemFile::Exists(candidatePath.c_str()))
|
||||
{
|
||||
fullFilePath = candidatePath;
|
||||
}
|
||||
}
|
||||
|
||||
size_t extensionLen = strlen(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION);
|
||||
if (fileName.substr(fileName.length() - extensionLen, extensionLen) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)
|
||||
// If the path still doesn't exist at this point, check the SettingsRegistryMergeUtils
|
||||
// FilePathKey_ProjectBuildPath key to see if a project-build-path argument has been supplied
|
||||
if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str()))
|
||||
{
|
||||
fileName = fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if(AZ::IO::FixedMaxPath projectModulePath;
|
||||
settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath))
|
||||
{
|
||||
projectModulePath /= fullFilePath;
|
||||
if (AZ::IO::SystemFile::Exists(projectModulePath.c_str()))
|
||||
{
|
||||
fullFilePath = projectModulePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Platform::ConstructModuleFullFileName(path, fileName, fullPath);
|
||||
|
||||
m_fileName = fullPath;
|
||||
m_fileName = AZStd::string_view{fullFilePath.Native()};
|
||||
}
|
||||
|
||||
~DynamicModuleHandleUnixLike() override
|
||||
@@ -81,9 +98,9 @@ namespace AZ
|
||||
{
|
||||
AZ::Debug::Trace::Printf("Module", "Attempting to load module:%s\n", m_fileName.c_str());
|
||||
bool alreadyOpen = false;
|
||||
|
||||
|
||||
m_handle = Platform::OpenModule(m_fileName, alreadyOpen);
|
||||
|
||||
|
||||
if(m_handle)
|
||||
{
|
||||
if (alreadyOpen)
|
||||
|
||||
+25
-3
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/Module/DynamicModuleHandle.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -31,13 +32,13 @@ namespace AZ
|
||||
{
|
||||
// Ensure filename ends in ".dll"
|
||||
// Otherwise filenames like "gem.1.0.0" fail to load (.0 is assumed to be the extension).
|
||||
if (m_fileName.substr(m_fileName.length() - 4) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)
|
||||
if (!m_fileName.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION))
|
||||
{
|
||||
m_fileName = m_fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION;
|
||||
m_fileName += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION;
|
||||
}
|
||||
|
||||
AZ::IO::PathView modulePathView{ m_fileName };
|
||||
// If the module path doesn't have a directory within it, prepend it to the path
|
||||
// If the module path doesn't have a directory within it, prepend the executable directory to the path
|
||||
// and check if the new path exist
|
||||
if (modulePathView.HasFilename() && !modulePathView.HasParentPath())
|
||||
{
|
||||
@@ -54,6 +55,27 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the module file path does not exist, attempt to search for the module within
|
||||
// the project's build directory
|
||||
if (!AZ::IO::SystemFile::Exists(m_fileName.c_str()))
|
||||
{
|
||||
// The Settings Registry may not exist in early startup if modules are loaded
|
||||
// before the ComponentApplication is crated(such as in the Editor main.cpp)
|
||||
// Therefore an existence check is needed
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if(AZ::IO::FixedMaxPath projectModulePath;
|
||||
settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath))
|
||||
{
|
||||
projectModulePath /= AZStd::string_view(m_fileName);
|
||||
if (AZ::IO::SystemFile::Exists(projectModulePath.c_str()))
|
||||
{
|
||||
m_fileName.assign(projectModulePath.c_str(), projectModulePath.Native().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~DynamicModuleHandleWindows() override
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <dlfcn.h>
|
||||
@@ -19,15 +18,9 @@ namespace AZ
|
||||
{
|
||||
namespace Platform
|
||||
{
|
||||
void GetModulePath(AZ::OSString& path)
|
||||
AZ::IO::FixedMaxPath GetModulePath()
|
||||
{
|
||||
char exePath[AZ_MAX_PATH_LEN];
|
||||
if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) ==
|
||||
AZ::Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
path = exePath;
|
||||
path.push_back('/');
|
||||
}
|
||||
return AZ::Utils::GetExecutableDirectory();
|
||||
}
|
||||
|
||||
void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen)
|
||||
@@ -40,10 +33,9 @@ namespace AZ
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath)
|
||||
|
||||
void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&)
|
||||
{
|
||||
fullPath = path + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <dlfcn.h>
|
||||
@@ -19,15 +18,9 @@ namespace AZ
|
||||
{
|
||||
namespace Platform
|
||||
{
|
||||
void GetModulePath(AZ::OSString& path)
|
||||
AZ::IO::FixedMaxPath GetModulePath()
|
||||
{
|
||||
char exePath[AZ_MAX_PATH_LEN];
|
||||
if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) ==
|
||||
AZ::Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
AZ::OSString frameworks = "/Frameworks/";
|
||||
path = exePath + frameworks;
|
||||
}
|
||||
return AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "Frameworks";
|
||||
}
|
||||
|
||||
void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen)
|
||||
@@ -40,10 +33,15 @@ namespace AZ
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath)
|
||||
|
||||
void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath)
|
||||
{
|
||||
fullPath = path + fileName + ".framework/" + fileName;
|
||||
// Append .framework to the name of full path
|
||||
// Afterwards use the AZ::IO::Path Append function append the filename as a child
|
||||
// of the framework directory
|
||||
AZ::IO::FixedMaxPathString fileName = fullPath.Filename().Native();
|
||||
fullPath.ReplaceFilename(fileName + ".framework");
|
||||
fullPath /= fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,6 +351,7 @@ namespace UnitTest
|
||||
public AZ::Data::AssetCatalog
|
||||
{
|
||||
static inline const AZ::Uuid TestAssetId{"{E970B177-5F45-44EB-A2C4-9F29D9A0B2A2}"};
|
||||
static inline const AZ::Uuid MissingAssetId{"{11111111-1111-1111-1111-111111111111}"};
|
||||
static inline constexpr AZStd::string_view TestAssetPath = "test";
|
||||
|
||||
void SetUp() override
|
||||
@@ -431,24 +432,40 @@ namespace UnitTest
|
||||
// AssetCatalogRequestBus implementation
|
||||
|
||||
// Minimalist mocks to provide our desired asset path or asset id
|
||||
AZStd::string GetAssetPathById([[maybe_unused]] const AZ::Data::AssetId& id) override
|
||||
AZStd::string GetAssetPathById(const AZ::Data::AssetId& id) override
|
||||
{
|
||||
return TestAssetPath;
|
||||
if (id == TestAssetId)
|
||||
{
|
||||
return TestAssetPath;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
AZ::Data::AssetId GetAssetIdByPath(
|
||||
[[maybe_unused]] const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister,
|
||||
const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister,
|
||||
[[maybe_unused]] bool autoRegisterIfNotFound) override
|
||||
{
|
||||
return TestAssetId;
|
||||
if (path == TestAssetPath)
|
||||
{
|
||||
return TestAssetId;
|
||||
}
|
||||
|
||||
return AZ::Data::AssetId();
|
||||
}
|
||||
|
||||
// Return the mocked-out information for our test asset
|
||||
AZ::Data::AssetInfo GetAssetInfoById([[maybe_unused]] const AZ::Data::AssetId& id) override
|
||||
AZ::Data::AssetInfo GetAssetInfoById(const AZ::Data::AssetId& id) override
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
assetInfo.m_assetId = TestAssetId;
|
||||
assetInfo.m_assetType = AZ::AzTypeInfo<EmptyAsset>::Uuid();
|
||||
assetInfo.m_relativePath = TestAssetPath;
|
||||
|
||||
if (id == TestAssetId)
|
||||
{
|
||||
assetInfo.m_assetId = TestAssetId;
|
||||
assetInfo.m_assetType = AZ::AzTypeInfo<EmptyAsset>::Uuid();
|
||||
assetInfo.m_relativePath = TestAssetPath;
|
||||
}
|
||||
|
||||
return assetInfo;
|
||||
}
|
||||
|
||||
@@ -456,15 +473,20 @@ namespace UnitTest
|
||||
|
||||
// Set the mocked-out asset load to have a 0-byte length so that the load skips I/O and immediately returns success
|
||||
AZ::Data::AssetStreamInfo GetStreamInfoForLoad(
|
||||
[[maybe_unused]] const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override
|
||||
const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override
|
||||
{
|
||||
EXPECT_TRUE(type == AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
AZ::Data::AssetStreamInfo info;
|
||||
|
||||
info.m_dataOffset = 0;
|
||||
info.m_streamName = TestAssetPath;
|
||||
info.m_dataLen = 0;
|
||||
info.m_streamFlags = AZ::IO::OpenMode::ModeRead;
|
||||
|
||||
if (id == TestAssetId)
|
||||
{
|
||||
info.m_streamName = TestAssetPath;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -489,4 +511,27 @@ namespace UnitTest
|
||||
EXPECT_TRUE(testAsset.IsReady());
|
||||
}
|
||||
|
||||
// This test verifies that even if the asset loading returns immediately with an error, all of the loading code works
|
||||
// successfully. The test itself loads a missing asset twice - the first time is a non-immediate error, where the error
|
||||
// isn't reported until the DispatchEvents() call. The second time is an immediate error, because now the asset is already
|
||||
// registered in an Error state. If the test fails, it will likely get caught in the shutdown of the test class, if any
|
||||
// assets still exist at the point that the asset handler is unregistered. If they're present, then handling of the immediate
|
||||
// error didn't work, as it left around extra references to the asset that haven't been cleaned up.
|
||||
TEST_F(AssetManagerStreamerImmediateCompletionTests, ImmediateAssetError_WorksSuccessfully)
|
||||
{
|
||||
AZ::Data::AssetLoadParameters loadParams;
|
||||
|
||||
// Attempt to load a missing asset the first time. It will get an error, but not until the DispatchEvents() call happens.
|
||||
auto testAsset1 = AssetManager::Instance().GetAsset<EmptyAsset>(MissingAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
EXPECT_TRUE(testAsset1.IsError());
|
||||
|
||||
// While the reference to the missing asset still exists, try to get it again. This will cause a more immediate error in
|
||||
// the AssetContainer code, which should still get handled correctly. In the failure condition, it will instead leave the
|
||||
// AssetContainer in a state where it never sends the final OnAssetContainerReady/Canceled message.
|
||||
auto testAsset2 = AssetManager::Instance().GetAsset<EmptyAsset>(MissingAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
EXPECT_TRUE(testAsset2.IsError());
|
||||
}
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace AZ::IO
|
||||
ePakPriorityPakOnly = 2
|
||||
};
|
||||
|
||||
// variables that control behavior of Archive/StreamEngine subsystems
|
||||
// variables that control behavior of the Archive subsystem
|
||||
struct ArchiveVars
|
||||
{
|
||||
#if defined(_RELEASE)
|
||||
|
||||
@@ -881,7 +881,7 @@ namespace AzFramework
|
||||
serializeContext->ClassDeprecate("NetBindable", "{80206665-D429-4703-B42E-94434F82F381}");
|
||||
|
||||
serializeContext->Class<TransformComponent, AZ::Component>()
|
||||
->Version(4, &TransformComponentVersionConverter)
|
||||
->Version(5, &TransformComponentVersionConverter)
|
||||
->Field("Parent", &TransformComponent::m_parentId)
|
||||
->Field("Transform", &TransformComponent::m_worldTM)
|
||||
->Field("LocalTransform", &TransformComponent::m_localTM)
|
||||
|
||||
@@ -979,7 +979,7 @@ namespace AzFramework
|
||||
};
|
||||
|
||||
serializeContext->Class<ScriptComponent, AZ::Component>()
|
||||
->Version(3, converter)
|
||||
->Version(4, converter)
|
||||
->Field("ContextID", &ScriptComponent::m_contextId)
|
||||
->Field("Properties", &ScriptComponent::m_properties)
|
||||
->Field("Script", &ScriptComponent::m_script)
|
||||
|
||||
@@ -57,13 +57,16 @@ namespace AzGameFramework
|
||||
|
||||
AZStd::vector<char> scratchBuffer;
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
#endif
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
|
||||
// Used the lowercase the platform name since the bootstrap.game.<config>.<platform>.setreg is being loaded
|
||||
// from the asset cache root where all the files are in lowercased from regardless of the filesystem case-sensitivity
|
||||
static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE "." AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER ".setreg";
|
||||
@@ -77,6 +80,7 @@ namespace AzGameFramework
|
||||
|
||||
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="22px" height="20px" viewBox="0 0 22 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Icon / Toolbar / Play Console / Simulate Physics</title>
|
||||
<defs>
|
||||
<filter id="filter-1">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1.000000 0 0 0 0 1.000000 0 0 0 0 1.000000 0 0 0 1.000000 0"></feColorMatrix>
|
||||
</filter>
|
||||
<path d="M15.6428742,11.9827626 C14.6770188,10.7687802 14.4956657,9.03975584 15.318317,7.61488202 C16.3923878,5.75453685 18.7712019,5.11713552 20.6315471,6.1912063 C22.4918923,7.26527709 23.1292936,9.64409122 22.0552228,11.5044364 C21.013572,13.3086286 18.7447543,13.9625898 16.9118187,13.0207075 C16.3649862,12.6909949 16.1306352,12.5503038 15.6428742,11.9827626 Z M21.8449657,10.7460039 C22.0595758,10.1342007 22.2373043,8.55906064 21.8449657,9.05833735 C21.4526271,9.55761407 21.2918858,9.96701497 20.8130083,10.4818331 C19.9042528,11.4587922 18.2692551,11.5405181 17.2685207,11.5405181 C16.2677863,11.5405181 17.2685207,12.7159692 18.7447536,12.7159692 C20.2209864,12.7159692 21.4894947,11.7593684 21.8449657,10.7460039 Z M16.197388,14.0090117 C16.3975463,13.8229455 16.701528,13.7946404 16.9039947,13.9824218 C17.1064613,14.1702033 17.0967404,14.4628636 16.9305845,14.6890285 C16.3625338,15.4622373 15.7176919,17.2794303 15.043117,20.0013354 L13.9731652,20.0013354 C13.74245,13.5862059 13.0475403,9.88991503 12.1237705,9.88991503 C11.4442663,9.88991503 10.8362307,11.6219 10.2533824,15.1128617 C10.1857467,15.5179652 9.53567637,19.2951617 9.47653253,20.0013354 L8.32801304,20.0013354 C8.32801304,11.4928776 6.37313749,5.95119082 2.36188186,4.12720757 C2.11050727,4.01290346 1.65264126,3.52516756 2.0367453,2.87964604 C2.42084934,2.23412452 3.17248781,2.63112648 3.42386239,2.7454306 C7.09988702,4.41697884 8.58435154,8.916133 9.2170288,15.2523916 C9.23745765,15.1271094 9.25478369,15.0215631 9.26703535,14.9481819 C9.97359325,10.7162629 10.1786779,8.42129315 12.1237705,8.42129315 C14.0688632,8.42129315 14.4491297,12.5275507 14.8251327,17.6881742 C15.0978485,16.4034552 15.5446067,14.6158341 16.197388,14.0090117 Z M2.0241711,20.6412764 L22.0595758,20.6412764 L20.6246231,21.7592943 L3.70859025,21.7592943 L2.0241711,20.6412764 Z" id="path-2"></path>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Play-Console-v2" transform="translate(-169.000000, -8.000000)">
|
||||
<g id="Play-Console" transform="translate(100.000000, 0.000000)">
|
||||
<g id="Icon-/-Toolbar-/-Play-Console-/-Simulate-Physics" transform="translate(68.000000, 6.000000)" filter="url(#filter-1)">
|
||||
<g>
|
||||
<mask id="mask-3" fill="white">
|
||||
<use xlink:href="#path-2"></use>
|
||||
</mask>
|
||||
<use id="Shape" fill="#FFFFFF" fill-rule="nonzero" xlink:href="#path-2"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -372,6 +372,7 @@
|
||||
<file>img/UI20/toolbar/Select.svg</file>
|
||||
<file>img/UI20/toolbar/select_object.svg</file>
|
||||
<file>img/UI20/toolbar/Select_terrain.svg</file>
|
||||
<file>img/UI20/toolbar/Simulate_Physics.svg</file>
|
||||
<file>img/UI20/toolbar/Simulate_Physics_on_selected_objects.svg</file>
|
||||
<file>img/UI20/toolbar/Terrain.svg</file>
|
||||
<file>img/UI20/toolbar/Terrain_Texture.svg</file>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <array>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4389 4800, "-Wunknown-warning-option"); // 'int' : forcing value to bool 'true' or 'false' (performance warning).
|
||||
#undef strdup // platform.h in CryCommon changes this define which is required by googletest
|
||||
#undef strdup // This define is required by googletest
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
AZ_POP_DISABLE_WARNING;
|
||||
@@ -477,8 +477,7 @@ int main(int argc, char** argv)
|
||||
} \
|
||||
} while (0); // safe multi-line macro - creates a single statement
|
||||
|
||||
// Avoid accidentally being managed by CryMemory, or problems with new/delete when
|
||||
// AZ allocators are not ready or properly un/initialized.
|
||||
// Avoid problems with new/delete when AZ allocators are not ready or properly un/initialized.
|
||||
#define AZ_TEST_CLASS_ALLOCATOR(Class_) \
|
||||
void* operator new (size_t size) \
|
||||
{ \
|
||||
|
||||
@@ -636,11 +636,18 @@ namespace AzToolsFramework
|
||||
|
||||
if (!EntitiesBelongToSameInstance(entityIds))
|
||||
{
|
||||
return AZ::Failure(AZStd::string("DeleteEntitiesAndAllDescendantsInInstance - Deletion Error. Cannot delete multiple "
|
||||
"entities belonging to different instances with one operation."));
|
||||
return AZ::Failure(AZStd::string("Cannot delete multiple entities belonging to different instances with one operation."));
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = GetOwnerInstanceByEntityId(entityIds[0]);
|
||||
AZ::EntityId firstEntityIdToDelete = entityIds[0];
|
||||
InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDelete);
|
||||
|
||||
// If the first entity id is a container entity id, then we need to mark its parent as the common owning instance because you
|
||||
// cannot delete an instance from itself.
|
||||
if (commonOwningInstance->get().GetContainerEntityId() == firstEntityIdToDelete)
|
||||
{
|
||||
commonOwningInstance = commonOwningInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
// Retrieve entityList from entityIds
|
||||
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
@@ -680,14 +687,14 @@ namespace AzToolsFramework
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "Internal::DeleteEntities:UndoCaptureAndPurgeEntities");
|
||||
|
||||
Prefab::PrefabDom instanceDomBefore;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBefore, instance->get());
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBefore, commonOwningInstance->get());
|
||||
|
||||
if (deleteDescendants)
|
||||
{
|
||||
AZStd::vector<AZ::Entity*> entities;
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
|
||||
|
||||
bool success = RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, instance->get(), entities, instances);
|
||||
bool success = RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonOwningInstance->get(), entities, instances);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
@@ -701,6 +708,7 @@ namespace AzToolsFramework
|
||||
|
||||
for (auto& nestedInstance : instances)
|
||||
{
|
||||
RemoveLink(nestedInstance, commonOwningInstance->get().GetTemplateId(), currentUndoBatch);
|
||||
nestedInstance.reset();
|
||||
}
|
||||
}
|
||||
@@ -712,22 +720,22 @@ namespace AzToolsFramework
|
||||
// If this is the container entity, it actually represents the instance so get its owner
|
||||
if (owningInstance->get().GetContainerEntityId() == entityId)
|
||||
{
|
||||
auto instancePtr = instance->get().DetachNestedInstance(owningInstance->get().GetInstanceAlias());
|
||||
instancePtr.reset();
|
||||
auto instancePtr = commonOwningInstance->get().DetachNestedInstance(owningInstance->get().GetInstanceAlias());
|
||||
RemoveLink(instancePtr, commonOwningInstance->get().GetTemplateId(), currentUndoBatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->get().DetachEntity(entityId);
|
||||
commonOwningInstance->get().DetachEntity(entityId);
|
||||
AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationRequests::DeleteEntity, entityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Prefab::PrefabDom instanceDomAfter;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, instance->get());
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, commonOwningInstance->get());
|
||||
|
||||
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance deletion");
|
||||
command->Capture(instanceDomBefore, instanceDomAfter, instance->get().GetTemplateId());
|
||||
command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId());
|
||||
command->SetParent(selCommand);
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -403,9 +403,12 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::EntityIdList selectedEntityIds;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
|
||||
selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
|
||||
|
||||
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationRequests::DeleteEntitiesAndAllDescendants, selectedEntityIds);
|
||||
PrefabOperationResult deleteSelectedResult =
|
||||
s_prefabPublicInterface->DeleteEntitiesAndAllDescendantsInInstance(selectedEntityIds);
|
||||
if (!deleteSelectedResult.IsSuccess())
|
||||
{
|
||||
WarnUserOfError("Delete selected entities error", deleteSelectedResult.GetError());
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabIntegrationManager::GenerateSuggestedFilenameFromEntities(const EntityIdList& entityIds, AZStd::string& outName)
|
||||
|
||||
Reference in New Issue
Block a user