Merge remote-tracking branch 'upstream/main' into nvsickle/EnableAtomViewport

This commit is contained in:
nvsickle
2021-04-14 10:47:18 -07:00
911 changed files with 9411 additions and 7169 deletions
@@ -111,7 +111,7 @@ namespace AZ
bool loadFileToMemory = Get().ShouldLoadFileToMemory(filename);
int assetMode = loadFileToMemory ? AASSET_MODE_BUFFER : AASSET_MODE_UNKNOWN;
asset = AAssetManager_open(Utils::GetAssetManager(), Utils::StripApkPrefix(filename), assetMode);
asset = AAssetManager_open(Utils::GetAssetManager(), Utils::StripApkPrefix(filename).c_str(), assetMode);
if (asset != nullptr)
{
@@ -192,7 +192,7 @@ namespace AZ
{
buf->m_offset = buf->m_totalSize - offset;
}
if (buf->m_offset > buf->m_totalSize)
{
buf->m_offset = buf->m_totalSize;
@@ -320,12 +320,19 @@ namespace AZ
bool APKFileHandler::DirectoryOrFileExists(const char* path)
{
ANDROID_IO_PROFILE_SECTION_ARGS("APK DirOrFileexists");
ANDROID_IO_PROFILE_SECTION_ARGS("APK DirOrFileExists");
AZ::IO::PathView insideApkPathView(Utils::StripApkPrefix(path));
AZ::IO::FixedMaxPath insideApkPath(Utils::StripApkPrefix(path));
AZ::IO::FixedMaxPathString filename{ insideApkPathView.Filename().Native() };
AZ::IO::FixedMaxPathString pathToFile{ insideApkPathView.ParentPath().Native() };
// Check for the case where the input path is equal to the APK Assets Prefix of /APK
// In that case the directory is the "root" of APK assets in which case the directory exist
if (insideApkPath.empty() && Utils::IsApkPath(path))
{
return true;
}
AZ::IO::FixedMaxPathString filename{ insideApkPath.Filename().Native() };
AZ::IO::FixedMaxPathString pathToFile{ insideApkPath.ParentPath().Native() };
bool foundFile = false;
ParseDirectory(pathToFile.c_str(), [&](const char* name)
+9 -14
View File
@@ -17,7 +17,7 @@
#include <AzCore/Debug/Trace.h>
#include <AzCore/Memory/OSAllocator.h>
#include <AzCore/IO/Path/Path.h>
namespace AZ
{
@@ -28,9 +28,9 @@ namespace AZ
namespace
{
////////////////////////////////////////////////////////////////
const char* GetApkAssetsPrefix()
constexpr const char* GetApkAssetsPrefix()
{
return "/APK/";
return "/APK";
}
}
@@ -104,19 +104,14 @@ namespace AZ
////////////////////////////////////////////////////////////////
bool IsApkPath(const char* filePath)
{
return (strncmp(filePath, GetApkAssetsPrefix(), 4) == 0); // +3 for "APK", +1 for '/' starting slash
return AZ::IO::PathView(filePath).IsRelativeTo(AZ::IO::PathView(GetApkAssetsPrefix()));
}
////////////////////////////////////////////////////////////////
const char* StripApkPrefix(const char* filePath)
AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath)
{
const int prefixLength = 5; // +3 for "APK", +2 for '/' on either end
if (!IsApkPath(filePath))
{
return filePath;
}
return filePath + prefixLength;
constexpr AZ::IO::PathView apkPrefixView = GetApkAssetsPrefix();
return AZ::IO::PathView(filePath).LexicallyProximate(apkPrefixView);
}
////////////////////////////////////////////////////////////////
@@ -130,7 +125,7 @@ namespace AZ
// first check to see if they are in public storage (application specific)
const char* publicAppStorage = GetAppPublicStoragePath();
OSString path = OSString::format("%s/bootstrap.cfg", publicAppStorage);
OSString path = OSString::format("%s/engine.json", publicAppStorage);
AZ_TracePrintf("Android::Utils", "Searching for %s\n", path.c_str());
FILE* f = fopen(path.c_str(), "r");
@@ -145,7 +140,7 @@ namespace AZ
AAssetManager* mgr = GetAssetManager();
if (mgr)
{
AAsset* asset = AAssetManager_open(mgr, "bootstrap.cfg", AASSET_MODE_UNKNOWN);
AAsset* asset = AAssetManager_open(mgr, "engine.json", AASSET_MODE_UNKNOWN);
if (asset)
{
AAsset_close(asset);
+3 -2
View File
@@ -11,6 +11,7 @@
*/
#pragma once
#include <AzCore/IO/Path/Path_fwd.h>
#include <AzCore/std/string/string.h>
#include <jni.h>
@@ -55,7 +56,7 @@ namespace AZ
const char* GetObbStoragePath();
//! Get the dot separated package name for the current application.
//! e.g. com.lumberyard.samples for SamplesProject
//! e.g. com.o3de.samples for SamplesProject
const char* GetPackageName();
//! Get the app version code (android:versionCode in the manifest).
@@ -70,7 +71,7 @@ namespace AZ
//! Will first check to verify the argument is an apk asset path and if so
//! will strip the prefix from the path.
//! \return The pointer position of the relative asset path
const char* StripApkPrefix(const char* filePath);
AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath);
//! Searches application storage and the APK for bootstrap.cfg. Will return nullptr
//! if bootstrap.cfg is not found.
@@ -10,7 +10,7 @@
*
*/
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Asset/AssetJsonSerializer.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/StackedString.h>
@@ -107,7 +107,8 @@ namespace AZ
result = ContinueLoading(&id, azrtti_typeid<AssetId>(), it->value, context);
if (!id.m_guid.IsNull())
{
*instance = Asset<AssetData>(id, instance->GetType());
*instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), AssetLoadBehavior::NoLoad);
result.Combine(context.Report(result, "Successfully created Asset<T> with id."));
}
@@ -12,7 +12,7 @@
/** @file
* Header file for the Component base class.
* In Lumberyard's component entity system, each component defines a discrete
* In Open 3D Engine's component entity system, each component defines a discrete
* feature that can be attached to an entity.
*/
@@ -76,7 +76,7 @@ namespace AZ
* practice to access other components through EBuses instead of accessing them directly.
* For more information, see the
* <a href="http://docs.aws.amazon.com/lumberyard/latest/developerguide/component-entity-system-pg-intro.html">Programmer's Guide to Entities and Components</a>
* in the Lumberyard Developer Guide.
* in the Open 3D Engine Developer Guide.
* @return A pointer to the entity. If the component is not attached to any entity,
* the return value is a null pointer.
*/
@@ -426,7 +426,7 @@ namespace AZ
/**
* Describes the properties of the component descriptor event bus.
* This bus uses AzTypeInfo::Uuid as the ID for the specific descriptor. Lumberyard allows only one
* This bus uses AzTypeInfo::Uuid as the ID for the specific descriptor. Open 3D Engine allows only one
* descriptor for each component type. When you call functions on the bus for a specific component
* type, you can safely pass only one result variable because aggregating or overwriting results
* is impossible.
@@ -27,7 +27,6 @@
#include <AzCore/Memory/OverrunDetectionAllocator.h>
#include <AzCore/Memory/AllocatorManager.h>
#include <AzCore/Memory/MallocSchema.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/ObjectStream.h>
@@ -174,6 +173,7 @@ namespace AZ
return true;
};
//! SettingsRegistry notifier handler which updates relevant registry settings based
//! on an update to '/Amazon/AzCore/Bootstrap/project_path' key.
struct UpdateProjectSettingsEventHandler
@@ -185,66 +185,57 @@ namespace AZ
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
{
UpdateProjectSpecializationInRegistry(path);
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
const auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
AZ::IO::FixedMaxPath newProjectPath;
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectPathKey, path)
&& m_registry.Get(newProjectPath.Native(), projectPathKey) && newProjectPath != m_oldProjectPath)
{
UpdateProjectSettingsFromProjectPath(AZ::IO::PathView(newProjectPath));
}
const auto projectNameKey = FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) + "/project_name";
FixedValueString newProjectName;
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectNameKey, path)
&& m_registry.Get(newProjectName, projectNameKey) && newProjectName != m_oldProjectName)
{
UpdateProjectSpecializationFromProjectName(newProjectName);
}
}
//! Add the project name as a specialization underneath the /Amazon/AzCore/Settings/Specializations path
//! and remove the current project name specialization if one exists.
void UpdateProjectSpecializationInRegistry(AZStd::string_view path)
void UpdateProjectSpecializationFromProjectName(AZStd::string_view newProjectName)
{
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
+ "/project_path";
if (path == projectPathKey)
{
AZ::SettingsRegistryInterface::FixedValueString newProjectPath;
if (m_registry.Get(newProjectPath, path) && !newProjectPath.empty())
{
// Make the path absolute by appending to app root, in case project path is relative.
// If the project path is already absolute it will remain the same.
// If we turn it from a relative path to an absolute path, write-back the absolute path to the registry.
AZ::IO::FixedMaxPath projectPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath;
if (projectPath.Compare(newProjectPath.c_str()))
{
m_registry.Set(path, projectPath.Native());
}
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
// Add the project_name as a specialization for loading the build system dependency .setreg files
auto newProjectNameSpecialization = FixedValueString::format("%s/%.*s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey,
aznumeric_cast<int>(newProjectName.size()), newProjectName.data());
auto oldProjectNameSpecialization = FixedValueString::format("%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey,
m_oldProjectName.c_str());
m_registry.Remove(oldProjectNameSpecialization);
m_oldProjectName = newProjectName;
m_registry.Set(newProjectNameSpecialization, true);
}
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
AZ::IO::FixedMaxPath projectMetadataFile{ projectPath };
projectMetadataFile /= "project.json";
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
void UpdateProjectSettingsFromProjectPath(AZ::IO::PathView newProjectPath)
{
// Update old Project path before attempting to merge in new Settings Registry values in order to prevent recursive calls
m_oldProjectPath = newProjectPath;
// Get the 'project_name' value from what was in the 'project.json' file...
auto projectNameKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
+ "/project_name";
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
AZ::IO::FixedMaxPath projectMetadataFile{ AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath };
projectMetadataFile /= "project.json";
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString projectSpecialization;
if (m_registry.Get(projectSpecialization, projectNameKey))
{
auto specializationKey = AZ::SettingsRegistryInterface::FixedValueString::format(
"%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey, projectSpecialization.c_str());
if (m_currentSpecialization != specializationKey)
{
m_registry.Set(specializationKey, true);
if (!m_currentSpecialization.empty())
{
// Remove the previous Project Name from the specialization path if it was set.
m_registry.Remove(m_currentSpecialization);
}
m_currentSpecialization = specializationKey;
// Update all the runtime file paths based on the new "project_path" value.
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
}
}
}
// Update all the runtime file paths based on the new "project_path" value.
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
private:
AZ::SettingsRegistryInterface::FixedValueString m_currentSpecialization;
AZ::IO::FixedMaxPath m_oldProjectPath;
AZ::SettingsRegistryInterface::FixedValueString m_oldProjectName;
AZ::SettingsRegistryInterface& m_registry;
};
@@ -424,7 +415,7 @@ namespace AZ
// Add the Command Line arguments into the SettingsRegistry
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
// Merge Command Line arguments
// Merge Command Line arguments
constexpr bool executeRegDumpCommands = false;
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
@@ -1395,10 +1386,7 @@ namespace AZ
//=========================================================================
void ComponentApplication::CalculateExecutablePath()
{
Utils::GetExecutableDirectory(m_exeDirectory.data(), m_exeDirectory.capacity());
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string stored within it
m_exeDirectory.resize_no_construct(AZStd::char_traits<char>::length(m_exeDirectory.data()));
m_exeDirectory.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
m_exeDirectory = Utils::GetExecutableDirectory();
}
void ComponentApplication::CalculateAppRoot()
@@ -1406,19 +1394,12 @@ namespace AZ
if (AZStd::optional<AZ::StringFunc::Path::FixedString> appRootPath = Utils::GetDefaultAppRootPath(); appRootPath)
{
m_appRoot = AZStd::move(*appRootPath);
if (!m_appRoot.empty() && !m_appRoot.ends_with(AZ_CORRECT_FILESYSTEM_SEPARATOR))
{
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
}
}
}
void ComponentApplication::CalculateEngineRoot()
{
if (m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native(); !m_engineRoot.empty())
{
m_engineRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
}
m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native();
}
void ComponentApplication::ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath)
@@ -21,6 +21,7 @@
#include <AzCore/Module/DynamicModuleHandle.h>
#include <AzCore/Module/ModuleManager.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/ReflectionManager.h>
@@ -392,9 +393,9 @@ namespace AZ
void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy.
IAllocatorAllocate* m_osAllocator{ nullptr };
EntitySetType m_entities;
AZ::IO::FixedMaxPathString m_exeDirectory;
AZ::IO::FixedMaxPathString m_engineRoot;
AZ::IO::FixedMaxPathString m_appRoot;
AZ::IO::FixedMaxPath m_exeDirectory;
AZ::IO::FixedMaxPath m_engineRoot;
AZ::IO::FixedMaxPath m_appRoot;
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectChangedHandler;
@@ -12,7 +12,7 @@
/** @file
* Header file for the Entity class.
* In Lumberyard's component entity system, an entity is an addressable container for
* In Open 3D Engine's component entity system, an entity is an addressable container for
* a group of components. The entity represents the functionality and properties of an
* object within your game.
*/
+1 -1
View File
@@ -15,7 +15,7 @@
* Header file for internal EBus classes.
* For more information about EBuses, see AZ::EBus and AZ::EBusTraits in this guide and
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*/
#pragma once
+5 -5
View File
@@ -13,11 +13,11 @@
/**
* @file
* Header file for event bus (EBus), a general-purpose communication system
* that Lumberyard uses to dispatch notifications and receive requests.
* that Open 3D Engine uses to dispatch notifications and receive requests.
* EBuses are configurable and support many different use cases.
* For more information about %EBuses, see AZ::EBus in this guide and
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*/
#pragma once
@@ -70,7 +70,7 @@ namespace AZ
*
* For more information about %EBuses, see EBus in this guide and
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*/
struct EBusTraits
{
@@ -256,7 +256,7 @@ namespace AZ
/**
* Event buses (EBuses) are a general-purpose communication system
* that Lumberyard uses to dispatch notifications and receive requests.
* that Open 3D Engine uses to dispatch notifications and receive requests.
*
* @tparam Interface A class whose virtual functions define the events
* dispatched or received by the %EBus.
@@ -268,7 +268,7 @@ namespace AZ
* For more information about EBuses, see
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* and [Components and EBuses: Best Practices ](http://docs.aws.amazon.com/lumberyard/latest/developerguide/component-entity-system-pg-components-ebuses-best-practices.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*
* ## How Components Use EBuses
* Components commonly use EBuses in two ways: to dispatch events or to handle requests.
+11 -11
View File
@@ -96,8 +96,8 @@ namespace AZ::IO
constexpr int Compare(const value_type* pathString) const noexcept;
// decomposition
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
//! "/lumberyard/foo/bar/name.txt"
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
//! "/O3DE/foo/bar/name.txt"
//! The following functions return the following
//! Returns the root name part of the path. if it has one.
@@ -114,10 +114,10 @@ namespace AZ::IO
constexpr PathView RootPath() const;
//! Returns the relative path portion of the path.
//! This contains the path parts after the root path
//! windows = "lumberyard\foo\bar\name.txt", posix = "lumberyard/foo/bar/name.txt"
//! windows = "O3DE\foo\bar\name.txt", posix = "O3DE/foo/bar/name.txt"
constexpr PathView RelativePath() const;
//! Returns the parent directory of filename contained within the path
//! windows = "C:\lumberyard\foo\bar", posix = "/lumberyard/foo/bar"
//! windows = "C:\O3DE\foo\bar", posix = "/O3DE/foo/bar"
//! NOTE: If the path ends with a trailing separator "test/foo/" it is treated as being a path of
//! "test/foo" as if the filename of the path is "foo" and the parent directory is "test"
constexpr PathView ParentPath() const;
@@ -150,7 +150,7 @@ namespace AZ::IO
//! The root portion of the path is made up of root_name() / root_directory()
[[nodiscard]] constexpr bool HasRootPath() const;
//! checks whether the relative part of path is empty
//! (C:\\ lumberyard\dev\)
//! (C:\\ O3DE\dev\)
//! ^ ^
//! root part relative part
[[nodiscard]] constexpr bool HasRelativePath() const;
@@ -485,10 +485,10 @@ namespace AZ::IO
constexpr PathView RootPath() const;
//! Returns the relative path portion of the path.
//! This contains the path parts after the root path
//! windows = "lumberyard\foo\bar\name.txt", posix = "lumberyard/foo/bar/name.txt"
//! windows = "O3DE\foo\bar\name.txt", posix = "O3DE/foo/bar/name.txt"
constexpr PathView RelativePath() const;
//! Returns the parent directory of filename contained within the path
//! windows = "C:\lumberyard\foo\bar", posix = "/lumberyard/foo/bar"
//! windows = "C:\O3DE\foo\bar", posix = "/O3DE/foo/bar"
//! NOTE: If the path ends with a trailing separator "test/foo/" it is treated as being a path of
//! "test/foo" as if the filename of the path is "foo" and the parent directory is "test"
constexpr PathView ParentPath() const;
@@ -521,8 +521,8 @@ namespace AZ::IO
//! The root portion of the path is made up of root_name() / root_directory()
[[nodiscard]] constexpr bool HasRootPath() const;
//! checks whether the relative part of path is empty
//! (C:\\ lumberyard\dev\)
//! ^ ^
//! (C:\\ O3DE\dev\)
//! ^ ^
//! root part relative part
[[nodiscard]] constexpr bool HasRelativePath() const;
//! checks whether the path has a parent path that empty
@@ -544,8 +544,8 @@ namespace AZ::IO
[[nodiscard]] constexpr bool IsRelativeTo(const PathView& base) const;
// decomposition
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
//! "/lumberyard/foo/bar/name.txt"
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
//! "/O3DE/foo/bar/name.txt"
//! The following functions return the following
// query
@@ -147,15 +147,18 @@ namespace AZ
ReadFile(request, args);
return;
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -146,15 +146,18 @@ namespace AZ
DestroyDedicatedCache(request, args);
return;
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -97,19 +97,22 @@ namespace AZ
CancelRequest(request, args.m_target);
return;
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
{
Report(args);
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
{
Report(args);
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -374,7 +374,7 @@ namespace AZ
targetForward.Normalize();
// Lumberyard is Z-up and is right-handed.
// Open 3D Engine is Z-up and is right-handed.
Vector3 up = Vector3::CreateAxisZ();
// We have a degenerate case if target forward is parallel to the up axis,
@@ -391,7 +391,7 @@ namespace AZ
up.Normalize();
// Passing in forwardAxis allows you to force a particular local-space axis to look
// at the target point. In Lumberyard, the default is forward is along Y+.
// at the target point. In Open 3D Engine, the default is forward is along Y+.
switch (forwardAxis)
{
case Axis::XPositive:
@@ -426,7 +426,7 @@ namespace AZ
Matrix4x4 Matrix4x4::CreateProjection(float fovY, float aspectRatio, float nearDist, float farDist)
{
// This section contains some notes about camera matrices and field of view, because there are some subtle differences
// between the convention Lumberyard uses and what you might be used to from other software packages.
// between the convention Open 3D Engine uses and what you might be used to from other software packages.
// Our camera space has the camera looking down the *positive* z-axis, the x-axis points towards the left of the screen,
// and the y-axis points towards the top of the screen.
//
+1 -1
View File
@@ -154,7 +154,7 @@ namespace AZ
return Obb::CreateFromPositionRotationAndHalfLengths(
transform.TransformPoint(obb.GetPosition()),
transform.GetRotation() * obb.GetRotation(),
obb.GetHalfLengths()
transform.GetScale() * obb.GetHalfLengths()
);
}
}
@@ -354,7 +354,7 @@ namespace AZ
targetForward.Normalize();
// Lumberyard is Z-up and is right-handed.
// Open 3D Engine is Z-up and is right-handed.
Vector3 up = Vector3::CreateAxisZ();
// We have a degenerate case if target forward is parallel to the up axis,
@@ -371,7 +371,7 @@ namespace AZ
up.Normalize();
// Passing in forwardAxis allows you to force a particular local-space axis to look
// at the target point. In Lumberyard, the default is forward is along Y+.
// at the target point. In Open 3D Engine, the default is forward is along Y+.
switch (forwardAxis)
{
case Axis::XPositive:
@@ -707,7 +707,7 @@ PoolSchema::GarbageCollect()
// occur exclusively in the destruction of the allocator.
//
// TODO: A better solution needs to be found for integrating back into mainline
// Lumberyard.
// Open 3D Engine.
//m_impl->GarbageCollect();
}
@@ -1600,7 +1600,7 @@ static int Global_Typeid(lua_State* l)
return 1;
}
#ifdef LUA_LUMBERYARD_EXTENSIONS
#ifdef LUA_O3DE_EXTENSIONS
//=========================================================================
// LUA Dummy Node Extension
@@ -1631,7 +1631,7 @@ LUA_API const Node* lua_getDummyNode()
return &(*s_luaDummyNodeVariable);
}
#endif // LUA_LUMBERYARD_EXTENSIONS
#endif // LUA_O3DE_EXTENSIONS
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -103,7 +103,7 @@ namespace AZ
const static AZ::Crc32 ChangeNotify = AZ_CRC("ChangeNotify", 0xf793bc19);
const static AZ::Crc32 ClearNotify = AZ_CRC("ClearNotify", 0x88914c8c);
//! Specifies a function to accept or reject a value changed in the Lumberyard Editor.
//! Specifies a function to accept or reject a value changed in the Open 3D Engine Editor.
//! For example, a component could reject AZ::EntityId values that reference its own entity.
//!
//! Element type to use this with: Any type that you reflect using AZ::EditContext::ClassInfo::DataElement().
@@ -22,9 +22,9 @@ namespace AZ
// JsonBaseContext
//
JsonBaseContext::JsonBaseContext(JsonSerializationMetadata metadata, JsonSerializationResult::JsonIssueCallback reporting,
JsonBaseContext::JsonBaseContext(JsonSerializationMetadata& metadata, JsonSerializationResult::JsonIssueCallback reporting,
StackedString::Format pathFormat, SerializeContext* serializeContext, JsonRegistrationContext* registrationContext)
: m_metadata(AZStd::move(metadata))
: m_metadata(metadata)
, m_serializeContext(serializeContext)
, m_registrationContext(registrationContext)
, m_path(pathFormat)
@@ -126,20 +126,13 @@ namespace AZ
// JsonDeserializerContext
//
JsonDeserializerContext::JsonDeserializerContext(const JsonDeserializerSettings& settings)
JsonDeserializerContext::JsonDeserializerContext(JsonDeserializerSettings& settings)
: JsonBaseContext(settings.m_metadata, settings.m_reporting,
StackedString::Format::JsonPointer, settings.m_serializeContext, settings.m_registrationContext)
, m_clearContainers(settings.m_clearContainers)
{
}
JsonDeserializerContext::JsonDeserializerContext(JsonDeserializerSettings&& settings)
: JsonBaseContext(AZStd::move(settings.m_metadata), AZStd::move(settings.m_reporting),
StackedString::Format::JsonPointer, settings.m_serializeContext, settings.m_registrationContext)
, m_clearContainers(settings.m_clearContainers)
{
}
bool JsonDeserializerContext::ShouldClearContainers() const
{
return m_clearContainers;
@@ -151,7 +144,7 @@ namespace AZ
// JsonSerializerContext
//
JsonSerializerContext::JsonSerializerContext(const JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator)
JsonSerializerContext::JsonSerializerContext(JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator)
: JsonBaseContext(settings.m_metadata, settings.m_reporting, StackedString::Format::ContextPath,
settings.m_serializeContext, settings.m_registrationContext)
, m_jsonAllocator(jsonAllocator)
@@ -159,14 +152,6 @@ namespace AZ
{
}
JsonSerializerContext::JsonSerializerContext(JsonSerializerSettings&& settings, rapidjson::Document::AllocatorType& jsonAllocator)
: JsonBaseContext(AZStd::move(settings.m_metadata), AZStd::move(settings.m_reporting), StackedString::Format::ContextPath,
settings.m_serializeContext, settings.m_registrationContext)
, m_jsonAllocator(jsonAllocator)
, m_keepDefaults(settings.m_keepDefaults)
{
}
rapidjson::Document::AllocatorType& JsonSerializerContext::GetJsonAllocator()
{
return m_jsonAllocator;
@@ -26,7 +26,7 @@ namespace AZ
class JsonBaseContext
{
public:
JsonBaseContext(JsonSerializationMetadata metadata, JsonSerializationResult::JsonIssueCallback reporting,
JsonBaseContext(JsonSerializationMetadata& metadata, JsonSerializationResult::JsonIssueCallback reporting,
StackedString::Format pathFormat, SerializeContext* serializeContext, JsonRegistrationContext* registrationContext);
virtual ~JsonBaseContext() = default;
@@ -71,10 +71,6 @@ namespace AZ
const JsonRegistrationContext* GetRegistrationContext() const;
protected:
//! Metadata that's passed in by the settings as additional configuration options or metadata that's collected
//! during processing for later use.
JsonSerializationMetadata m_metadata;
//! Callback used to report progress and issues. Users of the serialization can update the return code to change
//! the behavior of the serializer.
AZStd::stack<JsonSerializationResult::JsonIssueCallback> m_reporters;
@@ -82,6 +78,10 @@ namespace AZ
//! Path to the element that's currently being operated on.
StackedString m_path;
//! Metadata that's passed in by the settings as additional configuration options or metadata that's collected
//! during processing for later use.
JsonSerializationMetadata& m_metadata;
//! The Serialize Context that can be used to retrieve meta data during processing.
SerializeContext* m_serializeContext = nullptr;
//! The registration context for the json serialization. This can be used to retrieve the handlers for specific types.
@@ -92,8 +92,7 @@ namespace AZ
: public JsonBaseContext
{
public:
explicit JsonDeserializerContext(const JsonDeserializerSettings& settings);
explicit JsonDeserializerContext(JsonDeserializerSettings&& settings);
explicit JsonDeserializerContext(JsonDeserializerSettings& settings);
~JsonDeserializerContext() override = default;
JsonDeserializerContext(const JsonDeserializerContext&) = delete;
@@ -114,8 +113,7 @@ namespace AZ
: public JsonBaseContext
{
public:
explicit JsonSerializerContext(const JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator);
explicit JsonSerializerContext(JsonSerializerSettings&& settings, rapidjson::Document::AllocatorType& jsonAllocator);
JsonSerializerContext(JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator);
~JsonSerializerContext() override = default;
JsonSerializerContext(const JsonSerializerContext&) = delete;
@@ -20,7 +20,7 @@ namespace AZ
{
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings)
JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -122,7 +122,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreatePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, JsonCreatePatchSettings& settings)
{
StackedString element(StackedString::Format::JsonPointer);
return CreatePatchInternal(patch.SetArray(), allocator, source, target, element, settings);
@@ -130,7 +130,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyMergePatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings)
JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -196,14 +196,14 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreateMergePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, JsonCreatePatchSettings& settings)
{
StackedString element(StackedString::Format::JsonPointer);
return CreateMergePatchInternal(patch, allocator, source, target, element, settings);
}
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_GetFromValue(rapidjson::Value** fromValue, rapidjson::Pointer& fromPointer,
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, const JsonApplyPatchSettings& settings)
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -242,7 +242,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Add(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -261,7 +261,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_AddValue(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Pointer& path, rapidjson::Value&& newValue,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -347,7 +347,7 @@ namespace AZ
}
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Remove(rapidjson::Value& target, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -399,7 +399,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Replace(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -426,7 +426,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Move(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -445,7 +445,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Copy(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -463,7 +463,7 @@ namespace AZ
}
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Test(rapidjson::Value& target, const rapidjson::Value& entry,
const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings)
const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -495,7 +495,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreatePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -633,7 +633,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreateMergePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -30,43 +30,43 @@ namespace AZ
//! Implementation of the JSON Patch algorithm: https://tools.ietf.org/html/rfc6902
static JsonSerializationResult::ResultCode ApplyPatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings);
JsonApplyPatchSettings& settings);
//! Function to create JSON Patches: https://tools.ietf.org/html/rfc6902
static JsonSerializationResult::ResultCode CreatePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, JsonCreatePatchSettings& settings);
//! Implementation of the JSON Merge Patch algorithm: https://tools.ietf.org/html/rfc7386
static JsonSerializationResult::ResultCode ApplyMergePatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings);
JsonApplyPatchSettings& settings);
//! Function to create JSON Merge Patches: https://tools.ietf.org/html/rfc7386
static JsonSerializationResult::ResultCode CreateMergePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, JsonCreatePatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_GetFromValue(rapidjson::Value** fromValue, rapidjson::Pointer& fromPointer,
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, const JsonApplyPatchSettings& settings);
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Add(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_AddValue(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Pointer& path, rapidjson::Value&& newValue, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Pointer& path, rapidjson::Value&& newValue, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Remove(rapidjson::Value& target, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings);
StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Replace(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Move(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Copy(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Test(rapidjson::Value& target,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode CreatePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings);
static rapidjson::Value CreatePatchInternal_Add(rapidjson::Document::AllocatorType& allocator,
StackedString& path, const rapidjson::Value& value);
static rapidjson::Value CreatePatchInternal_Remove(rapidjson::Document::AllocatorType& allocator, StackedString& path);
@@ -75,6 +75,6 @@ namespace AZ
static JsonSerializationResult::ResultCode CreateMergePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings);
};
} // namespace AZ
@@ -97,9 +97,18 @@ namespace AZ
}
} // namespace JsonSerializationInternal
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(
rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonMergeApproach approach,
const JsonApplyPatchSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonApplyPatchSettings settingsCopy{ settings };
return ApplyPatch(target, allocator, patch, approach, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonMergeApproach approach,
JsonApplyPatchSettings settings)
JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -126,8 +135,17 @@ namespace AZ
}
}
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& patch, JsonMergeApproach approach, const JsonApplyPatchSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonApplyPatchSettings settingsCopy{settings};
return ApplyPatch(output, allocator, source, patch, approach, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings settings)
const rapidjson::Value& source, const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -166,9 +184,18 @@ namespace AZ
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::CreatePatch(
rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, JsonMergeApproach approach, const JsonCreatePatchSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonCreatePatchSettings settingsCopy{settings};
return CreatePatch(patch, allocator, source, target, approach, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::CreatePatch(rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& target, JsonMergeApproach approach, JsonCreatePatchSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::CreatePatch(
rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, JsonMergeApproach approach, JsonCreatePatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -194,7 +221,16 @@ namespace AZ
}
}
JsonSerializationResult::ResultCode JsonSerialization::Load(void* object, const Uuid& objectType, const rapidjson::Value& root, JsonDeserializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Load(
void* object, const Uuid& objectType, const rapidjson::Value& root, const JsonDeserializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonDeserializerSettings settingsCopy{settings};
return Load(object, objectType, root, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::Load(
void* object, const Uuid& objectType, const rapidjson::Value& root, JsonDeserializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -212,14 +248,23 @@ namespace AZ
if (result.GetOutcome() == Outcomes::Success)
{
StackedString path(StackedString::Format::JsonPointer);
JsonDeserializerContext context(AZStd::move(settings));
JsonDeserializerContext context(settings);
result = JsonDeserializer::Load(object, objectType, root, context);
}
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::LoadTypeId(
Uuid& typeId, const rapidjson::Value& input, const Uuid* baseClassTypeId, AZStd::string_view jsonPath,
const JsonDeserializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonDeserializerSettings settingsCopy{settings};
return LoadTypeId(typeId, input, baseClassTypeId, jsonPath, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::LoadTypeId(Uuid& typeId, const rapidjson::Value& input,
const Uuid* baseClassTypeId, AZStd::string_view jsonPath, JsonDeserializerSettings settings)
const Uuid* baseClassTypeId, AZStd::string_view jsonPath, JsonDeserializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -236,7 +281,7 @@ namespace AZ
ResultCode result = JsonSerializationInternal::GetContexts(settings, settings.m_serializeContext, settings.m_registrationContext);
if (result.GetOutcome() == Outcomes::Success)
{
JsonDeserializerContext context(AZStd::move(settings));
JsonDeserializerContext context(settings);
context.PushPath(jsonPath);
result = JsonDeserializer::LoadTypeId(typeId, input, context, baseClassTypeId);
@@ -244,8 +289,18 @@ namespace AZ
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const void* object, const void* defaultObject, const Uuid& objectType, JsonSerializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, const JsonSerializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonSerializerSettings settingsCopy{settings};
return Store(output, allocator, object, defaultObject, objectType, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, JsonSerializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -269,15 +324,24 @@ namespace AZ
settings.m_keepDefaults = false;
}
JsonSerializerContext context(AZStd::move(settings), allocator);
JsonSerializerContext context(settings, allocator);
StackedString path(StackedString::Format::ContextPath);
result = JsonSerializer::Store(output, object, defaultObject, objectType, context);
}
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::StoreTypeId(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const Uuid& typeId, AZStd::string_view elementPath,
const JsonSerializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonSerializerSettings settingsCopy{settings};
return StoreTypeId(output, allocator, typeId, elementPath, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::StoreTypeId(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const Uuid& typeId, AZStd::string_view elementPath, JsonSerializerSettings settings)
const Uuid& typeId, AZStd::string_view elementPath, JsonSerializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -294,7 +358,7 @@ namespace AZ
ResultCode result = JsonSerializationInternal::GetContexts(settings, settings.m_serializeContext, settings.m_registrationContext);
if (result.GetOutcome() == Outcomes::Success)
{
JsonSerializerContext context(AZStd::move(settings), allocator);
JsonSerializerContext context(settings, allocator);
context.PushPath(elementPath);
result = JsonSerializer::StoreTypeName(output, typeId, context);
}
@@ -48,14 +48,25 @@ namespace AZ
//! Merges two json values together by applying "patch" to "target" using the selected merge algorithm.
//! This version of ApplyPatch is destructive to "target". If the patch can't be correctly applied it will
//! leave target in a partially patched state. Use the over version of ApplyPatch if target should be copied.
//! leave target in a partially patched state. Use the other version of ApplyPatch if target should be copied.
//! @param target The value where the patch will be applied to.
//! @param allocator The allocator associated with the document that holds the target.
//! @param patch The value holding the patch information.
//! @param approach The merge algorithm that will be used to apply the patch on top of the target.
//! @param settings Optional additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings settings = JsonApplyPatchSettings{});
const rapidjson::Value& patch, JsonMergeApproach approach, const JsonApplyPatchSettings& settings = JsonApplyPatchSettings{});
//! Merges two json values together by applying "patch" to "target" using the selected merge algorithm.
//! This version of ApplyPatch is destructive to "target". If the patch can't be correctly applied it will
//! leave target in a partially patched state. Use the other version of ApplyPatch if target should be copied.
//! @param target The value where the patch will be applied to.
//! @param allocator The allocator associated with the document that holds the target.
//! @param patch The value holding the patch information.
//! @param approach The merge algorithm that will be used to apply the patch on top of the target.
//! @param settings Additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(
rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
JsonMergeApproach approach, JsonApplyPatchSettings& settings);
//! Merges two json values together by applying "patch" to a copy of "output" and written to output using the
//! selected merge algorithm. This version of ApplyPatch is non-destructive to "source". If the patch couldn't be
@@ -68,7 +79,19 @@ namespace AZ
//! @param settings Optional additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& patch, JsonMergeApproach approach,
JsonApplyPatchSettings settings = JsonApplyPatchSettings{});
const JsonApplyPatchSettings& settings = JsonApplyPatchSettings{});
//! Merges two json values together by applying "patch" to a copy of "output" and written to output using the
//! selected merge algorithm. This version of ApplyPatch is non-destructive to "source". If the patch couldn't be
//! fully applied "output" will be left set to an empty (default) object.
//! @param source A copy of source with the patch applied to it or an empty object if the patch couldn't be applied.
//! @param allocator The allocator associated with the document that holds the source.
//! @param target The value where the patch will be applied to.
//! @param patch The value holding the patch information.
//! @param approach The merge algorithm that will be used to apply the patch on top of the target.
//! @param settings Additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings& settings);
//! Creates a patch using the selected merge algorithm such that when applied to source it results in target.
//! @param patch The value containing the differences between source and target.
@@ -79,22 +102,46 @@ namespace AZ
//! @param settings Optional additional settings to control the way the patch is created.
static JsonSerializationResult::ResultCode CreatePatch(rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& target, JsonMergeApproach approach,
JsonCreatePatchSettings settings = JsonCreatePatchSettings{});
const JsonCreatePatchSettings& settings = JsonCreatePatchSettings{});
//! Creates a patch using the selected merge algorithm such that when applied to source it results in target.
//! @param patch The value containing the differences between source and target.
//! @param allocator The allocator associated with the document that will hold the patch.
//! @param source The value used as a starting point.
//! @param target The value that will result if the patch is applied to the source.
//! @param approach The algorithm that will be used when the patch is applied to the source.
//! @param settings Additional settings to control the way the patch is created.
static JsonSerializationResult::ResultCode CreatePatch(
rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, JsonMergeApproach approach, JsonCreatePatchSettings& settings);
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Object where the data will be loaded into.
//! @param root The Value or Document where the deserializer will start reading data from.
//! @param settings The settings used during deserialization. Use the value passed in from Load.
//! @param settings Optional additional settings to control the way document is deserialized.
template<typename T>
static JsonSerializationResult::ResultCode Load(T& object, const rapidjson::Value& root,
JsonDeserializerSettings settings = JsonDeserializerSettings{});
static JsonSerializationResult::ResultCode Load(
T& object, const rapidjson::Value& root, const JsonDeserializerSettings& settings = JsonDeserializerSettings{});
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Object where the data will be loaded into.
//! @param root The Value or Document where the deserializer will start reading data from.
//! @param settings Additional settings to control the way document is deserialized.
template<typename T>
static JsonSerializationResult::ResultCode Load(T& object, const rapidjson::Value& root, JsonDeserializerSettings& settings);
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Pointer to the object where the data will be loaded into.
//! @param objectType Type id of the object passed in.
//! @param root The Value or Document from where the deserializer will start reading data.
//! @param settings The settings used during deserialization. Use the value passed in from Load.
static JsonSerializationResult::ResultCode Load(void* object, const Uuid& objectType, const rapidjson::Value& root,
JsonDeserializerSettings settings = JsonDeserializerSettings{});
//! @param settings Optional additional settings to control the way document is deserialized.
static JsonSerializationResult::ResultCode Load(
void* object, const Uuid& objectType, const rapidjson::Value& root,
const JsonDeserializerSettings& settings = JsonDeserializerSettings{});
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Pointer to the object where the data will be loaded into.
//! @param objectType Type id of the object passed in.
//! @param root The Value or Document from where the deserializer will start reading data.
//! @param settings Additional settings to control the way document is deserialized.
static JsonSerializationResult::ResultCode Load(
void* object, const Uuid& objectType, const rapidjson::Value& root, JsonDeserializerSettings& settings);
//! Loads the type id from the provided input.
//! Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of the internal
@@ -105,20 +152,44 @@ namespace AZ
//! references multiple types then the baseClassTypeId will be used to disambiguate between the different types by looking
//! if exactly one of the types inherits from the base class that baseClassTypeId points to.
//! @param jsonPath An optional path to the json node. This will be used for reporting.
//! @param settings An optional settings object to change where this function collects information from. This can be same settings
//! @param settings Optional settings object to change where this function collects information from. This can be same settings
//! as used for the other Load functions.
static JsonSerializationResult::ResultCode LoadTypeId(Uuid& typeId, const rapidjson::Value& input,
const Uuid* baseClassTypeId = nullptr, AZStd::string_view jsonPath = AZStd::string_view{},
JsonDeserializerSettings settings = JsonDeserializerSettings{});
const JsonDeserializerSettings& settings = JsonDeserializerSettings{});
//! Loads the type id from the provided input.
//! Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of the
//! internal type structure and is therefore harder to use.
//! @param typeId The uuid where the loaded data will be written to. If loading fails this will be a null uuid.
//! @param input The json node to load from. The node is expected to contain a string.
//! @param baseClassTypeId. An optional type id for the base class, if known. If a type name is stored in the string which
//! references multiple types then the baseClassTypeId will be used to disambiguate between the different types by looking
//! if exactly one of the types inherits from the base class that baseClassTypeId points to.
//! @param jsonPath An optional path to the json node. This will be used for reporting.
//! @param settings Settings object to change where this function collects information from. This can be same settings
//! as used for the other Load functions.
static JsonSerializationResult::ResultCode LoadTypeId(
Uuid& typeId, const rapidjson::Value& input, const Uuid* baseClassTypeId,
AZStd::string_view jsonPath, JsonDeserializerSettings& settings);
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object The object that will be read from for values to convert.
//! @param settings The settings used during serialization. Use the value passed in from Store.
//! @param settings Optional additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, JsonSerializerSettings settings = JsonSerializerSettings{});
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object,
const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object The object that will be read from for values to convert.
//! @param settings Additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object,
JsonSerializerSettings& settings);
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
@@ -127,10 +198,23 @@ namespace AZ
//! @param defaultObject Default object used to compare the object to in order to determine if values are
//! defaulted or not. If this is argument is provided m_keepDefaults in the settings will automatically
//! be set to true.
//! @param settings The settings used during serialization. Use the value passed in from Store.
//! @param settings Optional additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, const T& defaultObject, JsonSerializerSettings settings = JsonSerializerSettings{});
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const T& defaultObject,
const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object The object that will be read from for values to convert.
//! @param defaultObject Default object used to compare the object to in order to determine if values are
//! defaulted or not. If this is argument is provided m_keepDefaults in the settings will automatically
//! be set to true.
//! @param settings Additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const T& defaultObject,
JsonSerializerSettings& settings);
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
@@ -140,10 +224,22 @@ namespace AZ
//! defaulted or not. This argument can be null, in which case a temporary default may be created if required by
//! the settings. If this is argument is provided m_keepDefaults in the settings will automatically be set to true.
//! @param objectType The type id of the object and default object.
//! @param settings The settings used during serialization. Use the value passed in from Store.
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const void* object, const void* defaultObject, const Uuid& objectType,
JsonSerializerSettings settings = JsonSerializerSettings{});
//! @param settings Optional additional settings to control the way document is serialized.
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object Pointer to the object that will be read from for values to convert.
//! @param defaultObject Pointer to a default object used to compare the object to in order to determine if values are
//! defaulted or not. This argument can be null, in which case a temporary default may be created if required by
//! the settings. If this is argument is provided m_keepDefaults in the settings will automatically be set to true.
//! @param objectType The type id of the object and default object.
//! @param settings Additional settings to control the way document is serialized.
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, JsonSerializerSettings& settings);
//! Stores a name for the type id in the provided output. The name can be safely used to reference a type such as a class during loading.
//! Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of the internal
@@ -152,10 +248,25 @@ namespace AZ
//! @param allocator The allocator associated with the document that will or already holds the output.
//! @param typeId The type id to store.
//! @param elementPath An optional path to the element. This will be used for reporting.
//! @param settings An optional settings object to change where this function collects information from. This can be same settings
//! @param settings Optional settings to change where this function collects information from. This can be the same settings
//! as used for the other Store functions.
static JsonSerializationResult::ResultCode StoreTypeId(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const Uuid& typeId, AZStd::string_view elementPath = AZStd::string_view{}, JsonSerializerSettings settings = JsonSerializerSettings{});
static JsonSerializationResult::ResultCode StoreTypeId(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const Uuid& typeId,
AZStd::string_view elementPath = AZStd::string_view{}, const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores a name for the type id in the provided output. The name can be safely used to reference a type such as a class during
//! loading. Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of
//! the internal
//! type structure and is therefore harder to use.
//! @param output The json value the result will be written to. If successful this will contain a string object otherwise a default
//! object.
//! @param allocator The allocator associated with the document that will or already holds the output.
//! @param typeId The type id to store.
//! @param elementPath The path to the element. This will be used for reporting.
//! @param settings Settings to change where this function collects information from. This can be the same settings
//! as used for the other Store functions.
static JsonSerializationResult::ResultCode StoreTypeId(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const Uuid& typeId,
AZStd::string_view elementPath, JsonSerializerSettings& settings);
//! Compares two json values of any type and determines if the left is less, equal or greater than the right.
//! @param lhs The left hand side value for the compare.
@@ -180,22 +291,43 @@ namespace AZ
};
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Load(T& object, const rapidjson::Value& root, JsonDeserializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Load(T& object, const rapidjson::Value& root, const JsonDeserializerSettings& settings)
{
return Load(&object, azrtti_typeid(object), root, settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, JsonSerializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Load(T& object, const rapidjson::Value& root, JsonDeserializerSettings& settings)
{
return Load(&object, azrtti_typeid(object), root, settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const JsonSerializerSettings& settings)
{
return Store(output, allocator, &object, nullptr, azrtti_typeid(object), settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, JsonSerializerSettings& settings)
{
return Store(output, allocator, &object, nullptr, azrtti_typeid(object), settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, const T& defaultObject, JsonSerializerSettings settings)
const T& object, const T& defaultObject, const JsonSerializerSettings& settings)
{
return Store(output, allocator, &object,& defaultObject, azrtti_typeid(object), settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const T& defaultObject,
JsonSerializerSettings& settings)
{
return Store(output, allocator, &object, &defaultObject, azrtti_typeid(object), settings);
}
} // namespace AZ
@@ -22,14 +22,20 @@ namespace AZ
class JsonSerializationMetadata final
{
public:
//! Creates a new settings object in the metadata collection.
//! Only one object of the same type can be added or created.
//! Returns false if an object of this type was already added.
template<typename MetadataT, typename... Args>
bool Create(Args&&... args);
//! Adds a new settings object to the metadata collection.
//! Only one object of the same type can be added.
//! Only one object of the same type can be added or created.
//! Returns false if an object of this type was already added.
template<typename MetadataT>
bool Add(MetadataT&& data);
//! Adds a new settings object to the metadata collection.
//! Only one object of the same type can be added.
//! Only one object of the same type can be added or created.
//! Returns false if an object of this type was already added.
template<typename MetadataT>
bool Add(const MetadataT& data);
@@ -16,19 +16,31 @@
namespace AZ
{
template<typename MetadataT>
bool JsonSerializationMetadata::Add(MetadataT&& data)
template<typename MetadataT, typename... Args>
bool JsonSerializationMetadata::Create(Args&&... args)
{
auto typeId = azrtti_typeid<MetadataT>();
auto iter = m_data.find(typeId);
if (iter != m_data.end())
const Uuid& typeId = azrtti_typeid<MetadataT>();
if (m_data.find(typeId) != m_data.end())
{
AZ_Warning("JsonSerializationMetadata", false, "Metadata object of type %s already added",
typeId.template ToString<AZStd::string>().c_str());
AZ_Assert(false, "Metadata object of type %s already added", typeId.template ToString<AZStd::string>().c_str());
return false;
}
m_data[typeId] = AZStd::any{ AZStd::forward<MetadataT>(data) };
m_data.emplace(typeId, MetadataT{AZStd::forward<Args>(args)...});
return true;
}
template<typename MetadataT>
bool JsonSerializationMetadata::Add(MetadataT&& data)
{
const Uuid& typeId = azrtti_typeid<MetadataT>();
if (m_data.find(typeId) != m_data.end())
{
AZ_Assert(false, "Metadata object of type %s already added", typeId.template ToString<AZStd::string>().c_str());
return false;
}
m_data.emplace(typeId, AZStd::forward<MetadataT>(data));
return true;
}
@@ -41,7 +53,7 @@ namespace AZ
template<typename MetadataT>
MetadataT* JsonSerializationMetadata::Find()
{
const auto& typeId = azrtti_typeid<MetadataT>();
const Uuid& typeId = azrtti_typeid<MetadataT>();
auto iter = m_data.find(typeId);
return iter != m_data.end() ? AZStd::any_cast<MetadataT>(&iter->second) : nullptr;
}
@@ -576,14 +576,32 @@ namespace AZ::SettingsRegistryMergeUtils
aznumeric_cast<int>(projectPathKey.size()), projectPathKey.data());
}
#if !AZ_TRAIT_USE_ASSET_CACHE_FOLDER
// Setup the cache and user paths for Platforms where the Asset Cache Folder isn't used
#if !AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
// Setup the cache and user paths when to platform specific locations when running on non-host platforms
path = engineRoot;
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
registry.Set(FilePathKey_DevWriteStorage, path.LexicallyNormal().Native());
registry.Set(FilePathKey_ProjectUserPath, (path / "user").LexicallyNormal().Native());
#endif // AZ_TRAIT_USE_ASSET_CACHE_FOLDER
if (AZStd::optional<AZ::IO::FixedMaxPathString> nonHostCacheRoot = Utils::GetDefaultAppRootPath();
nonHostCacheRoot)
{
registry.Set(FilePathKey_CacheProjectRootFolder, *nonHostCacheRoot);
registry.Set(FilePathKey_CacheRootFolder, *nonHostCacheRoot);
}
else
{
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
}
if (AZStd::optional<AZ::IO::FixedMaxPathString> devWriteStorage = Utils::GetDevWriteStoragePath();
devWriteStorage)
{
registry.Set(FilePathKey_DevWriteStorage, *devWriteStorage);
registry.Set(FilePathKey_ProjectUserPath, *devWriteStorage);
}
else
{
registry.Set(FilePathKey_DevWriteStorage, path.LexicallyNormal().Native());
registry.Set(FilePathKey_ProjectUserPath, (path / "user").LexicallyNormal().Native());
}
#endif // AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
}
void MergeSettingsToRegistry_TargetBuildDependencyRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
@@ -986,4 +1004,12 @@ namespace AZ::SettingsRegistryMergeUtils
return visitor.Finalize();
}
bool IsPathAncestorDescendantOrEqual(AZStd::string_view candidatePath, AZStd::string_view inputPath)
{
AZ::IO::PathView candidateView{ candidatePath, AZ::IO::PosixPathSeparator };
AZ::IO::PathView inputView{ inputPath, AZ::IO::PosixPathSeparator };
return inputView.empty() || candidateView.IsRelativeTo(inputView) || inputView.IsRelativeTo(candidateView);
}
}
@@ -256,4 +256,22 @@ namespace AZ::SettingsRegistryMergeUtils
aznumeric_cast<int>(keyName.size()), keyName.data());
return registry.Get(result, key);
}
//! Check if the supplied input path is an ancestor, a descendant or exactly equal to the candidate path
//! The can be used to check if a JSON pointer to a settings registry entry has potentially
//! "modified" the object at candidate path or its children in notifications
//! @param candidatePath Path which is being checked for the ancestor/descendant relationship
//! @param inputPath Path which is checked to determine if it is an ancestor or descendant of the candidate path
//! @return true if the input path is an ancestor, descendant or equal to the candidate path
//! Example: input path is ancestor path of candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore") = true
//! Example: input path is equal to candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap") = true
//! Example: input path is descendant of candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap/project_path") = true
//! //! Example: input path is unrelated to candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/Project/Settings/project_name") = false
//! //! Example: The path "" is the root JSON pointer therefore that is the ancestor of all paths
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "") = true
bool IsPathAncestorDescendantOrEqual(AZStd::string_view candidatePath, AZStd::string_view inputPath);
}
@@ -2900,7 +2900,7 @@ namespace AZ
{
AZ::Data::AssetCatalogRequestBus::BroadcastResult(referencedSliceAssetPath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, slice.GetSliceAsset()->GetId());
}
AZ_Error("Slices", false, "Slice with asset ID %s and path %s has an invalid slice reference to slice with path %s. The Lumberyard editor may be unstable, it is recommended you re-launch the editor.",
AZ_Error("Slices", false, "Slice with asset ID %s and path %s has an invalid slice reference to slice with path %s. The Open 3D Engine editor may be unstable, it is recommended you re-launch the editor.",
!m_myAsset ? "invalid asset" : m_myAsset->GetId().ToString<AZStd::string>().c_str(),
mySliceAssetPath.empty() ? "invalid path" : mySliceAssetPath.c_str(),
referencedSliceAssetPath.empty() ? "invalid path" : referencedSliceAssetPath.c_str());
@@ -769,8 +769,8 @@ namespace AZ
*! This has similar behavior to Python pathlib '/' operator and os.path.join
*! Specifically, that it uses the last absolute path as the anchor for the resulting path
*! https://docs.python.org/3/library/pathlib.html#pathlib.PurePath
*! This means that joining StringFunc::Path::Join("C:\\lumberyard" "F:\\lumberyard") results in "F:\\lumberyard"
*! not "C:\\lumberyard\\F:\\lumberyard"
*! This means that joining StringFunc::Path::Join("C:\\O3DE" "F:\\O3DE") results in "F:\\O3DE"
*! not "C:\\O3DE\\F:\\O3DE"
*! EX: StringFunc::Path::Join("C:\\p4\\game","info\\some.file", a) == true; a== "C:\\p4\\game\\info\\some.file"
*! EX: StringFunc::Path::Join("C:\\p4\\game\\info", "game\\info\\some.file", a) == true; a== "C:\\p4\\game\\info\\game\\info\\some.file"
*! EX: StringFunc::Path::Join("C:\\p4\\game\\info", "\\game\\info\\some.file", a) == true; a== "C:\\game\\info\\some.file"
@@ -0,0 +1,59 @@
/*
* 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/UnitTest/UnitTest.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <gmock/gmock.h>
namespace AZ
{
class MockSettingsRegistry;
using NiceSettingsRegistrySimpleMock = ::testing::NiceMock<MockSettingsRegistry>;
class MockSettingsRegistry
: public AZ::SettingsRegistryInterface
{
public:
MOCK_CONST_METHOD1(GetType, Type(AZStd::string_view));
MOCK_CONST_METHOD2(Visit, bool(Visitor&, AZStd::string_view));
MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view));
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&));
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&));
MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(u64&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(double&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(AZStd::string&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(FixedValueString&, AZStd::string_view));
MOCK_CONST_METHOD3(GetObject, bool(void*, Uuid, AZStd::string_view));
MOCK_METHOD2(Set, bool(AZStd::string_view, bool));
MOCK_METHOD2(Set, bool(AZStd::string_view, s64));
MOCK_METHOD2(Set, bool(AZStd::string_view, u64));
MOCK_METHOD2(Set, bool(AZStd::string_view, double));
MOCK_METHOD2(Set, bool(AZStd::string_view, AZStd::string_view));
MOCK_METHOD2(Set, bool(AZStd::string_view, const char*));
MOCK_METHOD3(SetObject, bool(AZStd::string_view, const void*, Uuid));
MOCK_METHOD1(Remove, bool(AZStd::string_view));
MOCK_METHOD3(MergeCommandLineArgument, bool(AZStd::string_view, AZStd::string_view, const CommandLineArgumentSettings&));
MOCK_METHOD2(MergeSettings, bool(AZStd::string_view, Format));
MOCK_METHOD4(MergeSettingsFile, bool(AZStd::string_view, Format, AZStd::string_view, AZStd::vector<char>*));
MOCK_METHOD5(
MergeSettingsFolder,
bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector<char>*));
};
} // namespace AZ
@@ -278,7 +278,7 @@ namespace UnitTest
#define AZ_TEST_STATIC_ASSERT(_Exp) static_assert(_Exp, "Test Static Assert")
#ifdef AZ_ENABLE_TRACING
/*
* The AZ_TEST_START_ASSERTTEST and AZ_TEST_STOP_ASSERTTEST macros have been deprecated and will be removed in a future Lumberyard release.
* The AZ_TEST_START_ASSERTTEST and AZ_TEST_STOP_ASSERTTEST macros have been deprecated and will be removed in a future Open 3D Engine release.
* The AZ_TEST_START_TRACE_SUPPRESSION and AZ_TEST_STOP_TRACE_SUPPRESSION is the recommend macros
* The reason for the deprecation is that the AZ_TEST_(START|STOP)_ASSERTTEST implies that they should be used to for writing assert unit test
* where the asserts themselves are expected to cause the test process to terminate.
@@ -15,4 +15,5 @@ set(FILES
UnitTest/UnitTest.h
UnitTest/TestTypes.h
UnitTest/Mocks/MockFileIOBase.h
UnitTest/Mocks/MockSettingsRegistry.h
)
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 1
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -193,7 +193,7 @@ namespace Platform::Internal
void FindFilesInApk(const char* filter, const SystemFile::FindFileCB& cb)
{
// Separate the directory from the filename portion of the filter
AZ::IO::PathView filterPath(AZ::Android::Utils::StripApkPrefix(filter));
AZ::IO::FixedMaxPath filterPath(AZ::Android::Utils::StripApkPrefix(filter));
AZ::IO::FixedMaxPathString filterDir{ filterPath.ParentPath().Native() };
AZStd::string_view fileFilter{ filterPath.Filename().Native() };
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE INVALID_RETURN_VALUE
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 1
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 0
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 1
@@ -106,7 +106,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -90,7 +90,7 @@ namespace UnitTest
TEST_F(OptionalFixture, ConstructorInPlaceWithInitializerList)
{
const optional<ConstructibleWithInitializerListClass> opt(in_place, {"Lumberyard"}, 4);
const optional<ConstructibleWithInitializerListClass> opt(in_place, {"O3DE"}, 4);
EXPECT_TRUE(bool(opt)) << "optional constructed with args should be true";
}
+2 -4
View File
@@ -1081,13 +1081,11 @@ namespace UnitTest
AZStd::string filePath;
if (providerId == UserSettings::CT_GLOBAL)
{
filePath.append(static_cast<AZStd::string_view>(m_exeDirectory));
filePath.append("GlobalUserSettings.xml");
filePath = (m_exeDirectory / "GlobalUserSettings.xml").String();
}
else if (providerId == UserSettings::CT_LOCAL)
{
filePath.append(static_cast<AZStd::string_view>(m_exeDirectory));
filePath.append("LocalUserSettings.xml");
filePath = (m_exeDirectory / "LocalUserSettings.xml").String();
}
return filePath;
}
@@ -547,7 +547,7 @@ namespace UnitTest
PathLexicallyNormalParams{ '/', "foo/./bar/..", "foo" },
PathLexicallyNormalParams{ '/', "foo/.///bar/../", "foo" },
PathLexicallyNormalParams{ '/', R"(/foo\./bar\..\)", "/foo" },
PathLexicallyNormalParams{ '\\', R"(C:/lumberyard/dev/Cache\game/../pc)", R"(C:\lumberyard\dev\Cache\pc)" }
PathLexicallyNormalParams{ '\\', R"(C:/O3DE/dev/Cache\game/../pc)", R"(C:\O3DE\dev\Cache\pc)" }
)
);
@@ -756,13 +756,13 @@ namespace UnitTest
PathPrefixParams{ "C:\\foo\\", "C:\\foo", true },
PathPrefixParams{ "C:", "C:\\foo", true },
PathPrefixParams{ "D:\\", "C:\\foo", false },
PathPrefixParams{ "/lumberyard/dev/", "/lumberyard/dev", true },
PathPrefixParams{ "/lumberyard/dev", "/lumberyard/dev/", true },
PathPrefixParams{ "/lumberyard/dev/", "/lumberyard/dev/Cache", true },
PathPrefixParams{ "/lumberyard/dev", "/lumberyard/dev/Cache", true },
PathPrefixParams{ "/lumberyard/dev", "/lumberyard/dev/Cache/", true },
PathPrefixParams{ "lumberyard/dev/", "lumberyard/dev/Cache/", true },
PathPrefixParams{ "lumberyard\\dev/Assets", "lumberyard/dev/Cache/", false }
PathPrefixParams{ "/O3DE/dev/", "/O3DE/dev", true },
PathPrefixParams{ "/O3DE/dev", "/O3DE/dev/", true },
PathPrefixParams{ "/O3DE/dev/", "/O3DE/dev/Cache", true },
PathPrefixParams{ "/O3DE/dev", "/O3DE/dev/Cache", true },
PathPrefixParams{ "/O3DE/dev", "/O3DE/dev/Cache/", true },
PathPrefixParams{ "O3DE/dev/", "O3DE/dev/Cache/", true },
PathPrefixParams{ "O3DE\\dev/Assets", "O3DE/dev/Cache/", false }
));
struct PathDecompositionParams
@@ -854,7 +854,7 @@ namespace Benchmark
}
protected:
AZStd::fixed_vector<const char*, 20> m_appendPaths{ "foo", "bar", "baz", "bazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"boo/bar/base", "C:\\path\\to\\lumberyard", "C", "\\\\", "/", R"(test\\path/with\mixed\separators)" };
"boo/bar/base", "C:\\path\\to\\O3DE", "C", "\\\\", "/", R"(test\\path/with\mixed\separators)" };
};
BENCHMARK_F(PathBenchmarkFixture, BM_PathAppendFixedPath)(benchmark::State& state)
@@ -56,6 +56,16 @@ namespace UnitTest
EXPECT_THAT(obb.GetAxisZ(), IsClose(Vector3(1.0f, 0.0f, 0.0f)));
}
TEST(MATH_Obb, TestScaleTransform)
{
Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
Vector3 scaleFactors = Vector3(1.0f, 2.0f, 3.0f);
Transform transform = Transform::CreateScale(scaleFactors);
obb = transform * obb;
EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(1.0f, 4.0f, 9.0f)));
EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(0.5f, 1.0f, 1.5f)));
}
TEST(MATH_Obb, TestSetPosition)
{
Obb obb;
@@ -93,8 +93,10 @@ namespace JsonSerializationTests
TEST_F(JsonSerializationMetadataTests, Add_MoveDuplicateValue_ReturnsFalse)
{
AZ_TEST_START_TRACE_SUPPRESSION;
m_metadata->Add(TestSettingsA{ 42 });
EXPECT_FALSE(m_metadata->Add(TestSettingsA{ 88 }));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(JsonSerializationMetadataTests, Add_CopyNewValue_ReturnsTrue)
@@ -119,11 +121,13 @@ namespace JsonSerializationTests
TEST_F(JsonSerializationMetadataTests, Find_MultipleValues_ReturnsFirstValue)
{
m_metadata->Add(TestSettingsA{ 42 });
AZ_TEST_START_TRACE_SUPPRESSION;
m_metadata->Add(TestSettingsA{42});
m_metadata->Add(TestSettingsA{ 88 });
TestSettingsA* value = m_metadata->Find<TestSettingsA>();
ASSERT_NE(nullptr, value);
EXPECT_EQ(42, value->m_number);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(JsonSerializationMetadataTests, FindConst_PreviouslyAddedValue_ReturnsConstPointer)
@@ -542,4 +542,14 @@ tags=tools,renderer,metal)"
EXPECT_STREQ("Foo", commandLine.GetMiscValue(1).c_str());
EXPECT_STREQ("Bat", commandLine.GetMiscValue(2).c_str());
}
using SettingsRegistryAncestorDescendantOrEqualPathFixture = SettingsRegistryMergeUtilsCommandLineFixture;
TEST_F(SettingsRegistryAncestorDescendantOrEqualPathFixture, ValidateThatAncestorOrDescendantOrPathWithTheSameValue_Succeeds)
{
EXPECT_TRUE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore"));
EXPECT_TRUE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap"));
EXPECT_TRUE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap/project_path"));
EXPECT_FALSE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/Project/Settings/project_name"));
}
}
@@ -82,9 +82,6 @@
static const char* s_azFrameworkWarningWindow = "AzFramework";
static const char* s_engineConfigFileName = "engine.json";
static const char* s_engineConfigEngineVersionKey = "LumberyardVersion";
namespace AzFramework
{
namespace ApplicationInternal
@@ -264,24 +261,8 @@ namespace AzFramework
void Application::PreModuleLoad()
{
// Calculate the engine root by reading the engine.json file
AZStd::string engineJsonPath = AZStd::string_view{ m_engineRoot };
engineJsonPath += s_engineConfigFileName;
AzFramework::StringFunc::Path::Normalize(engineJsonPath);
AZ::IO::LocalFileIO localFileIO;
auto readJsonResult = AzFramework::FileFunc::ReadJsonFile(engineJsonPath, &localFileIO);
if (readJsonResult.IsSuccess())
{
SetRootPath(RootPathType::EngineRoot, m_engineRoot.c_str());
AZ_TracePrintf(s_azFrameworkWarningWindow, "Engine Path: %s\n", m_engineRoot.c_str());
}
else
{
// If there is any problem reading the engine.json file, then default to engine root to the app root
AZ_Warning(s_azFrameworkWarningWindow, false, "Unable to read engine.json file '%s' (%s). Defaulting the engine root to '%s'", engineJsonPath.c_str(), readJsonResult.GetError().c_str(), m_appRoot.c_str());
SetRootPath(RootPathType::EngineRoot, m_appRoot.c_str());
}
SetRootPath(RootPathType::EngineRoot, m_engineRoot.c_str());
AZ_TracePrintf(s_azFrameworkWarningWindow, "Engine Path: %s\n", m_engineRoot.c_str());
}
@@ -504,13 +485,13 @@ namespace AzFramework
void Application::ResolveEnginePath(AZStd::string& engineRelativePath) const
{
AZStd::string fullPath = AZStd::string(m_engineRoot) + AZStd::string(AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING) + engineRelativePath;
engineRelativePath = fullPath;
AZ::IO::FixedMaxPath fullPath = m_engineRoot / engineRelativePath;
engineRelativePath = fullPath.String();
}
void Application::CalculateBranchTokenForEngineRoot(AZStd::string& token) const
{
AzFramework::StringFunc::AssetPath::CalculateBranchToken(AZStd::string(m_engineRoot), token);
AzFramework::StringFunc::AssetPath::CalculateBranchToken(m_engineRoot.String(), token);
}
////////////////////////////////////////////////////////////////////////////
@@ -648,37 +629,21 @@ namespace AzFramework
void Application::SetRootPath(RootPathType type, const char* source)
{
size_t sourceLen = strlen(source);
constexpr AZStd::string_view pathSeparators{ AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR };
// Determine if we need to append a trailing path separator
bool appendTrailingPathSep = sourceLen > 0 && pathSeparators.find_first_of(source[sourceLen - 1]) == AZStd::string_view::npos;
const size_t sourceLen = strlen(source);
// Copy the source path to the intended root path and correct the path separators as well
switch (type)
{
case RootPathType::AppRoot:
{
AZ_Assert(sourceLen < m_appRoot.max_size(), "String overflow for App Root: %s", source);
m_appRoot = source;
AZStd::replace(std::begin(m_appRoot), std::end(m_appRoot), AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR);
if (appendTrailingPathSep)
{
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
}
AZ_Assert(sourceLen < m_appRoot.Native().max_size(), "String overflow for App Root: %s", source);
m_appRoot = AZ::IO::PathView(source).LexicallyNormal();
}
break;
case RootPathType::EngineRoot:
{
AZ_Assert(sourceLen < m_engineRoot.max_size(), "String overflow for Engine Root: %s", source);
m_engineRoot = source;
AZStd::replace(std::begin(m_engineRoot), std::end(m_engineRoot), AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR);
if (appendTrailingPathSep)
{
m_engineRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
}
AZ_Assert(sourceLen < m_engineRoot.Native().max_size(), "String overflow for Engine Root: %s", source);
m_engineRoot = AZ::IO::PathView(source).LexicallyNormal();
}
break;
default:
@@ -28,7 +28,7 @@ namespace AZ::IO::Internal
static bool IsIgnored(const char* szPath);
// Do not report missing LOD files if no CGF files depend on them
// Do not report missing .cgfm files since they're not actually created and used in Lumberyard
// Do not report missing .cgfm files since they're not actually created and used in Open 3D Engine
// This checking prevents our missing dependency scanner from having a lot of false positives on these files
static bool IgnoreCGFDependencies(const char* szPath);
@@ -21,7 +21,7 @@ namespace AZ
namespace AzFramework
{
// Class to describe metadata about an AssetBundle in Lumberyard
// Class to describe metadata about an AssetBundle in Open 3D Engine
class AssetBundleManifest
{
public:
@@ -597,9 +597,9 @@ namespace AZ
{
// here we are making sure that the buffer being passed in has enough space to include the alias in it.
// we are trying to find the LONGEST match, meaning of the following two examples, the second should 'win'
// File: g:/lumberyard/dev/files/morefiles/blah.xml
// Alias1 links to 'g:/lumberyard/dev/'
// Alias2 links to 'g:/lumberyard/dev/files/morefiles'
// File: g:/O3DE/dev/files/morefiles/blah.xml
// Alias1 links to 'g:/O3DE/dev/'
// Alias2 links to 'g:/O3DE/dev/files/morefiles'
// so returning Alias2 is preferred as it is more specific, even though alias1 includes it.
// note that its not possible for this to be matched if the string is shorter than the length of the alias itself so we skip
// strings that are shorter than the alias's mapped path without checking.
@@ -126,19 +126,22 @@ namespace AzFramework
return;
}
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
{
Report(args);
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
{
Report(args);
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -168,7 +168,7 @@ namespace Physics
MaterialId m_id;
};
/// An asset that holds a list of materials to be edited and assigned in Lumberyard Editor
/// An asset that holds a list of materials to be edited and assigned in Open 3D Engine Editor
/// ======================================================================================
///
/// Use Asset Editor to create a MaterialLibraryAsset and add materials to it.\n
@@ -0,0 +1,238 @@
/*
* 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/Math/Matrix3x3.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Aabb.h>
#include <AzFramework/Physics/WorldBody.h>
#include <AzFramework/Physics/ShapeConfiguration.h>
namespace
{
class ReflectContext;
}
namespace Physics
{
class ShapeConfiguration;
class World;
class Shape;
/// Default values used for initializing RigidBodySettings.
/// These can be modified by Physics Implementation gems. // O3DE_DEPRECATED(LY-114472) - DefaultRigidBodyConfiguration values are not shared across modules.
// Use RigidBodyConfiguration default values.
struct DefaultRigidBodyConfiguration
{
static float m_mass;
static bool m_computeInertiaTensor;
static float m_linearDamping;
static float m_angularDamping;
static float m_sleepMinEnergy;
static float m_maxAngularVelocity;
};
enum class MassComputeFlags : AZ::u8
{
NONE = 0,
//! Flags indicating whether a certain mass property should be auto-computed or not.
COMPUTE_MASS = 1,
COMPUTE_INERTIA = 1 << 1,
COMPUTE_COM = 1 << 2,
//! If set, non-simulated shapes will also be included in the mass properties calculation.
INCLUDE_ALL_SHAPES = 1 << 3,
DEFAULT = COMPUTE_COM | COMPUTE_INERTIA | COMPUTE_MASS
};
class RigidBodyConfiguration
: public WorldBodyConfiguration
{
public:
AZ_CLASS_ALLOCATOR(RigidBodyConfiguration, AZ::SystemAllocator, 0);
AZ_RTTI(RigidBodyConfiguration, "{ACFA8900-8530-4744-AF00-AA533C868A8E}", WorldBodyConfiguration);
static void Reflect(AZ::ReflectContext* context);
enum PropertyVisibility : AZ::u16
{
InitialVelocities = 1 << 0, ///< Whether the initial linear and angular velocities are visible.
InertiaProperties = 1 << 1, ///< Whether the whole category of inertia properties (mass, compute inertia,
///< inertia tensor etc) is visible.
Damping = 1 << 2, ///< Whether linear and angular damping are visible.
SleepOptions = 1 << 3, ///< Whether the sleep threshold and start asleep options are visible.
Interpolation = 1 << 4, ///< Whether the interpolation option is visible.
Gravity = 1 << 5, ///< Whether the effected by gravity option is visible.
Kinematic = 1 << 6, ///< Whether the option to make the body kinematic is visible.
ContinuousCollisionDetection = 1 << 7, ///< Whether the option to enable continuous collision detection is visible.
MaxVelocities = 1 << 8 ///< Whether upper limits on velocities are visible.
};
RigidBodyConfiguration() = default;
RigidBodyConfiguration(const RigidBodyConfiguration& settings) = default;
// Visibility functions.
AZ::Crc32 GetPropertyVisibility(PropertyVisibility property) const;
void SetPropertyVisibility(PropertyVisibility property, bool isVisible);
AZ::Crc32 GetInitialVelocitiesVisibility() const;
/// Returns whether the whole category of inertia settings (mass, inertia, center of mass offset etc) is visible.
AZ::Crc32 GetInertiaSettingsVisibility() const;
/// Returns whether the individual inertia tensor field is visible or is hidden because the compute inertia option is selected.
AZ::Crc32 GetInertiaVisibility() const;
/// Returns whether the mass field is visible or is hidden because compute mass option is selected.
AZ::Crc32 GetMassVisibility() const;
/// Returns whether the individual centre of mass offset field is visible or is hidden because compute CoM option is selected.
AZ::Crc32 GetCoMVisibility() const;
AZ::Crc32 GetDampingVisibility() const;
AZ::Crc32 GetSleepOptionsVisibility() const;
AZ::Crc32 GetInterpolationVisibility() const;
AZ::Crc32 GetGravityVisibility() const;
AZ::Crc32 GetKinematicVisibility() const;
AZ::Crc32 GetCCDVisibility() const;
AZ::Crc32 GetMaxVelocitiesVisibility() const;
MassComputeFlags GetMassComputeFlags() const;
void SetMassComputeFlags(MassComputeFlags flags);
bool IsCCDEnabled() const;
// Basic initial settings.
AZ::Vector3 m_initialLinearVelocity = AZ::Vector3::CreateZero();
AZ::Vector3 m_initialAngularVelocity = AZ::Vector3::CreateZero();
AZ::Vector3 m_centerOfMassOffset = AZ::Vector3::CreateZero();
// Simulation parameters.
float m_mass = DefaultRigidBodyConfiguration::m_mass;
AZ::Matrix3x3 m_inertiaTensor = AZ::Matrix3x3::CreateIdentity();
float m_linearDamping = DefaultRigidBodyConfiguration::m_linearDamping;
float m_angularDamping = DefaultRigidBodyConfiguration::m_angularDamping;
float m_sleepMinEnergy = DefaultRigidBodyConfiguration::m_sleepMinEnergy;
float m_maxAngularVelocity = DefaultRigidBodyConfiguration::m_maxAngularVelocity;
// Visibility settings.
AZ::u16 m_propertyVisibilityFlags = (std::numeric_limits<AZ::u16>::max)();
bool m_startAsleep = false;
bool m_interpolateMotion = false;
bool m_gravityEnabled = true;
bool m_simulated = true;
bool m_kinematic = false;
bool m_ccdEnabled = false; ///< Whether continuous collision detection is enabled.
float m_ccdMinAdvanceCoefficient = 0.15f; ///< Coefficient affecting how granularly time is subdivided in CCD.
bool m_ccdFrictionEnabled = false; ///< Whether friction is applied when resolving CCD collisions.
bool m_computeCenterOfMass = true;
bool m_computeInertiaTensor = true;
bool m_computeMass = true;
//! If set, non-simulated shapes will also be included in the mass properties calculation.
bool m_includeAllShapesInMassCalculation = false;
};
/// Dynamic rigid body.
class RigidBody
: public WorldBody
{
public:
AZ_CLASS_ALLOCATOR(RigidBody, AZ::SystemAllocator, 0);
AZ_RTTI(RigidBody, "{156E459F-7BB7-4B4E-ADA0-2130D96B7E80}", WorldBody);
public:
RigidBody() = default;
explicit RigidBody(const RigidBodyConfiguration& settings);
virtual void AddShape(AZStd::shared_ptr<Shape> shape) = 0;
virtual void RemoveShape(AZStd::shared_ptr<Shape> shape) = 0;
virtual AZ::u32 GetShapeCount() { return 0; }
virtual AZStd::shared_ptr<Shape> GetShape(AZ::u32 /*index*/) { return nullptr; }
virtual AZ::Vector3 GetCenterOfMassWorld() const = 0;
virtual AZ::Vector3 GetCenterOfMassLocal() const = 0;
virtual AZ::Matrix3x3 GetInverseInertiaWorld() const = 0;
virtual AZ::Matrix3x3 GetInverseInertiaLocal() const = 0;
virtual float GetMass() const = 0;
virtual float GetInverseMass() const = 0;
virtual void SetMass(float mass) = 0;
virtual void SetCenterOfMassOffset(const AZ::Vector3& comOffset) = 0;
/// Retrieves the velocity at center of mass; only linear velocity, no rotational velocity contribution.
virtual AZ::Vector3 GetLinearVelocity() const = 0;
virtual void SetLinearVelocity(const AZ::Vector3& velocity) = 0;
virtual AZ::Vector3 GetAngularVelocity() const = 0;
virtual void SetAngularVelocity(const AZ::Vector3& angularVelocity) = 0;
virtual AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) = 0;
virtual void ApplyLinearImpulse(const AZ::Vector3& impulse) = 0;
virtual void ApplyLinearImpulseAtWorldPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) = 0;
virtual void ApplyAngularImpulse(const AZ::Vector3& angularImpulse) = 0;
virtual float GetLinearDamping() const = 0;
virtual void SetLinearDamping(float damping) = 0;
virtual float GetAngularDamping() const = 0;
virtual void SetAngularDamping(float damping) = 0;
virtual bool IsAwake() const = 0;
virtual void ForceAsleep() = 0;
virtual void ForceAwake() = 0;
virtual float GetSleepThreshold() const = 0;
virtual void SetSleepThreshold(float threshold) = 0;
virtual bool IsKinematic() const = 0;
virtual void SetKinematic(bool kinematic) = 0;
virtual void SetKinematicTarget(const AZ::Transform& targetPosition) = 0;
virtual bool IsGravityEnabled() const = 0;
virtual void SetGravityEnabled(bool enabled) = 0;
virtual void SetSimulationEnabled(bool enabled) = 0;
virtual void SetCCDEnabled(bool enabled) = 0;
//! Recalculates mass, inertia and center of mass based on the flags passed.
//! @param flags MassComputeFlags specifying which properties should be recomputed.
//! @param centerOfMassOffsetOverride Optional override of the center of mass. Note: This parameter will be ignored if COMPUTE_COM is passed in flags.
//! @param inertiaTensorOverride Optional override of the inertia. Note: This parameter will be ignored if COMPUTE_INERTIA is passed in flags.
//! @param massOverride Optional override of the mass. Note: This parameter will be ignored if COMPUTE_MASS is passed in flags.
virtual void UpdateMassProperties(MassComputeFlags flags = MassComputeFlags::DEFAULT,
const AZ::Vector3* centerOfMassOffsetOverride = nullptr,
const AZ::Matrix3x3* inertiaTensorOverride = nullptr,
const float* massOverride = nullptr) = 0;
};
/// Bitwise operators for MassComputeFlags
inline MassComputeFlags operator|(MassComputeFlags lhs, MassComputeFlags rhs)
{
return aznumeric_cast<MassComputeFlags>(aznumeric_cast<AZ::u8>(lhs) | aznumeric_cast<AZ::u8>(rhs));
}
inline MassComputeFlags operator&(MassComputeFlags lhs, MassComputeFlags rhs)
{
return aznumeric_cast<MassComputeFlags>(aznumeric_cast<AZ::u8>(lhs) & aznumeric_cast<AZ::u8>(rhs));
}
/// Static rigid body.
class RigidBodyStatic
: public WorldBody
{
public:
AZ_CLASS_ALLOCATOR(RigidBodyStatic, AZ::SystemAllocator, 0);
AZ_RTTI(RigidBodyStatic, "{13A677BB-7085-4EDB-BCC8-306548238692}", WorldBody);
virtual void AddShape(const AZStd::shared_ptr<Shape>& shape) = 0;
virtual AZ::u32 GetShapeCount() { return 0; }
virtual AZStd::shared_ptr<Shape> GetShape(AZ::u32 /*index*/) { return nullptr; }
};
} // namespace Physics
@@ -84,7 +84,7 @@ namespace AzFramework
{
if (IVisibilitySystem* visibilitySystem = AZ::Interface<IVisibilitySystem>::Get())
{
visibilitySystem->RemoveEntry(instance_it->second.m_visibilityEntry);
visibilitySystem->GetDefaultVisibilityScene()->RemoveEntry(instance_it->second.m_visibilityEntry);
m_entityVisibilityBoundsUnionInstanceMapping.erase(instance_it);
}
}
@@ -104,7 +104,7 @@ namespace AzFramework
if (visibilitySystem && !worldEntityBoundsUnion.IsClose(instance.m_visibilityEntry.m_boundingVolume))
{
instance.m_visibilityEntry.m_boundingVolume = worldEntityBoundsUnion;
visibilitySystem->InsertOrUpdateEntry(instance.m_visibilityEntry);
visibilitySystem->GetDefaultVisibilityScene()->InsertOrUpdateEntry(instance.m_visibilityEntry);
}
}
}
@@ -56,10 +56,10 @@ namespace AzFramework
m_octreeDebug.Clear();
m_visibleEntityIds.clear();
visSystem->Enumerate(
visSystem->GetDefaultVisibilityScene()->Enumerate(
viewFrustum,
[&viewFrustum, &visibleEntityIdsOut = m_visibleEntityIds,
&octreeDebug = m_octreeDebug](const AzFramework::IVisibilitySystem::NodeData& nodeData)
&octreeDebug = m_octreeDebug](const AzFramework::IVisibilityScene::NodeData& nodeData)
{
if (ed_visibility_showDebug)
{
@@ -13,11 +13,13 @@
#pragma once
#include <AzCore/base.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/Sphere.h>
#include <AzCore/Math/Frustum.h>
#include <AzCore/Name/Name.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/std/containers/vector.h>
@@ -45,12 +47,15 @@ namespace AzFramework
TypeFlags m_typeFlags = TYPE_None;
};
//! @class IVisibilitySystem
//! @brief This is an AZ::Interface<> useful for extremely fast, CPU only, proximity and visibility queries.
class IVisibilitySystem
//! @class IVisibilityScene
//! @brief This is the interface for managing objects and visibility queries for a given scene.
class IVisibilityScene
{
public:
AZ_RTTI(IVisibilitySystem, "{7C6C710F-ACDB-44CD-867D-A2C4B912ECF5}");
AZ_RTTI(IVisibilityScene, "{822BC414-3CE3-40B4-A9A2-A42EA5B9499F}");
IVisibilityScene() = default;
virtual ~IVisibilityScene() = default;
struct NodeData
{
@@ -59,8 +64,8 @@ namespace AzFramework
};
using EnumerateCallback = AZStd::function<void(const NodeData&)>;
IVisibilitySystem() = default;
virtual ~IVisibilitySystem() = default;
//! Get the unique scene name, used to look up the scene in the IVisibilitySystem. Duplicate names will assert on creation.
virtual const AZ::Name& GetName() const = 0;
//! Insert or update an entry within the visibility system.
//! This encompasses the following three scenarios:
@@ -68,11 +73,11 @@ namespace AzFramework
// 2. A previously added entry moves to a new position within its current node in the spatial hash.
// 3. A previously added entry moves to a new node in the spatial hash.
// (causing it to be removed from its original node and added to its new node)
//! @param visibilityEntry data for the object being added to the visibility system
//! @param visibilityEntry data for the object being added/updated
virtual void InsertOrUpdateEntry(VisibilityEntry& visibilityEntry) = 0;
//! Removes an entry from the visibility system.
//! @param visibilityEntry data for the object being added to the visibility system
//! @param visibilityEntry data for the object being removed
virtual void RemoveEntry(VisibilityEntry& visibilityEntry) = 0;
//! Intersects an axis aligned bounding box against the visibility system.
@@ -99,6 +104,34 @@ namespace AzFramework
//! Return the number of VisibilityEntries that have been added to the system
virtual uint32_t GetEntryCount() const = 0;
};
//! @class IVisibilitySystem
//! @brief This is an AZ::Interface<> useful for extremely fast, CPU only, proximity and visibility queries.
class IVisibilitySystem
{
public:
AZ_RTTI(IVisibilitySystem, "{7C6C710F-ACDB-44CD-867D-A2C4B912ECF5}");
IVisibilitySystem() = default;
virtual ~IVisibilitySystem() = default;
//! Return the default IVisibilityScene for entities.
virtual IVisibilityScene* GetDefaultVisibilityScene() = 0;
//! Create a new IVisibilityScene that is uniquely identified by the scene name.
virtual IVisibilityScene* CreateVisibilityScene(const AZ::Name& sceneName) = 0;
//! Destroy the visibility scene.
//! This does not destroy the entities that are a part of the scene, only the visibility scene.
//! This will set the visScene to nullptr
virtual void DestroyVisibilityScene(IVisibilityScene* visScene) = 0;
//! Find the IVisibilityScene that is identified by sceneName.
virtual IVisibilityScene* FindVisibilityScene(const AZ::Name& sceneName) = 0;
//! Logs stats about the visibility system to the console.
virtual void DumpStats(const AZ::ConsoleCommandContainer& arguments) = 0;
AZ_DISABLE_COPY_MOVE(IVisibilitySystem);
};
@@ -15,7 +15,7 @@
namespace AzFramework
{
AZ_CVAR(bool, bg_octreeUseQuadtree, false, nullptr, AZ::ConsoleFunctorFlags::ReadOnly, "If set to true, the octreeSystemComponent will degenerate to a quadtree split along the X/Y plane");
AZ_CVAR(bool, bg_octreeUseQuadtree, false, nullptr, AZ::ConsoleFunctorFlags::ReadOnly, "If set to true, the visibility octrees will degenerate to a quadtree split along the X/Y plane");
AZ_CVAR(float, bg_octreeMaxWorldExtents, 16384.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum supported world size by the world octreeSystemComponent");
AZ_CVAR(uint32_t, bg_octreeNodeMaxEntries, 64, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum number of entries to allow in any node before forcing a split");
AZ_CVAR(uint32_t, bg_octreeNodeMinEntries, 32, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum number of entries to allow in a node resulting from a merge operation");
@@ -67,9 +67,9 @@ namespace AzFramework
}
void OctreeNode::Insert(OctreeSystemComponent& octreeSystemComponent, VisibilityEntry* entry)
void OctreeNode::Insert(OctreeScene& octreeScene, VisibilityEntry* entry)
{
AZ_Assert(entry->m_internalNode == nullptr, "Double-insertion: Insert invoked for an entry already bound to the OctreeSystemComponent");
AZ_Assert(entry->m_internalNode == nullptr, "Double-insertion: Insert invoked for an entry already bound to the OctreeScene");
// If this is not a leaf node, try to insert into the child nodes
if (m_children != nullptr)
@@ -80,7 +80,7 @@ namespace AzFramework
{
if (AZ::ShapeIntersection::Contains(m_children[child].m_bounds, boundingVolume))
{
return m_children[child].Insert(octreeSystemComponent, entry);
return m_children[child].Insert(octreeScene, entry);
}
}
}
@@ -90,8 +90,8 @@ namespace AzFramework
if ((m_children == nullptr) && (m_entries.size() >= bg_octreeNodeMaxEntries))
{
// If we're not already split, and our entry list gets too large, split this node
Split(octreeSystemComponent);
Insert(octreeSystemComponent, entry);
Split(octreeScene);
Insert(octreeScene, entry);
}
else
{
@@ -102,7 +102,7 @@ namespace AzFramework
}
void OctreeNode::Update(OctreeSystemComponent& octreeSystemComponent, VisibilityEntry* entry)
void OctreeNode::Update(OctreeScene& octreeScene, VisibilityEntry* entry)
{
AZ_Assert(entry->m_internalNode == this, "Update invoked for an entry bound to a different OctreeNode");
@@ -116,7 +116,7 @@ namespace AzFramework
}
// Remove the entry from our current node, since it is no longer contained
Remove(octreeSystemComponent, entry);
Remove(octreeScene, entry);
// Traverse up our ancestor nodes to find the first node that fully contains the entry
// This strategy assumes an entry will typically move a small distance relative to the total world
@@ -125,14 +125,14 @@ namespace AzFramework
{
if (AZ::ShapeIntersection::Contains(insertCheck->m_bounds, boundingVolume))
{
return insertCheck->Insert(octreeSystemComponent, entry);
return insertCheck->Insert(octreeScene, entry);
}
insertCheck = insertCheck->m_parent;
}
}
void OctreeNode::Remove(OctreeSystemComponent& octreeSystemComponent, VisibilityEntry* entry)
void OctreeNode::Remove(OctreeScene& octreeScene, VisibilityEntry* entry)
{
AZ_Assert(entry->m_internalNode == this, "Remove invoked for an entry bound to a different OctreeNode");
AZ_Assert(m_entries[entry->m_internalNodeIndex] == entry, "Visibility entry data is corrupt");
@@ -150,29 +150,30 @@ namespace AzFramework
if (m_parent != nullptr)
{
m_parent->TryMerge(octreeSystemComponent);
m_parent->TryMerge(octreeScene);
}
}
void OctreeNode::Enumerate(const AZ::Aabb& aabb, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeNode::Enumerate(const AZ::Aabb& aabb, const IVisibilityScene::EnumerateCallback& callback) const
{
EnumerateHelper(aabb, callback);
}
void OctreeNode::Enumerate(const AZ::Sphere& sphere, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeNode::Enumerate(const AZ::Sphere& sphere, const IVisibilityScene::EnumerateCallback& callback) const
{
EnumerateHelper(sphere, callback);
}
void OctreeNode::Enumerate(const AZ::Frustum& frustum, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeNode::Enumerate(const AZ::Frustum& frustum, const IVisibilityScene::EnumerateCallback& callback) const
{
EnumerateHelper(frustum, callback);
}
void OctreeNode::EnumerateNoCull(const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeNode::EnumerateNoCull(const IVisibilityScene::EnumerateCallback& callback) const
{
// Invoke the callback for the current node
if (!m_entries.empty())
@@ -191,6 +192,7 @@ namespace AzFramework
}
}
const AZStd::vector<VisibilityEntry*>& OctreeNode::GetEntries() const
{
return m_entries;
@@ -209,7 +211,7 @@ namespace AzFramework
}
void OctreeNode::TryMerge(OctreeSystemComponent& octreeSystemComponent)
void OctreeNode::TryMerge(OctreeScene& octreeScene)
{
if (IsLeaf())
{
@@ -222,7 +224,7 @@ namespace AzFramework
const uint32_t childCount = GetChildNodeCount();
for (uint32_t child = 0; child < childCount; ++child)
{
m_children[child].TryMerge(octreeSystemComponent);
m_children[child].TryMerge(octreeScene);
if (!m_children[child].IsLeaf())
{
return;
@@ -232,13 +234,13 @@ namespace AzFramework
if (potentialNodeCount <= bg_octreeNodeMinEntries)
{
Merge(octreeSystemComponent);
Merge(octreeScene);
}
}
template <typename T>
void OctreeNode::EnumerateHelper(const T& boundingVolume, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeNode::EnumerateHelper(const T& boundingVolume, const IVisibilityScene::EnumerateCallback& callback) const
{
AZ_Assert(AZ::ShapeIntersection::Overlaps(boundingVolume, m_bounds), "EnumerateHelper invoked on an octreeSystemComponent node that is not within the bounding volume");
@@ -263,11 +265,11 @@ namespace AzFramework
}
void OctreeNode::Split(OctreeSystemComponent& octreeSystemComponent)
void OctreeNode::Split(OctreeScene& octreeScene)
{
AZ_Assert(m_children == nullptr, "Split invoked on an octreeSystemComponent node that has already been split");
m_childNodeIndex = octreeSystemComponent.AllocateChildNodes();
m_children = octreeSystemComponent.GetChildNodesAtIndex(m_childNodeIndex);
AZ_Assert(m_children == nullptr, "Split invoked on an octreeScene node that has already been split");
m_childNodeIndex = octreeScene.AllocateChildNodes();
m_children = octreeScene.GetChildNodesAtIndex(m_childNodeIndex);
// Set child split planes and bounding volumes
{
@@ -308,14 +310,14 @@ namespace AzFramework
{
entry->m_internalNode = nullptr;
entry->m_internalNodeIndex = 0;
Insert(octreeSystemComponent, entry);
Insert(octreeScene, entry);
}
}
void OctreeNode::Merge(OctreeSystemComponent& octreeSystemComponent)
void OctreeNode::Merge(OctreeScene& octreeScene)
{
AZ_Assert(m_children != nullptr, "Merge invoked on an octreeSystemComponent node that does not have children");
AZ_Assert(m_children != nullptr, "Merge invoked on an octreeScene node that does not have children");
// Move all child entries to our own entry set
const uint32_t childCount = GetChildNodeCount();
@@ -330,46 +332,20 @@ namespace AzFramework
m_children[child].m_entries.clear();
}
octreeSystemComponent.ReleaseChildNodes(m_childNodeIndex);
octreeScene.ReleaseChildNodes(m_childNodeIndex);
m_childNodeIndex = InvalidChildNodeIndex;
m_children = nullptr;
}
void OctreeSystemComponent::Reflect(AZ::ReflectContext* context)
OctreeScene::OctreeScene(const AZ::Name& sceneName)
: m_sceneName(sceneName)
, m_root(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-bg_octreeMaxWorldExtents), AZ::Vector3(bg_octreeMaxWorldExtents)))
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<OctreeSystemComponent, AZ::Component>()
->Version(1);
}
AZ_Assert(!sceneName.IsEmpty(), "sceneName must be a valid string");
}
void OctreeSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
OctreeScene::~OctreeScene()
{
provided.push_back(AZ_CRC_CE("VisibilityService"));
}
void OctreeSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC_CE("VisibilityService"));
}
OctreeSystemComponent::OctreeSystemComponent()
: m_root(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-bg_octreeMaxWorldExtents), AZ::Vector3(bg_octreeMaxWorldExtents)))
{
AZ::Interface<IVisibilitySystem>::Register(this);
IVisibilitySystemRequestBus::Handler::BusConnect();
}
OctreeSystemComponent::~OctreeSystemComponent()
{
IVisibilitySystemRequestBus::Handler::BusDisconnect();
AZ::Interface<IVisibilitySystem>::Unregister(this);
for (auto page : m_nodeCache)
{
delete page;
@@ -378,21 +354,14 @@ namespace AzFramework
m_nodeCache.shrink_to_fit();
}
void OctreeSystemComponent::Activate()
const AZ::Name& OctreeScene::GetName() const
{
;
return m_sceneName;
}
void OctreeSystemComponent::Deactivate()
{
;
}
void OctreeSystemComponent::InsertOrUpdateEntry(VisibilityEntry& entry)
void OctreeScene::InsertOrUpdateEntry(VisibilityEntry& entry)
{
AZStd::lock_guard<AZStd::shared_mutex> lock(m_sharedMutex);
if (entry.m_internalNode != nullptr)
{
static_cast<OctreeNode*>(entry.m_internalNode)->Update(*this, &entry);
@@ -405,8 +374,9 @@ namespace AzFramework
}
void OctreeSystemComponent::RemoveEntry(VisibilityEntry& entry)
void OctreeScene::RemoveEntry(VisibilityEntry& entry)
{
AZStd::lock_guard<AZStd::shared_mutex> lock(m_sharedMutex);
if (entry.m_internalNode)
{
static_cast<OctreeNode*>(entry.m_internalNode)->Remove(*this, &entry);
@@ -415,70 +385,71 @@ namespace AzFramework
}
void OctreeSystemComponent::Enumerate(const AZ::Aabb& aabb, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeScene::Enumerate(const AZ::Aabb& aabb, const IVisibilityScene::EnumerateCallback& callback) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
m_root.Enumerate(aabb, callback);
}
void OctreeSystemComponent::Enumerate(const AZ::Sphere& sphere, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeScene::Enumerate(const AZ::Sphere& sphere, const IVisibilityScene::EnumerateCallback& callback) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
m_root.Enumerate(sphere, callback);
}
void OctreeSystemComponent::Enumerate(const AZ::Frustum& frustum, const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeScene::Enumerate(const AZ::Frustum& frustum, const IVisibilityScene::EnumerateCallback& callback) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
m_root.Enumerate(frustum, callback);
}
void OctreeSystemComponent::EnumerateNoCull(const IVisibilitySystem::EnumerateCallback& callback) const
void OctreeScene::EnumerateNoCull(const IVisibilityScene::EnumerateCallback& callback) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sharedMutex);
m_root.EnumerateNoCull(callback);
}
uint32_t OctreeSystemComponent::GetEntryCount() const
uint32_t OctreeScene::GetEntryCount() const
{
return m_entryCount;
}
OctreeNode& OctreeSystemComponent::GetRoot()
{
return m_root;
}
uint32_t OctreeSystemComponent::GetNodeCount() const
uint32_t OctreeScene::GetNodeCount() const
{
return m_nodeCount;
}
uint32_t OctreeSystemComponent::GetFreeNodeCount() const
uint32_t OctreeScene::GetFreeNodeCount() const
{
// Each entry represents GetChildNodeCount() nodes
return aznumeric_cast<uint32_t>(m_freeOctreeNodes.size() * GetChildNodeCount());
}
uint32_t OctreeSystemComponent::GetPageCount() const
uint32_t OctreeScene::GetPageCount() const
{
return aznumeric_cast<uint32_t>(m_nodeCache.size());
}
uint32_t OctreeSystemComponent::GetChildNodeCount() const
uint32_t OctreeScene::GetChildNodeCount() const
{
return AzFramework::GetChildNodeCount();
}
void OctreeSystemComponent::DumpStats([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
void OctreeScene::DumpStats()
{
AZ_TracePrintf("Console", "OctreeNode::EntryCount = %u", GetEntryCount());
AZ_TracePrintf("Console", "OctreeNode::NodeCount = %u", GetNodeCount());
AZ_TracePrintf("Console", "OctreeNode::FreeNodeCount = %u", GetFreeNodeCount());
AZ_TracePrintf("Console", "OctreeNode::PageCount = %u", GetPageCount());
AZ_TracePrintf("Console", "OctreeNode::ChildNodeCount = %u", GetChildNodeCount());
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::EntryCount = %u", GetName().GetCStr(), GetEntryCount());
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::NodeCount = %u", GetName().GetCStr(), GetNodeCount());
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::FreeNodeCount = %u", GetName().GetCStr(), GetFreeNodeCount());
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::PageCount = %u", GetName().GetCStr(), GetPageCount());
AZ_TracePrintf("Console", "OctreeScene[\"%s\"]::ChildNodeCount = %u", GetName().GetCStr(), GetChildNodeCount());
}
@@ -496,7 +467,7 @@ namespace AzFramework
}
uint32_t OctreeSystemComponent::AllocateChildNodes()
uint32_t OctreeScene::AllocateChildNodes()
{
const uint32_t childCount = GetChildNodeCount();
m_nodeCount += childCount;
@@ -540,18 +511,124 @@ namespace AzFramework
}
void OctreeSystemComponent::ReleaseChildNodes(uint32_t nodeIndex)
void OctreeScene::ReleaseChildNodes(uint32_t nodeIndex)
{
m_nodeCount -= GetChildNodeCount();
m_freeOctreeNodes.push(nodeIndex);
}
OctreeNode* OctreeSystemComponent::GetChildNodesAtIndex(uint32_t nodeIndex) const
OctreeNode* OctreeScene::GetChildNodesAtIndex(uint32_t nodeIndex) const
{
uint32_t childPage;
uint32_t childOffset;
ExtractPageAndOffsetFromIndex(nodeIndex, childPage, childOffset);
return &(*m_nodeCache[childPage])[childOffset];
}
void OctreeSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<OctreeSystemComponent, AZ::Component>()
->Version(1);
}
}
void OctreeSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("OctreeService"));
}
void OctreeSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("OctreeService"));
}
OctreeSystemComponent::OctreeSystemComponent()
{
AZ::Interface<IVisibilitySystem>::Register(this);
IVisibilitySystemRequestBus::Handler::BusConnect();
m_defaultScene = aznew OctreeScene(AZ::Name("DefaultVisibilityScene"));
}
OctreeSystemComponent::~OctreeSystemComponent()
{
AZ_Assert(m_scenes.empty(), "All IVisibilityScenes must be destroyed before shutdown");
delete m_defaultScene;
IVisibilitySystemRequestBus::Handler::BusDisconnect();
AZ::Interface<IVisibilitySystem>::Unregister(this);
}
void OctreeSystemComponent::Activate()
{
;
}
void OctreeSystemComponent::Deactivate()
{
;
}
IVisibilityScene* OctreeSystemComponent::GetDefaultVisibilityScene()
{
return m_defaultScene;
}
IVisibilityScene* OctreeSystemComponent::CreateVisibilityScene(const AZ::Name& sceneName)
{
AZ_Assert(FindVisibilityScene(sceneName) == nullptr, "Scene with same name already created!");
OctreeScene* newScene = aznew OctreeScene(sceneName);
m_scenes.push_back(newScene);
return newScene;
}
void OctreeSystemComponent::DestroyVisibilityScene(IVisibilityScene* visScene)
{
for (auto iter = m_scenes.begin(); iter != m_scenes.end(); ++iter)
{
if (*iter == visScene)
{
delete visScene;
m_scenes.erase(iter);
return;
}
}
AZ_Assert(false, "visScene[\"%s\"] not found in the OctreeSystemComponent", visScene->GetName().GetCStr());
}
IVisibilityScene* OctreeSystemComponent::FindVisibilityScene(const AZ::Name& sceneName)
{
for (OctreeScene* scene : m_scenes)
{
if(scene->GetName() == sceneName)
{
return scene;
}
}
return nullptr;
}
void OctreeSystemComponent::DumpStats([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
{
for (OctreeScene* scene : m_scenes)
{
AZ_TracePrintf("Console", "============================================");
scene->DumpStats();
}
AZ_TracePrintf("Console", "============================================");
}
}
@@ -15,14 +15,15 @@
#include <AzFramework/Visibility/IVisibilitySystem.h>
#include <AzCore/Math/Plane.h>
#include <AzCore/Component/Component.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/std/containers/stack.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/fixed_vector.h>
#include <AzCore/std/parallel/shared_mutex.h>
namespace AzFramework
{
class OctreeSystemComponent;
class OctreeScene;
//! An internal node within the tree.
//! It contains all objects that are *fully contained* by the node, if an object spans multiple child nodes that object will be stored in the parent.
@@ -40,25 +41,25 @@ namespace AzFramework
OctreeNode& operator=(OctreeNode&& rhs);
//! Inserts a VisibilityEntry into this OctreeNode, potentially triggering a split.
void Insert(OctreeSystemComponent& octreeSystemComponent, VisibilityEntry* entry);
void Insert(OctreeScene& octreeScene, VisibilityEntry* entry);
//! Updates a VisibilityEntry that is currently bound to this OctreeNode.
//! The provided entry must be bound to this node, but may no longer be bound to this node upon function exit.
void Update(OctreeSystemComponent& octreeSystemComponent, VisibilityEntry* entry);
void Update(OctreeScene& octreeScene, VisibilityEntry* entry);
//! Removes a VisibilityEntry from this OctreeNode.
//! The provided entry must be bound to this node.
void Remove(OctreeSystemComponent& octreeSystemComponent, VisibilityEntry* entry);
void Remove(OctreeScene& octreeScene, VisibilityEntry* entry);
//! Recursively enumerates any OctreeNodes and their children that intersect the provided bounding volume.
//! @{
void Enumerate(const AZ::Aabb& aabb, const IVisibilitySystem::EnumerateCallback& callback) const;
void Enumerate(const AZ::Sphere& sphere, const IVisibilitySystem::EnumerateCallback& callback) const;
void Enumerate(const AZ::Frustum& frustum, const IVisibilitySystem::EnumerateCallback& callback) const;
void Enumerate(const AZ::Aabb& aabb, const IVisibilityScene::EnumerateCallback& callback) const;
void Enumerate(const AZ::Sphere& sphere, const IVisibilityScene::EnumerateCallback& callback) const;
void Enumerate(const AZ::Frustum& frustum, const IVisibilityScene::EnumerateCallback& callback) const;
//! @}
//! Recursively enumerate *all* OctreeNodes that have any entries in them (without any culling).
void EnumerateNoCull(const IVisibilitySystem::EnumerateCallback& callback) const;
void EnumerateNoCull(const IVisibilityScene::EnumerateCallback& callback) const;
//! Returns the set of entries bound to this node.
const AZStd::vector<VisibilityEntry*>& GetEntries() const;
@@ -71,13 +72,13 @@ namespace AzFramework
private:
void TryMerge(OctreeSystemComponent& octreeSystemComponent);
void TryMerge(OctreeScene& octreeScene);
template <typename T>
void EnumerateHelper(const T& boundingVolume, const IVisibilitySystem::EnumerateCallback& callback) const;
void EnumerateHelper(const T& boundingVolume, const IVisibilityScene::EnumerateCallback& callback) const;
void Split(OctreeSystemComponent& octreeSystemComponent);
void Merge(OctreeSystemComponent& octreeSystemComponent);
void Split(OctreeScene& octreeScene);
void Merge(OctreeScene& octreeScene);
// The page is stored in the upper 16-bits of the child node index, the offset into the page is the lower 16-bits
// This gives us a maximum of 65,536 pages and 65,536 nodes per page, for a total of 2^32 - 1 total pages (-1 reserved for the invalid index)
@@ -90,60 +91,47 @@ namespace AzFramework
};
//! Implementation of the visibility system interface.
//! This uses a simple adaptive octreeSystemComponent to support partitioning an object set and efficiently running gathers and visibility queries.
class OctreeSystemComponent
: public AZ::Component
, public IVisibilitySystemRequestBus::Handler
//! This uses a simple adaptive octree to support partitioning an object set for a specific scene and efficiently running gathers and visibility queries.
class OctreeScene
: public IVisibilityScene
{
public:
AZ_RTTI(OctreeScene, "{A88E4D86-11F1-4E3F-A91A-66DE99502B93}");
AZ_CLASS_ALLOCATOR(OctreeScene, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(OctreeScene);
AZ_COMPONENT(OctreeSystemComponent, "{CD4FF1C5-BAF4-421D-951B-1E05DAEEF67B}");
explicit OctreeScene(const AZ::Name& sceneName);
virtual ~OctreeScene();
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
OctreeSystemComponent();
virtual ~OctreeSystemComponent();
//! AZ::Component overrides.
//! @{
void Activate() override;
void Deactivate() override;
//! @}
//! IVisibilitySystem overrides.
//! IVisibilityScene overrides.
//! @{
const AZ::Name& GetName() const override;
void InsertOrUpdateEntry(VisibilityEntry& entry) override;
void RemoveEntry(VisibilityEntry& entry) override;
void Enumerate(const AZ::Aabb& aabb, const IVisibilitySystem::EnumerateCallback& callback) const override;
void Enumerate(const AZ::Sphere& sphere, const IVisibilitySystem::EnumerateCallback& callback) const override;
void Enumerate(const AZ::Frustum& frustum, const IVisibilitySystem::EnumerateCallback& callback) const override;
void EnumerateNoCull(const IVisibilitySystem::EnumerateCallback& callback) const override;
void Enumerate(const AZ::Aabb& aabb, const IVisibilityScene::EnumerateCallback& callback) const override;
void Enumerate(const AZ::Sphere& sphere, const IVisibilityScene::EnumerateCallback& callback) const override;
void Enumerate(const AZ::Frustum& frustum, const IVisibilityScene::EnumerateCallback& callback) const override;
void EnumerateNoCull(const IVisibilityScene::EnumerateCallback& callback) const override;
uint32_t GetEntryCount() const override;
//! @}
//! Returns the OctreeSystemComponent's root node.
OctreeNode& GetRoot();
//! OctreeSystemComponent stats
//! Stats
//! @{
uint32_t GetNodeCount() const;
uint32_t GetFreeNodeCount() const;
uint32_t GetPageCount() const;
uint32_t GetChildNodeCount() const;
void DumpStats(const AZ::ConsoleCommandContainer& arguments);
void DumpStats();
//! @}
private:
uint32_t AllocateChildNodes();
void ReleaseChildNodes(uint32_t nodeIndex);
OctreeNode* GetChildNodesAtIndex(uint32_t nodeIndex) const;
// Bind the DumpStats member function to the console as 'OctreeSystemComponent.DumpStats'
AZ_CONSOLEFUNC(OctreeSystemComponent, DumpStats, AZ::ConsoleFunctorFlags::Null, "Dump octreeSystemComponent stats to the console window");
mutable AZStd::shared_mutex m_sharedMutex;
AZ::Name m_sceneName; //< The uniquely identifying name for the visibility scene.
OctreeNode m_root; //< The root node for the octreeSystemComponent.
uint32_t m_entryCount = 0; //< Metric tracking the number of entries inserted into the octreeSystemComponent.
@@ -158,4 +146,47 @@ namespace AzFramework
friend class OctreeNode; // For access to the node allocator methods
};
//! Implementation of the visibility system interface.
//! This manages creating, destroying, and finding the underlying octrees that are associated with specific scenes
class OctreeSystemComponent
: public AZ::Component
, public IVisibilitySystemRequestBus::Handler
{
public:
AZ_COMPONENT(OctreeSystemComponent, "{CD4FF1C5-BAF4-421D-951B-1E05DAEEF67B}");
// Bind the DumpStats member function to the console as 'OctreeSystemComponent.DumpStats'
AZ_CONSOLEFUNC(OctreeSystemComponent, DumpStats, AZ::ConsoleFunctorFlags::Null, "Dump octreeSystemComponent stats to the console window");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
OctreeSystemComponent();
virtual ~OctreeSystemComponent();
//! AZ::Component overrides.
//! @{
void Activate() override;
void Deactivate() override;
//! @}
//! IVisibilitySystem overrides
//! @{
IVisibilityScene* GetDefaultVisibilityScene() override;
IVisibilityScene* CreateVisibilityScene(const AZ::Name& sceneName) override;
void DestroyVisibilityScene(IVisibilityScene* visScene) override;
IVisibilityScene* FindVisibilityScene(const AZ::Name& sceneName) override;
void DumpStats(const AZ::ConsoleCommandContainer& arguments) override;
//! @}
private:
//! The default scene used for most entities (e.g. gameplay, networking)
OctreeScene* m_defaultScene = nullptr;
//! Other scenes (e.g. each rendering scene) are stored here and looked up by name.
AZStd::vector<OctreeScene*> m_scenes; //using a vector<> here because we'll generally have a small number of scenes
};
}
@@ -16,13 +16,14 @@
#include <AzCore/Android/APKFileHandler.h>
#include <AzCore/Android/Utils.h>
#include <AzCore/IO/IOUtils.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/functional.h>
#include <android/api-level.h>
#if __ANDROID_API__ == 19
// The following were apparently introduced in API 21, however in earlier versions of the
// The following were apparently introduced in API 21, however in earlier versions of the
// platform specific headers they were defines. In the move to unified headers, the following
// defines were removed from stat.h
#ifndef stat64
@@ -52,7 +53,7 @@ namespace AZ
if (AZ::Android::Utils::IsApkPath(resolvedPath))
{
return AZ::Android::APKFileHandler::IsDirectory(AZ::Android::Utils::StripApkPrefix(resolvedPath));
return AZ::Android::APKFileHandler::IsDirectory(AZ::Android::Utils::StripApkPrefix(resolvedPath).c_str());
}
struct stat result;
@@ -108,7 +109,7 @@ namespace AZ
if (isInAPK)
{
AZ::OSString strippedPath = AZ::Android::Utils::StripApkPrefix(pathWithoutSlash.c_str());
AZ::IO::FixedMaxPath strippedPath = AZ::Android::Utils::StripApkPrefix(pathWithoutSlash.c_str());
char tempBuffer[AZ_MAX_PATH_LEN] = {0};
@@ -21,7 +21,7 @@ namespace AzFramework
{
AZStd::string GetPersistentName()
{
AZStd::string persistentName = "Lumberyard";
AZStd::string persistentName = "Open 3D Engine";
char procPath[AZ_MAX_PATH_LEN];
AZ::Utils::GetExecutablePathReturnType ret = AZ::Utils::GetExecutablePath(procPath, AZ_MAX_PATH_LEN);
@@ -56,7 +56,7 @@ namespace AzFramework
bool m_isInBorderlessWindowFullScreenState = false; //!< Was a borderless window used to enter full screen state?
};
const char* NativeWindowImpl_Win32::s_defaultClassName = "LumberyardWin32Class";
const char* NativeWindowImpl_Win32::s_defaultClassName = "O3DEWin32Class";
NativeWindow::Implementation* NativeWindow::Implementation::Create()
{
@@ -85,7 +85,7 @@ namespace AzFramework
//!
//! return another vector relative to the specified display orientation, and such that the
//! +y axis points out the back of the screen and z+ axis points out the top of the device.
//! This flipping of axes is to match Lumberyard's z-up and left-handed coordinate system.
//! This flipping of axes is to match Open 3D Engine's z-up and left-handed coordinate system.
//!
//! \param[in] x The x component of the vector to be aligned
//! \param[in] y The y component of the vector to be aligned
@@ -28,9 +28,9 @@ namespace AzGameFramework
GameApplication::GameApplication()
{
}
GameApplication::GameApplication(int* argc, char*** argv)
: Application(argc, argv)
GameApplication::GameApplication(int argc, char** argv)
: Application(&argc, &argv)
{
}
@@ -108,7 +108,7 @@ namespace AzGameFramework
}
void GameApplication::QueryApplicationType(AZ::ApplicationTypeQuery& appType) const
{
{
appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Game;
};
@@ -24,7 +24,7 @@ namespace AzGameFramework
AZ_CLASS_ALLOCATOR(GameApplication, AZ::SystemAllocator, 0);
GameApplication();
GameApplication(int* argc, char*** argvS);
GameApplication(int argc, char** argvS);
~GameApplication();
AZ::ComponentTypeList GetRequiredSystemComponents() const override;
@@ -14,19 +14,17 @@
/**
* \mainpage
*
* Introduced with Amazon Lumberyard version 1.25 and the release of UI 2.0, Lumberyard's
* custom Qt widget library provides developers with access to the same UI components used
* throughout Lumberyard. Using this library, UI developers can build their own tools and
* extensions for Lumberyard, while maintaining a coherent and standardized UI experience.
* Using this library, UI developers can build their own tools and
* extensions for Open 3D Engine, while maintaining a coherent and standardized UI experience.
* This custom library provides new and extended widgets, and includes a set of styles and
* user interaction patterns that are applied on top of the Qt framework - the C++ library
* that Lumberyard relies on for its UI. The library can be extended to support your own customizations and modifications.
* that Open 3D Engine relies on for its UI. The library can be extended to support your own customizations and modifications.
*
* With this UI 2.0 API reference guide, we're working towards offering a full and comprehensive
* API refernce for all tools developers that are extending Lumberyard. The API reference
* API refernce for all tools developers that are extending Open 3D Engine. The API reference
* is intended for C++ programmers building tools. For UX designers looking to understand
* the best patterns and practices when making a tool to comfortably integrate with
* the Lumberyard editor, see the [UI 2.0 design guide](https://docs.aws.amazon.com/lumberyard/latest/ui/).
* the Open 3D Engine editor, see the [UI 2.0 design guide](https://docs.aws.amazon.com/lumberyard/latest/ui/).
*/
#include <AzCore/PlatformDef.h>
@@ -17,7 +17,7 @@
#include <AzQtComponents/Components/Widgets/LineEdit.h>
#include <AzQtComponents/Utilities/ScreenUtilities.h>
#include "Components/ui_FilteredSearchWidget.h"
#include <AzQtComponents/Components/ui_FilteredSearchWidget.h>
#include <AzQtComponents/Components/FlowLayout.h>
@@ -16,10 +16,10 @@
namespace AzQtComponents
{
// Here for backwards compatibility with the old name of this class
class LumberyardStylesheet : public StyleManager
class O3DEStylesheet : public StyleManager
{
public:
LumberyardStylesheet(QObject* parent) : StyleManager(parent) {}
O3DEStylesheet(QObject* parent) : StyleManager(parent) {}
};
} // namespace AzQtComponents
@@ -39,7 +39,7 @@ namespace AzQtComponents
} // namespace Internal
/**
* The UI 2.0 Lumberyard Qt Style.
* The UI 2.0 Open 3D Engine Qt Style.
*
* Should not need to be used directly; use the AzQtComponents::StyleManager instead.
*
@@ -37,7 +37,7 @@ namespace AzQtComponents
class AutoCustomWindowDecorations;
/**
* Wrapper around classes dealing with Lumberyard style.
* Wrapper around classes dealing with Open 3D Engine style.
*
* New applications should work like this:
*
@@ -24,7 +24,7 @@ class QMimeData;
namespace AzQtComponents
{
static const QString MIME_TYPE_PALETTE = QStringLiteral("application/x-lumberyard-color-palette+xml");
static const QString MIME_TYPE_PALETTE = QStringLiteral("application/x-o3de-color-palette+xml");
class PaletteModel;
@@ -19,7 +19,7 @@
#include <QPushButton>
#include <QMessageBox>
#include <AzCore/Casting/numeric_cast.h>
#include <Components/Widgets/Internal/ui_OverlayWidgetLayer.h>
#include <AzQtComponents/Components/Widgets/Internal/ui_OverlayWidgetLayer.h>
#include <AzCore/Debug/Trace.h>
namespace AzQtComponents
@@ -264,4 +264,4 @@ namespace AzQtComponents
} // namespace Internal
} // namespace AzQtComponents
#include "Components/Widgets/Internal/moc_OverlayWidgetLayer.cpp"
#include "Components/Widgets/Internal/moc_OverlayWidgetLayer.cpp"
@@ -20,7 +20,7 @@ namespace AzQtComponents
class Style;
/**
* Lumberyard specific wrapper to do MessageBox type stuff, specifically to automatically handle
* Open 3D Engine specific wrapper to do MessageBox type stuff, specifically to automatically handle
* checking/writing "do not ask this question again" checkbox/settings.
*
* Called AzMessageBox instead of MessageBox because for windows.h does #define MessageBox MessageBoxA / MessageBoxW
@@ -179,7 +179,7 @@ namespace AzQtComponents
{
m_guestWidget = nullptr;
// the Lumberyard Editor has code that checks for Modal widgets, and blocks on doing other things
// the Open 3D Engine Editor has code that checks for Modal widgets, and blocks on doing other things
// if there are still active Modal dialogs.
// So we need to ensure that this WindowDecorationWrapper doesn't report itself as being modal
// after the guest widget has been deleted.
@@ -10,7 +10,7 @@
*
*/
#include "AssetBrowserFolderPage.h"
#include "Gallery/ui_AssetBrowserFolderPage.h"
#include <AzQtComponents/Gallery/ui_AssetBrowserFolderPage.h>
#include <AzToolsFramework/AssetBrowser/Views/AssetBrowserFolderWidget.h>
#include <AzCore/Casting/numeric_cast.h>
@@ -11,7 +11,7 @@
*/
#include "BreadCrumbsPage.h"
#include "Gallery/ui_BreadCrumbsPage.h"
#include <AzQtComponents/Gallery/ui_BreadCrumbsPage.h>
#include <QDebug>
#include <QStyle>
@@ -107,4 +107,4 @@ BreadCrumbsPage::~BreadCrumbsPage()
{
}
#include "Gallery/moc_BreadCrumbsPage.cpp"
#include "Gallery/moc_BreadCrumbsPage.cpp"
@@ -11,7 +11,7 @@
*/
#include "BrowseEditPage.h"
#include "Gallery/ui_BrowseEditPage.h"
#include <AzQtComponents/Gallery/ui_BrowseEditPage.h>
#include <AzQtComponents/Components/Widgets/BrowseEdit.h>
#include <QIntValidator>
@@ -12,7 +12,7 @@
#include "ButtonPage.h"
#include "FixedStateButton.h"
#include "Gallery/ui_ButtonPage.h"
#include <AzQtComponents/Gallery/ui_ButtonPage.h>
#include <AzQtComponents/Components/Widgets/PushButton.h>
@@ -110,4 +110,4 @@ ButtonPage::~ButtonPage()
{
}
#include "Gallery/moc_ButtonPage.cpp"
#include "Gallery/moc_ButtonPage.cpp"
@@ -11,7 +11,7 @@
*/
#include "CardPage.h"
#include "Gallery/ui_CardPage.h"
#include <AzQtComponents/Gallery/ui_CardPage.h>
#include <AzQtComponents/Components/Widgets/Card.h>
#include <AzQtComponents/Components/Widgets/CardNotification.h>
@@ -11,7 +11,7 @@
*/
#include "CheckBoxPage.h"
#include "Gallery/ui_CheckBoxPage.h"
#include <AzQtComponents/Gallery/ui_CheckBoxPage.h>
#include <AzQtComponents/Components/Widgets/CheckBox.h>
@@ -71,4 +71,4 @@ CheckBoxPage::~CheckBoxPage()
{
}
#include "Gallery/moc_CheckBoxPage.cpp"
#include "Gallery/moc_CheckBoxPage.cpp"
@@ -11,7 +11,7 @@
*/
#include "ColorLabelPage.h"
#include "Gallery/ui_ColorLabelPage.h"
#include <AzQtComponents/Gallery/ui_ColorLabelPage.h>
#include <AzQtComponents/Utilities/Conversions.h>
@@ -11,7 +11,7 @@
*/
#include "ColorPickerPage.h"
#include "Gallery/ui_ColorPickerPage.h"
#include <AzQtComponents/Gallery/ui_ColorPickerPage.h>
#include <AzQtComponents/Components/Widgets/ColorPicker.h>
#include <AzQtComponents/Utilities/Conversions.h>
@@ -11,7 +11,7 @@
*/
#include "ComboBoxPage.h"
#include "Gallery/ui_ComboBoxPage.h"
#include <AzQtComponents/Gallery/ui_ComboBoxPage.h>
#include <AzQtComponents/Components/Widgets/CheckBox.h>
#include <AzQtComponents/Components/Widgets/ComboBox.h>
@@ -11,7 +11,7 @@
*/
#include "ComponentDemoWidget.h"
#include "Gallery/ui_ComponentDemoWidget.h"
#include "AzQtComponents/Gallery/ui_ComponentDemoWidget.h"
#include "AssetBrowserFolderPage.h"
#include "BreadCrumbsPage.h"
#include "BrowseEditPage.h"
@@ -11,7 +11,7 @@
*/
#include "DragAndDropPage.h"
#include <Gallery/ui_DragAndDropPage.h>
#include <AzQtComponents/Gallery/ui_DragAndDropPage.h>
#include <QLabel>
#include <AzQtComponents/Components/Style.h>
@@ -11,7 +11,7 @@
*/
#include "FilteredSearchWidgetPage.h"
#include "Gallery/ui_FilteredSearchWidgetPage.h"
#include <AzQtComponents/Gallery/ui_FilteredSearchWidgetPage.h>
FilteredSearchWidgetPage::FilteredSearchWidgetPage(QWidget* parent)
: QWidget(parent)
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fe52372c907d680df52dbf32d863a4007a15db90e9ad35fbe153870a72e2d0ef
size 108402
@@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "Gallery.ico"
@@ -12,7 +12,7 @@
#include "GradientSliderPage.h"
#include <AzQtComponents/Utilities/Conversions.h>
#include "Gallery/ui_GradientSliderPage.h"
#include <AzQtComponents/Gallery/ui_GradientSliderPage.h>
#include <AzQtComponents/Components/Widgets/GradientSlider.h>
#include <AzCore/Casting/numeric_cast.h>
@@ -11,7 +11,7 @@
*/
#include "HyperlinkPage.h"
#include <Gallery/ui_HyperlinkPage.h>
#include <AzQtComponents/Gallery/ui_HyperlinkPage.h>
#include <QLabel>
#include <AzQtComponents/Components/Style.h>
@@ -11,7 +11,7 @@
*/
#include "LineEditPage.h"
#include "Gallery/ui_LineEditPage.h"
#include <AzQtComponents/Gallery/ui_LineEditPage.h>
#include <QValidator>
#include <QDoubleValidator>
@@ -11,7 +11,7 @@
*/
#include "MenuPage.h"
#include <Gallery/ui_MenuPage.h>
#include <AzQtComponents/Gallery/ui_MenuPage.h>
#include <QMenu>
@@ -83,7 +83,7 @@ action->setChecked(true);
auto submenu = menu->addMenu(QStringLiteral("Submenu"));
submenu->addAction(actionText);
// Note: some Lumberyard menus (like the one in the MainWindow) forcefully hide icons by design.
// Note: some Open 3D Engine menus (like the one in the MainWindow) forcefully hide icons by design.
</pre>
@@ -11,7 +11,7 @@
*/
#include "ProgressIndicatorPage.h"
#include "Gallery/ui_ProgressIndicatorPage.h"
#include <AzQtComponents/Gallery/ui_ProgressIndicatorPage.h>
ProgressIndicatorPage::ProgressIndicatorPage(QWidget* parent)
: QWidget(parent)
@@ -75,4 +75,4 @@ ProgressIndicatorPage::~ProgressIndicatorPage()
{
}
#include "Gallery/moc_ProgressIndicatorPage.cpp"
#include "Gallery/moc_ProgressIndicatorPage.cpp"
@@ -11,7 +11,7 @@
*/
#include "RadioButtonPage.h"
#include "Gallery/ui_RadioButtonPage.h"
#include <AzQtComponents/Gallery/ui_RadioButtonPage.h>
#include <AzQtComponents/Components/Widgets/RadioButton.h>
@@ -59,4 +59,4 @@ RadioButtonPage::~RadioButtonPage()
{
}
#include "Gallery/moc_RadioButtonPage.cpp"
#include "Gallery/moc_RadioButtonPage.cpp"
@@ -11,7 +11,7 @@
*/
#include "ReflectedPropertyEditorPage.h"
#include <Gallery/ui_ReflectedPropertyEditorPage.h>
#include <AzQtComponents/Gallery/ui_ReflectedPropertyEditorPage.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Serialization/SerializeContext.h>
@@ -11,7 +11,7 @@
*/
#include "ScrollBarPage.h"
#include <Gallery/ui_ScrollBarPage.h>
#include <AzQtComponents/Gallery/ui_ScrollBarPage.h>
#include <AzQtComponents/Components/Widgets/ScrollBar.h>
@@ -11,7 +11,7 @@
*/
#include "SegmentControlPage.h"
#include "Gallery/ui_SegmentControlPage.h"
#include <AzQtComponents/Gallery/ui_SegmentControlPage.h>
#include <AzQtComponents/Components/Widgets/SegmentBar.h>
#include <AzQtComponents/Components/Widgets/SegmentControl.h>
@@ -11,7 +11,7 @@
*/
#include "SliderComboPage.h"
#include <Gallery/ui_SliderComboPage.h>
#include <AzQtComponents/Gallery/ui_SliderComboPage.h>
#include <AzQtComponents/Components/Widgets/Slider.h>
#include <AzQtComponents/Components/Widgets/SliderCombo.h>
@@ -11,7 +11,7 @@
*/
#include "SliderPage.h"
#include "Gallery/ui_SliderPage.h"
#include <AzQtComponents/Gallery/ui_SliderPage.h>
#include <AzQtComponents/Components/Widgets/Slider.h>
@@ -155,4 +155,4 @@ SliderPage::~SliderPage()
{
}
#include "Gallery/moc_SliderPage.cpp"
#include "Gallery/moc_SliderPage.cpp"

Some files were not shown because too many files have changed in this diff Show More