Merge branch 'main' into non-uniform-scale-mesh

This commit is contained in:
greerdv
2021-04-19 11:05:10 +01:00
296 changed files with 5966 additions and 2949 deletions
@@ -178,14 +178,16 @@ namespace AZ
//! 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)
{
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)
@@ -194,6 +196,7 @@ namespace AZ
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)
@@ -201,6 +204,12 @@ namespace AZ
{
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
@@ -233,10 +242,16 @@ namespace AZ
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
void UpdateCommandLine()
{
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(m_registry, m_commandLine);
}
private:
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)
@@ -415,6 +430,12 @@ namespace AZ
// Add the Command Line arguments into the SettingsRegistry
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
// 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);
@@ -429,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, {});
@@ -909,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)
@@ -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>;
@@ -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())
{
@@ -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")
@@ -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
@@ -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,18 +500,6 @@ 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);
}
@@ -501,9 +526,10 @@ namespace AZ::SettingsRegistryMergeUtils
// 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);
// Use the platform codename to retrieve the default asset platform value
SettingsRegistryInterface::FixedValueString assetPlatform = AZ::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
if (!registry.Get(assetPlatform, assetPlatformKey))
{
buffer = AZStd::fixed_string<bufferSize>::format("%s/assets", BootstrapSettingsRootKey);
@@ -807,6 +833,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)
@@ -823,10 +854,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 };
@@ -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.
@@ -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
@@ -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
@@ -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