Merge branch 'main' into cgalvan/EntityHelperRefactor
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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."));
|
||||
}
|
||||
|
||||
@@ -1117,7 +1117,7 @@ namespace AZ
|
||||
return asset;
|
||||
}
|
||||
|
||||
void AssetManager::UpdateDebugStatus(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
void AssetManager::UpdateDebugStatus(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
|
||||
{
|
||||
if(!m_debugAssetEvents)
|
||||
{
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace AZ
|
||||
|
||||
Asset<AssetData> GetAssetInternal(const AssetId& assetId, const AssetType& assetType, AssetLoadBehavior assetReferenceLoadBehavior, const AssetLoadParameters& loadParams = AssetLoadParameters{}, AssetInfo assetInfo = AssetInfo(), bool signalLoaded = false);
|
||||
|
||||
void UpdateDebugStatus(AZ::Data::Asset<AZ::Data::AssetData> asset);
|
||||
void UpdateDebugStatus(const AZ::Data::Asset<AZ::Data::AssetData>& asset);
|
||||
|
||||
/**
|
||||
* Gets a root asset and dependencies as individual async loads if necessary.
|
||||
|
||||
@@ -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,78 +173,85 @@ 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
|
||||
{
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry)
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
|
||||
: m_registry{ registry }
|
||||
, m_commandLine{ commandLine }
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
UpdateProjectSpecializationInRegistry(path);
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
// #1 Update the project settings when the project path is set
|
||||
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));
|
||||
}
|
||||
|
||||
// #2 Update the project specialization when the project name is set
|
||||
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);
|
||||
}
|
||||
|
||||
// #3 Update the ComponentApplication CommandLine instance when the command line settings are merged into the Settings Registry
|
||||
if (path == AZ::SettingsRegistryMergeUtils::CommandLineValueChangedKey)
|
||||
{
|
||||
UpdateCommandLine();
|
||||
}
|
||||
}
|
||||
|
||||
//! 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void UpdateCommandLine()
|
||||
{
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(m_registry, m_commandLine);
|
||||
}
|
||||
|
||||
private:
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_currentSpecialization;
|
||||
AZ::IO::FixedMaxPath m_oldProjectPath;
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_oldProjectName;
|
||||
AZ::SettingsRegistryInterface& m_registry;
|
||||
AZ::CommandLine& m_commandLine;
|
||||
};
|
||||
|
||||
void ComponentApplication::Descriptor::AllocatorRemapping::Reflect(ReflectContext* context, ComponentApplication* app)
|
||||
@@ -424,7 +430,13 @@ namespace AZ
|
||||
// Add the Command Line arguments into the SettingsRegistry
|
||||
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
|
||||
|
||||
// Merge Command Line arguments
|
||||
// Add a notifier to update the project_settings when
|
||||
// 1. The 'project_path' key changes
|
||||
// 2. The project specialization when the 'project-name' key changes
|
||||
// 3. The ComponentApplication command line when the command line is stored to the registry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry, m_commandLine });
|
||||
|
||||
// Merge Command Line arguments
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
|
||||
@@ -438,10 +450,6 @@ namespace AZ
|
||||
// for the application root.
|
||||
CalculateAppRoot();
|
||||
|
||||
// Add a notifier to update the /Amazon/AzCore/Settings/Specializations
|
||||
// when the 'project_path' property changes within the SettingsRegistry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry });
|
||||
|
||||
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
@@ -918,6 +926,8 @@ namespace AZ
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations)
|
||||
@@ -1395,10 +1405,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 +1413,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.
|
||||
*/
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace AZ
|
||||
{
|
||||
class Vector3;
|
||||
|
||||
//! Do not allow the scale to be zero to avoid problems with inverting scale.
|
||||
static constexpr float MinNonUniformScale = 1e-3f;
|
||||
|
||||
using NonUniformScaleChangedEvent = AZ::Event<const AZ::Vector3&>;
|
||||
|
||||
//! Requests for working with non-uniform scale.
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace AZ
|
||||
{
|
||||
class Transform;
|
||||
|
||||
using TransformChangedEvent = Event<Transform, Transform>;
|
||||
using TransformChangedEvent = Event<const Transform&, const Transform&>;
|
||||
|
||||
using ParentChangedEvent = Event<EntityId, EntityId>;
|
||||
|
||||
|
||||
@@ -42,9 +42,8 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
#define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
|
||||
|
||||
#ifdef AZ_PROFILE_TELEMETRY
|
||||
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
|
||||
# define AZ_TRACE_METHOD_NAME(name) \
|
||||
AZ_TRACE_METHOD_NAME_CATEGORY(name, "") \
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzTrace, name)
|
||||
@@ -53,6 +52,7 @@ namespace AZ
|
||||
AZ_TRACE_METHOD_NAME_CATEGORY(AZ_FUNCTION_SIGNATURE, "") \
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzTrace)
|
||||
#else
|
||||
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category)
|
||||
# define AZ_TRACE_METHOD_NAME(name) AZ_TRACE_METHOD_NAME_CATEGORY(name, "")
|
||||
# define AZ_TRACE_METHOD() AZ_TRACE_METHOD_NAME(AZ_FUNCTION_SIGNATURE)
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
//
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -38,6 +38,13 @@ namespace AZ
|
||||
bool CompareValueData(const void* lhs, const void* rhs) override;
|
||||
};
|
||||
|
||||
//! Limits for transform scale values.
|
||||
//! The scale should not be zero to avoid problems with inverting.
|
||||
//! @{
|
||||
static constexpr float MinTransformScale = 1e-2f;
|
||||
static constexpr float MaxTransformScale = 1e9f;
|
||||
//! @}
|
||||
|
||||
//! The basic transformation class, represented using a quaternion rotation, vector scale and vector translation.
|
||||
//! By design, cannot represent skew transformations.
|
||||
class Transform
|
||||
|
||||
@@ -167,14 +167,14 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector2::Vector2(const Vector3& source)
|
||||
Vector2::Vector2(const Vector3& source)
|
||||
: m_x(source.GetX())
|
||||
, m_y(source.GetY())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector2::Vector2(const Vector4& source)
|
||||
Vector2::Vector2(const Vector4& source)
|
||||
: m_x(source.GetX())
|
||||
, m_y(source.GetY())
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AZ::PC:
|
||||
return "PC";
|
||||
case AZ::ES3:
|
||||
return "Android";
|
||||
case AZ::IOS:
|
||||
return "iOS";
|
||||
case AZ::OSX:
|
||||
return "Mac";
|
||||
case AZ::PROVO:
|
||||
return "Provo";
|
||||
case AZ::SALEM:
|
||||
return "Salem";
|
||||
case AZ::JASPER:
|
||||
return "Jasper";
|
||||
case AZ::SERVER:
|
||||
return "Server";
|
||||
case AZ::ALL:
|
||||
case AZ::ALL_CLIENT:
|
||||
case AZ::NumPlatformIds:
|
||||
case AZ::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if (checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string < (AssetPlatformFixedString{}.max_size() + 1)* PlatformId::NumPlatformIds > ;
|
||||
|
||||
const char* PlatformIdToPalFolder(PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
}
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ByteStreamSerializer.h"
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace ByteSerializerInternal
|
||||
{
|
||||
static JsonSerializationResult::Result Load(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context)
|
||||
{
|
||||
using JsonSerializationResult::Outcomes;
|
||||
using JsonSerializationResult::Tasks;
|
||||
|
||||
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
|
||||
|
||||
switch (inputValue.GetType())
|
||||
{
|
||||
case rapidjson::kStringType: {
|
||||
JsonByteStream buffer;
|
||||
if (AZ::StringFunc::Base64::Decode(buffer, inputValue.GetString(), inputValue.GetStringLength()))
|
||||
{
|
||||
JsonByteStream* valAsByteStream = static_cast<JsonByteStream*>(outputValue);
|
||||
*valAsByteStream = AZStd::move(buffer);
|
||||
return context.Report(Tasks::ReadField, Outcomes::Success, "Successfully read ByteStream.");
|
||||
}
|
||||
return context.Report(Tasks::ReadField, Outcomes::Invalid, "Decode of Base64 encoded ByteStream failed.");
|
||||
}
|
||||
case rapidjson::kArrayType:
|
||||
case rapidjson::kObjectType:
|
||||
case rapidjson::kNullType:
|
||||
case rapidjson::kFalseType:
|
||||
case rapidjson::kTrueType:
|
||||
case rapidjson::kNumberType:
|
||||
return context.Report(
|
||||
Tasks::ReadField, Outcomes::Unsupported,
|
||||
"Unsupported type. ByteStream values cannot be read from arrays, objects, nulls, booleans or numbers.");
|
||||
default:
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unknown, "Unknown json type encountered for ByteStream value.");
|
||||
}
|
||||
}
|
||||
|
||||
static JsonSerializationResult::Result StoreWithDefault(
|
||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, JsonSerializerContext& context)
|
||||
{
|
||||
using JsonSerializationResult::Outcomes;
|
||||
using JsonSerializationResult::Tasks;
|
||||
|
||||
const JsonByteStream& valAsByteStream = *static_cast<const JsonByteStream*>(inputValue);
|
||||
if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast<const JsonByteStream*>(defaultValue)))
|
||||
{
|
||||
const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size());
|
||||
outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator());
|
||||
return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored.");
|
||||
}
|
||||
|
||||
return context.Report(Tasks::WriteValue, Outcomes::DefaultsUsed, "Default ByteStream used.");
|
||||
}
|
||||
} // namespace ByteSerializerInternal
|
||||
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonByteStreamSerializer, SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result JsonByteStreamSerializer::Load(
|
||||
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context)
|
||||
{
|
||||
AZ_Assert(
|
||||
azrtti_typeid<JsonByteStream>() == outputValueTypeId,
|
||||
"Unable to deserialize AZStd::vector<AZ::u8>> to json because the provided type is %s",
|
||||
outputValueTypeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
return ByteSerializerInternal::Load(outputValue, inputValue, context);
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonByteStreamSerializer::Store(
|
||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
|
||||
JsonSerializerContext& context)
|
||||
{
|
||||
AZ_Assert(
|
||||
azrtti_typeid<JsonByteStream>() == valueTypeId,
|
||||
"Unable to serialize AZStd::vector<AZ::u8> to json because the provided type is %s",
|
||||
valueTypeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
return ByteSerializerInternal::StoreWithDefault(outputValue, inputValue, defaultValue, context);
|
||||
}
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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/Serialization/Json/BaseJsonSerializer.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
using JsonByteStream = AZStd::vector<AZ::u8>; //!< Alias for AZStd::vector<AZ::u8>.
|
||||
|
||||
//! Serialize a stream of bytes (usually binary data) as a json string value.
|
||||
//! @note Related to GenericClassByteStream (part of SerializeGenericTypeInfo<AZStd::vector<AZ::u8>> - see AZStdContainers.inl for more
|
||||
//! details).
|
||||
class JsonByteStreamSerializer : public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonByteStreamSerializer, "{30F0EA5A-CD13-4BA7-BAE1-D50D851CAC45}", BaseJsonSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
JsonSerializationResult::Result Load(
|
||||
void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context) override;
|
||||
JsonSerializationResult::Result Store(
|
||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId,
|
||||
JsonSerializerContext& context) override;
|
||||
};
|
||||
} // namespace AZ
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Serialization/Json/ArraySerializer.h>
|
||||
#include <AzCore/Serialization/Json/BasicContainerSerializer.h>
|
||||
#include <AzCore/Serialization/Json/BoolSerializer.h>
|
||||
#include <AzCore/Serialization/Json/ByteStreamSerializer.h>
|
||||
#include <AzCore/Serialization/Json/DoubleSerializer.h>
|
||||
#include <AzCore/Serialization/Json/IntSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
|
||||
@@ -68,6 +69,8 @@ namespace AZ
|
||||
jsonContext->Serializer<JsonStringSerializer>()->HandlesType<AZStd::string>();
|
||||
jsonContext->Serializer<JsonOSStringSerializer>()->HandlesType<OSString>();
|
||||
|
||||
jsonContext->Serializer<JsonByteStreamSerializer>()->HandlesType<JsonByteStream>();
|
||||
|
||||
jsonContext->Serializer<JsonBasicContainerSerializer>()
|
||||
->HandlesType<AZStd::fixed_vector>()
|
||||
->HandlesType<AZStd::forward_list>()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/JSON/pointer.h>
|
||||
#include <AzCore/JSON/prettywriter.h>
|
||||
#include <AzCore/JSON/writer.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
@@ -132,23 +133,14 @@ namespace AZ::Internal
|
||||
|
||||
AZ::IO::FixedMaxPath ScanUpRootLocator(AZStd::string_view rootFileToLocate)
|
||||
{
|
||||
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
|
||||
if (AZ::Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string
|
||||
// stored within it
|
||||
executableDir.resize_no_construct(AZStd::char_traits<char>::length(executableDir.data()));
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath engineRootCandidate{ executableDir };
|
||||
AZ::IO::FixedMaxPath rootCandidate{ AZ::Utils::GetExecutableDirectory() };
|
||||
|
||||
bool rootPathVisited = false;
|
||||
do
|
||||
{
|
||||
if (AZ::IO::SystemFile::Exists((engineRootCandidate / rootFileToLocate).c_str()))
|
||||
if (AZ::IO::SystemFile::Exists((rootCandidate / rootFileToLocate).c_str()))
|
||||
{
|
||||
return engineRootCandidate;
|
||||
return rootCandidate;
|
||||
}
|
||||
|
||||
// Note for posix filesystems the parent directory of '/' is '/' and for windows
|
||||
@@ -156,38 +148,69 @@ namespace AZ::Internal
|
||||
|
||||
// Validate that the parent directory isn't itself, that would imply
|
||||
// that it is the filesystem root path
|
||||
AZ::IO::PathView parentPath = engineRootCandidate.ParentPath();
|
||||
rootPathVisited = (engineRootCandidate == parentPath);
|
||||
AZ::IO::PathView parentPath = rootCandidate.ParentPath();
|
||||
rootPathVisited = (rootCandidate == parentPath);
|
||||
// Recurse upwards one directory
|
||||
engineRootCandidate = AZStd::move(parentPath);
|
||||
rootCandidate = AZStd::move(parentPath);
|
||||
|
||||
} while (!rootPathVisited);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
|
||||
AZStd::string_view path, AZStd::string_view value)
|
||||
{
|
||||
AZ::CommandLine commandLine;
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
|
||||
AZ::CommandLine::ParamContainer paramContainer;
|
||||
commandLine.Dump(paramContainer);
|
||||
|
||||
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
|
||||
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
|
||||
paramContainer.emplace(paramContainer.begin(), AZStd::move(projectPathOverride));
|
||||
commandLine.Parse(paramContainer);
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
}
|
||||
} // namespace AZ::Internal
|
||||
|
||||
namespace AZ::SettingsRegistryMergeUtils
|
||||
{
|
||||
constexpr AZStd::string_view InternalScanUpEngineRootKey{ "/O3DE/Settings/Internal/engine_root_scan_up_path" };
|
||||
constexpr AZStd::string_view InternalScanUpProjectRootKey{ "/O3DE/Settings/Internal/project_root_scan_up_path" };
|
||||
|
||||
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry)
|
||||
{
|
||||
AZ::IO::FixedMaxPath engineRoot;
|
||||
|
||||
// This is the 'external' engine root key, as in passed from command-line or .setreg files.
|
||||
auto engineRootKey = SettingsRegistryInterface::FixedValueString::format("%s/engine_path", BootstrapSettingsRootKey);
|
||||
|
||||
// Step 1 Run the scan upwards logic once to find the location of the engine.json if it exist
|
||||
// Once this step is run the {InternalScanUpEngineRootKey} is set in the Settings Registry
|
||||
// to have this scan logic only run once InternalScanUpEngineRootKey the supplied registry
|
||||
if (settingsRegistry.GetType(InternalScanUpEngineRootKey) == SettingsRegistryInterface::Type::NoType)
|
||||
{
|
||||
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
|
||||
engineRoot = Internal::ScanUpRootLocator("engine.json");
|
||||
// Set the {InternalScanUpEngineRootKey} to make sure this code path isn't called again for this settings registry
|
||||
settingsRegistry.Set(InternalScanUpEngineRootKey, engineRoot.Native());
|
||||
if (!engineRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.Native());
|
||||
// Inject the engine root into the front of the command line settings
|
||||
Internal::InjectSettingToCommandLineFront(settingsRegistry, engineRootKey, engineRoot.Native());
|
||||
return engineRoot;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2 check if the engine_path key has been supplied
|
||||
if (settingsRegistry.Get(engineRoot.Native(), engineRootKey); !engineRoot.empty())
|
||||
{
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
|
||||
if (engineRoot = Internal::ScanUpRootLocator("engine.json"); !engineRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.c_str());
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
// Step 3 locate the project root and attempt to find the engine root using the registered engine
|
||||
// for the project in the project.json file
|
||||
AZ::IO::FixedMaxPath projectRoot = FindProjectRoot(settingsRegistry);
|
||||
if (projectRoot.empty())
|
||||
{
|
||||
@@ -207,16 +230,30 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry)
|
||||
{
|
||||
AZ::IO::FixedMaxPath projectRoot;
|
||||
// This is the 'external' project root key, as in passed from command-line or .setreg files.
|
||||
auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
|
||||
const auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
|
||||
// Step 1 Run the scan upwards logic once to find the location of the project.json if it exist
|
||||
// Once this step is run the {InternalScanUpProjectRootKey} is set in the Settings Registry
|
||||
// to have this scan logic only run once for the supplied registry
|
||||
// SettingsRegistryInterface::GetType is used to check if a key is set
|
||||
if (settingsRegistry.GetType(InternalScanUpProjectRootKey) == SettingsRegistryInterface::Type::NoType)
|
||||
{
|
||||
return projectRoot;
|
||||
projectRoot = Internal::ScanUpRootLocator("project.json");
|
||||
// Set the {InternalScanUpProjectRootKey} to make sure this code path isn't called again for this settings registry
|
||||
settingsRegistry.Set(InternalScanUpProjectRootKey, projectRoot.Native());
|
||||
if (!projectRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
|
||||
// Inject the project root into the front of the command line settings
|
||||
Internal::InjectSettingToCommandLineFront(settingsRegistry, projectRootKey, projectRoot.Native());
|
||||
return projectRoot;
|
||||
}
|
||||
}
|
||||
|
||||
if (projectRoot = Internal::ScanUpRootLocator("project.json"); !projectRoot.empty())
|
||||
// Step 2 Check the project-path key
|
||||
// This is the project path root key, as in passed from command-line or .setreg files.
|
||||
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
|
||||
{
|
||||
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
|
||||
return projectRoot;
|
||||
}
|
||||
|
||||
@@ -463,24 +500,13 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
void MergeSettingsToRegistry_Bootstrap(SettingsRegistryInterface& registry)
|
||||
{
|
||||
ConfigParserSettings parserSettings;
|
||||
parserSettings.m_commentPrefixFunc = [](AZStd::string_view line) -> AZStd::string_view
|
||||
{
|
||||
constexpr AZStd::string_view commentPrefixes[]{ "--", ";","#" };
|
||||
for (AZStd::string_view commentPrefix : commentPrefixes)
|
||||
{
|
||||
if (size_t commentOffset = line.find(commentPrefix); commentOffset != AZStd::string_view::npos)
|
||||
{
|
||||
return line.substr(0, commentOffset);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
};
|
||||
parserSettings.m_registryRootPointerPath = BootstrapSettingsRootKey;
|
||||
MergeSettingsToRegistry_ConfigFile(registry, "bootstrap.cfg", parserSettings);
|
||||
}
|
||||
|
||||
void MergeSettingsToRegistry_AddRuntimeFilePaths(SettingsRegistryInterface& registry)
|
||||
{
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
// Binary folder
|
||||
AZ::IO::FixedMaxPath path = AZ::Utils::GetExecutableDirectory();
|
||||
registry.Set(FilePathKey_BinaryFolder, path.LexicallyNormal().Native());
|
||||
@@ -489,27 +515,25 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZ::IO::FixedMaxPath engineRoot = FindEngineRoot(registry);
|
||||
registry.Set(FilePathKey_EngineRootFolder, engineRoot.LexicallyNormal().Native());
|
||||
|
||||
constexpr size_t bufferSize = 64;
|
||||
auto buffer = AZStd::fixed_string<bufferSize>::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectPathKey(buffer);
|
||||
auto projectPathKey = FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
SettingsRegistryInterface::FixedValueString projectPathValue;
|
||||
if (registry.Get(projectPathValue, projectPathKey))
|
||||
{
|
||||
// Cache folder
|
||||
// Get the name of the asset platform assigned by the bootstrap. First check for platform version such as "windows_assets"
|
||||
// and if that's missing just get "assets".
|
||||
constexpr char platformName[] = AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER;
|
||||
|
||||
SettingsRegistryInterface::FixedValueString assetPlatform;
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/%s_assets", BootstrapSettingsRootKey, platformName);
|
||||
AZStd::string_view assetPlatformKey(buffer);
|
||||
if (!registry.Get(assetPlatform, assetPlatformKey))
|
||||
FixedValueString assetPlatform;
|
||||
if (auto assetPlatformKey = FixedValueString::format("%s/%s_assets", BootstrapSettingsRootKey, AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER);
|
||||
!registry.Get(assetPlatform, assetPlatformKey))
|
||||
{
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/assets", BootstrapSettingsRootKey);
|
||||
assetPlatformKey = AZStd::string_view(buffer);
|
||||
assetPlatformKey = FixedValueString::format("%s/assets", BootstrapSettingsRootKey);
|
||||
registry.Get(assetPlatform, assetPlatformKey);
|
||||
}
|
||||
if (assetPlatform.empty())
|
||||
{
|
||||
// Use the platform codename to retrieve the default asset platform value
|
||||
assetPlatform = AZ::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
|
||||
}
|
||||
|
||||
// Project path - corresponds to the @devassets@ alias
|
||||
// NOTE: Here we append to engineRoot, but if projectPathValue is absolute then engineRoot is discarded.
|
||||
@@ -549,8 +573,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
{
|
||||
// Cache: project root - no corresponding fileIO alias, but this is where the asset database lives.
|
||||
// A registry override is accepted using the "project_cache_path" key.
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/project_cache_path", BootstrapSettingsRootKey);
|
||||
AZStd::string_view projectCacheRootOverrideKey(buffer);
|
||||
auto projectCacheRootOverrideKey = FixedValueString::format("%s/project_cache_path", BootstrapSettingsRootKey);
|
||||
// Clear path to make sure that the `project_cache_path` value isn't concatenated to the project path
|
||||
path.clear();
|
||||
if (registry.Get(path.Native(), projectCacheRootOverrideKey))
|
||||
@@ -576,14 +599,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,
|
||||
@@ -789,6 +830,11 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
++argumentIndex;
|
||||
commandLinePath.resize(commandLineRootSize);
|
||||
}
|
||||
|
||||
// This key is used allow Notification Handlers to know when the command line has been updated within the
|
||||
// registry. The value itself is meaningless. The JSON path of {CommandLineValueChangedKey}
|
||||
// being passed to the Notification Event Handler indicates that the command line has be updated
|
||||
registry.Set(CommandLineValueChangedKey, true);
|
||||
}
|
||||
|
||||
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
|
||||
@@ -805,10 +851,16 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
else if (valueName == "Value" && !value.empty())
|
||||
{
|
||||
m_arguments.push_back(value);
|
||||
// Make sure value types are in quotes in case they start with a command option prefix
|
||||
m_arguments.push_back(QuoteArgument(value));
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string QuoteArgument(AZStd::string_view arg)
|
||||
{
|
||||
return !arg.empty() ? AZStd::string::format(R"("%.*s")", aznumeric_cast<int>(arg.size()), arg.data()) : AZStd::string{ arg };
|
||||
}
|
||||
|
||||
// The first parameter is skipped by the ComamndLine::Parse function so initialize
|
||||
// the container with one empty element
|
||||
AZ::CommandLine::ParamContainer m_arguments{ 1 };
|
||||
@@ -986,4 +1038,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
|
||||
//! Root key for where command line are stored at within the settings registry
|
||||
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
|
||||
//! Key set to trigger a notification that the CommandLine has been stored within the settings registry
|
||||
//! The value of the key has no meaning. Notification Handlers only need to check if the key was supplied
|
||||
inline static constexpr char CommandLineValueChangedKey[] = "/Amazon/AzCore/Runtime/CommandLineChanged";
|
||||
|
||||
//! Root key where raw project settings (project.json) file is merged to settings registry
|
||||
inline static constexpr char ProjectSettingsRootKey[] = "/Amazon/Project/Settings";
|
||||
@@ -74,6 +77,20 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! If it's still not found, attempt to find the project (by similar means) then reconcile the
|
||||
//! engine root by inspecting project.json and the engine manifest file.
|
||||
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
|
||||
//! The algorithm that is used to find the project root is as follows
|
||||
//! 1. The first time this function is it performs a upward scan for a project.json file from
|
||||
//! the executable directory and if found stores that path to an internal key.
|
||||
//! In the same step it injects the path into the front of list of command line parameters
|
||||
//! using the --regset="{BootstrapSettingsRootKey}/project_path=<path>" value
|
||||
//! 2. Next the "{BootstrapSettingsRootKey}/project_path" is checked to see if it has a project path set
|
||||
//!
|
||||
//! The order in which the project path settings are overridden proceeds in the following order
|
||||
//! 1. project_path set in the <engine-root>/bootstrap.cfg file
|
||||
//! 2. project_path set in a *.setreg/*.setregpatch file
|
||||
//! 3. project_path found by scanning upwards from the executable directory to the project.json path
|
||||
//! 4. project_path set on the Command line via either --regset="{BootstrapSettingsRootKey}/project_path=<path>"
|
||||
//! or --project_path=<path>
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
|
||||
//! Query the specializations that will be used when loading the Settings Registry.
|
||||
@@ -256,4 +273,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.
|
||||
|
||||
@@ -505,6 +505,8 @@ set(FILES
|
||||
Serialization/Json/BasicContainerSerializer.cpp
|
||||
Serialization/Json/BoolSerializer.h
|
||||
Serialization/Json/BoolSerializer.cpp
|
||||
Serialization/Json/ByteStreamSerializer.h
|
||||
Serialization/Json/ByteStreamSerializer.cpp
|
||||
Serialization/Json/CastingHelpers.h
|
||||
Serialization/Json/DoubleSerializer.h
|
||||
Serialization/Json/DoubleSerializer.cpp
|
||||
@@ -605,6 +607,8 @@ set(FILES
|
||||
Utils/Utils.h
|
||||
Script/lua/lua.h
|
||||
Memory/HeapSchema.cpp
|
||||
PlatformId/PlatformDefaults.h
|
||||
PlatformId/PlatformDefaults.cpp
|
||||
PlatformId/PlatformId.h
|
||||
PlatformId/PlatformId.cpp
|
||||
Socket/AzSocket_fwd.h
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/Json/ByteStreamSerializer.h>
|
||||
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
|
||||
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
|
||||
|
||||
namespace JsonSerializationTests
|
||||
{
|
||||
class ByteStreamSerializerTestDescription : public JsonSerializerConformityTestDescriptor<AZ::JsonByteStream>
|
||||
{
|
||||
public:
|
||||
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
|
||||
{
|
||||
return AZStd::make_shared<AZ::JsonByteStreamSerializer>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AZ::JsonByteStream> CreateDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<AZ::JsonByteStream>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AZ::JsonByteStream> CreateFullySetInstance() override
|
||||
{
|
||||
// create a JsonByteStream (AZStd::vector<u8>) with ten 'a's
|
||||
return AZStd::make_shared<AZ::JsonByteStream>(10, 'a');
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForFullySetInstance() override
|
||||
{
|
||||
// Base64 encoded version of 'aaaaaaaaaa' (see CreateFullySetInstance)
|
||||
return R"("YWFhYWFhYWFhYQ==")";
|
||||
}
|
||||
|
||||
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
|
||||
{
|
||||
features.EnableJsonType(rapidjson::kStringType);
|
||||
features.m_supportsPartialInitialization = false;
|
||||
features.m_supportsInjection = false;
|
||||
}
|
||||
|
||||
bool AreEqual(const AZ::JsonByteStream& lhs, const AZ::JsonByteStream& rhs) override
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
using ByteStreamConformityTestTypes = ::testing::Types<ByteStreamSerializerTestDescription>;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(JsonByteStreamSerialzier, JsonSerializerConformityTests, ByteStreamConformityTestTypes);
|
||||
} // namespace JsonSerializationTests
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ set(FILES
|
||||
Serialization/Json/BaseJsonSerializerTests.cpp
|
||||
Serialization/Json/BasicContainerSerializerTests.cpp
|
||||
Serialization/Json/BoolSerializerTests.cpp
|
||||
Serialization/Json/ByteStreamSerializerTests.cpp
|
||||
Serialization/Json/ColorSerializerTests.cpp
|
||||
Serialization/Json/DoubleSerializerTests.cpp
|
||||
Serialization/Json/IntSerializerTests.cpp
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -617,9 +617,9 @@ namespace AzFramework
|
||||
// won't free the mutex until the load is complete.
|
||||
// So instead, queue the notification until the next tick, so that it doesn't occur within the AssetCatalogRequestBus mutex, and also
|
||||
// so that the entire AssetCatalog initialization is complete.
|
||||
AZ::TickBus::QueueFunction([catalogRegistryFile]()
|
||||
AZ::TickBus::QueueFunction([catalogRegistryString = AZStd::string(catalogRegistryFile)]()
|
||||
{
|
||||
AssetCatalogEventBus::Broadcast(&AssetCatalogEventBus::Events::OnCatalogLoaded, catalogRegistryFile);
|
||||
AssetCatalogEventBus::Broadcast(&AssetCatalogEventBus::Events::OnCatalogLoaded, catalogRegistryString.c_str());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <AzFramework/Components/NonUniformScaleComponent.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/Math/ToString.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
|
||||
@@ -81,13 +82,13 @@ namespace AzFramework
|
||||
|
||||
void NonUniformScaleComponent::SetScale(const AZ::Vector3& scale)
|
||||
{
|
||||
if (scale.GetMinElement() >= AZ::MinNonUniformScale)
|
||||
if (scale.GetMinElement() >= AZ::MinTransformScale && scale.GetMaxElement() <= AZ::MaxTransformScale)
|
||||
{
|
||||
m_scale = scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::Vector3 clampedScale = scale.GetMax(AZ::Vector3(AZ::MinNonUniformScale));
|
||||
AZ::Vector3 clampedScale = scale.GetClamp(AZ::Vector3(AZ::MinTransformScale), AZ::Vector3(AZ::MaxTransformScale));
|
||||
AZ_Warning("Non-uniform Scale Component", false, "SetScale value was clamped from %s to %s for entity %s",
|
||||
AZ::ToString(scale).c_str(), AZ::ToString(clampedScale).c_str(), GetEntity()->GetName().c_str());
|
||||
m_scale = clampedScale;
|
||||
|
||||
@@ -105,8 +105,6 @@ namespace AzFramework
|
||||
virtual bool SetDrawInFrontMode(bool bOn) { (void)bOn; return false; }
|
||||
virtual AZ::u32 GetState() { return 0; }
|
||||
virtual AZ::u32 SetState(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual AZ::u32 SetStateFlag(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual AZ::u32 ClearStateFlag(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual void PushMatrix(const AZ::Transform& tm) { (void)tm; }
|
||||
virtual void PopMatrix() {}
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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/RTTI/RTTI.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
using FontId = uint32_t;
|
||||
static constexpr FontId InvalidFontId = 0xffffffffu;
|
||||
|
||||
enum class TextHorizontalAlignment : uint16_t
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Center
|
||||
};
|
||||
|
||||
enum class TextVerticalAlignment : uint16_t
|
||||
{
|
||||
Top,
|
||||
Bottom,
|
||||
Center,
|
||||
};
|
||||
|
||||
//! Standard parameters for drawing text on screen
|
||||
struct TextDrawParameters
|
||||
{
|
||||
ViewportId m_drawViewportId = InvalidViewportId; //! Viewport to draw into
|
||||
AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d.
|
||||
AZ::Color m_color = AZ::Colors::White; //! Color to draw the text
|
||||
AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale
|
||||
TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment
|
||||
TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment
|
||||
bool m_monospace = false; //! disable character proportional spacing
|
||||
bool m_depthTest = false; //! Test character against the depth buffer
|
||||
bool m_virtual800x600ScreenSize = true; //! Text placement and size are scaled relative to a virtual 800x600 resolution
|
||||
bool m_scaleWithWindow = false; //! Font gets bigger as the window gets bigger
|
||||
bool m_multiline = true; //! text respects ascii newline characters
|
||||
};
|
||||
|
||||
class FontDrawInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(FontDrawInterface, "{545A7C14-CB3E-4A5B-B435-13EA606708EE}");
|
||||
|
||||
FontDrawInterface() = default;
|
||||
virtual ~FontDrawInterface() = default;
|
||||
|
||||
virtual void DrawScreenAlignedText2d(
|
||||
const TextDrawParameters& params,
|
||||
const AZStd::string_view& string) = 0;
|
||||
virtual void DrawScreenAlignedText3d(
|
||||
const TextDrawParameters& params,
|
||||
const AZStd::string_view& string) = 0;
|
||||
};
|
||||
|
||||
class FontQueryInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(FontQueryInterface, "{4BDD8520-EBC1-4680-B25E-421BDF31750F}");
|
||||
|
||||
FontQueryInterface() = default;
|
||||
virtual ~FontQueryInterface() = default;
|
||||
|
||||
FontId GetFontId(const AZStd::string_view& fontName) const {return FontId(AZ::Crc32(fontName));}
|
||||
virtual FontDrawInterface* GetFontDrawInterface(FontId) const = 0;
|
||||
virtual FontDrawInterface* GetDefaultFontDrawInterface() const = 0;
|
||||
|
||||
};
|
||||
} // namespace AzFramework
|
||||
@@ -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
|
||||
@@ -142,6 +142,7 @@ namespace Physics
|
||||
->Field("PhysicsAsset", &PhysicsAssetShapeConfiguration::m_asset)
|
||||
->Field("AssetScale", &PhysicsAssetShapeConfiguration::m_assetScale)
|
||||
->Field("UseMaterialsFromAsset", &PhysicsAssetShapeConfiguration::m_useMaterialsFromAsset)
|
||||
->Field("SubdivisionLevel", &PhysicsAssetShapeConfiguration::m_subdivisionLevel)
|
||||
;
|
||||
|
||||
if (auto editContext = serializeContext->GetEditContext())
|
||||
|
||||
@@ -141,6 +141,7 @@ namespace Physics
|
||||
AZ::Data::Asset<AZ::Data::AssetData> m_asset{ AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ::Vector3 m_assetScale = AZ::Vector3::CreateOne();
|
||||
bool m_useMaterialsFromAsset = true;
|
||||
AZ::u8 m_subdivisionLevel = 4; ///< The level of subdivision if a primitive shape is replaced with a convex mesh due to scaling.
|
||||
};
|
||||
|
||||
class NativeShapeConfiguration : public ShapeConfiguration
|
||||
|
||||
@@ -142,13 +142,6 @@ namespace Physics
|
||||
|
||||
virtual AZStd::shared_ptr<Shape> CreateShape(const ColliderConfiguration& colliderConfiguration, const ShapeConfiguration& configuration) = 0;
|
||||
|
||||
/// Adds an appropriate collider component to the entity based on the provided shape configuration.
|
||||
/// @param entity Entity where the component should be added to.
|
||||
/// @param colliderConfiguration Configuration of the collider.
|
||||
/// @param shapeConfiguration Configuration of the shape of the collider.
|
||||
/// @param addEditorComponents Tells whether to add the Editor version of the collider component or the Game one.
|
||||
virtual void AddColliderComponentToEntity(AZ::Entity* entity, const Physics::ColliderConfiguration& colliderConfiguration, const Physics::ShapeConfiguration& shapeConfiguration, bool addEditorComponents = false) = 0;
|
||||
|
||||
/// Releases the mesh object created by the physics backend.
|
||||
/// @param nativeMeshObject Pointer to the mesh object.
|
||||
virtual void ReleaseNativeMeshObject(void* nativeMeshObject) = 0;
|
||||
|
||||
@@ -1,338 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AzFramework::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AzFramework::PC:
|
||||
return "PC";
|
||||
case AzFramework::ES3:
|
||||
return "Android";
|
||||
case AzFramework::IOS:
|
||||
return "iOS";
|
||||
case AzFramework::OSX:
|
||||
return "Mac";
|
||||
case AzFramework::PROVO:
|
||||
return "Provo";
|
||||
case AzFramework::SALEM:
|
||||
return "Salem";
|
||||
case AzFramework::JASPER:
|
||||
return "Jasper";
|
||||
case AzFramework::SERVER:
|
||||
return "Server";
|
||||
case AzFramework::ALL:
|
||||
case AzFramework::ALL_CLIENT:
|
||||
case AzFramework::NumPlatformIds:
|
||||
case AzFramework::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if(platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if(checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,144 +12,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
// As the Platform defaults is needed within AzCore,
|
||||
// those structures have been moved to AzCore and brought into
|
||||
// The AzFramework namespace for backwards compatibility
|
||||
namespace AzFramework
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string<(AssetPlatformFixedString{}.max_size() + 1) * PlatformId::NumPlatformIds>;
|
||||
|
||||
const char* PlatformIdToPalFolder(AzFramework::PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
using namespace AZ::PlatformDefaults;
|
||||
}
|
||||
|
||||
#pragma pop_macro("IOS")
|
||||
|
||||
@@ -42,8 +42,14 @@ namespace AzFramework::ProjectManager
|
||||
AZ::CommandLine commandLine;
|
||||
commandLine.Parse(argc, argv);
|
||||
AZ::SettingsRegistryImpl settingsRegistry;
|
||||
// Store the Command line to the Setting Registry
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
// Retrieve Command Line from Settings Registry, it may have been updated by the call to FindEngineRoot()
|
||||
// in MergeSettingstoRegistry_ConfigFile
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(settingsRegistry, commandLine, false);
|
||||
engineRootPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(settingsRegistry);
|
||||
projectRootPath = AZ::SettingsRegistryMergeUtils::FindProjectRoot(settingsRegistry);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -133,6 +134,18 @@ namespace AzFramework
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
inline ScreenPoint ScreenPointFromNDC(const AZ::Vector3& screenNDC, const AZ::Vector2& viewportSize)
|
||||
{
|
||||
return ScreenPoint(
|
||||
aznumeric_caster(std::round(screenNDC.GetX() * viewportSize.GetX())),
|
||||
aznumeric_caster(std::round((1.0f - screenNDC.GetY()) * viewportSize.GetY())));
|
||||
}
|
||||
|
||||
inline AZ::Vector2 NDCFromScreenPoint(const ScreenPoint& screenPoint, const AZ::Vector2& viewportSize)
|
||||
{
|
||||
return AZ::Vector2(aznumeric_cast<float>(screenPoint.m_x), viewportSize.GetY() - aznumeric_cast<float>(screenPoint.m_y)) / viewportSize;
|
||||
}
|
||||
|
||||
//! Return an AZ::Vector2 from a ScreenPoint.
|
||||
inline AZ::Vector2 Vector2FromScreenPoint(const ScreenPoint& screenPoint)
|
||||
{
|
||||
|
||||
@@ -101,20 +101,25 @@ namespace AzFramework
|
||||
cameraState.m_nearClip, cameraState.m_farClip);
|
||||
}
|
||||
|
||||
ScreenPoint WorldToScreen(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection,
|
||||
const AZ::Vector2& viewportSize)
|
||||
AZ::Vector3 WorldToScreenNDC(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection)
|
||||
{
|
||||
// transform the world space position to clip space
|
||||
const auto clipSpacePosition = cameraProjection * cameraView * AZ::Vector3ToVector4(worldPosition, 1.0f);
|
||||
// transform the clip space position to ndc space (perspective divide)
|
||||
const auto ndcPosition = clipSpacePosition / clipSpacePosition.GetW();
|
||||
// transform ndc space from <-1,1> to <0, 1> range
|
||||
const auto ndcNormalizedPosition = (AZ::Vector4ToVector2(ndcPosition) + AZ::Vector2::CreateOne()) * 0.5f;
|
||||
return (AZ::Vector4ToVector3(ndcPosition) + AZ::Vector3::CreateOne()) * 0.5f;
|
||||
}
|
||||
|
||||
|
||||
ScreenPoint WorldToScreen(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection,
|
||||
const AZ::Vector2& viewportSize)
|
||||
{
|
||||
const auto ndcNormalizedPosition = WorldToScreenNDC(worldPosition, cameraView, cameraProjection);
|
||||
// scale ndc position by screen dimensions to return screen position
|
||||
return ScreenPoint(
|
||||
aznumeric_caster(std::round(ndcNormalizedPosition.GetX() * viewportSize.GetX())),
|
||||
aznumeric_caster(std::round(viewportSize.GetY() - (ndcNormalizedPosition.GetY() * viewportSize.GetY()))));
|
||||
return ScreenPointFromNDC(ndcNormalizedPosition, viewportSize);
|
||||
}
|
||||
|
||||
ScreenPoint WorldToScreen(const AZ::Vector3& worldPosition, const CameraState& cameraState)
|
||||
@@ -127,12 +132,8 @@ namespace AzFramework
|
||||
const ScreenPoint& screenPosition, const AZ::Matrix4x4& inverseCameraView,
|
||||
const AZ::Matrix4x4& inverseCameraProjection, const AZ::Vector2& viewportSize)
|
||||
{
|
||||
const auto screenHeight = viewportSize.GetY();
|
||||
const auto flippedScreenPosition =
|
||||
AZ::Vector2(aznumeric_caster(screenPosition.m_x), aznumeric_caster(screenHeight - screenPosition.m_y));
|
||||
|
||||
// convert screen space coordinates to <-1,1> range
|
||||
const auto ndcPosition = (flippedScreenPosition / viewportSize) * 2.0f - AZ::Vector2::CreateOne();
|
||||
// convert screen space coordinates from <0, 1> to <-1,1> range
|
||||
const auto ndcPosition = NDCFromScreenPoint(screenPosition, viewportSize) * 2.0f - AZ::Vector2::CreateOne();
|
||||
|
||||
// transform ndc space position to clip space
|
||||
const auto clipSpacePosition = inverseCameraProjection * Vector2ToVector4(ndcPosition, -1.0f, 1.0f);
|
||||
|
||||
@@ -28,6 +28,11 @@ namespace AzFramework
|
||||
struct ScreenPoint;
|
||||
struct ViewportInfo;
|
||||
|
||||
//! Projects a position in world space to screen space normalized device coordinates for the given camera.
|
||||
AZ::Vector3 WorldToScreenNDC(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection);
|
||||
|
||||
|
||||
//! Projects a position in world space to screen space for the given camera.
|
||||
ScreenPoint WorldToScreen(const AZ::Vector3& worldPosition, const CameraState& cameraState);
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -145,6 +145,7 @@ set(FILES
|
||||
Components/NonUniformScaleComponent.cpp
|
||||
FileFunc/FileFunc.h
|
||||
FileFunc/FileFunc.cpp
|
||||
Font/FontInterface.h
|
||||
Gem/GemInfo.cpp
|
||||
Gem/GemInfo.h
|
||||
StringFunc/StringFunc.h
|
||||
@@ -316,7 +317,6 @@ set(FILES
|
||||
Terrain/TerrainDataRequestBus.h
|
||||
Terrain/TerrainDataRequestBus.cpp
|
||||
Platform/PlatformDefaults.h
|
||||
Platform/PlatformDefaults.cpp
|
||||
Windowing/WindowBus.h
|
||||
Windowing/NativeWindow.cpp
|
||||
Windowing/NativeWindow.h
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -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()
|
||||
{
|
||||
|
||||
+1
-1
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -80,6 +80,8 @@ namespace AzGameFramework
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList GameApplication::GetRequiredSystemComponents() const
|
||||
@@ -108,7 +110,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;
|
||||
|
||||
@@ -114,6 +114,9 @@ namespace AzNetworking
|
||||
void ClearUnusedBits();
|
||||
|
||||
ContainerType m_container;
|
||||
|
||||
template <AZStd::size_t, typename>
|
||||
friend class FixedSizeVectorBitset;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -192,19 +192,11 @@ namespace AzNetworking
|
||||
template <AZStd::size_t CAPACITY, typename ElementType>
|
||||
inline void FixedSizeVectorBitset<CAPACITY, ElementType>::ClearUnusedBits()
|
||||
{
|
||||
constexpr ElementType AllOnes = static_cast<ElementType>(~0);
|
||||
const ElementType LastUsedBits = (GetSize() % BitsetType::ElementTypeBits);
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4293) // shift count negative or too big, undefined behaviour
|
||||
#pragma warning(disable : 6326) // constant constant comparison
|
||||
const ElementType ShiftAmount = (LastUsedBits == 0) ? 0 : BitsetType::ElementTypeBits - LastUsedBits;
|
||||
const ElementType ClearBitMask = AllOnes >> ShiftAmount;
|
||||
#pragma warning(pop)
|
||||
uint32_t usedElementSize = (GetSize() + BitsetType::ElementTypeBits - 1) / BitsetType::ElementTypeBits;
|
||||
for (uint32_t i = usedElementSize + 1; i < CAPACITY; ++i)
|
||||
for (uint32_t i = usedElementSize + 1; i < BitsetType::ElementCount; ++i)
|
||||
{
|
||||
m_bitset.GetContainer()[i] = 0;
|
||||
}
|
||||
m_bitset.GetContainer()[m_bitset.GetContainer().size() - 1] &= ClearBitMask;
|
||||
m_bitset.ClearUnusedBits();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ namespace AzNetworking
|
||||
value.StoreToFloat3(values);
|
||||
serializer.Serialize(values[0], "xValue");
|
||||
serializer.Serialize(values[1], "yValue");
|
||||
serializer.Serialize(values[1], "zValue");
|
||||
serializer.Serialize(values[2], "zValue");
|
||||
value = AZ::Vector3::CreateFromFloat3(values);
|
||||
return serializer.IsValid();
|
||||
}
|
||||
@@ -285,8 +285,8 @@ namespace AzNetworking
|
||||
value.StoreToFloat4(values);
|
||||
serializer.Serialize(values[0], "xValue");
|
||||
serializer.Serialize(values[1], "yValue");
|
||||
serializer.Serialize(values[1], "zValue");
|
||||
serializer.Serialize(values[1], "wValue");
|
||||
serializer.Serialize(values[2], "zValue");
|
||||
serializer.Serialize(values[3], "wValue");
|
||||
value = AZ::Vector4::CreateFromFloat4(values);
|
||||
return serializer.IsValid();
|
||||
}
|
||||
@@ -301,8 +301,8 @@ namespace AzNetworking
|
||||
value.StoreToFloat4(values);
|
||||
serializer.Serialize(values[0], "xValue");
|
||||
serializer.Serialize(values[1], "yValue");
|
||||
serializer.Serialize(values[1], "zValue");
|
||||
serializer.Serialize(values[1], "wValue");
|
||||
serializer.Serialize(values[2], "zValue");
|
||||
serializer.Serialize(values[3], "wValue");
|
||||
value = AZ::Quaternion::CreateFromFloat4(values);
|
||||
return serializer.IsValid();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user